Blame SOURCES/dnsmasq-2.66-Allow-option_number_zero_in_encapsulated_DHCP_options.patch

cab8d5
From bd08ae67f9a0cae2ce15be885254cad9449d4551 Mon Sep 17 00:00:00 2001
cab8d5
From: Simon Kelley <simon@thekelleys.org.uk>
cab8d5
Date: Fri, 19 Apr 2013 10:22:06 +0100
cab8d5
Subject: [PATCH] Allow option number zero in encapsulated DHCP options.
cab8d5
cab8d5
---
cab8d5
 src/dhcp-common.c |  6 +++---
cab8d5
 src/dnsmasq.h     |  4 ++--
cab8d5
 src/option.c      | 33 ++++++++++++++++++++-------------
cab8d5
 3 files changed, 25 insertions(+), 18 deletions(-)
cab8d5
cab8d5
diff --git a/src/dhcp-common.c b/src/dhcp-common.c
cab8d5
index f4fd088..8de4268 100644
cab8d5
--- a/src/dhcp-common.c
cab8d5
+++ b/src/dhcp-common.c
cab8d5
@@ -512,7 +512,7 @@ void display_opts6(void)
cab8d5
 }
cab8d5
 #endif
cab8d5
 
cab8d5
-u16 lookup_dhcp_opt(int prot, char *name)
cab8d5
+int lookup_dhcp_opt(int prot, char *name)
cab8d5
 {
cab8d5
   const struct opttab_t *t;
cab8d5
   int i;
cab8d5
@@ -528,10 +528,10 @@ u16 lookup_dhcp_opt(int prot, char *name)
cab8d5
     if (strcasecmp(t[i].name, name) == 0)
cab8d5
       return t[i].val;
cab8d5
   
cab8d5
-  return 0;
cab8d5
+  return -1;
cab8d5
 }
cab8d5
 
