diff --git a/CHANGELOG b/CHANGELOG index 260b587..4d88d94 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -54,6 +54,11 @@ version 2.62 two addresses in the same network. Thanks to Jim Bos for his help nailing this. + Teach DHCPv6 about the RFC 4242 information-refresh-time + option, and add parsing if the minutes, hours and days + format for options. Thanks to Francois-Xavier Le Bail for + the suggestion. + version 2.61 Re-write interface discovery code on *BSD to use diff --git a/dnsmasq.conf.example b/dnsmasq.conf.example index bde2fb3..4a4ac5b 100644 --- a/dnsmasq.conf.example +++ b/dnsmasq.conf.example @@ -326,6 +326,9 @@ # dnsmasq and another. #dhcp-option=option6:dns-server,[::],[1234::88] +# Ask client to poll for option changes every six hours. (RFC4242) +#dhcp-option=option6:information-refresh-time,6h + # Set the NTP time server address to be the same machine as # is running dnsmasq #dhcp-option=42,0.0.0.0 diff --git a/src/dhcp-common.c b/src/dhcp-common.c index b793311..da982aa 100644 --- a/src/dhcp-common.c +++ b/src/dhcp-common.c @@ -487,15 +487,15 @@ static const struct opttab_t { { "x-windows-fs", 48, OT_ADDR_LIST }, { "x-windows-dm", 49, OT_ADDR_LIST }, { "requested-address", 50, OT_INTERNAL | OT_ADDR_LIST }, - { "lease-time", 51, OT_INTERNAL | OT_DEC }, + { "lease-time", 51, OT_INTERNAL | OT_TIME }, { "option-overload", 52, OT_INTERNAL }, { "message-type", 53, OT_INTERNAL | OT_DEC }, { "server-identifier", 54, OT_INTERNAL | OT_ADDR_LIST }, { "parameter-request", 55, OT_INTERNAL }, { "message", 56, OT_INTERNAL }, { "max-message-size", 57, OT_INTERNAL }, - { "T1", 58, OT_INTERNAL | OT_DEC}, - { "T2", 59, OT_INTERNAL | OT_DEC}, + { "T1", 58, OT_INTERNAL | OT_TIME}, + { "T2", 59, OT_INTERNAL | OT_TIME}, { "vendor-class", 60, 0 }, { "client-id", 61, OT_INTERNAL }, { "nis+-domain", 64, OT_NAME }, @@ -546,6 +546,7 @@ static const struct opttab_t opttab6[] = { { "nis-domain", 29, OT_RFC1035_NAME }, { "nis+-domain", 30, OT_RFC1035_NAME }, { "sntp-server", 31, OT_ADDR_LIST }, + { "information-refresh-time", 32, OT_TIME }, { "FQDN", 39, OT_INTERNAL | OT_RFC1035_NAME }, { "ntp-server", 56, OT_ADDR_LIST }, { "bootfile-url", 59, OT_NAME }, @@ -710,14 +711,17 @@ char *option_string(int prot, unsigned int opt, unsigned char *val, int opt_len, } } #endif - else if ((ot[o].size & OT_DEC) && opt_len != 0) + else if ((ot[o].size & (OT_DEC | OT_TIME)) && opt_len != 0) { unsigned int dec = 0; for (i = 0; i < opt_len; i++) dec = (dec << 8) | val[i]; - sprintf(buf, "%u", dec); + if (ot[o].size & OT_TIME) + prettyprint_time(buf, dec); + else + sprintf(buf, "%u", dec); } else nodecode = 1; diff --git a/src/dnsmasq.h b/src/dnsmasq.h index 987934b..de26e8d 100644 --- a/src/dnsmasq.h +++ b/src/dnsmasq.h @@ -475,7 +475,7 @@ struct frec { #define OT_NAME 0x1000 #define OT_CSTRING 0x0800 #define OT_DEC 0x0400 - +#define OT_TIME 0x0200 /* actions in the daemon->helper RPC */ #define ACTION_DEL 1 diff --git a/src/option.c b/src/option.c index faef72a..7cdd243 100644 --- a/src/option.c +++ b/src/option.c @@ -764,7 +764,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags) } else if (c == '.') { - is_addr6 =is_dec = is_hex = 0; + is_addr6 = is_dec = is_hex = 0; dots++; } else if (c == '-') @@ -811,8 +811,36 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags) /* or names */ else if (opt_len & (OT_NAME | OT_RFC1035_NAME | OT_CSTRING)) is_addr6 = is_addr = is_dec = is_hex = 0; - - if (is_hex && digs > 1) + + if (found_dig && (opt_len & OT_TIME) && strlen(comma) > 0) + { + int val, fac = 1; + + switch (comma[strlen(comma) - 1]) + { + case 'd': + case 'D': + fac *= 24; + /* fall though */ + case 'h': + case 'H': + fac *= 60; + /* fall through */ + case 'm': + case 'M': + fac *= 60; + /* fall through */ + case 's': + case 'S': + comma[strlen(comma) - 1] = 0; + } + + new->len = 4; + new->val = opt_malloc(4); + val = atoi(comma); + *((int *)new->val) = htonl(val * fac); + } + else if (is_hex && digs > 1) { new->len = digs; new->val = opt_malloc(new->len);