]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Remove previous toggles for classid, clientid, userclass and vendor - they call ...
authorRoy Marples <roy@marples.name>
Wed, 2 Jul 2008 17:05:41 +0000 (17:05 +0000)
committerRoy Marples <roy@marples.name>
Wed, 2 Jul 2008 17:05:41 +0000 (17:05 +0000)
client.c
config.h
dhcp.c
dhcpcd.c
dhcpcd.h

index d71561c3166efe17b024b59831d3c1f190a2774a..756c9b812e9ff5c9732a758f6c0d9d386753928c 100644 (file)
--- a/client.c
+++ b/client.c
@@ -465,9 +465,7 @@ client_setup(struct if_state *state, const struct options *options)
        struct interface *iface = state->interface;
        struct dhcp_lease *lease = &state->lease;
        struct in_addr addr;
-#ifdef ENABLE_CLIENTID
        size_t len = 0;
-#endif
 #ifdef ENABLE_DUID
        unsigned char *duid = NULL;
        uint32_t ul;
@@ -524,7 +522,6 @@ client_setup(struct if_state *state, const struct options *options)
                iface->net.s_addr = lease->net.s_addr;
        }
 
-#ifdef ENABLE_CLIENTID
        if (*options->clientid) {
                /* Attempt to see if the ClientID is a hardware address */
                if ((len = hwaddr_aton(NULL, options->clientid))) {
@@ -578,7 +575,6 @@ client_setup(struct if_state *state, const struct options *options)
                        memcpy(iface->clientid + 2, iface->hwaddr, iface->hwlen);
                }
        }
-#endif
 
        return 0;
 }
index e6f6a9b0b1ff359adfabdcd7d689b117bd4bc433..a18e3c2798be6a832d8e4a9c5a357ac8e0e82dea 100644 (file)
--- a/config.h
+++ b/config.h
 # ifndef DISABLE_ARP
 #  define DISABLE_ARP
 # endif
-# ifndef DISABLE_CLASSID
-#  define DISABLE_CLASSID
-# endif
-# ifndef DISABLE_CLIENTID
-#  define DISABLE_CLIENTID
-# endif
 # ifndef DISABLE_IPV4LL
 #  define DISABLE_IPV4LL
 # endif
 # ifndef DISABLE_DUID
 #  define DISABLE_DUID
 # endif
-# ifndef DISABLE_USERCLASS
-#  define DISABLE_USERCLASS
-# endif
-# ifndef DISABLE_VENDOR
-#  define DISABLE_VENDOR
-# endif
 #endif
 
 /* Enable ARP by default. */
 # define ENABLE_ARP
 #endif
 
-/* Allow dhcpcd to send a ClassID */
-#ifndef DISABLE_CLASSID
-# define ENABLE_CLASSID
-#endif
-
-/* Send a ClientID in all messages. */
-#ifndef DISABLE_CLIENTID
-# define ENABLE_CLIENTID
-#endif
-
 /* Allow dhcpcd to create a DUID (LLT) and use it to make an IAID for the
  * ClientID. Even enabled here, we need a config directive to actually use it
  * so this toggle is just to remove it from dhcpcd to make the binary smaller.
@@ -81,9 +59,7 @@
  * hex string that represents the DUID.
  * See RFC 3315 for details on this. */
 #ifndef DISABLE_DUID
-# ifdef ENABLE_CLIENTID
-#  define ENABLE_DUID
-# endif
+# define ENABLE_DUID
 #endif
 
 /* IPV4LL, aka ZeroConf, aka APIPA, aka RFC 3927.
  */
 // #define ENABLE_IPV4LL_ALWAYSROUTE 
 
-/* Allow dhcpcd to send user class options. */
-#ifndef DISABLE_USERCLASS
-# define ENABLE_USERCLASS
-#endif
-
-/* Allow dhcpcd to send encapsulated vendor options (code 43).
- * Although this is enabled by default, only custom networks would really
- * need it. */
-#ifndef DISABLE_VENDOR
-# define ENABLE_VENDOR
-#endif
-
 /* Some systems do not have a working fork. */
 /* #define THERE_IS_NO_FORK */
 
