diff options
| -rw-r--r-- | networking/udhcp/common.h | 3 | ||||
| -rw-r--r-- | networking/udhcp/dhcpc.c | 3 | ||||
| -rw-r--r-- | networking/udhcp/dhcpd.c | 3 | ||||
| -rw-r--r-- | networking/udhcp/packet.c | 18 |
4 files changed, 23 insertions, 4 deletions
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index 3cbd2d3c8..cc0abd269 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h | |||
| @@ -343,7 +343,8 @@ int udhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt, | |||
| 343 | 343 | ||
| 344 | int udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt, | 344 | int udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt, |
| 345 | uint32_t source_nip, int source_port, | 345 | uint32_t source_nip, int source_port, |
| 346 | uint32_t dest_nip, int dest_port) FAST_FUNC; | 346 | uint32_t dest_nip, int dest_port, |
| 347 | const char *ifname) FAST_FUNC; | ||
| 347 | 348 | ||
| 348 | void udhcp_sp_setup(void) FAST_FUNC; | 349 | void udhcp_sp_setup(void) FAST_FUNC; |
| 349 | void udhcp_sp_fd_set(struct pollfd *pfds, int extra_fd) FAST_FUNC; | 350 | void udhcp_sp_fd_set(struct pollfd *pfds, int extra_fd) FAST_FUNC; |
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 66aa38c20..98720b45b 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
| @@ -702,7 +702,8 @@ static int bcast_or_ucast(struct dhcp_packet *packet, uint32_t ciaddr, uint32_t | |||
| 702 | if (server) | 702 | if (server) |
| 703 | return udhcp_send_kernel_packet(packet, | 703 | return udhcp_send_kernel_packet(packet, |
| 704 | ciaddr, CLIENT_PORT, | 704 | ciaddr, CLIENT_PORT, |
| 705 | server, SERVER_PORT); | 705 | server, SERVER_PORT, |
| 706 | client_data.interface); | ||
| 706 | return raw_bcast_from_client_data_ifindex(packet, ciaddr); | 707 | return raw_bcast_from_client_data_ifindex(packet, ciaddr); |
| 707 | } | 708 | } |
| 708 | 709 | ||
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index de16cf955..9e950ca1f 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c | |||
| @@ -612,7 +612,8 @@ static void send_packet_to_relay(struct dhcp_packet *dhcp_pkt) | |||
| 612 | 612 | ||
| 613 | udhcp_send_kernel_packet(dhcp_pkt, | 613 | udhcp_send_kernel_packet(dhcp_pkt, |
| 614 | server_data.server_nip, SERVER_PORT, | 614 | server_data.server_nip, SERVER_PORT, |
| 615 | dhcp_pkt->gateway_nip, SERVER_PORT); | 615 | dhcp_pkt->gateway_nip, SERVER_PORT, |
| 616 | server_data.interface); | ||
| 616 | } | 617 | } |
| 617 | 618 | ||
| 618 | static void send_packet(struct dhcp_packet *dhcp_pkt, int force_broadcast) | 619 | static void send_packet(struct dhcp_packet *dhcp_pkt, int force_broadcast) |
diff --git a/networking/udhcp/packet.c b/networking/udhcp/packet.c index 51374646d..4d8e005d4 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, | |||
| 189 | /* Let the kernel do all the work for packet generation */ | 189 | /* Let the kernel do all the work for packet generation */ |
| 190 | int FAST_FUNC udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt, | 190 | int FAST_FUNC udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt, |
| 191 | uint32_t source_nip, int source_port, | 191 | uint32_t source_nip, int source_port, |
| 192 | uint32_t dest_nip, int dest_port) | 192 | uint32_t dest_nip, int dest_port, |
| 193 | const char *ifname) | ||
| 193 | { | 194 | { |
| 194 | struct sockaddr_in sa; | 195 | struct sockaddr_in sa; |
| 195 | unsigned padding; | 196 | unsigned padding; |
| @@ -204,6 +205,21 @@ int FAST_FUNC udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt, | |||
| 204 | } | 205 | } |
| 205 | setsockopt_reuseaddr(fd); | 206 | setsockopt_reuseaddr(fd); |
| 206 | 207 | ||
| 208 | /* If interface carrier goes down, unless we | ||
| 209 | * bind socket to a particular netdev, the packet | ||
| 210 | * can go out through another interface, eg. via | ||
| 211 | * default route despite being bound to a specific | ||
| 212 | * source IP. As such, bind to device hard and fail | ||
| 213 | * otherwise. Sending renewal packets on foreign | ||
| 214 | * interfaces makes no sense. | ||
| 215 | */ | ||
| 216 | if (ifname) { | ||
| 217 | if (setsockopt_bindtodevice(fd, ifname) < 0) { | ||
| 218 | msg = "bindtodevice"; | ||
| 219 | goto ret_close; | ||
| 220 | } | ||
| 221 | } | ||
| 222 | |||
| 207 | memset(&sa, 0, sizeof(sa)); | 223 | memset(&sa, 0, sizeof(sa)); |
| 208 | sa.sin_family = AF_INET; | 224 | sa.sin_family = AF_INET; |
| 209 | sa.sin_port = htons(source_port); | 225 | sa.sin_port = htons(source_port); |
