udhcpc: add -o "do not request options by default" switch
authorDenis Vlasenko <vda.linux@googlemail.com>
Wed, 2 Apr 2008 13:04:19 +0000 (13:04 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Wed, 2 Apr 2008 13:04:19 +0000 (13:04 -0000)
(by L. Gabriel Somlo <somlo AT cmu.edu>)

function                                             old     new   delta
udhcpc_main                                         2513    2554     +41
static.udhcpc_longopts                               226     247     +21
add_param_req_option                                 119     132     +13
packed_usage                                       23952   23964     +12
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/0 up/down: 87/0)               Total: 87 bytes

include/usage.h
networking/ifupdown.c
networking/udhcp/clientpacket.c
networking/udhcp/dhcpc.c
networking/udhcp/dhcpc.h
networking/udhcp/files.c

index 3be317bfffbeb436dc077beb4a1a41062615c7f1..529a228ec88f118f412fe22c70bde5d9eaf3c741 100644 (file)
        "Adjust filesystem options on ext[23] filesystems"
 
 #define udhcpc_trivial_usage \
-       "[-Cfbnqtv] [-c CID] [-V VCLS] [-H HOSTNAME] [-i INTERFACE]\n" \
+       "[-Cfbnqtvo] [-c CID] [-V VCLS] [-H HOSTNAME] [-i INTERFACE]\n" \
        "       [-p pidfile] [-r IP] [-s script] [-O dhcp-option]..." USE_FEATURE_UDHCP_PORT(" [-P N]")
 #define udhcpc_full_usage \
        USE_GETOPT_LONG( \
      "\n       -C,--clientid-none      Suppress default client identifier" \
      "\n       -p,--pidfile=file       Create pidfile" \
      "\n       -r,--request=IP         IP address to request" \
-     "\n       -s,--script=file        Run file at dhcp events (default /usr/share/udhcpc/default.script)" \
+     "\n       -s,--script=file        Run file at DHCP events (default "CONFIG_DHCPC_DEFAULT_SCRIPT")" \
      "\n       -t,--retries=N          Send up to N request packets" \
      "\n       -T,--timeout=N          Try to get a lease for N seconds (default 3)" \
      "\n       -A,--tryagain=N         Wait N seconds (default 20) after failure" \
+     "\n       -O,--request-option=OPT Request DHCP option OPT (cumulative)" \
+     "\n       -o,--no-default-options Do not request any options (unless -O is also given)" \
      "\n       -f,--foreground Run in foreground" \
      "\n       -b,--background Background if lease is not immediately obtained" \
      "\n       -S,--syslog     Log to syslog too" \
      "\n       -n,--now        Exit with failure if lease is not immediately obtained" \
      "\n       -q,--quit       Quit after obtaining lease" \
      "\n       -R,--release    Release IP on quit" \
-     "\n       -O,--request-option=OPT Request DHCP option OPT from server" \
        USE_FEATURE_UDHCP_PORT( \
      "\n       -P,--client-port N  Use port N instead of default 68" \
        ) \
      "\n       -C              Suppress default client identifier" \
      "\n       -p file         Create pidfile" \
      "\n       -r IP           IP address to request" \
-     "\n       -s file         Run file at dhcp events (default /usr/share/udhcpc/default.script)" \
+     "\n       -s file         Run file at DHCP events (default "CONFIG_DHCPC_DEFAULT_SCRIPT")" \
      "\n       -t N            Send up to N request packets" \
      "\n       -T N            Try to get a lease for N seconds (default 3)" \
      "\n       -A N            Wait N seconds (default 20) after failure" \
+     "\n       -O OPT          Request DHCP option OPT (cumulative)" \
+     "\n       -o              Do not request any options (unless -O is also given)" \
      "\n       -f              Run in foreground" \
      "\n       -b              Background if lease is not immediately obtained" \
      "\n       -S              Log to syslog too" \
      "\n       -n              Exit with failure if lease is not immediately obtained" \
      "\n       -q              Quit after obtaining lease" \
      "\n       -R              Release IP on quit" \
-     "\n       -O OPT          Request DHCP option OPT from server" \
        USE_FEATURE_UDHCP_PORT( \
      "\n       -P N            Use port N instead of default 68" \
        ) \
index 7c31448e8b5cf839b56bbdce5a35f122ae2a5f8a..50b96261b7fb44736910feb83bfb59112e0e1a70 100644 (file)
@@ -476,7 +476,8 @@ static const struct dhcp_client_t ext_dhcp_clients[] = {
                "pump -i %iface% -k",
        },
        { "udhcpc",
-               "udhcpc -R -n -p /var/run/udhcpc.%iface%.pid -i %iface%[[ -H %hostname%]][[ -c %clientid%]][[ -s %script%]][[ -t %retries%]]",
+               "udhcpc -R -n -p /var/run/udhcpc.%iface%.pid -i %iface%[[ -H %hostname%]][[ -c %clientid%]]"
+                               "[[ -s %script%]][[ %udhcpc_opts%]]",
                "kill `cat /var/run/udhcpc.%iface%.pid` 2>/dev/null",
        },
 };
