static int __do_arp_validate(struct arp_handle *handle) { ni_capture_devinfo_t dev_info; int ret; if ((ret = __do_arp_validate_init(handle, &dev_info)) != 0) return ret; handle->sock = ni_arp_socket_open(&dev_info, __do_arp_validate_process, handle); if (!handle->sock || !handle->sock->user_data) { ni_error("%s: Cannot initialize arp socket", handle->ifname); __do_arp_handle_close(handle); return NI_LSB_RC_ERROR; } if (!__do_arp_validate_send(handle)) { __do_arp_handle_close(handle); ni_error("%s: Cannot send arp packet", handle->ifname); return NI_LSB_RC_ERROR; } ret = NI_WICKED_RC_ERROR; while (!ni_caught_terminal_signal()) { long timeout; ret = NI_LSB_RC_SUCCESS; timeout = ni_timer_next_timeout(); if (ni_socket_wait(timeout) != 0) break; ret = NI_WICKED_RC_ERROR; } if (handle->timer) { ni_timer_cancel(handle->timer); handle->timer = NULL; } __do_arp_handle_close(handle); return handle->hwaddr.len ? NI_LSB_RC_NOT_ALLOWED : ret; }
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; }