diff options
-rw-r--r-- | src/dhcp.c | 45 |
1 files changed, 25 insertions, 20 deletions
@@ -376,10 +376,9 @@ void dhcp_packet(time_t now, int pxe_fd) } } #if defined(HAVE_LINUX_NETWORK) - else if ((ntohs(mess->flags) & 0x8000) || mess->hlen == 0 || - mess->hlen > sizeof(ifr.ifr_addr.sa_data) || mess->htype == 0) + else { - /* broadcast to 255.255.255.255 (or mac address invalid) */ + /* fill cmsg for outbound interface (both broadcast & unicast) */ struct in_pktinfo *pkt; msg.msg_control = control_u.control; msg.msg_controllen = sizeof(control_u); @@ -389,23 +388,29 @@ void dhcp_packet(time_t now, int pxe_fd) pkt->ipi_spec_dst.s_addr = 0; msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); cmptr->cmsg_level = IPPROTO_IP; - cmptr->cmsg_type = IP_PKTINFO; - dest.sin_addr.s_addr = INADDR_BROADCAST; - dest.sin_port = htons(daemon->dhcp_client_port); - } - else - { - /* unicast to unconfigured client. Inject mac address direct into ARP cache. - struct sockaddr limits size to 14 bytes. */ - dest.sin_addr = mess->yiaddr; - dest.sin_port = htons(daemon->dhcp_client_port); - memcpy(&arp_req.arp_pa, &dest, sizeof(struct sockaddr_in)); - arp_req.arp_ha.sa_family = mess->htype; - memcpy(arp_req.arp_ha.sa_data, mess->chaddr, mess->hlen); - /* interface name already copied in */ - arp_req.arp_flags = ATF_COM; - if (ioctl(daemon->dhcpfd, SIOCSARP, &arp_req) == -1) - my_syslog(MS_DHCP | LOG_ERR, _("ARP-cache injection failed: %s"), strerror(errno)); + cmptr->cmsg_type = IP_PKTINFO; + + if ((ntohs(mess->flags) & 0x8000) || mess->hlen == 0 || + mess->hlen > sizeof(ifr.ifr_addr.sa_data) || mess->htype == 0) + { + /* broadcast to 255.255.255.255 (or mac address invalid) */ + dest.sin_addr.s_addr = INADDR_BROADCAST; + dest.sin_port = htons(daemon->dhcp_client_port); + } + else + { + /* unicast to unconfigured client. Inject mac address direct into ARP cache. + struct sockaddr limits size to 14 bytes. */ + dest.sin_addr = mess->yiaddr; + dest.sin_port = htons(daemon->dhcp_client_port); + memcpy(&arp_req.arp_pa, &dest, sizeof(struct sockaddr_in)); + arp_req.arp_ha.sa_family = mess->htype; + memcpy(arp_req.arp_ha.sa_data, mess->chaddr, mess->hlen); + /* interface name already copied in */ + arp_req.arp_flags = ATF_COM; + if (ioctl(daemon->dhcpfd, SIOCSARP, &arp_req) == -1) + my_syslog(MS_DHCP | LOG_ERR, _("ARP-cache injection failed: %s"), strerror(errno)); + } } #elif defined(HAVE_SOLARIS_NETWORK) else if ((ntohs(mess->flags) & 0x8000) || mess->hlen != ETHER_ADDR_LEN || mess->htype != ARPHRD_ETHER) |