@@ -507,7 +508,7 @@ static int dhcp_up(struct interface_defn_t *ifd, execfn *exec)
                return 0;
 #endif
        return execute("udhcpc -R -n -p /var/run/udhcpc.%iface%.pid "
-                       "-i %iface%[[ -H %hostname%]][[ -c %clientid%]][[ -s %script%]][[ -t %retries%]]",
+                       "-i %iface%[[ -H %hostname%]][[ -c %clientid%]][[ -s %script%]][[ %udhcpc_opts%]]",
                        ifd, exec);
 }
 #else
index 29d0d9a1d7a12a2c9618ec504d4bc915404599be..f826c1b949e4671a7eaaa3a6260f1e96ab992286 100644 (file)
@@ -62,17 +62,20 @@ static void add_param_req_option(struct dhcpMessage *packet)
        int end = end_option(packet->options);
        int i, len = 0;
 
-       packet->options[end + OPT_CODE] = DHCP_PARAM_REQ;
        for (i = 0; (c = dhcp_options[i].code) != 0; i++) {
-               if ((dhcp_options[i].flags & OPTION_REQ)
+               if (((dhcp_options[i].flags & OPTION_REQ)
+                     && !client_config.no_default_options)
                 || (client_config.opt_mask[c >> 3] & (1 << (c & 7)))
                ) {
                        packet->options[end + OPT_DATA + len] = c;
                        len++;
                }
        }
-       packet->options[end + OPT_LEN] = len;
-       packet->options[end + OPT_DATA + len] = DHCP_END;
+       if (len) {
+               packet->options[end + OPT_CODE] = DHCP_PARAM_REQ;
+               packet->options[end + OPT_LEN] = len;
+               packet->options[end + OPT_DATA + len] = DHCP_END;
+       }
 }
 
 
@@ -107,7 +110,9 @@ int send_discover(uint32_t xid, uint32_t requested)
        /* Explicitly saying that we want RFC-compliant packets helps
         * some buggy DHCP servers to NOT send bigger packets */
        add_simple_option(packet.options, DHCP_MAX_SIZE, htons(576));
+
        add_param_req_option(&packet);
+
        bb_info_msg("Sending discover...");
        return udhcp_send_raw_packet(&packet, INADDR_ANY, CLIENT_PORT, INADDR_BROADCAST,
                        SERVER_PORT, MAC_BCAST_ADDR, client_config.ifindex);
@@ -125,8 +130,8 @@ int send_selecting(uint32_t xid, uint32_t server, uint32_t requested)
 
        add_simple_option(packet.options, DHCP_REQUESTED_IP, requested);
        add_simple_option(packet.options, DHCP_SERVER_ID, server);
