Commit bd08ae67 authored by Simon Kelley's avatar Simon Kelley

Allow option number zero in encapsulated DHCP options.

parent 4582c0ef
...@@ -512,7 +512,7 @@ void display_opts6(void) ...@@ -512,7 +512,7 @@ void display_opts6(void)
} }
#endif #endif
u16 lookup_dhcp_opt(int prot, char *name) int lookup_dhcp_opt(int prot, char *name)
{ {
const struct opttab_t *t; const struct opttab_t *t;
int i; int i;
...@@ -528,10 +528,10 @@ u16 lookup_dhcp_opt(int prot, char *name) ...@@ -528,10 +528,10 @@ u16 lookup_dhcp_opt(int prot, char *name)
if (strcasecmp(t[i].name, name) == 0) if (strcasecmp(t[i].name, name) == 0)
return t[i].val; 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; const struct opttab_t *t;
int i; int i;
......
...@@ -1216,8 +1216,8 @@ void log_tags(struct dhcp_netid *netid, u32 xid); ...@@ -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); int match_bytes(struct dhcp_opt *o, unsigned char *p, int len);
void dhcp_update_configs(struct dhcp_config *configs); void dhcp_update_configs(struct dhcp_config *configs);
void display_opts(void); void display_opts(void);
u16 lookup_dhcp_opt(int prot, char *name); int lookup_dhcp_opt(int prot, char *name);
u16 lookup_dhcp_len(int prot, u16 val); int lookup_dhcp_len(int prot, int val);
char *option_string(int prot, unsigned int opt, unsigned char *val, char *option_string(int prot, unsigned int opt, unsigned char *val,
int opt_len, char *buf, int buf_len); int opt_len, char *buf, int buf_len);
#ifdef HAVE_LINUX_NETWORK #ifdef HAVE_LINUX_NETWORK
......
...@@ -750,6 +750,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags) ...@@ -750,6 +750,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
struct dhcp_netid *np = NULL; struct dhcp_netid *np = NULL;
u16 opt_len = 0; u16 opt_len = 0;
int is6 = 0; int is6 = 0;
int option_ok = 0;
new->len = 0; new->len = 0;
new->flags = flags; new->flags = flags;
...@@ -769,16 +770,19 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags) ...@@ -769,16 +770,19 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
{ {
new->opt = atoi(arg); new->opt = atoi(arg);
opt_len = 0; opt_len = 0;
option_ok = 1;
break; break;
} }
if (strstr(arg, "option:") == arg) if (strstr(arg, "option:") == arg)
{ {
new->opt = lookup_dhcp_opt(AF_INET, arg+7); 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. */ opt_len = lookup_dhcp_len(AF_INET, new->opt);
if ((opt_len & OT_INTERNAL) && flags != DHOPT_MATCH) /* option:<optname> must follow tag and vendor string. */
new->opt = 0; if (!(opt_len & OT_INTERNAL) || flags == DHOPT_MATCH)
option_ok = 1;
}
break; break;
} }
#ifdef HAVE_DHCP6 #ifdef HAVE_DHCP6
...@@ -792,13 +796,16 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags) ...@@ -792,13 +796,16 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
{ {
new->opt = atoi(arg+8); new->opt = atoi(arg+8);
opt_len = 0; opt_len = 0;
option_ok = 1;
} }
else else
{ {
new->opt = lookup_dhcp_opt(AF_INET6, arg+8); 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) opt_len = lookup_dhcp_len(AF_INET6, new->opt);
new->opt = 0; if (!(opt_len & OT_INTERNAL) || flags == DHOPT_MATCH)
option_ok = 1;
}
} }
/* option6:<opt>|<optname> must follow tag and vendor string. */ /* option6:<opt>|<optname> must follow tag and vendor string. */
is6 = 1; is6 = 1;
...@@ -821,7 +828,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags) ...@@ -821,7 +828,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
new->flags |= DHOPT_RFC3925; new->flags |= DHOPT_RFC3925;
if (flags == DHOPT_MATCH) if (flags == DHOPT_MATCH)
{ {
new->opt = 1; /* avoid error below */ option_ok = 1;
break; break;
} }
} }
...@@ -848,16 +855,16 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags) ...@@ -848,16 +855,16 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
if (opt_len == 0 && if (opt_len == 0 &&
!(new->flags & DHOPT_RFC3925)) !(new->flags & DHOPT_RFC3925))
opt_len = lookup_dhcp_len(AF_INET6 ,new->opt); opt_len = lookup_dhcp_len(AF_INET6, new->opt);
} }
else else
#endif #endif
if (opt_len == 0 && if (opt_len == 0 &&
!(new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE | DHOPT_RFC3925))) !(new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE | DHOPT_RFC3925)))
opt_len = lookup_dhcp_len(AF_INET ,new->opt); opt_len = lookup_dhcp_len(AF_INET, new->opt);
/* option may be missing with rfc3925 match */ /* option may be missing with rfc3925 match */
if (new->opt == 0) if (!option_ok)
ret_err(_("bad dhcp-option")); ret_err(_("bad dhcp-option"));
if (comma) if (comma)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment