/* Send a packet to a specific mac address and ip address by creating our own ip packet */ static void send_packet_to_client(struct dhcp_packet *dhcp_pkt, int force_broadcast) { const uint8_t *chaddr; uint32_t ciaddr; // Was: //if (force_broadcast) { /* broadcast */ } //else if (dhcp_pkt->ciaddr) { /* unicast to dhcp_pkt->ciaddr */ } //else if (dhcp_pkt->flags & htons(BROADCAST_FLAG)) { /* broadcast */ } //else { /* unicast to dhcp_pkt->yiaddr */ } // But this is wrong: yiaddr is _our_ idea what client's IP is // (for example, from lease file). Client may not know that, // and may not have UDP socket listening on that IP! // We should never unicast to dhcp_pkt->yiaddr! // dhcp_pkt->ciaddr, OTOH, comes from client's request packet, // and can be used. if (force_broadcast || (dhcp_pkt->flags & htons(BROADCAST_FLAG)) || dhcp_pkt->ciaddr == 0 ) { log1("Broadcasting packet to client"); ciaddr = INADDR_BROADCAST; chaddr = MAC_BCAST_ADDR; } else { log1("Unicasting packet to client ciaddr"); ciaddr = dhcp_pkt->ciaddr; chaddr = dhcp_pkt->chaddr; } udhcp_send_raw_packet(dhcp_pkt, /*src*/ server_config.server_nip, SERVER_PORT, /*dst*/ ciaddr, CLIENT_PORT, chaddr, server_config.ifindex); }
/* send a packet to a specific arp address and ip address by creating our own ip packet */ static int send_packet_to_client(struct dhcpMessage *payload, int force_broadcast) { const uint8_t *chaddr; uint32_t ciaddr; if (force_broadcast) { DEBUG("broadcasting packet to client (NAK)"); ciaddr = INADDR_BROADCAST; chaddr = MAC_BCAST_ADDR; } else if (payload->ciaddr) { DEBUG("unicasting packet to client ciaddr"); ciaddr = payload->ciaddr; chaddr = payload->chaddr; } else if (payload->flags & htons(BROADCAST_FLAG)) { DEBUG("broadcasting packet to client (requested)"); ciaddr = INADDR_BROADCAST; chaddr = MAC_BCAST_ADDR; } else { DEBUG("unicasting packet to client yiaddr"); ciaddr = payload->yiaddr; chaddr = payload->chaddr; } return udhcp_send_raw_packet(payload, /*src*/ server_config.server, SERVER_PORT, /*dst*/ ciaddr, CLIENT_PORT, chaddr, server_config.ifindex); }