]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Add -o opt1,opt2 and -O to disable requesting optional options. Rejig our defaults...
authorRoy Marples <roy@marples.name>
Mon, 14 Apr 2008 03:45:54 +0000 (03:45 +0000)
committerRoy Marples <roy@marples.name>
Mon, 14 Apr 2008 03:45:54 +0000 (03:45 +0000)
dhcp.c
dhcp.h
dhcpcd.8.in
dhcpcd.c
dhcpcd.h
dhcpcd.sh

diff --git a/dhcp.c b/dhcp.c
index 2dd2e5a999bdcaa6c1c8f182142e4c23a8ec1031..a352fc1d00aba2b85691f608ea03cce3fe17c12d 100644 (file)
--- a/dhcp.c
+++ b/dhcp.c
@@ -65,19 +65,46 @@ const struct dhcp_option dhcp_options[] = {
        { DHCP_MTU,             OPT_UINT16R,    "MTU" },
        { DHCP_STATICROUTE,     OPT_IPV4R,      NULL },
        { DHCP_ROUTER,          OPT_IPV4R,      NULL },
-       { DHCP_HOSTNAME,        OPT_STRINGR,    "HOSTNAME" },
-       { DHCP_DNSSERVER,       OPT_IPV4R,      "DNSSERVER" },
-       { DHCP_DNSDOMAIN,       OPT_STRINGR,    "DNSDOMAIN" },
-       { DHCP_DNSSEARCH,       OPT_STRINGR | OPT_RFC3397,      "DNSSEARCH" },
-       { DHCP_NTPSERVER,       OPT_IPV4R,      "NTPSERVER" },
-       { DHCP_NISSERVER,       OPT_IPV4R,      "NISSERVER" },
-       { DHCP_NISDOMAIN,       OPT_IPV4R,      "NISDOMAIN" },
-       { DHCP_ROOTPATH,        OPT_STRINGR,    "ROOTPATH" },
-       { DHCP_SIPSERVER,       OPT_STRINGR | OPT_RFC3361,      "SIPSERVER" },
+       { DHCP_HOSTNAME,        OPT_STRING    "HOSTNAME" },
+       { DHCP_DNSSERVER,       OPT_IPV4      "DNSSERVER" },
+       { DHCP_DNSDOMAIN,       OPT_STRING    "DNSDOMAIN" },
+       { DHCP_DNSSEARCH,       OPT_STRING | OPT_RFC3397,       "DNSSEARCH" },
+       { DHCP_NTPSERVER,       OPT_IPV4      "NTPSERVER" },
+       { DHCP_NISSERVER,       OPT_IPV4      "NISSERVER" },
+       { DHCP_NISDOMAIN,       OPT_IPV4      "NISDOMAIN" },
+       { DHCP_ROOTPATH,        OPT_STRING    "ROOTPATH" },
+       { DHCP_SIPSERVER,       OPT_STRING | OPT_RFC3361,       "SIPSERVER" },
        { DHCP_MESSAGE,         OPT_STRING,     NULL},
        { 0, 0, NULL }
 };
 
