struct dhcp6_message *m;
struct dhcp6_option *o, *so;
const struct dhcp6_option *si, *unicast;
- size_t l, len, ml, auth_len;
+ size_t l, n, len, ml, auth_len;
uint8_t u8, type;
uint16_t *u16, n_options;
struct if_options *ifo;
- const struct dhcp_opt *opt;
+ const struct dhcp_opt *opt, *opt2;
uint8_t IA, *p;
uint32_t u32;
const struct ipv6_addr *ap;
for (l = 0, opt = ifp->ctx->dhcp6_opts;
l < ifp->ctx->dhcp6_opts_len;
l++, opt++)
+ {
+ for (n = 0, opt2 = ifo->dhcp6_override;
+ n < ifo->dhcp6_override_len;
+ n++, opt2++)
+ {
+ if (opt->option == opt2->option)
+ break;
+ }
+ if (n < ifo->dhcp6_override_len)
+ continue;
+ if (!(opt->type & NOREQ) &&
+ (opt->type & REQUEST ||
+ has_option_mask(ifo->requestmask6, opt->option)))
+ {
+ n_options++;
+ len += sizeof(*u16);
+ }
+ }
+ for (l = 0, opt = ifo->dhcp6_override;
+ l < ifo->dhcp6_override_len;
+ l++, opt++)
{
if (!(opt->type & NOREQ) &&
(opt->type & REQUEST ||
for (l = 0, opt = ifp->ctx->dhcp6_opts;
l < ifp->ctx->dhcp6_opts_len;
l++, opt++)
+ {
+ for (n = 0, opt2 = ifo->dhcp6_override;
+ n < ifo->dhcp6_override_len;
+ n++, opt2++)
+ {
+ if (opt->option == opt2->option)
+ break;
+ }
+ if (n < ifo->dhcp6_override_len)
+ continue;
+ if (!(opt->type & NOREQ) &&
+ (opt->type & REQUEST ||
+ has_option_mask(ifo->requestmask6,
+ opt->option)))
+ {
+ *u16++ = htons(opt->option);
+ o->len += sizeof(*u16);
+ }
+ }
+ for (l = 0, opt = ifo->dhcp6_override;
+ l < ifo->dhcp6_override_len;
+ l++, opt++)
{
if (!(opt->type & NOREQ) &&
(opt->type & REQUEST ||
static const char *
set_option_space(struct dhcpcd_ctx *ctx,
- const char *arg, const struct dhcp_opt **d, size_t *dl,
+ const char *arg,
+ const struct dhcp_opt **d, size_t *dl,
+ const struct dhcp_opt **od, size_t *odl,
struct if_options *ifo,
uint8_t *request[], uint8_t *require[], uint8_t *no[])
{
if (strncmp(arg, "dhcp6_", strlen("dhcp6_")) == 0) {
*d = ctx->dhcp6_opts;
*dl = ctx->dhcp6_opts_len;
+ *od = ifo->dhcp6_override;
+ *odl = ifo->dhcp6_override_len;
*request = ifo->requestmask6;
*require = ifo->requiremask6;
*no = ifo->nomask6;
#ifdef INET
*d = ctx->dhcp_opts;
*dl = ctx->dhcp_opts_len;
+ *od = ifo->dhcp_override;
+ *odl = ifo->dhcp_override_len;
#else
*d = NULL;
*dl = 0;
+ *od = NULL;
+ *odl = 0;
#endif
*request = ifo->requestmask;
*require = ifo->requiremask;
struct in_addr addr, addr2;
in_addr_t *naddr;
struct rt *rt;
- const struct dhcp_opt *d;
+ const struct dhcp_opt *d, *od;
uint8_t *request, *require, *no;
struct dhcp_opt **dop, *ndop;
- size_t *dop_len, dl;
+ size_t *dop_len, dl, odl;
struct vivco *vivco;
struct token *token;
struct group *grp;
}
break;
case 'o':
- arg = set_option_space(ctx, arg, &d, &dl, ifo,
+ arg = set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo,
&request, &require, &no);
- if (make_option_mask(d, dl, request, arg, 1) != 0 ||
- make_option_mask(d, dl, no, arg, -1) != 0)
+ if (make_option_mask(d, dl, od, odl, request, arg, 1) != 0 ||
+ make_option_mask(d, dl, od, odl, no, arg, -1) != 0)
{
syslog(LOG_ERR, "unknown option `%s'", arg);
return -1;
ifo->options |= DHCPCD_MASTER;
break;
case 'O':
- arg = set_option_space(ctx, arg, &d, &dl, ifo,
+ arg = set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo,
&request, &require, &no);
- if (make_option_mask(d, dl, request, arg, -1) != 0 ||
- make_option_mask(d, dl, require, arg, -1) != 0 ||
- make_option_mask(d, dl, no, arg, 1) != 0)
+ if (make_option_mask(d, dl, od, odl, request, arg, -1) != 0 ||
+ make_option_mask(d, dl, od, odl, require, arg, -1) != 0 ||
+ make_option_mask(d, dl, od, odl, no, arg, 1) != 0)
{
syslog(LOG_ERR, "unknown option `%s'", arg);
return -1;
}
break;
case 'Q':
- arg = set_option_space(ctx, arg, &d, &dl, ifo,
+ arg = set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo,
&request, &require, &no);
- if (make_option_mask(d, dl, require, arg, 1) != 0 ||
- make_option_mask(d, dl, request, arg, 1) != 0 ||
- make_option_mask(d, dl, no, arg, -1) != 0)
+ if (make_option_mask(d, dl, od, odl, require, arg, 1) != 0 ||
+ make_option_mask(d, dl, od, odl, request, arg, 1) != 0 ||
+ make_option_mask(d, dl, od, odl, no, arg, -1) != 0)
{
syslog(LOG_ERR, "unknown option `%s'", arg);
return -1;
}
break;
case O_DESTINATION:
- if (make_option_mask(ctx->dhcp_opts, ctx->dhcp_opts_len,
- ifo->dstmask, arg, 2) != 0) {
+ arg = set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo,
+ &request, &require, &no);
+ if (make_option_mask(d, dl, od, odl,
+ ifo->dstmask, arg, 2) != 0)
+ {
if (errno == EINVAL)
syslog(LOG_ERR, "option `%s' does not take"
" an IPv4 address", arg);