ntpd: let user know if spike was detected
[oweals/busybox.git] / networking / udhcp / dhcpc.c
index ca31e1cb82e0e3d4e2a9841070efa2a12a40539e..8dee916d9892cdb6d2eb249916109a8ccff9478c 100644 (file)
@@ -667,6 +667,15 @@ static int raw_bcast_from_client_config_ifindex(struct dhcp_packet *packet)
                client_config.ifindex);
 }
 
+static int bcast_or_ucast(struct dhcp_packet *packet, uint32_t ciaddr, uint32_t server)
+{
+       if (server)
+               return udhcp_send_kernel_packet(packet,
+                       ciaddr, CLIENT_PORT,
+                       server, SERVER_PORT);
+       return raw_bcast_from_client_config_ifindex(packet);
+}
+
 /* Broadcast a DHCP discover packet to the network, with an optionally requested IP */
 /* NOINLINE: limit stack usage in caller */
 static NOINLINE int send_discover(uint32_t xid, uint32_t requested)
@@ -773,11 +782,7 @@ static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr)
        add_client_options(&packet);
 
        bb_info_msg("Sending renew...");
-       if (server)
-               return udhcp_send_kernel_packet(&packet,
-                       ciaddr, CLIENT_PORT,
-                       server, SERVER_PORT);
-       return raw_bcast_from_client_config_ifindex(&packet);
+       return bcast_or_ucast(&packet, ciaddr, server);
 }
 
 #if ENABLE_FEATURE_UDHCPC_ARPING
@@ -826,7 +831,11 @@ static int send_release(uint32_t server, uint32_t ciaddr)
        udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server);
 
        bb_info_msg("Sending release...");
-       return udhcp_send_kernel_packet(&packet, ciaddr, CLIENT_PORT, server, SERVER_PORT);
+       /* Note: normally we unicast here since "server" is not zero.
+        * However, there _are_ people who run "address-less" DHCP servers,
+        * and reportedly ISC dhcp client and Windows allow that.
+        */
+       return bcast_or_ucast(&packet, ciaddr, server);
 }
 
 /* Returns -1 on errors that are fatal for the socket, -2 for those that aren't */
@@ -1135,18 +1144,21 @@ static void client_background(void)
 //usage:# define IF_UDHCP_VERBOSE(...)
 //usage:#endif
 //usage:#define udhcpc_trivial_usage
-//usage:       "[-fbq"IF_UDHCP_VERBOSE("v")IF_FEATURE_UDHCPC_ARPING("a")"oCRB] [-t N] [-T SEC] [-A SEC/-n]\n"
-//usage:       "       [-i IFACE]"IF_FEATURE_UDHCP_PORT(" [-P PORT]")" [-r IP] [-s PROG] [-p PIDFILE]\n"
-//usage:       "       [-V VENDOR] [-x OPT:VAL]... [-O OPT]..."
+//usage:       "[-fbq"IF_UDHCP_VERBOSE("v")IF_FEATURE_UDHCPC_ARPING("a")"RB] [-t N] [-T SEC] [-A SEC/-n]\n"
+//usage:       "       [-i IFACE]"IF_FEATURE_UDHCP_PORT(" [-P PORT]")" [-s PROG] [-p PIDFILE]\n"
+//usage:       "       [-oC] [-r IP] [-V VENDOR] [-F NAME] [-x OPT:VAL]... [-O OPT]..."
 //usage:#define udhcpc_full_usage "\n"
 //usage:       IF_LONG_OPTS(
 //usage:     "\n       -i,--interface IFACE    Interface to use (default eth0)"
-//usage:     "\n       -p,--pidfile FILE       Create pidfile"
+//usage:       IF_FEATURE_UDHCP_PORT(
+//usage:     "\n       -P,--client-port PORT   Use PORT (default 68)"
+//usage:       )
 //usage:     "\n       -s,--script PROG        Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")"
+//usage:     "\n       -p,--pidfile FILE       Create pidfile"
 //usage:     "\n       -B,--broadcast          Request broadcast replies"
 //usage:     "\n       -t,--retries N          Send up to N discover packets (default 3)"
 //usage:     "\n       -T,--timeout SEC        Pause between packets (default 3)"
-//usage:     "\n       -A,--tryagain SEC       Wait after failure (default 20)"
+//usage:     "\n       -A,--tryagain SEC       Wait if lease is not obtained (default 20)"
 //usage:     "\n       -n,--now                Exit if lease is not obtained"
 //usage:     "\n       -q,--quit               Exit after obtaining lease"
 //usage:     "\n       -R,--release            Release IP on exit"
