if (!p)
return -1;
- *i = *(p);
+ if (i)
+ *i = *(p);
return 0;
}
if ((type == DHCP_INFORM ||
type == DHCP_RELEASE ||
type == DHCP_REQUEST) &&
- !IN_LINKLOCAL(ntohl(iface->addr.s_addr)))
+ !IN_LINKLOCAL(ntohl(iface->addr.s_addr)))
{
dhcp->ciaddr = iface->addr.s_addr;
/* Just incase we haven't actually configured the address yet */
uint8_t l;
uint8_t o = 0;
+ /* We don't write BOOTP leases */
+ if (is_bootp(dhcp)) {
+ unlink(iface->leasefile);
+ return 0;
+ }
+
fd = open(iface->leasefile, O_WRONLY | O_CREAT | O_TRUNC, 0400);
if (fd == -1)
return -1;
tv.tv_sec = state->interval + DHCP_RAND_MIN;
tv.tv_usec = arc4random() % (DHCP_RAND_MAX_U - DHCP_RAND_MIN_U);
syslog(LOG_DEBUG,
- "%s: sending %s with xid 0x%x, next in %0.2f seconds",
+ "%s: sending %s (xid 0x%x), next in %0.2f seconds",
iface->name, get_dhcp_op(type), state->xid,
timeval_to_double(&tv));
}
/* If we couldn't open a UDP port for our IP address
* then we cannot renew.
- * This could happen if our IP was pulled out from underneath us. */
- if (iface->udp_fd == -1) {
+ * This could happen if our IP was pulled out from underneath us.
+ * Also, we should not unicast from a BOOTP lease. */
+ if (iface->udp_fd == -1 || is_bootp(iface->state->new)) {
a = iface->addr.s_addr;
iface->addr.s_addr = 0;
}
len = make_message(&dhcp, iface, type);
- if (iface->udp_fd == -1)
+ if (a)
iface->addr.s_addr = a;
from.s_addr = dhcp->ciaddr;
if (from.s_addr)
drop_config(iface, "EXPIRE");
unlink(iface->leasefile);
iface->state->interval = 0;
- if (iface->carrier != LINK_DOWN) {
- if (IN_LINKLOCAL(htonl(iface->state->lease.addr.s_addr)))
- start_interface(iface);
- else
- start_ipv4ll(iface);
- }
+ if (iface->carrier != LINK_DOWN)
+ start_interface(iface);
}
void
}
close_sockets(iface);
- free(state->offer);
- state->offer = dhcp;
- *dhcpp = NULL;
+ /* BOOTP could have already assigned this above, so check we still
+ * have a pointer. */
+ if (*dhcpp) {
+ free(state->offer);
+ state->offer = dhcp;
+ *dhcpp = NULL;
+ }
/* Delete all timeouts for this interface. */
delete_timeout(NULL, iface);
lease->frominfo = 0;
}
iface->start_uptime = uptime();
+ free(iface->state->offer);
+ iface->state->offer = NULL;
+
if (options & DHCPCD_TEST) {
start_discover(iface);
return;
int get_option_uint32(uint32_t *, const struct dhcp_message *, uint8_t);
int get_option_uint16(uint16_t *, const struct dhcp_message *, uint8_t);
int get_option_uint8(uint8_t *, const struct dhcp_message *, uint8_t);
+#define is_bootp(m) (m && get_option_uint8(NULL, m, DHO_MESSAGETYPE) == -1)
struct rt *get_option_routes(const struct dhcp_message *);
ssize_t configure_env(char **, const char *, const struct dhcp_message *,
const struct if_options *);