|
|
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 |
|