aboutsummaryrefslogtreecommitdiff
path: root/networking/udhcp/dhcpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/udhcp/dhcpc.c')
-rw-r--r--networking/udhcp/dhcpc.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index 99d91bf70..55f21c187 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -1,7 +1,6 @@
1/* vi: set sw=4 ts=4: */ 1/* vi: set sw=4 ts=4: */
2/* 2/*
3 * udhcp client 3 * udhcp client
4 *
5 * Russ Dill <Russ.Dill@asu.edu> July 2001 4 * Russ Dill <Russ.Dill@asu.edu> July 2001
6 * 5 *
7 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
@@ -694,10 +693,16 @@ static int raw_bcast_from_client_config_ifindex(struct dhcp_packet *packet, uint
694 693
695static int bcast_or_ucast(struct dhcp_packet *packet, uint32_t ciaddr, uint32_t server) 694static int bcast_or_ucast(struct dhcp_packet *packet, uint32_t ciaddr, uint32_t server)
696{ 695{
697 if (server) 696 if (server) {
697 /* Without MSG_DONTROUTE, the packet was seen routed over
698 * _other interface_ if server ID is bogus (example: 1.1.1.1).
699 */
698 return udhcp_send_kernel_packet(packet, 700 return udhcp_send_kernel_packet(packet,
699 ciaddr, CLIENT_PORT, 701 ciaddr, CLIENT_PORT,
700 server, SERVER_PORT); 702 server, SERVER_PORT,
703 /*send_flags: "to hosts only on directly connected networks" */ MSG_DONTROUTE
704 );
705 }
701 return raw_bcast_from_client_config_ifindex(packet, ciaddr); 706 return raw_bcast_from_client_config_ifindex(packet, ciaddr);
702} 707}
703 708
@@ -735,7 +740,7 @@ static NOINLINE int send_discover(uint32_t xid, uint32_t requested)
735static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requested) 740static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requested)
736{ 741{
737 struct dhcp_packet packet; 742 struct dhcp_packet packet;
738 struct in_addr addr; 743 struct in_addr temp_addr;
739 744
740/* 745/*
741 * RFC 2131 4.3.2 DHCPREQUEST message 746 * RFC 2131 4.3.2 DHCPREQUEST message
@@ -766,8 +771,8 @@ static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requeste
766 */ 771 */
767 add_client_options(&packet); 772 add_client_options(&packet);
768 773
769 addr.s_addr = requested; 774 temp_addr.s_addr = requested;
770 bb_error_msg("sending select for %s", inet_ntoa(addr)); 775 bb_error_msg("sending select for %s", inet_ntoa(temp_addr));
771 return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); 776 return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY);
772} 777}
773 778
@@ -776,6 +781,7 @@ static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requeste
776static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr) 781static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr)
777{ 782{
778 struct dhcp_packet packet; 783 struct dhcp_packet packet;
784 struct in_addr temp_addr;
779 785
780/* 786/*
781 * RFC 2131 4.3.2 DHCPREQUEST message 787 * RFC 2131 4.3.2 DHCPREQUEST message
@@ -806,7 +812,8 @@ static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr)
806 */ 812 */
807 add_client_options(&packet); 813 add_client_options(&packet);
808 814
809 bb_error_msg("sending %s", "renew"); 815 temp_addr.s_addr = server;
816 bb_error_msg("sending renew to %s", inet_ntoa(temp_addr));
810 return bcast_or_ucast(&packet, ciaddr, server); 817 return bcast_or_ucast(&packet, ciaddr, server);
811} 818}
812 819
@@ -1010,9 +1017,14 @@ static int udhcp_raw_socket(int ifindex)
1010 */ 1017 */
1011 log2("got raw socket fd"); 1018 log2("got raw socket fd");
1012 1019
1020 memset(&sock, 0, sizeof(sock)); /* let's be deterministic */
1013 sock.sll_family = AF_PACKET; 1021 sock.sll_family = AF_PACKET;
1014 sock.sll_protocol = htons(ETH_P_IP); 1022 sock.sll_protocol = htons(ETH_P_IP);
1015 sock.sll_ifindex = ifindex; 1023 sock.sll_ifindex = ifindex;
1024 /*sock.sll_hatype = ARPHRD_???;*/
1025 /*sock.sll_pkttype = PACKET_???;*/
1026 /*sock.sll_halen = ???;*/
1027 /*sock.sll_addr[8] = ???;*/
1016 xbind(fd, (struct sockaddr *) &sock, sizeof(sock)); 1028 xbind(fd, (struct sockaddr *) &sock, sizeof(sock));
1017 1029
1018#if 0 /* Several users reported breakage when BPF filter is used */ 1030#if 0 /* Several users reported breakage when BPF filter is used */
@@ -1519,11 +1531,24 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1519 * Anyway, it does recover by eventually failing through 1531 * Anyway, it does recover by eventually failing through
1520 * into INIT_SELECTING state. 1532 * into INIT_SELECTING state.
1521 */ 1533 */
1522 send_renew(xid, server_addr, requested_ip); 1534 if (send_renew(xid, server_addr, requested_ip) >= 0) {
1523 timeout >>= 1; 1535 timeout >>= 1;
1524 continue; 1536//TODO: the timeout to receive an answer for our renew should not be selected
1537//with "timeout = lease_seconds / 2; ...; timeout = timeout / 2": it is often huge.
1538//Waiting e.g. 4*3600 seconds for a reply does not make sense
1539//(if reply isn't coming, we keep an open socket for hours),
1540//it should be something like 10 seconds.
1541//Also, it's probably best to try sending renew in kernel mode a few (3-5) times
1542//and fall back to raw mode if it does not work.
1543 continue;
1544 }
1545 /* else: error sending.
1546 * example: ENETUNREACH seen with server
1547 * which gave us bogus server ID 1.1.1.1
1548 * which wasn't reachable (and probably did not exist).
1549 */
1525 } 1550 }
1526 /* Timed out, enter rebinding state */ 1551 /* Timed out or error, enter rebinding state */
1527 log1("entering rebinding state"); 1552 log1("entering rebinding state");
1528 state = REBINDING; 1553 state = REBINDING;
1529 /* fall right through */ 1554 /* fall right through */
@@ -1605,7 +1630,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1605 len = udhcp_recv_raw_packet(&packet, sockfd); 1630 len = udhcp_recv_raw_packet(&packet, sockfd);
1606 if (len == -1) { 1631 if (len == -1) {
1607 /* Error is severe, reopen socket */ 1632 /* Error is severe, reopen socket */
1608 bb_error_msg("read error: %s, reopening socket", strerror(errno)); 1633 bb_error_msg("read error: "STRERROR_FMT", reopening socket" STRERROR_ERRNO);
1609 sleep(discover_timeout); /* 3 seconds by default */ 1634 sleep(discover_timeout); /* 3 seconds by default */
1610 change_listen_mode(listen_mode); /* just close and reopen */ 1635 change_listen_mode(listen_mode); /* just close and reopen */
1611 } 1636 }