diff --git a/dhcp.c b/dhcp.c
index 3cb9cd23f128d64a3660307c977a76a34d52a96e..451881c254c9c5da47ae31035502e71ff4225deb 100644 (file)
--- a/dhcp.c
+++ b/dhcp.c
@@ -710,7 +710,6 @@ make_message(struct dhcp_message **message,
        uint8_t *d, *m, *p;
        const char *c;
        uint8_t *n_params = NULL;
-       size_t l;
        time_t up = uptime() - iface->start_uptime;
        uint32_t ul;
        uint16_t sz;
@@ -782,21 +781,17 @@ make_message(struct dhcp_message **message,
        }
 
        if (type != DHCP_DECLINE && type != DHCP_RELEASE) {
-#ifdef ENABLE_USERCLASS
                if (options->userclass[0]) {
                        *p++ = DHCP_USERCLASS;
                        memcpy(p, options->userclass, options->userclass[0] + 1);
                        p += options->userclass[0] + 1;
                }
-#endif
 
-#ifdef ENABLE_CLASSID
                if (options->classid[0]) {
                        *p++ = DHCP_CLASSID;
                        memcpy(p, options->classid, options->classid[0] + 1);
                        p += options->classid[0] + 1;
                }
-#endif
        }
 
        if (type == DHCP_DISCOVER || type == DHCP_REQUEST) {
@@ -833,13 +828,12 @@ make_message(struct dhcp_message **message,
                if (options->hostname[0]) {
                        if (options->fqdn == FQDN_DISABLE) {
                                *p++ = DHCP_HOSTNAME;
-                               *p++ = l = strlen(options->hostname);
-                               memcpy(p, options->hostname, l);
-                               p += l;
+                               memcpy(p, options->hostname, options->hostname[0] + 1);
+                               p += options->hostname[0] + 1;
                        } else {
                                /* Draft IETF DHC-FQDN option (81) */
                                *p++ = DHCP_FQDN;
-                               *p++ = strlen(options->hostname) + 5;
+                               *p++ = options->hostname[0] + 4;
                                /*
                                 * Flags: 0000NEOS
                                 * S: 1 => Client requests Server to update
@@ -853,7 +847,7 @@ make_message(struct dhcp_message **message,
                                *p++ = (options->fqdn & 0x9) | 0x4;
                                *p++ = 0; /* from server for PTR RR */
                                *p++ = 0; /* from server for A RR if S=1 */
-                               c = options->hostname;
+                               c = options->hostname + 1;
                                d = p++;
                                while (*c) {
                                        if (*c == '.') {
@@ -867,14 +861,12 @@ make_message(struct dhcp_message **message,
                        }
                }
 
-#ifdef ENABLE_VENDOR
                /* vendor is already encoded correctly, so just add it */
                if (options->vendor[0]) {
                        *p++ = DHCP_VENDOR;
                        memcpy(p, options->vendor, options->vendor[0] + 1);
                        p += options->vendor[0] + 1;
                }
-#endif
 
                *p++ = DHCP_PARAMETERREQUESTLIST;
                n_params = p;
index 17668472fdb0a71e1bc32afd95fad302786b43a7..7617d3a6831f00687a2a9cc4179534d3c2fa9dd9 100644 (file)
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -33,6 +33,7 @@ const char copyright[] = "Copyright (c) 2006-2008 Roy Marples";
 
 #include <arpa/inet.h>
 
+#include <ctype.h>
 #include <errno.h>
 #include <getopt.h>
 #include <paths.h>
@@ -204,54 +205,133 @@ add_environ(struct options *options, const char *value, int uniq)
        return newlist[i];
 }
 
+static ssize_t
+parse_string(char *buffer, ssize_t len, char *oarg)
+{
+       ssize_t l;
+       int i;
+       char *p, *bp = buffer;
+       char c[4];
+
+       /* If surrounded by quotes then it's a string */
+       if (*oarg == '"') {
+               oarg++;
+               len = strlen(oarg);
+               p = oarg + len - 1;
+               if (*p == '"')
+                       *p = '\0';
+       } else {
+               l = hwaddr_aton(NULL, oarg);
+               if (l > 1) {
+                       if (l > len) {
+                               errno = ENOBUFS;
+                               return -1;
+                       }
+                       hwaddr_aton((uint8_t*)buffer, oarg);
+                       return l;
+               }
+       }
+
+       /* Process escapes */
+       p = oarg;
+       l = 0;
+       c[3] = '\0';
+       while (*p) {
+               if (++l > len) {
+                       errno = ENOBUFS;
+                       return -1;
+               }
+               if (*p == '\\') {
+                       p++;
+                       switch(*p++) {
+                       case '\0':
+                               break;
+                       case 'b':
+                               *bp++ = '\b';
+                               break;
+                       case 'n':
+                               *bp++ = '\n';
+                               break;
+                       case 'r':
+                               *bp++ = '\r';
+                               break;
+                       case 't':
+                               *bp++ = '\t';
+                               break;
+                       case 'x':
+                               /* Grab a hex code */
+                               c[1] = '\0';
+                               for (i = 0; i < 2; i++) {
+                                       if (isxdigit((unsigned char)*p) == 0)
+                                               break;
+                                       c[i] = *p++;
+                               }
+                               if (c[1] != '\0') {
+                                       c[2] = '\0';
+                                       *bp++ = strtol(c, NULL, 16);
+                               } else
+                                       l--;
+                               break;
+                       case '0':
+                               /* Grab an octal code */
+                               c[2] = '\0';
+                               for (i = 0; i < 3; i++) {
+                                       if (*p < '0' || *p > '7')
+                                               break;
+                                       c[i] = *p++;
+                               }
+                               if (c[2] != '\0') {
+                                       i = strtol(c, NULL, 8);
+                                       if (i > 255)
+                                               i = 255;
+                                       *bp ++= i;
+                               } else
+                                       l--;
+                               break;
+                       default:
+                               *bp++ = *p++;
+                       }
+               } else
+                       *bp++ = *p++;
+       }
+       return l;
+}
+
 static int
 parse_option(int opt, char *oarg, struct options *options)
 {
        int i;
        char *p;
-       size_t olen, s;
-       uint8_t *u;
-#ifdef ENABLE_VENDOR
-       int j;
+       ssize_t s;
        struct in_addr addr;
-#endif
-
-       if (oarg)
-               olen = strlen(oarg);
-       else
-               olen = 0;
 
        switch(opt) {
        case 'c':
                strlcpy(options->script, oarg, sizeof(options->script));
                break;
        case 'h':
-               if (!oarg)
-                       *options->hostname = '\0';
-               else if (olen >= MAXHOSTNAMELEN) {
-                       logger(LOG_ERR,
-                              "`%s' too long for HostName string, max is %d",
-                              oarg, MAXHOSTNAMELEN);
+               if (oarg)
+                       s = parse_string(options->hostname + 1,
+                                        MAXHOSTNAMELEN, oarg);
+               else
+                       s = 0;
+               if (s == -1) {
+                       logger(LOG_ERR, "hostname: %s", strerror(errno));
                        return -1;
-               } else
-                       strlcpy(options->hostname, oarg,
-                               sizeof(options->hostname));
+               }
+               options->hostname[0] = (uint8_t)s;
                break;
        case 'i':
-#ifdef ENABLE_CLASSID
-               if (!oarg) {
-                       *options->classid = '\0';
-               } else if (olen >= CLASSID_MAX_LEN) {
-                       logger(LOG_ERR,
-                              "`%s' too long for ClassID string, max is %d",
-                              oarg, CLASSID_MAX_LEN);
+               if (oarg)
+                       s = parse_string((char *)options->classid + 1,
+                                        CLASSID_MAX_LEN, oarg);
+               else
+                       s = 0;
+               if (s == -1) {
+                       logger(LOG_ERR, "classid: %s", strerror(errno));
                        return -1;
-               } else {
-                       options->classid[0] = strlen(oarg);
-                       strlcpy((char *)options->classid + 1, oarg,
-                               sizeof(options->classid));
                }
-#endif
+               *options->classid = (uint8_t)s;
                break;
        case 'l':
                if (*oarg == '-') {
@@ -286,7 +366,7 @@ parse_option(int opt, char *oarg, struct options *options)
                options->options |= DHCPCD_INFORM;
                options->options |= DHCPCD_PERSISTENT;
                options->options &= ~DHCPCD_ARP;
-               if (!oarg || olen == 0) {
+               if (!oarg || *oarg == '\0') {
                        options->request_address.s_addr = 0;
                        break;
                } else {
@@ -308,7 +388,7 @@ parse_option(int opt, char *oarg, struct options *options)
        case 'r':
                if (!(options->options & DHCPCD_INFORM))
                        options->options |= DHCPCD_REQUEST;
-               if (olen > 0 && !inet_aton(oarg, &options->request_address)) {
+               if (*oarg && !inet_aton(oarg, &options->request_address)) {
                        logger(LOG_ERR, "`%s' is not a valid IP address",
                               oarg);
                        return -1;
@@ -322,21 +402,19 @@ parse_option(int opt, char *oarg, struct options *options)
                }
                break;
        case 'u':
-#ifdef ENABLE_USERCLASS
-               if (options->userclass[0] + olen + 1 >= USERCLASS_MAX_LEN) {
-                       logger(LOG_ERR,
-                              "userclass overrun, max is %d",
-                              USERCLASS_MAX_LEN);
+               s = USERCLASS_MAX_LEN - options->userclass[0] - 1;
+               s = parse_string((char *)options->userclass + options->userclass[0] + 2,
+                                s, oarg);
+               if (s == -1) {
+                       logger(LOG_ERR, "userclass: %s", strerror(errno));
                        return -1;
                }
-               u = options->userclass + options->userclass[0] + 1;
-               *u++ = olen;
-               memcpy(u, oarg, olen);
-               options->userclass[0] += olen + 1;
-#endif
+               if (s != 0) {
+                       options->userclass[options->userclass[0] + 1] = s;
+                       options->userclass[0] += s + 1;
+               }
                break;
        case 'v':
-#ifdef ENABLE_VENDOR
                p = strchr(oarg, ',');
                if (!p || !p[1]) {
                        logger(LOG_ERR, "invalid vendor format");
@@ -350,50 +428,27 @@ parse_option(int opt, char *oarg, struct options *options)
                                        " 1 and 254 inclusive");
                        return -1;
                }
-               /* string */
-               j = 0;
-               if (*oarg == '"') {
-                       p = oarg + strlen(oarg) - 1;
-                       if (*p == '"') {
-                               oarg++;
-                               *p = '\0';
-                       }
+               s = VENDOR_MAX_LEN - options->vendor[0] - 2;
+               if (inet_aton(oarg, &addr) == 1) {
+                       if (s < 6) {
+                               s = -1;
+                               errno = ENOBUFS;
+                       } else
+                               memcpy(options->vendor + options->vendor[0] + 3,
+                                      &addr.s_addr, sizeof(addr.s_addr));
                } else {
-                       /* hex encoding */
-                       errno = 0;
-                       s = hwaddr_aton(NULL, oarg);
-                       if (s > 0)
-                               j = 1;
-                       else {
-                               if (inet_aton(oarg, &addr) == 1) {
-                                       s = sizeof(addr.s_addr);
-                                       j = 2;
-                               }
-                       }
+                       s = parse_string((char *)options->vendor + options->vendor[0] + 3,
+                                        s, oarg);
                }
-               if (j == 0)
-                       s = strlen(oarg);
-               /* Need to include then len char */
-               if (options->vendor[0] + s + 1 > VENDOR_MAX_LEN) {
-                       logger(LOG_ERR, "vendor option is too long");
+               if (s == -1) {
+                       logger(LOG_ERR, "vendor: %s", strerror(errno));
                        return -1;
                }
-               u = options->vendor + options->vendor[0] + 1;
-               options->vendor[0] += s + 2;
-               *u++ = (uint8_t)i;
-               *u++ = (uint8_t)s;
-               switch(j) {
-               case 0:
-                       memcpy(u, oarg, s);
-                       break;
-               case 1: 
-                       hwaddr_aton(u, oarg);
-                       break;
-               case 2:
-                       memcpy(u, &addr.s_addr, s);
-                       break;
+               if (s != 0) {
+                       options->vendor[options->vendor[0] + 1] = i;
+                       options->vendor[options->vendor[0] + 2] = s;
+                       options->vendor[0] += s + 2;
                }
-#endif
                break;
        case 'A':
                options->options &= ~DHCPCD_ARP;
@@ -404,7 +459,7 @@ parse_option(int opt, char *oarg, struct options *options)
                /* Commas to spaces for shell */
                while ((p = strchr(oarg, ',')))
                        *p = ' ';
-               s = strlen("skip_hooks=") + olen + 1;
+               s = strlen("skip_hooks=") + strlen(oarg) + 1;
                p = xmalloc(sizeof(char) * s);
                snprintf(p, s, "skip_hooks=%s", oarg);
                add_environ(options, p, 0);
@@ -437,27 +492,20 @@ parse_option(int opt, char *oarg, struct options *options)
                options->options &= ~DHCPCD_GATEWAY;
                break;
        case 'I':
-#ifdef ENABLE_CLIENTID
-               if (oarg) {
-                       if (olen >= CLIENTID_MAX_LEN) {
-                               logger(LOG_ERR, "`%s' is too long for"
-                                      " ClientID, max is %d",
-                                      oarg, CLIENTID_MAX_LEN);
-                               return -1;
-                       }
-                       if (strlcpy(options->clientid, oarg,
-                                   CLIENTID_MAX_LEN) == 0)
-                       {
-                               /* empty string disabled duid */
-                               options->options &= ~DHCPCD_DUID;
-                               options->options &= ~DHCPCD_CLIENTID;
-                       }
-               } else {
-                       options->clientid[0] = '\0';
+               if (oarg)
+                       s = parse_string((char *)options->classid + 1,
+                                        CLIENTID_MAX_LEN, oarg);
+               else
+                       s = 0;
+               if (s == -1) {
+                       logger(LOG_ERR, "classid: %s", strerror(errno));
+                       return -1;
+               }
+               options->clientid[0] = (uint8_t)s;
+               if (s == 0) {
                        options->options &= ~DHCPCD_DUID;
                        options->options &= ~DHCPCD_CLIENTID;
                }
-#endif
                break;
        case 'K':
                options->options &= ~DHCPCD_DAEMONISE;
@@ -509,8 +557,7 @@ main(int argc, char **argv)
        int pid_fd = -1;
        int sig = 0;
        int retval = EXIT_FAILURE;
-       char *line, *option, *p, *lp, *buffer = NULL;
-       char lt;
+       char *line, *option, *p, *buffer = NULL;
        size_t len = 0;
        FILE *f;
        char *cf = NULL;
@@ -521,20 +568,15 @@ main(int argc, char **argv)
 
        options = xzalloc(sizeof(*options));
        strlcpy(options->script, SCRIPT, sizeof(options->script));
-#ifdef ENABLE_CLASSID
        options->classid[0] = snprintf((char *)options->classid + 1, CLASSID_MAX_LEN,
                                       "%s %s", PACKAGE, VERSION);
-#endif
 
-       options->options |= DHCPCD_GATEWAY | DHCPCD_DAEMONISE;
+       options->options |= DHCPCD_CLIENTID | DHCPCD_GATEWAY | DHCPCD_DAEMONISE;
 #ifdef ENABLE_ARP
        options->options |= DHCPCD_ARP;
  #ifdef ENABLE_IPV4LL
        options->options |= DHCPCD_IPV4LL;
  #endif
-#endif
-#ifdef ENABLE_CLIENTID
-       options->options |= DHCPCD_CLIENTID;
 #endif
        options->timeout = DEFAULT_TIMEOUT;
 
@@ -566,10 +608,11 @@ main(int argc, char **argv)
        }
 #endif
 
-       gethostname(options->hostname, sizeof(options->hostname));
-       if (strcmp(options->hostname, "(none)") == 0 ||
-           strcmp(options->hostname, "localhost") == 0)
-               *options->hostname = '\0';
+       gethostname(options->hostname + 1, sizeof(options->hostname));
+       if (strcmp(options->hostname + 1, "(none)") == 0 ||
+           strcmp(options->hostname + 1, "localhost") == 0)
+               options->hostname[1] = '\0';
+       *options->hostname = strlen(options->hostname + 1);
 
        while ((opt = getopt_long(argc, argv, OPTS EXTRA_OPTS,
                                  longopts, &option_index)) != -1)
@@ -599,24 +642,12 @@ main(int argc, char **argv)
 #ifdef ENABLE_ARP
                       " ARP"
 #endif
-#ifdef ENABLE_CLASSID
-                      " CLASSID"
-#endif
-#ifdef ENABLE_CLIENTID
-                      " CLIENTID"
-#endif
 #ifdef ENABLE_DUID
                       " DUID"
 #endif
 #ifdef ENABLE_IPV4LL
                       " IPV4LL"
 #endif
-#ifdef ENABLE_USERCLASS
-                      " USERCLASS"
-#endif
-#ifdef ENABLE_VENDOR
-                      " VENDOR"
-#endif
 #ifdef THERE_IS_NO_FORK
                       " THERE_IS_NO_FORK"
 #endif
@@ -663,38 +694,13 @@ main(int argc, char **argv)
                                        line++;
                        }
                        /* Trim trailing whitespace */
-                       lt = '\\';
                        if (line && *line) {
                                p = line + strlen(line) - 1;
-                               while (p != line && (*p == ' ' || *p == '\t')) {
-                                       /* Remember the last char trimmed */
-                                       lt = *p;
+                               while (p != line &&
+                                      (*p == ' ' || *p == '\t') &&
+                                      *(p - 1) != '\\')
                                        *p-- = '\0';
-                               }
                        }
-                       /* Remove quotes if present */
-                       if (line && *line == '"') {
-                               p = line + strlen(line) - 1;
-                               if (*p == '"') {
-                                       line++;
-                                       *p = '\0';
-                               }
-                       }
-                       /* Process escapes */
-                       lp = p = line;
-                       while (p && *p) {
-                               if (*p == '\\')
-                                       p++;
-                               /* EOL? */
-                               if (*p == '\0') {
-                                       /* Restore the last char trimmed */
-                                       *lp++ = lt;
-                                       break;
-                               }
-                               *lp++ = *p++;
-                       }
-                       if (lp)
-                               *lp = '\0';
                        if (strcmp(option, "interface") == 0) {
                                free(intf);
                                intf = xstrdup(line);
@@ -929,13 +935,11 @@ main(int argc, char **argv)
                logger(LOG_INFO, PACKAGE " " VERSION " starting");
        }
 
-#ifdef ENABLE_VENDOR
        /* Terminate the encapsulated options */
        if (options->vendor[0]) {
                options->vendor[0]++;
                options->vendor[options->vendor[0]] = DHCP_END;
        }
-#endif
 
        if (dhcp_run(options, &pid_fd) == 0)
                retval = EXIT_SUCCESS;
index 21ddf699d38e40ddc4a694ab6525cc791dfb94f2..4f2c841c607f4399cf185dba36d36309657367d8 100644 (file)
--- a/dhcpcd.h
+++ b/dhcpcd.h
@@ -73,18 +73,10 @@ struct options {
        char interface[IF_NAMESIZE];
        char hostname[MAXHOSTNAMELEN];
        int fqdn;
-#ifdef ENABLE_CLASSID
        uint8_t classid[CLASSID_MAX_LEN + 1];
-#endif
-#ifdef ENABLE_CLIENTID
        char clientid[CLIENTID_MAX_LEN + 1];
-#endif
-#ifdef ENABLE_USERCLASS
        uint8_t userclass[USERCLASS_MAX_LEN + 1];
-#endif
-#ifdef ENABLE_VENDOR
        uint8_t vendor[VENDOR_MAX_LEN + 1];
-#endif
        uint8_t reqmask[256 / 8];
        uint8_t nomask[256 / 8];
        uint32_t leasetime;