From: Steven Barth Date: Sat, 31 Aug 2013 08:11:15 +0000 (+0200) Subject: Merge branch 'hnet' X-Git-Tag: debian/1.1+git20160131-1~133 X-Git-Url: https://git.decadent.org.uk/gitweb/?p=odhcp6c.git;a=commitdiff_plain;h=9c409ef5ce654ed5dd3ce706317eaac718a22983;hp=d19d55cec4083b942a9e13a188659c7097d659d2 Merge branch 'hnet' Conflicts: src/ra.c --- diff --git a/README b/README index cccb3ea..32b6893 100644 --- a/README +++ b/README @@ -67,7 +67,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 3f5bc83..fe4cc0b 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 38b8e82..b2c6b98 100644 --- a/src/odhcp6c.c +++ b/src/odhcp6c.c @@ -459,6 +459,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 4c1302c..9c1ed74 100644 --- a/src/ra.c +++ b/src/ra.c @@ -133,7 +133,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