diff options
Diffstat (limited to 'networking/udhcp/packet.c')
-rw-r--r-- | networking/udhcp/packet.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/networking/udhcp/packet.c b/networking/udhcp/packet.c index 5137464..4d8e005 100644 --- a/networking/udhcp/packet.c +++ b/networking/udhcp/packet.c @@ -189,7 +189,8 @@ int FAST_FUNC udhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt, /* Let the kernel do all the work for packet generation */ int FAST_FUNC udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt, uint32_t source_nip, int source_port, - uint32_t dest_nip, int dest_port) + uint32_t dest_nip, int dest_port, + const char *ifname) { struct sockaddr_in sa; unsigned padding; @@ -204,6 +205,21 @@ int FAST_FUNC udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt, } setsockopt_reuseaddr(fd); + /* If interface carrier goes down, unless we + * bind socket to a particular netdev, the packet + * can go out through another interface, eg. via + * default route despite being bound to a specific + * source IP. As such, bind to device hard and fail + * otherwise. Sending renewal packets on foreign + * interfaces makes no sense. + */ + if (ifname) { + if (setsockopt_bindtodevice(fd, ifname) < 0) { + msg = "bindtodevice"; + goto ret_close; + } + } + memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_port = htons(source_port); |