+int make_reqmask(struct options *options, char **opts)
+{
+       char *token;
+       char *p = *opts;
+       uint8_t i;
+       const char *v;
+       int max = sizeof(dhcp_options) / sizeof(dhcp_options[0]);
+
+       while ((token = strsep(&p, ","))) {
+               for (i = 0; i < max; i++) {
+                       if (!(v = dhcp_options[i].var))
+                               continue;
+                       if (strcmp(v, token) == 0) {
+                               add_reqmask(options->reqmask,
+                                           dhcp_options[i].option);
+                               break;
+                       }
+               }
+               if (i >= max) {
+                       *opts = token;
+                       errno = ENOENT;
+                       return -1;
+               }
+       }
+       return 0;
+}
+
 static int
 valid_length(uint8_t option, const uint8_t *data, int *type)
 {
@@ -512,6 +539,7 @@ make_message(struct dhcp_message **message,
        time_t up = uptime() - iface->start_uptime;
        uint32_t ul;
        uint16_t sz;
+       uint8_t o;
 
        dhcp = xzalloc(sizeof (*dhcp));
        m = (uint8_t *)dhcp;
@@ -656,9 +684,11 @@ make_message(struct dhcp_message **message,
                n_params = p;
                *p++ = 0;
                for (l = 0; l < sizeof(dhcp_options) / sizeof(dhcp_options[0]); l++) {
-                       if (!(dhcp_options[l].type & OPT_REQUEST))
+                       o = dhcp_options[l].option;
+                       if (!(dhcp_options[l].type & OPT_REQUEST) &&
+                           !has_reqmask(options->reqmask, o))
                                continue;
-                       switch (dhcp_options[l].option) {
+                       switch (o) {
                        case DHCP_RENEWALTIME:  /* FALLTHROUGH */
                        case DHCP_REBINDTIME:
                                if (type == DHCP_INFORM)
@@ -669,7 +699,7 @@ make_message(struct dhcp_message **message,
                                        continue;
                                break;
                        }
-                       *p++ = dhcp_options[l].option;
+                       *p++ = o;
                }
                if (options->domscsr)
                        *p++ = DHCP_MSCSR;
diff --git a/dhcp.h b/dhcp.h
index 1aa38ecd6534df1c5c99b63781da84434db301a1..7c279601ceb6eb3a92556d45f3c7805bd5025619 100644 (file)
--- a/dhcp.h
+++ b/dhcp.h
@@ -170,6 +170,9 @@ struct dhcp_lease {
        uint8_t frominfo;
 };
 
+#define add_reqmask(var, val) (var[val >> 3] |= 1 << (val & 7))
+#define has_reqmask(var, val) (var[val >> 3] & (1 << (val & 7)))
+int make_reqmask(struct options *options, char **opts);
 const uint8_t *get_option(const struct dhcp_message *, uint8_t);
 char *get_option_string(const struct dhcp_message *, uint8_t);
 int get_option_addr(uint32_t *a, const struct dhcp_message *dhcp, uint8_t option);
index 71d964de4845639be1327e96431963a071bb4ee5..1f90d8b38cfd5f26b9a3f10632ed45abc91757e0 100644 (file)
 .Nd an RFC 2131 compliant DHCP client
 .Sh SYNOPSIS
 .Nm
-.Op Fl dknpAEGHMLNRSTY
+.Op Fl dknpAEGHMOLNRSTY
 .Op Fl c , -script Ar script
 .Op Fl h , -hostname Ar hostname
 .Op Fl i , -classid Ar classid
 .Op Fl l , -leasetime Ar seconds
 .Op Fl m , -metric Ar metric
+.Op Fl o , -option Ar option
 .Op Fl r , -request Ar address
 .Op Fl t , -timeout Ar seconds
 .Op Fl u , -userclass Ar class
@@ -167,6 +168,11 @@ presently only Linux
 .Pc .
 Route metrics allow the addition of routes to the same destination across
 different interfaces, the lower the metric the more it is preferred.
+.It Fl o , -option Ar option
+Request the DHCP
+.Ar option
+variable for use in
+.Pa @PREFIX@/etc/dhcpcd.sh .
 .It Fl n , -renew
 Notifies an existing
 .Nm
@@ -278,6 +284,8 @@ Don't set the MTU of the
 Don't touch
 .Pa /etc/ntpd.conf
 or restart the ntp service.
+.It Fl O , -nooptions
+Don't request any options beyond what is needed to configure the interface.
 .It Fl R , -nodns
 Don't send DNS information to resolvconf or touch
 .Pa /etc/resolv.conf .
index 490ebc2ff5b7b749a9da72345405aa2ada24acbb..af080f03d8bfd2dbac207c1cb114e9e3d305156c 100644 (file)
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -62,6 +62,7 @@ static const struct option longopts[] = {
        {"leasetime",   required_argument,  NULL, 'l'},
        {"metric",      required_argument,  NULL, 'm'},
        {"renew",       no_argument,        NULL, 'n'},
+       {"option",      required_argument,  NULL, 'o'},
        {"persistent",  no_argument,        NULL, 'p'},
        {"inform",      optional_argument,  NULL, 's'},
        {"request",     optional_argument,  NULL, 'r'},
@@ -76,6 +77,7 @@ static const struct option longopts[] = {
        {"noipv4ll",    no_argument,        NULL, 'L'},
        {"nomtu",       no_argument,        NULL, 'M'},
        {"nontp",       no_argument,        NULL, 'N'},
+       {"nooptions",   no_argument,        NULL, 'O'},
        {"nodns",       no_argument,        NULL, 'R'},
        {"msscr",       no_argument,        NULL, 'S'},
        {"test",        no_argument,        NULL, 'T'},
@@ -136,9 +138,9 @@ read_pid(const char *pidfile)
 static void
 usage(void)
 {
-       printf("usage: "PACKAGE" [-adknpEGHMNRSTY] [-c script] [-h hostname] [-i classID]\n"
-              "              [-l leasetime] [-m metric] [-r ipaddress] [-s ipaddress]\n"
-              "              [-t timeout] [-u userclass] [-F none | ptr | both]\n"
+       printf("usage: "PACKAGE" [-adknpEGHMNORSTY] [-c script] [-h hostname] [-i classID]\n"
+              "              [-l leasetime] [-m metric] [-o option] [-r ipaddress]\n"
+              "              [-s ipaddress] [-t timeout] [-u userclass] [-F none | ptr | both]\n"
               "              [-I clientID] <interface>\n");
 }
 
@@ -158,6 +160,7 @@ main(int argc, char **argv)
        int sig = 0;
        int retval = EXIT_FAILURE;
        char *p;
+       int doopts = 1, dodns = 1, dohostname = 0, donis = 1, dontp = 1;
 
        /* Close any un-needed fd's */
        for (i = getdtablesize() - 1; i >= 3; --i)
@@ -179,15 +182,10 @@ main(int argc, char **argv)
            strcmp(options->hostname, "localhost") == 0)
                *options->hostname = '\0';
 
-       setenv("PEERDNS", "yes", 1);
-       setenv("PEERHOSTNAME", "no", 1);
-       setenv("PEERNIS", "yes", 1);
-       setenv("PEERNTP", "yes", 1);
-
        /* Don't set any optional arguments here so we retain POSIX
         * compatibility with getopt */
        while ((opt = getopt_long(argc, argv, EXTRA_OPTS
-                                 "c:dh:i:kl:m:npr:s:t:u:xAEF:GHI:LMNRSTY",
+                                 "c:dh:i:kl:m:no:pr:s:t:u:xAEF:GHI:LMNORSTY",
                                  longopts, &option_index)) != -1)
        {
                switch (opt) {
@@ -271,6 +269,11 @@ main(int argc, char **argv)
                case 'n':
                        sig = SIGALRM;
                        break;
+               case 'o':
+                       if (make_reqmask(options, &optarg) != 0) {
+                               logger(LOG_ERR, "unknown option `%s'", optarg);
+                               goto abort;
+                       }
                case 'p':
                        options->options |= DHCPCD_PERSISTENT;
                        break;
@@ -367,7 +370,7 @@ main(int argc, char **argv)
                        options->options &= ~DHCPCD_GATEWAY;
                        break;
                case 'H':
-                       setenv("PEERHOSTNAME", "yes", 1);
+                       dohostname = 1;
                        break;
                case 'I':
                        if (optarg) {
@@ -394,10 +397,13 @@ main(int argc, char **argv)
                        options->options &= ~DHCPCD_MTU;
                        break;
                case 'N':
-                       setenv("PEERNTP", "no", 1);
+                       dontp = 0;
+                       break;
+               case 'O':
+                       doopts = 0;
                        break;
                case 'R':
-                       setenv("PEERDNS", "no", 1);
+                       dodns = 0;
                        break;
                case 'S':
                        options->domscsr++;
@@ -406,7 +412,7 @@ main(int argc, char **argv)
                        options->options |= DHCPCD_TEST | DHCPCD_PERSISTENT;
                        break;
                case 'Y':
-                       setenv("PEERNIS", "no", 1);
+                       donis = 0;
                        break;
                case '?':
                        usage();
@@ -440,6 +446,22 @@ main(int argc, char **argv)
        if (dohelp)
                usage();
 
+       if (doopts) {
+               if (dodns) {
+                       add_reqmask(options->reqmask, DHCP_DNSSERVER);
+                       add_reqmask(options->reqmask, DHCP_DNSDOMAIN);
+                       add_reqmask(options->reqmask, DHCP_DNSSEARCH);
+               }
+               if (dohostname)
+                       add_reqmask(options->reqmask, DHCP_HOSTNAME);
+               if (donis) {
+                       add_reqmask(options->reqmask, DHCP_NISSERVER);
+                       add_reqmask(options->reqmask, DHCP_NISDOMAIN);
+               }
+               if (dontp)
+                       add_reqmask(options->reqmask, DHCP_NTPSERVER);
+       }
+
 #ifdef THERE_IS_NO_FORK
        dhcpcd_argv = argv;
        dhcpcd_argc = argc;
index d3b6bb3b28923aad341962fa324e9a40342b34a7..23b184ebca76a6e1b5a79d397d517920fadfc31d 100644 (file)
--- a/dhcpcd.h
+++ b/dhcpcd.h
@@ -76,6 +76,7 @@ struct options {
        char classid[CLASS_ID_MAX_LEN];
        char clientid[CLIENT_ID_MAX_LEN];
        char userclass[USERCLASS_MAX_LEN];
+       uint8_t reqmask[256 / 8];
        size_t userclass_len;
        uint32_t leasetime;
        time_t timeout;
index 1861e3e16a1ec5d96c4d37fe1c2aaca79434da70..caaa4f37d242a253c540e7621fa4fedf2adf347f 100755 (executable)
--- a/dhcpcd.sh
+++ b/dhcpcd.sh
@@ -116,7 +116,6 @@ restore_conf()
 }
 
 make_nis_conf() {
-       yesno "${PEERNIS}" || return 0
        [ -z "${NISDOMAIN}" -a -z "${NISSERVER}" ] && return 0
        local cf=/etc/yp.conf."${INTERFACE}" prefix= x= pidfile=
        echo "# Generated by dhcpcd for interface ${INTERFACE}" > "${cf}"
@@ -143,7 +142,6 @@ make_nis_conf() {
 
 restore_nis_conf()
 {
-       yesno "${PEERNIS}" || return 0
        restore_conf /etc/yp.conf || return 0
        pidfile="$(service_pidfile ypbind)"
        if [ -s "${pidfile}" ]; then
@@ -153,7 +151,6 @@ restore_nis_conf()
 
 make_ntp_conf()
 {
-       yesno "${PEERNTP}" || return 0
        [ -z "${NTPSERVER}" ] && return 0
        local cf=/etc/ntp.conf."${INTERFACE}" x=
        echo "# Generated by dhcpcd for interface ${INTERFACE}" > "${cf}"
@@ -181,14 +178,12 @@ make_ntp_conf()
 
 restore_ntp_conf()
 {
-       yesno "${PEERNTP}" || return 0
        restore_conf /etc/ntp.conf || return 0
        do_service ntp restart
 }
 
 make_resolv_conf()
 {
-       yesno "${PEERDNS}" || return 0
        if [ -z "${DNSSERVER}" -a -z "${DNSDOMAIN}" -a -z "${DNSSEARCH}" ]; then
                return 0
        fi
@@ -212,7 +207,6 @@ make_resolv_conf()
 
 restore_resolv_conf()
 {
-       yesno "${PEERDNS}" || return 0
        if type resolvconf >/dev/null 2>&1; then
                resolvconf -d "${INTERFACE}"
        else
@@ -242,7 +236,7 @@ lookup_hostname()
 
 make_hostname()
 {
-       if yesno "${PEERHOSTNAME}" || need_hostname; then
+       if need_hostname; then
                local name="${HOSTNAME}"
                [ -z "${name}" ] && name="$(lookup_hostname)"
                [ -n "${name}" ] && hostname "${name}"