cab8d5
-u16 lookup_dhcp_len(int prot, u16 val)
cab8d5
+int lookup_dhcp_len(int prot, int val)
cab8d5
 {
cab8d5
   const struct opttab_t *t;
cab8d5
   int i;
cab8d5
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
cab8d5
index 69ae7a7..41e2798 100644
cab8d5
--- a/src/dnsmasq.h
cab8d5
+++ b/src/dnsmasq.h
cab8d5
@@ -1216,8 +1216,8 @@ void log_tags(struct dhcp_netid *netid, u32 xid);
cab8d5
 int match_bytes(struct dhcp_opt *o, unsigned char *p, int len);
cab8d5
 void dhcp_update_configs(struct dhcp_config *configs);
cab8d5
 void display_opts(void);
cab8d5
-u16 lookup_dhcp_opt(int prot, char *name);
cab8d5
-u16 lookup_dhcp_len(int prot, u16 val);
cab8d5
+int lookup_dhcp_opt(int prot, char *name);
cab8d5
+int lookup_dhcp_len(int prot, int val);
cab8d5
 char *option_string(int prot, unsigned int opt, unsigned char *val, 
cab8d5
 		    int opt_len, char *buf, int buf_len);
cab8d5
 #ifdef HAVE_LINUX_NETWORK
cab8d5
diff --git a/src/option.c b/src/option.c
cab8d5
index b2596ec..2a61017 100644
cab8d5
--- a/src/option.c
cab8d5
+++ b/src/option.c
cab8d5
@@ -750,6 +750,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
cab8d5
   struct dhcp_netid *np = NULL;
cab8d5
   u16 opt_len = 0;
cab8d5
   int is6 = 0;
cab8d5
+  int option_ok = 0;
cab8d5
 
cab8d5
   new->len = 0;
cab8d5
   new->flags = flags;
cab8d5
@@ -769,16 +770,19 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
cab8d5
 	{
cab8d5
 	  new->opt = atoi(arg);
cab8d5
 	  opt_len = 0;
cab8d5
+	  option_ok = 1;
cab8d5
 	  break;
cab8d5
 	}
cab8d5
       
cab8d5
       if (strstr(arg, "option:") == arg)
cab8d5
 	{
cab8d5
-	  new->opt = lookup_dhcp_opt(AF_INET, arg+7);
cab8d5
-	  opt_len = lookup_dhcp_len(AF_INET, new->opt);
cab8d5
-	  /* option:<optname> must follow tag and vendor string. */
cab8d5
-	  if ((opt_len & OT_INTERNAL) && flags != DHOPT_MATCH)
cab8d5
-	    new->opt = 0;
cab8d5
+	  if ((new->opt = lookup_dhcp_opt(AF_INET, arg+7)) != -1)
cab8d5
+	    {
cab8d5
+	      opt_len = lookup_dhcp_len(AF_INET, new->opt);
cab8d5
+	      /* option:<optname> must follow tag and vendor string. */
cab8d5
+	      if (!(opt_len & OT_INTERNAL) || flags == DHOPT_MATCH)
cab8d5
+		option_ok = 1;
cab8d5
+	    }
cab8d5
 	  break;
cab8d5
 	}
cab8d5
 #ifdef HAVE_DHCP6
cab8d5
@@ -792,13 +796,16 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
cab8d5
 	    {
cab8d5
 	      new->opt = atoi(arg+8);
cab8d5
 	      opt_len = 0;
cab8d5
+	      option_ok = 1;
cab8d5
 	    }
cab8d5
 	  else
cab8d5
 	    {
cab8d5
-	      new->opt = lookup_dhcp_opt(AF_INET6, arg+8);
cab8d5
-	      opt_len = lookup_dhcp_len(AF_INET6, new->opt);
cab8d5
-	      if ((opt_len & OT_INTERNAL) && flags != DHOPT_MATCH)
cab8d5
-		new->opt = 0;
cab8d5
+	      if ((new->opt = lookup_dhcp_opt(AF_INET6, arg+8)) != -1)
cab8d5
+		{
cab8d5
+		  opt_len = lookup_dhcp_len(AF_INET6, new->opt);
cab8d5
+		  if (!(opt_len & OT_INTERNAL) || flags == DHOPT_MATCH)
cab8d5
+		    option_ok = 1;
cab8d5
+		}
cab8d5
 	    }
cab8d5
 	  /* option6:<opt>|<optname> must follow tag and vendor string. */
cab8d5
 	  is6 = 1;
cab8d5
@@ -821,7 +828,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
cab8d5
 	  new->flags |= DHOPT_RFC3925;
cab8d5
 	  if (flags == DHOPT_MATCH)
cab8d5
 	    {
cab8d5
-	      new->opt = 1; /* avoid error below */
cab8d5
+	      option_ok = 1;
cab8d5
 	      break;
cab8d5
 	    }
cab8d5
 	}
cab8d5
@@ -848,16 +855,16 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
cab8d5
       
cab8d5
       if (opt_len == 0 &&
cab8d5
 	  !(new->flags & DHOPT_RFC3925))
cab8d5
-	opt_len = lookup_dhcp_len(AF_INET6 ,new->opt);
cab8d5
+	opt_len = lookup_dhcp_len(AF_INET6, new->opt);
cab8d5
     }
cab8d5
   else
cab8d5
 #endif
cab8d5
     if (opt_len == 0 &&
cab8d5
 	!(new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE | DHOPT_RFC3925)))
cab8d5
-      opt_len = lookup_dhcp_len(AF_INET ,new->opt);
cab8d5
+      opt_len = lookup_dhcp_len(AF_INET, new->opt);
cab8d5
   
cab8d5
   /* option may be missing with rfc3925 match */
cab8d5
-  if (new->opt == 0)
cab8d5
+  if (!option_ok)
cab8d5
     ret_err(_("bad dhcp-option"));
cab8d5
   
cab8d5
   if (comma)
cab8d5
-- 
cab8d5
1.8.1.4
cab8d5