]> git.ipfire.org Git - people/ms/dnsmasq.git/commitdiff
Allow option number zero in encapsulated DHCP options.
authorSimon Kelley <simon@thekelleys.org.uk>
Fri, 19 Apr 2013 09:22:06 +0000 (10:22 +0100)
committerSimon Kelley <simon@thekelleys.org.uk>
Fri, 19 Apr 2013 09:22:06 +0000 (10:22 +0100)
src/dhcp-common.c
src/dnsmasq.h
src/option.c

index f4fd0889bc21b6cffaf0c79d4077657307b48811..8de426854e45f2b111d3b0482eba7640cfc31905 100644 (file)
@@ -512,7 +512,7 @@ void display_opts6(void)
 }
 #endif
 
-u16 lookup_dhcp_opt(int prot, char *name)
+int lookup_dhcp_opt(int prot, char *name)
 {
   const struct opttab_t *t;
   int i;
@@ -528,10 +528,10 @@ u16 lookup_dhcp_opt(int prot, char *name)
     if (strcasecmp(t[i].name, name) == 0)
       return t[i].val;
   
-  return 0;
+  return -1;
 }
 
-u16 lookup_dhcp_len(int prot, u16 val)
+int lookup_dhcp_len(int prot, int val)
 {
   const struct opttab_t *t;
   int i;
index 69ae7a7ad3ff31e899814876e5d29bb54fb913b5..41e27984eb21e338e3814e954f900379dd7fbde2 100644 (file)
@@ -1216,8 +1216,8 @@ void log_tags(struct dhcp_netid *netid, u32 xid);
 int match_bytes(struct dhcp_opt *o, unsigned char *p, int len);
 void dhcp_update_configs(struct dhcp_config *configs);
 void display_opts(void);
-u16 lookup_dhcp_opt(int prot, char *name);
-u16 lookup_dhcp_len(int prot, u16 val);
+int lookup_dhcp_opt(int prot, char *name);
+int lookup_dhcp_len(int prot, int val);
 char *option_string(int prot, unsigned int opt, unsigned char *val, 
                    int opt_len, char *buf, int buf_len);
 #ifdef HAVE_LINUX_NETWORK
index b2596ec07ea38cc167409afc338b5d5d0c9df6d5..2a6101737f7ec076226ffa366a41915f8a67e3d0 100644 (file)
@@ -750,6 +750,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
   struct dhcp_netid *np = NULL;
   u16 opt_len = 0;
   int is6 = 0;
+  int option_ok = 0;
 
   new->len = 0;
   new->flags = flags;
@@ -769,16 +770,19 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
        {
          new->opt = atoi(arg);
          opt_len = 0;
+         option_ok = 1;
          break;
        }
       
       if (strstr(arg, "option:") == arg)
        {
-         new->opt = lookup_dhcp_opt(AF_INET, arg+7);
-         opt_len = lookup_dhcp_len(AF_INET, new->opt);
-         /* option:<optname> must follow tag and vendor string. */
-         if ((opt_len & OT_INTERNAL) && flags != DHOPT_MATCH)
-           new->opt = 0;
+         if ((new->opt = lookup_dhcp_opt(AF_INET, arg+7)) != -1)
+           {
+             opt_len = lookup_dhcp_len(AF_INET, new->opt);
+             /* option:<optname> must follow tag and vendor string. */
+             if (!(opt_len & OT_INTERNAL) || flags == DHOPT_MATCH)
+               option_ok = 1;
+           }
          break;
        }
 #ifdef HAVE_DHCP6
@@ -792,13 +796,16 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
            {
              new->opt = atoi(arg+8);
              opt_len = 0;
+             option_ok = 1;
            }
          else
            {
-             new->opt = lookup_dhcp_opt(AF_INET6, arg+8);
-             opt_len = lookup_dhcp_len(AF_INET6, new->opt);
-             if ((opt_len & OT_INTERNAL) && flags != DHOPT_MATCH)
-               new->opt = 0;
+             if ((new->opt = lookup_dhcp_opt(AF_INET6, arg+8)) != -1)
+               {
+                 opt_len = lookup_dhcp_len(AF_INET6, new->opt);
+                 if (!(opt_len & OT_INTERNAL) || flags == DHOPT_MATCH)
+                   option_ok = 1;
+               }
            }
          /* option6:<opt>|<optname> must follow tag and vendor string. */
          is6 = 1;
@@ -821,7 +828,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
          new->flags |= DHOPT_RFC3925;
          if (flags == DHOPT_MATCH)
            {
-             new->opt = 1; /* avoid error below */
+             option_ok = 1;
              break;
            }
        }
@@ -848,16 +855,16 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
       
       if (opt_len == 0 &&
          !(new->flags & DHOPT_RFC3925))
-       opt_len = lookup_dhcp_len(AF_INET6 ,new->opt);
+       opt_len = lookup_dhcp_len(AF_INET6new->opt);
     }
   else
 #endif
     if (opt_len == 0 &&
        !(new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE | DHOPT_RFC3925)))
-      opt_len = lookup_dhcp_len(AF_INET ,new->opt);
+      opt_len = lookup_dhcp_len(AF_INETnew->opt);
   
   /* option may be missing with rfc3925 match */
-  if (new->opt == 0)
+  if (!option_ok)
     ret_err(_("bad dhcp-option"));
   
   if (comma)