From: Markus Stenberg Date: Wed, 31 Jul 2013 21:58:33 +0000 (+0200) Subject: Merge remote-tracking branch 'up/master' into hnet X-Git-Tag: debian/1.1+git20160131-1~133^2~1 X-Git-Url: https://git.decadent.org.uk/gitweb/?p=odhcp6c.git;a=commitdiff_plain;h=74ef11cad687fd165457f212cfe15bc5ad7a2cd1;hp=b5c20853fcbc081ad950ef2083a4f5c31d6ecb54 Merge remote-tracking branch 'up/master' into hnet --- diff --git a/README b/README index 16ac904..3f2087f 100644 --- a/README +++ b/README @@ -68,7 +68,7 @@ Environment: * SIP_DOMAIN A space-separated list of SIP domains * OPTION_ Custom option received as base-16 * PREFIXES A space-separated list of prefixes currently assigned - Format: /,preferred,valid[,excluded=/] + Format: /,preferred,valid[,excluded=/][,class=] * ADDRESSES A space-separated list of addresses currently assigned Format:
/,preferred,valid * RA_ADDRESSES A space-separated list of addresses from RA-prefixes diff --git a/src/dhcpv6.c b/src/dhcpv6.c index 9742c39..1df31cd 100644 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -142,8 +142,10 @@ int init_dhcpv6(const char *ifname, int request_pd) htons(DHCPV6_OPT_DNS_SERVERS), htons(DHCPV6_OPT_DNS_DOMAIN), htons(DHCPV6_OPT_NTP_SERVER), + htons(DHCPV6_OPT_SIP_SERVER_A), htons(DHCPV6_OPT_AFTR_NAME), htons(DHCPV6_OPT_PD_EXCLUDE), + htons(DHCPV6_OPT_PREFIX_CLASS), }; odhcp6c_add_state(STATE_ORO, oro, sizeof(oro)); @@ -827,11 +829,11 @@ static uint32_t dhcpv6_parse_ia(void *opt, void *end) uint16_t otype, olen; uint8_t *odata; - struct odhcp6c_entry entry = {IN6ADDR_ANY_INIT, - 0, 0, IN6ADDR_ANY_INIT, 0, 0}; - // Update address IA dhcpv6_for_each_option(opt, end, otype, olen, odata) { + struct odhcp6c_entry entry = {IN6ADDR_ANY_INIT, + 0, 0, IN6ADDR_ANY_INIT, 0, 0, 0}; + if (otype == DHCPV6_OPT_IA_PREFIX) { struct dhcpv6_ia_prefix *prefix = (void*)&odata[-4]; if (olen + 4U < sizeof(*prefix)) @@ -845,11 +847,17 @@ static uint32_t dhcpv6_parse_ia(void *opt, void *end) entry.length = prefix->prefix; entry.target = prefix->addr; + uint16_t stype, slen; + uint8_t *sdata; + + // Find prefix class, if any + dhcpv6_for_each_option(&prefix[1], odata + olen, + stype, slen, sdata) + if (stype == DHCPV6_OPT_PREFIX_CLASS && slen == 2) + entry.prefix_class = ntohs(*((uint16_t*)sdata)); // Parse PD-exclude bool ok = true; - uint16_t stype, slen; - uint8_t *sdata; dhcpv6_for_each_option(odata + sizeof(*prefix) - 4U, odata + olen, stype, slen, sdata) { if (stype != DHCPV6_OPT_PD_EXCLUDE || slen < 2) @@ -904,6 +912,15 @@ static uint32_t dhcpv6_parse_ia(void *opt, void *end) entry.length = 128; entry.target = addr->addr; + uint16_t stype, slen; + uint8_t *sdata; + + // Find prefix class, if any + dhcpv6_for_each_option(&addr[1], odata + olen, + stype, slen, sdata) + if (stype == DHCPV6_OPT_PREFIX_CLASS && slen == 2) + entry.prefix_class = ntohs(*((uint16_t*)sdata)); + odhcp6c_update_entry(STATE_IA_NA, &entry); } diff --git a/src/odhcp6c.c b/src/odhcp6c.c index f732d9e..d47e17c 100644 --- a/src/odhcp6c.c +++ b/src/odhcp6c.c @@ -460,6 +460,7 @@ void odhcp6c_update_entry_safe(enum odhcp6c_state state, struct odhcp6c_entry *n if (x) { x->valid = new->valid; x->preferred = new->preferred; + x->prefix_class = new->prefix_class; } else { odhcp6c_add_state(state, new, sizeof(*new)); } diff --git a/src/odhcp6c.h b/src/odhcp6c.h index ac0932f..e0f6f62 100644 --- a/src/odhcp6c.h +++ b/src/odhcp6c.h @@ -53,6 +53,8 @@ enum dhcvp6_opt { DHCPV6_OPT_SIP_SERVER_A = 22, DHCPV6_OPT_AFTR_NAME = 64, DHCPV6_OPT_PD_EXCLUDE = 67, + /* draft-bhandari-dhc-class-based-prefix */ + DHCPV6_OPT_PREFIX_CLASS = 200, /* NOT STANDARDIZED! */ }; enum dhcpv6_opt_npt { @@ -215,6 +217,7 @@ struct odhcp6c_entry { struct in6_addr target; uint32_t valid; uint32_t preferred; + uint32_t prefix_class; }; diff --git a/src/ra.c b/src/ra.c index 4690d41..9a57985 100644 --- a/src/ra.c +++ b/src/ra.c @@ -142,7 +142,7 @@ static void update_proc(const char *sect, const char *opt, uint32_t value) static bool ra_deduplicate(const struct in6_addr *any, uint8_t length) { - struct odhcp6c_entry entry = {IN6ADDR_ANY_INIT, length, 0, *any, 0, 0}; + struct odhcp6c_entry entry = {IN6ADDR_ANY_INIT, length, 0, *any, 0, 0, 0}; struct odhcp6c_entry *x = odhcp6c_find_entry(STATE_RA_PREFIX, &entry); if (x && IN6_ARE_ADDR_EQUAL(&x->target, any)) { odhcp6c_random(&x->target.s6_addr32[2], 2 * sizeof(uint32_t)); @@ -202,7 +202,7 @@ bool ra_process(void) bool found = false; uint8_t buf[1500]; struct nd_router_advert *adv = (struct nd_router_advert*)buf; - struct odhcp6c_entry entry = {IN6ADDR_ANY_INIT, 0, 0, IN6ADDR_ANY_INIT, 0, 0}; + struct odhcp6c_entry entry = {IN6ADDR_ANY_INIT, 0, 0, IN6ADDR_ANY_INIT, 0, 0, 0}; const struct in6_addr any = IN6ADDR_ANY_INIT; while (true) { diff --git a/src/script.c b/src/script.c index bda9749..74aea64 100644 --- a/src/script.c +++ b/src/script.c @@ -187,6 +187,9 @@ static void entry_to_env(const char *name, const void *data, size_t len, enum en } else { buf_len += snprintf(&buf[buf_len], 24, ",%u,%u", e[i].preferred, e[i].valid); } + if ((type == ENTRY_PREFIX || type == ENTRY_ADDRESS) && e[i].prefix_class) { + buf_len += snprintf(&buf[buf_len], 12, ",class=%u", e[i].prefix_class); + } if (type == ENTRY_PREFIX && e[i].priority) { // priority and router are abused for prefix exclusion