From: Markus Stenberg Date: Tue, 26 Mar 2013 13:12:50 +0000 (+0200) Subject: First hnet-based version. X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=4ad21618ad863b5f590ed00f2c7677605a98e39f;p=oweals%2Fodhcp6c.git First hnet-based version. --- diff --git a/README b/README index 5555a83..2a7ab63 100644 --- a/README +++ b/README @@ -55,7 +55,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 + Format: /,preferred,valid[,cls] * 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 e991958..013e215 100644 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -135,7 +135,8 @@ int init_dhcpv6(const char *ifname, int request_pd) htons(DHCPV6_OPT_DNS_DOMAIN), htons(DHCPV6_OPT_NTP_SERVER), htons(DHCPV6_OPT_SIP_SERVER_A), - htons(DHCPV6_OPT_SIP_SERVER_D)}; + htons(DHCPV6_OPT_PREFIX_CLASS) + }; odhcp6c_add_state(STATE_ORO, oro, sizeof(oro)); @@ -725,11 +726,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)) @@ -743,6 +744,14 @@ 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(odata, 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_PD, &entry); } else if (otype == DHCPV6_OPT_IA_ADDR) { diff --git a/src/odhcp6c.c b/src/odhcp6c.c index 6451312..64d363f 100644 --- a/src/odhcp6c.c +++ b/src/odhcp6c.c @@ -427,6 +427,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 eae9b7a..1b46af0 100644 --- a/src/odhcp6c.h +++ b/src/odhcp6c.h @@ -51,6 +51,9 @@ enum dhcvp6_opt { DHCPV6_OPT_NTP_SERVER = 56, DHCPV6_OPT_SIP_SERVER_D = 21, DHCPV6_OPT_SIP_SERVER_A = 22, + + /* draft-bhandari-dhc-class-based-prefix */ + DHCPV6_OPT_PREFIX_CLASS = 200, /* NOT STANDARDIZED! */ }; enum dhcpv6_opt_npt { @@ -131,7 +134,6 @@ struct dhcpv6_duid { uint8_t data[128]; } _packed; - #define dhcpv6_for_each_option(start, end, otype, olen, odata)\ for (uint8_t *_o = (uint8_t*)(start); _o + 4 <= (uint8_t*)(end) &&\ ((otype) = _o[0] << 8 | _o[1]) && ((odata) = (void*)&_o[4]) &&\ @@ -197,6 +199,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 4ed5371..580d4cd 100644 --- a/src/ra.c +++ b/src/ra.c @@ -123,7 +123,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)); @@ -173,7 +173,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; odhcp6c_expire(); diff --git a/src/script.c b/src/script.c index 205c581..7368080 100644 --- a/src/script.c +++ b/src/script.c @@ -152,6 +152,8 @@ static void entry_to_env(const char *name, const void *data, size_t len, bool ho buf_len += snprintf(&buf[buf_len], 12, ",%u", e[i].priority); } else { buf_len += snprintf(&buf[buf_len], 24, ",%u,%u", e[i].preferred, e[i].valid); + if (e[i].prefix_class) + buf_len += snprintf(&buf[buf_len], 12, ",%u", e[i].prefix_class); } } buf[buf_len++] = ' ';