@@ -1155,15 +1167,12 @@ static void client_background(void)
 //usage:     "\n       -b,--background         Background if lease is not obtained"
 //usage:       )
 //usage:     "\n       -S,--syslog             Log to syslog too"
-//usage:       IF_FEATURE_UDHCP_PORT(
-//usage:     "\n       -P,--client-port PORT   Use PORT (default 68)"
-//usage:       )
 //usage:       IF_FEATURE_UDHCPC_ARPING(
 //usage:     "\n       -a,--arping             Use arping to validate offered address"
 //usage:       )
-//usage:     "\n       -O,--request-option OPT Request option OPT from server (cumulative)"
-//usage:     "\n       -o,--no-default-options Don't request any options (unless -O is given)"
 //usage:     "\n       -r,--request IP         Request this IP address"
+//usage:     "\n       -o,--no-default-options Don't request any options (unless -O is given)"
+//usage:     "\n       -O,--request-option OPT Request option OPT from server (cumulative)"
 //usage:     "\n       -x OPT:VAL              Include option OPT in sent packets (cumulative)"
 //usage:     "\n                               Examples of string, numeric, and hex byte opts:"
 //usage:     "\n                               -x hostname:bbox - option 12"
@@ -1178,12 +1187,15 @@ static void client_background(void)
 //usage:       )
 //usage:       IF_NOT_LONG_OPTS(
 //usage:     "\n       -i IFACE        Interface to use (default eth0)"
-//usage:     "\n       -p FILE         Create pidfile"
+//usage:       IF_FEATURE_UDHCP_PORT(
+//usage:     "\n       -P PORT         Use PORT (default 68)"
+//usage:       )
 //usage:     "\n       -s PROG         Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")"
+//usage:     "\n       -p FILE         Create pidfile"
 //usage:     "\n       -B              Request broadcast replies"
 //usage:     "\n       -t N            Send up to N discover packets (default 3)"
 //usage:     "\n       -T SEC          Pause between packets (default 3)"
-//usage:     "\n       -A SEC          Wait after failure (default 20)"
+//usage:     "\n       -A SEC          Wait if lease is not obtained (default 20)"
 //usage:     "\n       -n              Exit if lease is not obtained"
 //usage:     "\n       -q              Exit after obtaining lease"
 //usage:     "\n       -R              Release IP on exit"
@@ -1192,15 +1204,12 @@ static void client_background(void)
 //usage:     "\n       -b              Background if lease is not obtained"
 //usage:       )
 //usage:     "\n       -S              Log to syslog too"
-//usage:       IF_FEATURE_UDHCP_PORT(
-//usage:     "\n       -P PORT         Use PORT (default 68)"
-//usage:       )
 //usage:       IF_FEATURE_UDHCPC_ARPING(
 //usage:     "\n       -a              Use arping to validate offered address"
 //usage:       )
-//usage:     "\n       -O OPT          Request option OPT from server (cumulative)"
-//usage:     "\n       -o              Don't request any options (unless -O is given)"
 //usage:     "\n       -r IP           Request this IP address"
+//usage:     "\n       -o              Don't request any options (unless -O is given)"
+//usage:     "\n       -O OPT          Request option OPT from server (cumulative)"
 //usage:     "\n       -x OPT:VAL      Include option OPT in sent packets (cumulative)"
 //usage:     "\n                       Examples of string, numeric, and hex byte opts:"
 //usage:     "\n                       -x hostname:bbox - option 12"
@@ -1648,14 +1657,19 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
  * might work too.
  * "Next server" and router are definitely wrong ones to use, though...
  */
+/* We used to ignore pcakets without DHCP_SERVER_ID.
+ * I've got user reports from people who run "address-less" servers.
+ * They either supply DHCP_SERVER_ID of 0.0.0.0 or don't supply it at all.
+ * They say ISC DHCP client supports this case.
+ */
+                               server_addr = 0;
                                temp = udhcp_get_option(&packet, DHCP_SERVER_ID);
                                if (!temp) {
-                                       bb_error_msg("no server ID, ignoring packet");
-                                       continue;
-                                       /* still selecting - this server looks bad */
+                                       bb_error_msg("no server ID, using 0.0.0.0");
+                               } else {
+                                       /* it IS unaligned sometimes, don't "optimize" */
+                                       move_from_unaligned32(server_addr, temp);
                                }
-                               /* it IS unaligned sometimes, don't "optimize" */
-                               move_from_unaligned32(server_addr, temp);
                                /*xid = packet.xid; - already is */
                                requested_ip = packet.yiaddr;