]>
Commit | Line | Data |
---|---|---|
efbd3a9a MT |
1 | From ca85a28241ef87919d68d52c843b6964b7070e11 Mon Sep 17 00:00:00 2001 |
2 | From: Simon Kelley <simon@thekelleys.org.uk> | |
3 | Date: Wed, 13 May 2015 22:33:04 +0100 | |
4 | Subject: [PATCH 92/98] Allow T1 and T2 DHCPv4 options to be set. | |
5 | ||
6 | --- | |
7 | CHANGELOG | 3 +++ | |
8 | dnsmasq.conf.example | 8 ++++++ | |
9 | src/dhcp-common.c | 4 +-- | |
10 | src/rfc2131.c | 71 ++++++++++++++++++++++++++++++++++++---------------- | |
11 | 4 files changed, 63 insertions(+), 23 deletions(-) | |
12 | ||
13 | diff --git a/CHANGELOG b/CHANGELOG | |
14 | index 94a521f996e2..ef39a415788b 100644 | |
15 | --- a/CHANGELOG | |
16 | +++ b/CHANGELOG | |
17 | @@ -118,6 +118,9 @@ version 2.73 | |
18 | Check IPv4-mapped IPv6 addresses when --stop-rebind | |
19 | is active. Thanks to Jordan Milne for spotting this. | |
20 | ||
21 | + Allow DHCPv4 options T1 and T2 to be set using --dhcp-option. | |
22 | + Thanks to Kevin Benton for patches and work on this. | |
23 | + | |
24 | ||
25 | version 2.72 | |
26 | Add ra-advrouter mode, for RFC-3775 mobile IPv6 support. | |
27 | diff --git a/dnsmasq.conf.example b/dnsmasq.conf.example | |
28 | index 67be99acb028..1ae11dfb5358 100644 | |
29 | --- a/dnsmasq.conf.example | |
30 | +++ b/dnsmasq.conf.example | |
31 | @@ -345,6 +345,14 @@ | |
32 | # Ask client to poll for option changes every six hours. (RFC4242) | |
33 | #dhcp-option=option6:information-refresh-time,6h | |
34 | ||
35 | +# Set option 58 client renewal time (T1). Defaults to half of the | |
36 | +# lease time if not specified. (RFC2132) | |
37 | +#dhcp-option=option:T1:1m | |
38 | + | |
39 | +# Set option 59 rebinding time (T2). Defaults to 7/8 of the | |
40 | +# lease time if not specified. (RFC2132) | |
41 | +#dhcp-option=option:T2:2m | |
42 | + | |
43 | # Set the NTP time server address to be the same machine as | |
44 | # is running dnsmasq | |
45 | #dhcp-option=42,0.0.0.0 | |
46 | diff --git a/src/dhcp-common.c b/src/dhcp-common.c | |
47 | index ce115202a646..bc48f41a14d7 100644 | |
48 | --- a/src/dhcp-common.c | |
49 | +++ b/src/dhcp-common.c | |
50 | @@ -545,8 +545,8 @@ static const struct opttab_t { | |
51 | { "parameter-request", 55, OT_INTERNAL }, | |
52 | { "message", 56, OT_INTERNAL }, | |
53 | { "max-message-size", 57, OT_INTERNAL }, | |
54 | - { "T1", 58, OT_INTERNAL | OT_TIME}, | |
55 | - { "T2", 59, OT_INTERNAL | OT_TIME}, | |
56 | + { "T1", 58, OT_TIME}, | |
57 | + { "T2", 59, OT_TIME}, | |
58 | { "vendor-class", 60, 0 }, | |
59 | { "client-id", 61, OT_INTERNAL }, | |
60 | { "nis+-domain", 64, OT_NAME }, | |
61 | diff --git a/src/rfc2131.c b/src/rfc2131.c | |
62 | index 55526443dc84..a10e499ef768 100644 | |
63 | --- a/src/rfc2131.c | |
64 | +++ b/src/rfc2131.c | |
65 | @@ -52,7 +52,9 @@ static void do_options(struct dhcp_context *context, | |
66 | int null_term, int pxearch, | |
67 | unsigned char *uuid, | |
68 | int vendor_class_len, | |
69 | - time_t now); | |
70 | + time_t now, | |
71 | + unsigned int lease_time, | |
72 | + unsigned short fuzz); | |
73 | ||
74 | ||
75 | static void match_vendor_opts(unsigned char *opt, struct dhcp_opt *dopt); | |
76 | @@ -610,7 +612,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, | |
77 | ||
78 | clear_packet(mess, end); | |
79 | do_options(context, mess, end, NULL, hostname, get_domain(mess->yiaddr), | |
80 | - netid, subnet_addr, 0, 0, -1, NULL, vendor_class_len, now); | |
81 | + netid, subnet_addr, 0, 0, -1, NULL, vendor_class_len, now, 0xffffffff, 0); | |
82 | } | |
83 | } | |
84 | ||
85 | @@ -1042,13 +1044,8 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, | |
86 | option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr)); | |
87 | option_put(mess, end, OPTION_LEASE_TIME, 4, time); | |
88 | /* T1 and T2 are required in DHCPOFFER by HP's wacky Jetdirect client. */ | |
89 | - if (time != 0xffffffff) | |
90 | - { | |
91 | - option_put(mess, end, OPTION_T1, 4, (time/2)); | |
92 | - option_put(mess, end, OPTION_T2, 4, (time*7)/8); | |
93 | - } | |
94 | do_options(context, mess, end, req_options, offer_hostname, get_domain(mess->yiaddr), | |
95 | - netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now); | |
96 | + netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now, time, fuzz); | |
97 | ||
98 | return dhcp_packet_size(mess, agent_id, real_end); | |
99 | ||
100 | @@ -1367,15 +1364,8 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, | |
101 | option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK); | |
102 | option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr)); | |
103 | option_put(mess, end, OPTION_LEASE_TIME, 4, time); | |
104 | - if (time != 0xffffffff) | |
105 | - { | |
106 | - while (fuzz > (time/16)) | |
107 | - fuzz = fuzz/2; | |
108 | - option_put(mess, end, OPTION_T1, 4, (time/2) - fuzz); | |
109 | - option_put(mess, end, OPTION_T2, 4, ((time/8)*7) - fuzz); | |
110 | - } | |
111 | do_options(context, mess, end, req_options, hostname, get_domain(mess->yiaddr), | |
112 | - netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now); | |
113 | + netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now, time, fuzz); | |
114 | } | |
115 | ||
116 | return dhcp_packet_size(mess, agent_id, real_end); | |
117 | @@ -1440,7 +1430,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, | |
118 | } | |
119 | ||
120 | do_options(context, mess, end, req_options, hostname, get_domain(mess->ciaddr), | |
121 | - netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now); | |
122 | + netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now, 0xffffffff, 0); | |
123 | ||
124 | *is_inform = 1; /* handle reply differently */ | |
125 | return dhcp_packet_size(mess, agent_id, real_end); | |
126 | @@ -2137,7 +2127,9 @@ static void do_options(struct dhcp_context *context, | |
127 | int null_term, int pxe_arch, | |
128 | unsigned char *uuid, | |
129 | int vendor_class_len, | |
130 | - time_t now) | |
131 | + time_t now, | |
132 | + unsigned int lease_time, | |
133 | + unsigned short fuzz) | |
134 | { | |
135 | struct dhcp_opt *opt, *config_opts = daemon->dhcp_opts; | |
136 | struct dhcp_boot *boot; | |
137 | @@ -2261,7 +2253,42 @@ static void do_options(struct dhcp_context *context, | |
138 | /* rfc3011 says this doesn't need to be in the requested options list. */ | |
139 | if (subnet_addr.s_addr) | |
140 | option_put(mess, end, OPTION_SUBNET_SELECT, INADDRSZ, ntohl(subnet_addr.s_addr)); | |
141 | - | |
142 | + | |
143 | + if (lease_time != 0xffffffff) | |
144 | + { | |
145 | + unsigned int t1val = lease_time/2; | |
146 | + unsigned int t2val = (lease_time*7)/8; | |
147 | + unsigned int hval; | |
148 | + | |
149 | + /* If set by user, sanity check, so not longer than lease. */ | |
150 | + if ((opt = option_find2(OPTION_T1))) | |
151 | + { | |
152 | + hval = ntohl(*((unsigned int *)opt->val)); | |
153 | + if (hval < lease_time && hval > 2) | |
154 | + t1val = hval; | |
155 | + } | |
156 | + | |
157 | + if ((opt = option_find2(OPTION_T2))) | |
158 | + { | |
159 | + hval = ntohl(*((unsigned int *)opt->val)); | |
160 | + if (hval < lease_time && hval > 2) | |
161 | + t2val = hval; | |
162 | + } | |
163 | + | |
164 | + while (fuzz > (t1val/8)) | |
165 | + fuzz = fuzz/2; | |
166 | + | |
167 | + t1val -= fuzz; | |
168 | + t2val -= fuzz; | |
169 | + | |
170 | + /* ensure T1 is still < T2 */ | |
171 | + if (t2val <= t1val) | |
172 | + t1val = t2val - 1; | |
173 | + | |
174 | + option_put(mess, end, OPTION_T1, 4, t1val); | |
175 | + option_put(mess, end, OPTION_T2, 4, t2val); | |
176 | + } | |
177 | + | |
178 | /* replies to DHCPINFORM may not have a valid context */ | |
179 | if (context) | |
180 | { | |
181 | @@ -2356,12 +2383,14 @@ static void do_options(struct dhcp_context *context, | |
182 | if (!(opt->flags & DHOPT_FORCE) && !in_list(req_options, optno)) | |
183 | continue; | |
184 | ||
185 | - /* prohibit some used-internally options */ | |
186 | + /* prohibit some used-internally options. T1 and T2 already handled. */ | |
187 | if (optno == OPTION_CLIENT_FQDN || | |
188 | optno == OPTION_MAXMESSAGE || | |
189 | optno == OPTION_OVERLOAD || | |
190 | optno == OPTION_PAD || | |
191 | - optno == OPTION_END) | |
192 | + optno == OPTION_END || | |
193 | + optno == OPTION_T1 || | |
194 | + optno == OPTION_T2) | |
195 | continue; | |
196 | ||
197 | if (optno == OPTION_SNAME && done_server) | |
198 | -- | |
199 | 2.1.0 | |
200 |