From a76c62d6a528d7b22aff49f5fd662af02976cfbe Mon Sep 17 00:00:00 2001 From: Steven Barth Date: Mon, 14 Oct 2013 14:14:15 +0200 Subject: [PATCH] Prefer servers with bigger prefixes --- src/dhcpv6.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/dhcpv6.c b/src/dhcpv6.c index f8a0385..e9e6aaf 100644 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -570,7 +570,8 @@ static int dhcpv6_handle_advert(enum dhcpv6_msg orig, uint16_t olen, otype; uint8_t *odata; struct dhcpv6_server_cand cand = {false, false, 0, 0, {0}, NULL, NULL, 0, 0}; - bool have_na = false, have_pd = false; + bool have_na = false; + int have_pd = 0; dhcpv6_for_each_option(opt, end, otype, olen, odata) { if (orig == DHCPV6_MSG_SOLICIT && @@ -594,9 +595,13 @@ static int dhcpv6_handle_advert(enum dhcpv6_msg orig, } else if (otype == DHCPV6_OPT_IA_PD && request_prefix) { struct dhcpv6_ia_hdr *h = (struct dhcpv6_ia_hdr*)&odata[-4]; uint8_t *oend = odata + olen, *d; - dhcpv6_for_each_option(&h[1], oend, otype, olen, d) - if (otype == DHCPV6_OPT_IA_PREFIX) - have_pd = true; + dhcpv6_for_each_option(&h[1], oend, otype, olen, d) { + if (otype == DHCPV6_OPT_IA_PREFIX && (olen + 4) >= + (uint16_t)sizeof(struct dhcpv6_ia_prefix)) { + struct dhcpv6_ia_prefix *p = (struct dhcpv6_ia_prefix*)&odata[-4]; + have_pd = p->prefix; + } + } } else if (otype == DHCPV6_OPT_IA_NA) { struct dhcpv6_ia_hdr *h = (struct dhcpv6_ia_hdr*)&odata[-4]; uint8_t *oend = odata + olen, *d; @@ -617,7 +622,7 @@ static int dhcpv6_handle_advert(enum dhcpv6_msg orig, if (pd_mode != IA_MODE_NONE) { if (have_pd) - cand.preference += 2000; + cand.preference += 2000 + (128 - have_pd); else cand.preference -= 2000; } -- 2.39.2