htons(DHCPV6_OPT_S46_CONT_LW),
};
odhcp6c_add_state(STATE_ORO, oro, sizeof(oro));
-
- if (!(client_options & DHCPV6_IGNORE_OPT_UNICAST)) {
- uint16_t otype = htons(DHCPV6_OPT_UNICAST);
-
- odhcp6c_add_state(STATE_ORO, &otype, sizeof(otype));
- }
}
+ // Required oro
+ uint16_t req_oro[] = {
+ htons(DHCPV6_OPT_INF_MAX_RT),
+ htons(DHCPV6_OPT_SOL_MAX_RT),
+ htons(DHCPV6_OPT_INFO_REFRESH),
+ };
+ odhcp6c_add_state(STATE_ORO, req_oro, sizeof(req_oro));
// Configure IPv6-options
int val = 1;
enum {
IOV_HDR=0,
IOV_ORO,
- IOV_ORO_REFRESH,
IOV_CL_ID,
IOV_SRV_ID,
IOV_OPTS,
uint16_t length;
} reconf_accept = {htons(DHCPV6_OPT_RECONF_ACCEPT), 0};
- // Request Information Refresh
- uint16_t oro_refresh = htons(DHCPV6_OPT_INFO_REFRESH);
-
// Option list
size_t opts_len;
void *opts = odhcp6c_get_state(STATE_OPTS, &opts_len);
+ // Option Request List
+ size_t oro_entries, oro_len = 0;
+ uint16_t *oro, *s_oro = odhcp6c_get_state(STATE_ORO, &oro_entries);
+
+ oro_entries /= sizeof(*s_oro);
+ oro = alloca(oro_entries * sizeof(*oro));
+
+ for (size_t i = 0; i < oro_entries; i++) {
+ struct odhcp6c_opt *opt = odhcp6c_find_opt(htons(s_oro[i]));
+
+ if (opt) {
+ if (!(opt->flags & OPT_ORO))
+ continue;
+
+ if ((opt->flags & OPT_ORO_SOLICIT) && type != DHCPV6_MSG_SOLICIT)
+ continue;
+
+ if ((opt->flags & OPT_ORO_STATELESS) && type != DHCPV6_MSG_INFO_REQ)
+ continue;
+
+ if ((opt->flags & OPT_ORO_STATEFUL) && type == DHCPV6_MSG_INFO_REQ)
+ continue;
+ }
+
+ oro[oro_len++] = s_oro[i];
+ }
+ oro_len *= sizeof(*oro);
+
// Prepare Header
- size_t oro_len;
- void *oro = odhcp6c_get_state(STATE_ORO, &oro_len);
struct {
uint8_t type;
uint8_t trid[3];
struct iovec iov[IOV_TOTAL] = {
[IOV_HDR] = {&hdr, sizeof(hdr)},
[IOV_ORO] = {oro, oro_len},
- [IOV_ORO_REFRESH] = {&oro_refresh, 0},
[IOV_CL_ID] = {cl_id, cl_id_len},
[IOV_SRV_ID] = {srv_id, srv_id_len},
[IOV_OPTS] = { opts, opts_len },
};
size_t cnt = IOV_TOTAL;
- if (type == DHCPV6_MSG_INFO_REQ) {
- cnt = 9;
- iov[IOV_ORO_REFRESH].iov_len = sizeof(oro_refresh);
- hdr.oro_len = htons(oro_len + sizeof(oro_refresh));
- } else if (!request_prefix)
- cnt = 13;
+ if (type == DHCPV6_MSG_INFO_REQ)
+ cnt = 8;
+ else if (!request_prefix)
+ cnt = 12;
// Disable IAs if not used
if (type != DHCPV6_MSG_SOLICIT && ia_na_len == 0)
{ .code = DHCPV6_OPT_INTERFACE_ID, .flags = OPT_INTERNAL, .str = NULL },
{ .code = DHCPV6_OPT_RECONF_MESSAGE, .flags = OPT_INTERNAL, .str = NULL },
{ .code = DHCPV6_OPT_RECONF_ACCEPT, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
- { .code = DHCPV6_OPT_DNS_SERVERS, .flags = OPT_IP6 | OPT_ARRAY, .str = "dns" },
- { .code = DHCPV6_OPT_DNS_DOMAIN, .flags = OPT_DNS_STR, .str = "search" },
+ { .code = DHCPV6_OPT_SIP_SERVER_D, .flags = OPT_DNS_STR | OPT_ORO, .str = "sipserver_d" },
+ { .code = DHCPV6_OPT_SIP_SERVER_A, .flags = OPT_IP6 | OPT_ARRAY | OPT_ORO, .str = "sipserver_a" },
+ { .code = DHCPV6_OPT_DNS_SERVERS, .flags = OPT_IP6 | OPT_ARRAY | OPT_ORO, .str = "dns" },
+ { .code = DHCPV6_OPT_DNS_DOMAIN, .flags = OPT_DNS_STR | OPT_ORO, .str = "search" },
{ .code = DHCPV6_OPT_IA_PD, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
{ .code = DHCPV6_OPT_IA_PREFIX, .flags = OPT_INTERNAL, .str = NULL },
- { .code = DHCPV6_OPT_SNTP_SERVERS, .flags = OPT_IP6 | OPT_ARRAY, .str = "sntpservers" },
- { .code = DHCPV6_OPT_INFO_REFRESH, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
- { .code = DHCPV6_OPT_FQDN, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
- { .code = DHCPV6_OPT_NTP_SERVER, .flags = OPT_U8, .str = "ntpserver" },
- { .code = DHCPV6_OPT_SIP_SERVER_D, .flags = OPT_DNS_STR, .str = "sipserver_d" },
- { .code = DHCPV6_OPT_SIP_SERVER_A, .flags = OPT_IP6 | OPT_ARRAY, .str = "sipserver_a" },
- { .code = DHCPV6_OPT_AFTR_NAME, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
- { .code = DHCPV6_OPT_PD_EXCLUDE, .flags = OPT_INTERNAL, .str = NULL },
- { .code = DHCPV6_OPT_SOL_MAX_RT, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
- { .code = DHCPV6_OPT_INF_MAX_RT, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
+ { .code = DHCPV6_OPT_SNTP_SERVERS, .flags = OPT_IP6 | OPT_ARRAY | OPT_ORO, .str = "sntpservers" },
+ { .code = DHCPV6_OPT_INFO_REFRESH, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU | OPT_ORO | OPT_ORO_STATELESS, .str = NULL },
+ { .code = DHCPV6_OPT_FQDN, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU | OPT_ORO, .str = NULL },
+ { .code = DHCPV6_OPT_NTP_SERVER, .flags = OPT_U8 | OPT_ORO, .str = "ntpserver" },
+ { .code = DHCPV6_OPT_AFTR_NAME, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU | OPT_ORO, .str = NULL },
+ { .code = DHCPV6_OPT_PD_EXCLUDE, .flags = OPT_INTERNAL | OPT_ORO | OPT_ORO_STATEFUL, .str = NULL },
+ { .code = DHCPV6_OPT_SOL_MAX_RT, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU | OPT_ORO | OPT_ORO_SOLICIT, .str = NULL },
+ { .code = DHCPV6_OPT_INF_MAX_RT, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU | OPT_ORO | OPT_ORO_STATELESS, .str = NULL },
#ifdef EXT_CER_ID
{ .code = DHCPV6_OPT_CER_ID, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
#endif
{ .code = DHCPV6_OPT_S46_DMR, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
{ .code = DHCPV6_OPT_S46_V4V6BIND, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
{ .code = DHCPV6_OPT_S46_PORTPARAMS, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
- { .code = DHCPV6_OPT_S46_CONT_MAPE, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
- { .code = DHCPV6_OPT_S46_CONT_MAPT, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
- { .code = DHCPV6_OPT_S46_CONT_LW, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
+ { .code = DHCPV6_OPT_S46_CONT_MAPE, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU | OPT_ORO, .str = NULL },
+ { .code = DHCPV6_OPT_S46_CONT_MAPT, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU | OPT_ORO, .str = NULL },
+ { .code = DHCPV6_OPT_S46_CONT_LW, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU | OPT_ORO, .str = NULL },
{ .code = 0, .flags = 0, .str = NULL },
};
DHCPV6_OPT_INTERFACE_ID = 18,
DHCPV6_OPT_RECONF_MESSAGE = 19,
DHCPV6_OPT_RECONF_ACCEPT = 20,
+ DHCPV6_OPT_SIP_SERVER_D = 21,
+ DHCPV6_OPT_SIP_SERVER_A = 22,
DHCPV6_OPT_DNS_SERVERS = 23,
DHCPV6_OPT_DNS_DOMAIN = 24,
DHCPV6_OPT_IA_PD = 25,
DHCPV6_OPT_INFO_REFRESH = 32,
DHCPV6_OPT_FQDN = 39,
DHCPV6_OPT_NTP_SERVER = 56,
- DHCPV6_OPT_SIP_SERVER_D = 21,
- DHCPV6_OPT_SIP_SERVER_A = 22,
DHCPV6_OPT_AFTR_NAME = 64,
DHCPV6_OPT_PD_EXCLUDE = 67,
DHCPV6_OPT_SOL_MAX_RT = 82,
OPT_ARRAY = 0x10,
OPT_INTERNAL = 0x20,
OPT_NO_PASSTHRU = 0x40,
+ OPT_ORO = 0x80,
+ OPT_ORO_STATEFUL = 0x100,
+ OPT_ORO_STATELESS = 0x200,
+ OPT_ORO_SOLICIT = 0x400
};
struct odhcp6c_opt {
uint16_t code;
- uint8_t flags;
+ uint16_t flags;
const char *str;
};