udhcpc broadcast flag

Keith Young stripydog7 at gmail.com
Wed Feb 9 12:23:11 UTC 2011


Correct me if I'm wrong, but there doesn't appear to be a way to tell
the udhcp client to set the broadcast flag in dhcp discover/request
packets. There are some situations (especially with virtualized guest
machines sharing the host's hardware address on a network link) where
a packet (Layer 2) unicast by a dhcp server to the address in the
chaddr field will never been seen by the intended recipient.

dhclient and dhcpcd both have options to set the broadcast flag which
forces dhcp servers to broadcast replies.

Below is the hack I used to add an option to set the broadcast flag in
udhcpc. It added 44 bytes to my stripped busybox binary and may be
better implemented differently or as a config option.

I think such an option is worth considering: Busybox is fantastic for
making compact "Virtual Appliances".  If nothing else, this caters for
the case where a VMwhere guest machine has an interface "bridged" onto
a host's wireless interface and the dhcp server is on a separate
physical machine.

Keith

diff -uNrp udhcp.orig/dhcpc.c udhcp/dhcpc.c
--- udhcp.orig/dhcpc.c  2011-02-01 15:05:48.000000000 +0000
+++ udhcp/dhcpc.c       2011-02-07 13:11:53.000000000 +0000
@@ -391,6 +391,10 @@ static void add_client_options(struct dh
        if (client_config.fqdn)
                udhcp_add_binary_option(packet, client_config.fqdn);

+       /* Request broadcast replies if required */
+       if (client_config.need_broadcast && packet->ciaddr == 0)
+               packet->flags |= htons(BROADCAST_FLAG);
+
        /* Add -x options if any */
        {
                struct option_set *curr = client_config.options;
@@ -849,7 +853,7 @@ static void client_background(void)
 //usage:# define IF_UDHCP_VERBOSE(...)
 //usage:#endif
 //usage:#define udhcpc_trivial_usage
-//usage:       "[-fbnq"IF_UDHCP_VERBOSE("v")"oCR] [-i IFACE] [-r IP]
[-s PROG] [-p PIDFILE]\n"
+//usage:       "[-fbnq"IF_UDHCP_VERBOSE("v")"oCRB] [-i IFACE] [-r IP]
[-s PROG] [-p PIDFILE]\n"
 //usage:       "       [-H HOSTNAME] [-V VENDOR] [-x OPT:VAL]... [-O
OPT]..." IF_FEATURE_UDHCP_PORT(" [-P N]")
 //usage:#define udhcpc_full_usage "\n"
 //usage:       IF_LONG_OPTS(
@@ -860,6 +864,7 @@ static void client_background(void)
 //usage:     "\n       -T,--timeout N          Pause between packets
(default 3 seconds)"
 //usage:     "\n       -A,--tryagain N         Wait N seconds after
failure (default 20)"
 //usage:     "\n       -f,--foreground         Run in foreground"
+//usage:     "\n       -B,--broadcast          Set the BROADCAST flag"
 //usage:       USE_FOR_MMU(
 //usage:     "\n       -b,--background         Background if lease is
not obtained"
 //usage:       )
@@ -897,6 +902,7 @@ static void client_background(void)
 //usage:     "\n       -T N            Pause between packets (default
3 seconds)"
 //usage:     "\n       -A N            Wait N seconds (default 20)
after failure"
 //usage:     "\n       -f              Run in foreground"
+//usage:     "\n       -B              Set the BROADCAST flag"
 //usage:       USE_FOR_MMU(
 //usage:     "\n       -b              Background if lease is not obtained"
 //usage:       )
@@ -975,6 +981,7 @@ int udhcpc_main(int argc UNUSED_PARAM, c
                "no-default-options\0" No_argument   "o"
                "foreground\0"     No_argument       "f"
                "background\0"     No_argument       "b"
+               "broadcast\0"      No_argument       "B"
                IF_FEATURE_UDHCPC_ARPING("arping\0"     No_argument       "a")
                IF_FEATURE_UDHCP_PORT("client-port\0"   Required_argument "P")
                ;
@@ -1000,8 +1007,9 @@ int udhcpc_main(int argc UNUSED_PARAM, c
                OPT_o = 1 << 17,
                OPT_x = 1 << 18,
                OPT_f = 1 << 19,
+               OPT_B = 1 << 20,
 /* The rest has variable bit positions, need to be clever */
-               OPTBIT_f = 19,
+               OPTBIT_B = 20,
                USE_FOR_MMU(             OPTBIT_b,)
                IF_FEATURE_UDHCPC_ARPING(OPTBIT_a,)
                IF_FEATURE_UDHCP_PORT(   OPTBIT_P,)
@@ -1015,6 +1023,7 @@ int udhcpc_main(int argc UNUSED_PARAM, c
        IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;)
        client_config.interface = "eth0";
        client_config.script = CONFIG_UDHCPC_DEFAULT_SCRIPT;
+       client_config.need_broadcast = 0;
        str_V = "udhcp "BB_VER;

        /* Parse command line */
@@ -1025,7 +1034,7 @@ int udhcpc_main(int argc UNUSED_PARAM, c
 #endif
                ;
        IF_LONG_OPTS(applet_long_options = udhcpc_longopts;)
-       opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:f"
+       opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:fB"
                USE_FOR_MMU("b")
                IF_FEATURE_UDHCPC_ARPING("a")
                IF_FEATURE_UDHCP_PORT("P:")
@@ -1114,6 +1123,9 @@ int udhcpc_main(int argc UNUSED_PARAM, c
                logmode |= LOGMODE_SYSLOG;
        }

+       if (opt & OPT_B)
+               client_config.need_broadcast = 1;
+
        /* Make sure fd 0,1,2 are open */
        bb_sanitize_stdio();
        /* Equivalent of doing a fflush after every \n */
diff -uNrp udhcp.orig/dhcpc.h udhcp/dhcpc.h
--- udhcp.orig/dhcpc.h  2011-02-01 16:42:30.000000000 +0000
+++ udhcp/dhcpc.h       2011-02-01 16:42:37.000000000 +0000
@@ -21,6 +21,7 @@ struct client_config_t {
        uint8_t *vendorclass;           /* Optional vendor class-id to use */
        uint8_t *hostname;              /* Optional hostname to use */
        uint8_t *fqdn;                  /* Optional fully qualified
domain name to use */
+       char need_broadcast;            /* Set Broadcast flag on
DISCOVER and REQUEST packets */
 } FIX_ALIASING;

 /* server_config sits in 1st half of bb_common_bufsiz1 */


More information about the busybox mailing list