-
        add_param_req_option(&packet);
+
        addr.s_addr = requested;
        bb_info_msg("Sending select for %s...", inet_ntoa(addr));
        return udhcp_send_raw_packet(&packet, INADDR_ANY, CLIENT_PORT, INADDR_BROADCAST,
index bc067615229e036871a5fe70e2e06235f1f66dca..fb328cb030e796158cf0473ff7d463fb72930f99 100644 (file)
@@ -182,6 +182,7 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv)
                OPT_W = 1 << 21,
 #endif
                OPT_P = 1 << 22,
+               OPT_o = 1 << 23,
        };
 #if ENABLE_GETOPT_LONG
        static const char udhcpc_longopts[] ALIGN1 =
@@ -211,6 +212,7 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv)
 #if ENABLE_FEATURE_UDHCP_PORT
                "client-port\0"    Required_argument "P"
 #endif
+               "no-default-options\0" No_argument   "o"
                ;
 #endif
        /* Default options. */
@@ -230,7 +232,7 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv)
        opt = getopt32(argv, "c:CV:fbH:h:F:i:np:qRr:s:T:t:vSA:"
                USE_FEATURE_UDHCPC_ARPING("aW:")
                USE_FEATURE_UDHCP_PORT("P:")
-               "O:"
+               "O:o"
                , &str_c, &str_V, &str_h, &str_h, &str_F
                , &client_config.interface, &client_config.pidfile, &str_r
                , &client_config.script
@@ -291,6 +293,8 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv)
                SERVER_PORT = CLIENT_PORT - 1;
        }
 #endif
+       if (opt & OPT_o)
+               client_config.no_default_options = 1;
        while (list_O) {
                int n = index_in_strings(dhcp_option_strings, list_O->data);
                if (n < 0)
index d0fde73022ed30186fd7b079a50ac9e8fa3f6a57..c8acd498237efe01f33e02c1b4bf357cd0a8d91a 100644 (file)
@@ -21,6 +21,7 @@ struct client_config_t {
        char release_on_quit;           /* Perform release on quit */
        char abort_if_no_lease;         /* Abort if no lease */
        char background_if_no_lease;    /* Fork to background if no lease */
+       char no_default_options;        /* Do not include default optins in request */
        const char *interface;          /* The name of the interface to use */
        char *pidfile;                  /* Optionally store the process ID */
        const char *script;             /* User script to run at dhcp events */
index 6a93bd0e212609d8efd016ce3d58f8b6a4ac3d87..043a95bb07c47dfbf279b440f54905a65bf1717b 100644 (file)
@@ -396,6 +396,7 @@ void write_leases(void)
        close(fp);
 
        if (server_config.notify_file) {
+// TODO: vfork-based child creation
                char *cmd = xasprintf("%s %s", server_config.notify_file, server_config.lease_file);
                system(cmd);
                free(cmd);
@@ -406,7 +407,7 @@ void write_leases(void)
 void read_leases(const char *file)
 {
        int fp;
-       unsigned int i = 0;
+       unsigned i;
        struct dhcpOfferedAddr lease;
 
        fp = open_or_warn(file, O_RDONLY);
@@ -414,6 +415,7 @@ void read_leases(const char *file)
                return;
        }
 
+       i = 0;
        while (i < server_config.max_leases
         && full_read(fp, &lease, sizeof(lease)) == sizeof(lease)
        ) {
@@ -422,7 +424,7 @@ void read_leases(const char *file)
                if (y >= server_config.start_ip && y <= server_config.end_ip) {
                        lease.expires = ntohl(lease.expires);
                        if (!server_config.remaining)
-                               lease.expires -= time(0);
+                               lease.expires -= time(NULL);
                        if (!(add_lease(lease.chaddr, lease.yiaddr, lease.expires))) {
                                bb_error_msg("too many leases while loading %s", file);
                                break;