int ni_dhcp4_fsm_arp_validate(ni_dhcp4_device_t *dev) { struct in_addr null = { 0 }; struct in_addr claim; if (!dev || !dev->lease) return -1; claim = dev->lease->dhcp4.address; if (dev->arp.handle == NULL) { dev->arp.handle = ni_arp_socket_open(&dev->system, ni_dhcp4_fsm_process_arp_packet, dev); if (!dev->arp.handle->user_data) { ni_error("%s: unable to create ARP handle", dev->ifname); return -1; } } if (dev->arp.nprobes) { ni_debug_dhcp("%s: arp validate: probing for %s", dev->ifname, inet_ntoa(claim)); ni_arp_send_request(dev->arp.handle, null, claim); dev->arp.nprobes--; } else if (dev->arp.nclaims) { ni_debug_dhcp("%s: arp validate: claiming %s", dev->ifname, inet_ntoa(claim)); ni_arp_send_grat_request(dev->arp.handle, claim); dev->arp.nclaims--; } else { /* Wow, we're done! */ ni_info("%s: Successfully validated DHCPv4 address %s", dev->ifname, inet_ntoa(claim)); ni_dhcp4_fsm_commit_lease(dev, dev->lease); ni_dhcp4_device_arp_close(dev); return 0; } ni_dhcp4_fsm_set_timeout_msec(dev, NI_DHCP4_ARP_TIMEOUT); return 0; }
static ni_bool_t __do_arp_validate_send(struct arp_handle *handle) { struct in_addr null = { 0 }; ni_bool_t ret = FALSE; if (!handle->hwaddr.len && handle->nprobes) { ni_debug_application("%s: arp validate: probing for %s", handle->ifname, ni_sockaddr_print(&handle->ipaddr)); handle->nprobes--; handle->replies = TRUE; if ((ret = ni_arp_send_request(handle->sock, null, handle->ipaddr.sin.sin_addr) > 0)) { __do_arp_validate_arm_timer(handle); } } else if (!handle->hwaddr.len && handle->nclaims) { ni_debug_application("%s: arp validate: claiming %s use", handle->ifname, ni_sockaddr_print(&handle->ipaddr)); handle->nclaims--; handle->replies = FALSE; if ((ret = ni_arp_send_grat_request(handle->sock, handle->ipaddr.sin.sin_addr) > 0)) { if (handle->nclaims) { __do_arp_validate_arm_timer(handle); } else if (handle->sock) { __do_arp_handle_close(handle); } } } return ret; }