return -1;
}
+void
+arp_report_conflicted(const struct arp_state *astate, const struct arp_msg *amsg)
+{
+ char buf[HWADDR_LEN * 3];
+
+ syslog(LOG_ERR, "%s: hardware address %s claims %s",
+ astate->iface->name,
+ hwaddr_ntoa(amsg->sha, astate->iface->hwlen, buf, sizeof(buf)),
+ inet_ntoa(astate->failed));
+}
+
static void
arp_packet(void *arg)
{
/* Run the conflicts */
TAILQ_FOREACH_SAFE(astate, &state->arp_states, next, astaten) {
- astate->conflicted_cb(astate, &arm);
+ if (astate->conflicted_cb)
+ astate->conflicted_cb(astate, &arm);
}
}
}
struct in_addr addr;
int probes;
int claims;
+ struct in_addr failed;
};
TAILQ_HEAD(arp_statehead, arp_state);
+void arp_report_conflicted(const struct arp_state *, const struct arp_msg *);
void arp_announce(struct arp_state *);
void arp_probe(struct arp_state *);
struct arp_state *arp_new(struct interface *);
(amsg->sip.s_addr == 0 &&
amsg->tip.s_addr == ifo->arping[state->arping_index - 1])))
{
- struct in_addr addr;
char buf[HWADDR_LEN * 3];
- addr.s_addr = ifo->arping[state->arping_index - 1];
- syslog(LOG_INFO,
- "%s: found %s on hardware address %s",
- astate->iface->name, inet_ntoa(addr),
- hwaddr_ntoa(amsg->sha, astate->iface->hwlen,
- buf, sizeof(buf)));
+ astate->failed.s_addr = ifo->arping[state->arping_index - 1];
+ arp_report_conflicted(astate, amsg);
+ hwaddr_ntoa(amsg->sha, astate->iface->hwlen, buf, sizeof(buf));
if (dhcpcd_selectprofile(astate->iface, buf) == -1 &&
- dhcpcd_selectprofile(astate->iface, inet_ntoa(addr)) == -1)
+ dhcpcd_selectprofile(astate->iface,
+ inet_ntoa(astate->failed)) == -1)
{
/* We didn't find a profile for this
* address or hwaddr, so move to the next
if (amsg->sip.s_addr == state->offer->yiaddr ||
(amsg->sip.s_addr == 0 && amsg->tip.s_addr == state->offer->yiaddr))
{
- struct in_addr fail;
- char buf[HWADDR_LEN * 3];
-
- fail.s_addr = state->offer->yiaddr;
- syslog(LOG_ERR, "%s: hardware address %s claims %s",
- astate->iface->name,
- hwaddr_ntoa(amsg->sha, astate->iface->hwlen,
- buf, sizeof(buf)),
- inet_ntoa(fail));
-
- arp_free(astate);
+ astate->failed.s_addr = state->offer->yiaddr;
+ arp_report_conflicted(astate, amsg);
unlink(state->leasefile);
if (!state->lease.frominfo)
dhcp_decline(astate->iface);
eloop_timeout_delete(astate->iface->ctx->eloop, NULL,
astate->iface);
- if (state->lease.frominfo)
- dhcpcd_startinterface(astate->iface);
- else
- eloop_timeout_add_sec(astate->iface->ctx->eloop,
- DHCP_ARP_FAIL,
- dhcpcd_startinterface, astate->iface);
+ eloop_timeout_add_sec(astate->iface->ctx->eloop,
+ DHCP_RAND_MAX, dhcp_discover, astate->iface);
}
}
#define DHCP_MAX 64
#define DHCP_RAND_MIN -1
#define DHCP_RAND_MAX 1
-#define DHCP_ARP_FAIL 2
#ifdef RFC2131_STRICT
/* Be strictly conformant for section 4.1.1 */
unsigned int conflicts;
time_t defend;
char randomstate[128];
- struct in_addr failed;
};
#define D_STATE(ifp) \
* See ipv4ll_start for why we don't use arc4_random. */
addr = ntohl(LINKLOCAL_ADDR | ((random() % 0xFD00) + 0x0100));
- state = D_CSTATE(astate->iface);
/* No point using a failed address */
- if (addr == state->failed.s_addr)
+ if (addr == astate->failed.s_addr)
continue;
+ state = D_CSTATE(astate->iface);
/* Ensure we don't have the address on another interface */
TAILQ_FOREACH(ifp, astate->iface->ctx->ifaces, next) {
state = D_CSTATE(ifp);
ipv4ll_conflicted(struct arp_state *astate, const struct arp_msg *amsg)
{
struct dhcp_state *state = D_STATE(astate->iface);
- uint32_t fail;
- char buf[HWADDR_LEN * 3];
+ in_addr_t fail;
if (state->offer == NULL)
return;
if (fail == 0)
return;
- state->failed.s_addr = fail;
- syslog(LOG_ERR, "%s: hardware address %s claims %s",
- astate->iface->name,
- hwaddr_ntoa(amsg->sha, astate->iface->hwlen, buf, sizeof(buf)),
- inet_ntoa(state->failed));
+ astate->failed.s_addr = fail;
+ arp_report_conflicted(astate, amsg);
- if (state->failed.s_addr == state->addr.s_addr) {
+ if (astate->failed.s_addr == state->addr.s_addr) {
time_t up;
/* RFC 3927 Section 2.5 */