static void
handle_arp_failure(struct interface *iface)
{
- if (IN_LINKLOCAL(htonl(iface->state->fail.s_addr))) {
+ if (iface->state->offer->cookie != htonl(MAGIC_COOKIE)) {
handle_ipv4ll_failure(iface);
return;
}
add_timeout_sec(ANNOUNCE_WAIT, send_arp_announce, iface);
return;
}
- if (IN_LINKLOCAL(htonl(state->new->yiaddr))) {
+ if (state->new->cookie != htonl(MAGIC_COOKIE)) {
/* We should pretend to be at the end
* of the DHCP negotation cycle unless we rebooted */
if (state->interval != 0)
lease->leasetime = ~0U;
lease->net.s_addr = ifo->req_mask.s_addr;
state->reason = "STATIC";
- } else if (IN_LINKLOCAL(htonl(state->new->yiaddr))) {
+ } else if (state->new->cookie != htonl(MAGIC_COOKIE)) {
syslog(LOG_INFO, "%s: using IPv4LL address %s",
iface->name, inet_ntoa(lease->addr));
lease->leasetime = ~0U;
m = (uint8_t *)dhcp;
p = dhcp->options;
- if ((type == DHCP_INFORM ||
- type == DHCP_RELEASE ||
- type == DHCP_REQUEST) &&
- !IN_LINKLOCAL(ntohl(iface->addr.s_addr)))
+ if ((type == DHCP_INFORM || type == DHCP_RELEASE ||
+ (type == DHCP_REQUEST &&
+ iface->net.s_addr == lease->net.s_addr &&
+ (iface->state->new == NULL ||
+ iface->state->new->cookie == htonl(MAGIC_COOKIE)))))
{
dhcp->ciaddr = iface->addr.s_addr;
/* In-case we haven't actually configured the address yet */
if (type == DHCP_INFORM && iface->addr.s_addr == 0)
dhcp->ciaddr = lease->addr.s_addr;
- /* Zero the address if we're currently on a different subnet */
- if (type == DHCP_REQUEST &&
- iface->net.s_addr != lease->net.s_addr)
- dhcp->ciaddr = 0;
}
dhcp->op = DHCP_BOOTREQUEST;
p += iface->clientid[0] + 1;
}
- if (lease->addr.s_addr && !IN_LINKLOCAL(htonl(lease->addr.s_addr))) {
+ if (lease->addr.s_addr && lease->cookie == htonl(MAGIC_COOKIE)) {
if (type == DHCP_DECLINE ||
type == DHCP_DISCOVER ||
(type == DHCP_REQUEST &&
{
struct timeval now;
+ lease->cookie = dhcp->cookie;
/* BOOTP does not set yiaddr for replies when ciaddr is set. */
if (dhcp->yiaddr)
lease->addr.s_addr = dhcp->yiaddr;
time_t leasedfrom;
struct timeval boundtime;
uint8_t frominfo;
+ uint32_t cookie;
};
#include "dhcpcd.h"
{
lease->frominfo = 0;
lease->addr.s_addr = dhcp->yiaddr;
+ lease->cookie = dhcp->cookie;
if (type == 0 ||
get_option_addr(&lease->server, dhcp, DHO_SERVERID) != 0)
lease->server.s_addr = INADDR_ANY;
{
struct timespec ts;
- if (iface->state->lease.addr.s_addr &&
- !IN_LINKLOCAL(htonl(iface->state->lease.addr.s_addr)))
+ if (iface->state->new != NULL &&
+ iface->state->new->cookie == htonl(MAGIC_COOKIE))
{
syslog(LOG_INFO, "%s: releasing lease of %s",
iface->name, inet_ntoa(iface->state->lease.addr));
start_static(iface);
return;
}
- if (ifo->reboot == 0) {
+ if (ifo->reboot == 0 || iface->state->offer == NULL) {
start_discover(iface);
return;
}
- if (IN_LINKLOCAL(htonl(iface->state->lease.addr.s_addr))) {
+ if (ifo->options & DHCPCD_INFORM) {
+ syslog(LOG_INFO, "%s: informing address of %s",
+ iface->name, inet_ntoa(iface->state->lease.addr));
+ } else if (iface->state->offer->cookie == 0) {
if (ifo->options & DHCPCD_IPV4LL) {
iface->state->claims = 0;
send_arp_announce(iface);
} else
start_discover(iface);
return;
- }
- if (ifo->options & DHCPCD_INFORM) {
- syslog(LOG_INFO, "%s: informing address of %s",
- iface->name, inet_ntoa(iface->state->lease.addr));
} else {
syslog(LOG_INFO, "%s: rebinding lease of %s",
iface->name, inet_ntoa(iface->state->lease.addr));
if (iface->state->offer) {
get_lease(&iface->state->lease, iface->state->offer);
iface->state->lease.frominfo = 1;
- if (IN_LINKLOCAL(htonl(iface->state->offer->yiaddr))) {
+ if (iface->state->offer->cookie == 0) {
if (iface->state->offer->yiaddr ==
iface->addr.s_addr)
{
}
}
}
- if (!iface->state->offer)
+ if (iface->state->offer == NULL)
start_discover(iface);
- else if (IN_LINKLOCAL(htonl(iface->state->lease.addr.s_addr)) &&
+ else if (iface->state->offer->cookie == 0 &&
iface->state->options->options & DHCPCD_IPV4LL)
start_ipv4ll(iface);
else
return 1;
/* If we are either, they neither have a lease, or they both have.
* We need to check for IPv4LL and make it non-preferred. */
- if (si->state->new) {
- sill = IN_LINKLOCAL(htonl(si->state->new->yiaddr));
- till = IN_LINKLOCAL(htonl(ti->state->new->yiaddr));
+ if (si->state->new && ti->state->new) {
+ sill = (si->state->new->cookie == htonl(MAGIC_COOKIE));
+ till = (ti->state->new->cookie == htonl(MAGIC_COOKIE));
if (!sill && till)
return -1;
if (sill && !till)
iface->state->offer = make_ipv4ll_lease(0);
iface->state->lease.frominfo = 0;
}
+ /* Ensure we don't have a cookie */
+ iface->state->offer->cookie = 0;
send_arp_probe(iface);
}