1 /*
2 * dhcpcd - DHCP client daemon
3 * Copyright (c) 2006-2010 Roy Marples <roy@marples.name>
4 * All rights reserved
5
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28 #include <sys/param.h>
29 #include <sys/kmem.h>
30
31 #include "dhcp_common.h"
32 #include "dhcp_dhcp.h"
33
34 #define REQUEST (1 << 0)
35 #define UINT8 (1 << 1)
36 #define UINT16 (1 << 2)
37 #define SINT16 (1 << 3)
38 #define UINT32 (1 << 4)
39 #define SINT32 (1 << 5)
40 #define IPV4 (1 << 6)
41 #define STRING (1 << 7)
42 #define PAIR (1 << 8)
43 #define ARRAY (1 << 9)
44 #define RFC3361 (1 << 10)
45 #define RFC3397 (1 << 11)
46 #define RFC3442 (1 << 12)
47
48 #define IPV4R IPV4 | REQUEST
49
50 #define DAD "Duplicate address detected"
51
52 /* Our aggregate option buffer.
53 * We ONLY use this when options are split, which for most purposes is
54 * practically never. See RFC3396 for details. */
55 static uint8_t *opt_buffer;
56
57 struct dhcp_opt {
58 uint8_t option;
59 int type;
60 const char *var;
61 };
62
63 static const struct dhcp_opt dhcp_opts[] = {
64 { 1, IPV4 | REQUEST, "subnet_mask" },
65 /* RFC 3442 states that the CSR has to come before all other
66 * routes. For completeness, we also specify static routes,
67 * then routers. */
68 { 121, RFC3442, "classless_static_routes" },
69 { 249, RFC3442, "ms_classless_static_routes" },
70 { 33, IPV4 | ARRAY | REQUEST, "static_routes" },
71 { 3, IPV4 | ARRAY | REQUEST, "routers" },
72 { 2, UINT32, "time_offset" },
73 { 4, IPV4 | ARRAY, "time_servers" },
74 { 5, IPV4 | ARRAY, "ien116_name_servers" },
75 { 6, IPV4 | ARRAY, "domain_name_servers" },
76 { 7, IPV4 | ARRAY, "log_servers" },
77 { 8, IPV4 | ARRAY, "cookie_servers" },
78 { 9, IPV4 | ARRAY, "lpr_servers" },
79 { 10, IPV4 | ARRAY, "impress_servers" },
80 { 11, IPV4 | ARRAY, "resource_location_servers" },
81 { 12, STRING, "host_name" },
82 { 13, UINT16, "boot_size" },
83 { 14, STRING, "merit_dump" },
84 { 15, STRING, "domain_name" },
85 { 16, IPV4, "swap_server" },
86 { 17, STRING, "root_path" },
87 { 18, STRING, "extensions_path" },
88 { 19, UINT8, "ip_forwarding" },
89 { 20, UINT8, "non_local_source_routing" },
90 { 21, IPV4 | ARRAY, "policy_filter" },
91 { 22, SINT16, "max_dgram_reassembly" },
92 { 23, UINT16, "default_ip_ttl" },
93 { 24, UINT32, "path_mtu_aging_timeout" },
94 { 25, UINT16 | ARRAY, "path_mtu_plateau_table" },
95 { 26, UINT16, "interface_mtu" },
96 { 27, UINT8, "all_subnets_local" },
97 { 28, IPV4 | REQUEST, "broadcast_address" },
98 { 29, UINT8, "perform_mask_discovery" },
99 { 30, UINT8, "mask_supplier" },
100 { 31, UINT8, "router_discovery" },
101 { 32, IPV4, "router_solicitation_address" },
102 { 34, UINT8, "trailer_encapsulation" },
103 { 35, UINT32, "arp_cache_timeout" },
104 { 36, UINT16, "ieee802_3_encapsulation" },
105 { 37, UINT8, "default_tcp_ttl" },
106 { 38, UINT32, "tcp_keepalive_interval" },
107 { 39, UINT8, "tcp_keepalive_garbage" },
108 { 40, STRING, "nis_domain" },
109 { 41, IPV4 | ARRAY, "nis_servers" },
110 { 42, IPV4 | ARRAY, "ntp_servers" },
111 { 43, STRING, "vendor_encapsulated_options" },
112 { 44, IPV4 | ARRAY, "netbios_name_servers" },
113 { 45, IPV4, "netbios_dd_server" },
114 { 46, UINT8, "netbios_node_type" },
115 { 47, STRING, "netbios_scope" },
116 { 48, IPV4 | ARRAY, "font_servers" },
117 { 49, IPV4 | ARRAY, "x_display_manager" },
118 { 50, IPV4, "dhcp_requested_address" },
119 { 51, UINT32 | REQUEST, "dhcp_lease_time" },
120 { 52, UINT8, "dhcp_option_overload" },
121 { 53, UINT8, "dhcp_message_type" },
122 { 54, IPV4, "dhcp_server_identifier" },
123 { 55, UINT8 | ARRAY, "dhcp_parameter_request_list" },
124 { 56, STRING, "dhcp_message" },
125 { 57, UINT16, "dhcp_max_message_size" },
126 { 58, UINT32 | REQUEST, "dhcp_renewal_time" },
127 { 59, UINT32 | REQUEST, "dhcp_rebinding_time" },
128 { 64, STRING, "nisplus_domain" },
129 { 65, IPV4 | ARRAY, "nisplus_servers" },
130 { 66, STRING, "tftp_server_name" },
131 { 67, STRING, "bootfile_name" },
132 { 68, IPV4 | ARRAY, "mobile_ip_home_agent" },
133 { 69, IPV4 | ARRAY, "smtp_server" },
134 { 70, IPV4 | ARRAY, "pop_server" },
135 { 71, IPV4 | ARRAY, "nntp_server" },
136 { 72, IPV4 | ARRAY, "www_server" },
137 { 73, IPV4 | ARRAY, "finger_server" },
138 { 74, IPV4 | ARRAY, "irc_server" },
139 { 75, IPV4 | ARRAY, "streettalk_server" },
140 { 76, IPV4 | ARRAY, "streettalk_directory_assistance_server" },
141 { 77, STRING, "user_class" },
142 { 81, STRING | RFC3397, "fqdn_name" },
143 { 85, IPV4 | ARRAY, "nds_servers" },
144 { 86, STRING, "nds_tree_name" },
145 { 87, STRING, "nds_context" },
146 { 88, STRING | RFC3397, "bcms_controller_names" },
147 { 89, IPV4 | ARRAY, "bcms_controller_address" },
148 { 91, UINT32, "client_last_transaction_time" },
149 { 92, IPV4 | ARRAY, "associated_ip" },
150 { 98, STRING, "uap_servers" },
151 { 112, IPV4 | ARRAY, "netinfo_server_address" },
152 { 113, STRING, "netinfo_server_tag" },
153 { 114, STRING, "default_url" },
154 { 118, IPV4, "subnet_selection" },
155 { 119, STRING | RFC3397, "domain_search" },
156 { 0, 0, NULL }
157 };
158
159 static int
valid_length(uint8_t option,int dl,int * type)160 valid_length(uint8_t option, int dl, int *type)
161 {
162 const struct dhcp_opt *opt;
163 ssize_t sz;
164
165 if (dl == 0)
166 return -1;
167
168 for (opt = dhcp_opts; opt->option; opt++) {
169 if (opt->option != option)
170 continue;
171
172 if (type)
173 *type = opt->type;
174
175 if (opt->type == 0 ||
176 opt->type & STRING ||
177 opt->type & RFC3442)
178 return 0;
179
180 sz = 0;
181 if (opt->type & UINT32 || opt->type & IPV4)
182 sz = sizeof(uint32_t);
183 if (opt->type & UINT16)
184 sz = sizeof(uint16_t);
185 if (opt->type & UINT8)
186 sz = sizeof(uint8_t);
187 if (opt->type & IPV4 || opt->type & ARRAY)
188 return dl % sz;
189 return (dl == sz ? 0 : -1);
190 }
191
192 /* unknown option, so let it pass */
193 return 0;
194 }
195
196 #define get_option_raw(dhcp, opt) get_option(dhcp, opt, NULL, NULL)
197 static const uint8_t *
get_option(const struct dhcp_message * dhcp,uint8_t opt,int * len,int * type)198 get_option(const struct dhcp_message *dhcp, uint8_t opt, int *len, int *type)
199 {
200 const uint8_t *p = dhcp->options;
201 const uint8_t *e = p + sizeof(dhcp->options);
202 uint8_t l, ol = 0;
203 uint8_t o = 0;
204 uint8_t overl = 0;
205 uint8_t *bp = NULL;
206 const uint8_t *op = NULL;
207 int bl = 0;
208
209 while (p < e) {
210 o = *p++;
211 if (o == opt) {
212 if (op) {
213 if (!opt_buffer) {
214 opt_buffer = kmem_alloc(sizeof(*dhcp), KM_SLEEP);
215 }
216 if (!bp)
217 bp = opt_buffer;
218 memcpy(bp, op, ol);
219 bp += ol;
220 }
221 ol = *p;
222 op = p + 1;
223 bl += ol;
224 }
225 switch (o) {
226 case DHO_PAD:
227 continue;
228 case DHO_END:
229 if (overl & 1) {
230 /* bit 1 set means parse boot file */
231 overl &= ~1;
232 p = dhcp->bootfile;
233 e = p + sizeof(dhcp->bootfile);
234 } else if (overl & 2) {
235 /* bit 2 set means parse server name */
236 overl &= ~2;
237 p = dhcp->servername;
238 e = p + sizeof(dhcp->servername);
239 } else
240 goto exit;
241 break;
242 case DHO_OPTIONSOVERLOADED:
243 /* Ensure we only get this option once */
244 if (!overl)
245 overl = p[1];
246 break;
247 }
248 l = *p++;
249 p += l;
250 }
251
252 exit:
253 if (valid_length(opt, bl, type) == -1) {
254 return NULL;
255 }
256 if (len)
257 *len = bl;
258 if (bp) {
259 memcpy(bp, op, ol);
260 return (const uint8_t *)opt_buffer;
261 }
262 if (op)
263 return op;
264 return NULL;
265 }
266
267 int
get_option_addr(struct in_addr * a,const struct dhcp_message * dhcp,uint8_t option)268 get_option_addr(struct in_addr *a, const struct dhcp_message *dhcp,
269 uint8_t option)
270 {
271 const uint8_t *p = get_option_raw(dhcp, option);
272
273 if (!p)
274 return 1;
275 memcpy(&a->s_addr, p, sizeof(a->s_addr));
276 return 0;
277 }
278
279 int
get_option_uint32(uint32_t * i,const struct dhcp_message * dhcp,uint8_t option)280 get_option_uint32(uint32_t *i, const struct dhcp_message *dhcp, uint8_t option)
281 {
282 const uint8_t *p = get_option_raw(dhcp, option);
283 uint32_t d;
284
285 if (!p)
286 return 1;
287 memcpy(&d, p, sizeof(d));
288 *i = ntohl(d);
289 return 0;
290 }
291
292 int
get_option_uint16(uint16_t * i,const struct dhcp_message * dhcp,uint8_t option)293 get_option_uint16(uint16_t *i, const struct dhcp_message *dhcp, uint8_t option)
294 {
295 const uint8_t *p = get_option_raw(dhcp, option);
296 uint16_t d;
297
298 if (!p)
299 return 1;
300 memcpy(&d, p, sizeof(d));
301 *i = ntohs(d);
302 return 0;
303 }
304
305 int
get_option_uint8(uint8_t * i,const struct dhcp_message * dhcp,uint8_t option)306 get_option_uint8(uint8_t *i, const struct dhcp_message *dhcp, uint8_t option)
307 {
308 const uint8_t *p = get_option_raw(dhcp, option);
309
310 if (!p)
311 return 1;
312 if (i)
313 *i = *(p);
314 return 0;
315 }
316
317 static struct rt *
decode_rfc3442_rt(int dl,const uint8_t * data)318 decode_rfc3442_rt(int dl, const uint8_t *data)
319 {
320 const uint8_t *p = data;
321 const uint8_t *e;
322 uint8_t cidr;
323 size_t ocets;
324 struct rt *routes = NULL;
325 struct rt *rt = NULL;
326
327 /* Minimum is 5 -first is CIDR and a router length of 4 */
328 if (dl < 5)
329 return NULL;
330
331 e = p + dl;
332 while (p < e) {
333 cidr = *p++;
334 if (cidr > 32) {
335 free_routes(routes);
336 return NULL;
337 }
338
339 if (rt) {
340 rt->next = kmem_zalloc(sizeof(*rt), KM_SLEEP);
341 rt = rt->next;
342 } else {
343 routes = rt = kmem_zalloc(sizeof(*routes), KM_SLEEP);
344 }
345 rt->next = NULL;
346
347 ocets = (cidr + 7) / 8;
348 /* If we have ocets then we have a destination and netmask */
349 if (ocets > 0) {
350 memcpy(&rt->dest.s_addr, p, ocets);
351 p += ocets;
352 rt->net.s_addr = htonl(~0U << (32 - cidr));
353 }
354
355 /* Finally, snag the router */
356 memcpy(&rt->gate.s_addr, p, 4);
357 p += 4;
358 }
359 return routes;
360 }
361
362
363 /* This calculates the netmask that we should use for static routes.
364 * This IS different from the calculation used to calculate the netmask
365 * for an interface address. */
366 static uint32_t
route_netmask(uint32_t ip_in)367 route_netmask(uint32_t ip_in)
368 {
369 /* used to be unsigned long - check if error */
370 uint32_t p = ntohl(ip_in);
371 uint32_t t;
372
373 if (IN_CLASSA(p))
374 t = ~IN_CLASSA_NET;
375 else {
376 if (IN_CLASSB(p))
377 t = ~IN_CLASSB_NET;
378 else {
379 if (IN_CLASSC(p))
380 t = ~IN_CLASSC_NET;
381 else
382 t = 0;
383 }
384 }
385
386 while (t & p)
387 t >>= 1;
388
389 return (htonl(~t));
390 }
391
392 /* We need to obey routing options.
393 * If we have a CSR then we only use that.
394 * Otherwise we add static routes and then routers. */
395 struct rt *
get_option_routes(const struct dhcp_message * dhcp,const char * ifname,int * opts)396 get_option_routes(const struct dhcp_message *dhcp,
397 const char *ifname, int *opts)
398 {
399 const uint8_t *p;
400 const uint8_t *e;
401 struct rt *routes = NULL;
402 struct rt *route = NULL;
403 int len;
404
405 /* If we have CSR's then we MUST use these only */
406 p = get_option(dhcp, DHO_CSR, &len, NULL);
407 /* Check for crappy MS option */
408 if (!p)
409 p = get_option(dhcp, DHO_MSCSR, &len, NULL);
410 if (p) {
411 routes = decode_rfc3442_rt(len, p);
412 if (routes && !(*opts & DHCPCD_CSR_WARNED)) {
413 *opts |= DHCPCD_CSR_WARNED;
414 return routes;
415 }
416 }
417
418 /* OK, get our static routes first. */
419 p = get_option(dhcp, DHO_STATICROUTE, &len, NULL);
420 if (p) {
421 e = p + len;
422 while (p < e) {
423 if (route) {
424 route->next = kmem_alloc(sizeof(*route), KM_SLEEP);
425 route = route->next;
426 } else
427 routes = route = kmem_alloc(sizeof(*routes), KM_SLEEP);
428 route->next = NULL;
429 memcpy(&route->dest.s_addr, p, 4);
430 p += 4;
431 memcpy(&route->gate.s_addr, p, 4);
432 p += 4;
433 route->net.s_addr = route_netmask(route->dest.s_addr);
434 }
435 }
436
437 /* Now grab our routers */
438 p = get_option(dhcp, DHO_ROUTER, &len, NULL);
439 if (p) {
440 e = p + len;
441 while (p < e) {
442 if (route) {
443 route->next = kmem_zalloc(sizeof(*route), KM_SLEEP);
444 route = route->next;
445 } else
446 routes = route = kmem_zalloc(sizeof(*route), KM_SLEEP);
447 memcpy(&route->gate.s_addr, p, 4);
448 p += 4;
449 }
450 }
451
452 return routes;
453 }
454
455 static size_t
encode_rfc1035(const char * src,uint8_t * dst)456 encode_rfc1035(const char *src, uint8_t *dst)
457 {
458 uint8_t *p = dst;
459 uint8_t *lp = p++;
460
461 if (*src == '\0')
462 return 0;
463 for (; *src; src++) {
464 if (*src == '\0')
465 break;
466 if (*src == '.') {
467 /* Skip the trailing . */
468 if (src[1] == '\0')
469 break;
470 *lp = p - lp - 1;
471 if (*lp == '\0')
472 return p - dst;
473 lp = p++;
474 } else
475 *p++ = (uint8_t)*src;
476 }
477 *lp = p - lp - 1;
478 *p++ = '\0';
479 return p - dst;
480 }
481
482 #define PUTADDR(_type, _val) \
483 { \
484 *p++ = _type; \
485 *p++ = 4; \
486 memcpy(p, &_val.s_addr, 4); \
487 p += 4; \
488 }
489
490 ssize_t
make_message(struct dhcp_message ** message,const struct interface * iface,uint8_t type)491 make_message(struct dhcp_message **message,
492 const struct interface *iface,
493 uint8_t type)
494 {
495 struct dhcp_message *dhcp;
496 uint8_t *m, *lp, *p;
497 uint8_t *n_params = NULL;
498 time_t up = uptime() - iface->start_uptime;
499 uint32_t ul;
500 uint16_t sz;
501 size_t len;
502 const char *hp;
503 const struct dhcp_opt *opt;
504 const struct if_options *ifo = iface->state->options;
505 const struct dhcp_lease *lease = &iface->state->lease;
506
507 dhcp = kmem_zalloc(sizeof (*dhcp), KM_SLEEP);
508 m = (uint8_t *)dhcp;
509 p = dhcp->options;
510
511 if ((type == DHCP_INFORM || type == DHCP_RELEASE ||
512 (type == DHCP_REQUEST &&
513 iface->net.s_addr == lease->net.s_addr &&
514 (iface->state->new == NULL ||
515 iface->state->new->cookie == htonl(MAGIC_COOKIE)))))
516 {
517 dhcp->ciaddr = iface->addr.s_addr;
518 /* In-case we haven't actually configured the address yet */
519 if (type == DHCP_INFORM && iface->addr.s_addr == 0)
520 dhcp->ciaddr = lease->addr.s_addr;
521 }
522
523 dhcp->op = DHCP_BOOTREQUEST;
524 dhcp->hwtype = iface->family;
525 switch (iface->family) {
526 case ARPHRD_ETHER:
527 case ARPHRD_IEEE802:
528 dhcp->hwlen = iface->hwlen;
529 memcpy(&dhcp->chaddr, &iface->hwaddr, iface->hwlen);
530 break;
531 }
532
533 if (ifo->options & DHCPCD_BROADCAST &&
534 dhcp->ciaddr == 0 &&
535 type != DHCP_DECLINE &&
536 type != DHCP_RELEASE)
537 dhcp->flags = htons(BROADCAST_FLAG);
538
539 if (type != DHCP_DECLINE && type != DHCP_RELEASE) {
540 if (up < 0 || up > (time_t)UINT16_MAX)
541 dhcp->secs = htons((uint16_t)UINT16_MAX);
542 else
543 dhcp->secs = htons(up);
544 }
545 dhcp->xid = iface->state->xid;
546 dhcp->cookie = htonl(MAGIC_COOKIE);
547
548 *p++ = DHO_MESSAGETYPE;
549 *p++ = 1;
550 *p++ = type;
551
552 if (iface->clientid) {
553 *p++ = DHO_CLIENTID;
554 memcpy(p, iface->clientid, iface->clientid[0] + 1);
555 p += iface->clientid[0] + 1;
556 }
557
558 if (lease->addr.s_addr && lease->cookie == htonl(MAGIC_COOKIE)) {
559 if (type == DHCP_DECLINE ||
560 (type == DHCP_REQUEST &&
561 lease->addr.s_addr != iface->addr.s_addr))
562 {
563 PUTADDR(DHO_IPADDRESS, lease->addr);
564 if (lease->server.s_addr)
565 PUTADDR(DHO_SERVERID, lease->server);
566 }
567
568 if (type == DHCP_RELEASE) {
569 if (lease->server.s_addr)
570 PUTADDR(DHO_SERVERID, lease->server);
571 }
572 }
573
574 if (type == DHCP_DECLINE) {
575 *p++ = DHO_MESSAGE;
576 len = strlen(DAD);
577 *p++ = len;
578 memcpy(p, DAD, len);
579 p += len;
580 }
581
582 if (type == DHCP_DISCOVER && ifo->options & DHCPCD_REQUEST)
583 PUTADDR(DHO_IPADDRESS, ifo->req_addr);
584
585 if (type == DHCP_DISCOVER ||
586 type == DHCP_INFORM ||
587 type == DHCP_REQUEST)
588 {
589 *p++ = DHO_MAXMESSAGESIZE;
590 *p++ = 2;
591 sz = get_mtu(iface->name);
592 if (sz < MTU_MIN) {
593 if (set_mtu(iface->name, MTU_MIN) == 0)
594 sz = MTU_MIN;
595 } else if (sz > MTU_MAX) {
596 /* Even though our MTU could be greater than
597 * MTU_MAX (1500) dhcpcd does not presently
598 * handle DHCP packets any bigger. */
599 sz = MTU_MAX;
600 }
601 sz = htons(sz);
602 memcpy(p, &sz, 2);
603 p += 2;
604
605 if (ifo->userclass[0]) {
606 *p++ = DHO_USERCLASS;
607 memcpy(p, ifo->userclass, ifo->userclass[0] + 1);
608 p += ifo->userclass[0] + 1;
609 }
610
611 if (ifo->vendorclassid[0]) {
612 *p++ = DHO_VENDORCLASSID;
613 memcpy(p, ifo->vendorclassid,
614 ifo->vendorclassid[0] + 1);
615 p += ifo->vendorclassid[0] + 1;
616 }
617
618
619 if (type != DHCP_INFORM) {
620 if (ifo->leasetime != 0) {
621 *p++ = DHO_LEASETIME;
622 *p++ = 4;
623 ul = htonl(ifo->leasetime);
624 memcpy(p, &ul, 4);
625 p += 4;
626 }
627 }
628
629 /* Regardless of RFC2132, we should always send a hostname
630 * upto the first dot (the short hostname) as otherwise
631 * confuses some DHCP servers when updating DNS.
632 * The FQDN option should be used if a FQDN is required. */
633 if (ifo->options & DHCPCD_HOSTNAME && ifo->hostname[0]) {
634 *p++ = DHO_HOSTNAME;
635 hp = strchr(ifo->hostname, '.');
636 if (hp)
637 len = hp - ifo->hostname;
638 else
639 len = strlen(ifo->hostname);
640 *p++ = len;
641 memcpy(p, ifo->hostname, len);
642 p += len;
643 }
644 if (ifo->fqdn != FQDN_DISABLE && ifo->hostname[0]) {
645 /* IETF DHC-FQDN option (81), RFC4702 */
646 *p++ = DHO_FQDN;
647 lp = p;
648 *p++ = 3;
649 /*
650 * Flags: 0000NEOS
651 * S: 1 => Client requests Server to update
652 * a RR in DNS as well as PTR
653 * O: 1 => Server indicates to client that
654 * DNS has been updated
655 * E: 1 => Name data is DNS format
656 * N: 1 => Client requests Server to not
657 * update DNS
658 */
659 *p++ = (ifo->fqdn & 0x09) | 0x04;
660 *p++ = 0; /* from server for PTR RR */
661 *p++ = 0; /* from server for A RR if S=1 */
662 ul = encode_rfc1035(ifo->hostname, p);
663 *lp += ul;
664 p += ul;
665 }
666
667 /* vendor is already encoded correctly, so just add it */
668 if (ifo->vendor[0]) {
669 *p++ = DHO_VENDOR;
670 memcpy(p, ifo->vendor, ifo->vendor[0] + 1);
671 p += ifo->vendor[0] + 1;
672 }
673
674 *p++ = DHO_PARAMETERREQUESTLIST;
675 n_params = p;
676 *p++ = 0;
677 for (opt = dhcp_opts; opt->option; opt++) {
678 if (!(opt->type & REQUEST ||
679 has_option_mask(ifo->requestmask, opt->option)))
680 continue;
681 if (type == DHCP_INFORM &&
682 (opt->option == DHO_RENEWALTIME ||
683 opt->option == DHO_REBINDTIME))
684 continue;
685 *p++ = opt->option;
686 }
687 *n_params = p - n_params - 1;
688 }
689 *p++ = DHO_END;
690
691 #ifdef BOOTP_MESSAGE_LENTH_MIN
692 /* Some crappy DHCP servers think they have to obey the BOOTP minimum
693 * message length.
694 * They are wrong, but we should still cater for them. */
695 while (p - m < BOOTP_MESSAGE_LENTH_MIN)
696 *p++ = DHO_PAD;
697 #endif
698
699 *message = dhcp;
700 return p - m;
701 }
702
703 void
get_lease(struct dhcp_lease * lease,const struct dhcp_message * dhcp)704 get_lease(struct dhcp_lease *lease, const struct dhcp_message *dhcp)
705 {
706 struct timeval now;
707
708 lease->cookie = dhcp->cookie;
709 /* BOOTP does not set yiaddr for replies when ciaddr is set. */
710 if (dhcp->yiaddr)
711 lease->addr.s_addr = dhcp->yiaddr;
712 else
713 lease->addr.s_addr = dhcp->ciaddr;
714 if (get_option_addr(&lease->net, dhcp, DHO_SUBNETMASK) != 0)
715 lease->net.s_addr = get_netmask(lease->addr.s_addr);
716 if (get_option_addr(&lease->brd, dhcp, DHO_BROADCAST) != 0)
717 lease->brd.s_addr = lease->addr.s_addr | ~lease->net.s_addr;
718 if (get_option_uint32(&lease->leasetime, dhcp, DHO_LEASETIME) == 0) {
719 /* Ensure that we can use the lease */
720 get_monotonic(&now);
721 if (now.tv_sec + (time_t)lease->leasetime < now.tv_sec)
722 lease->leasetime = ~0U; /* Infinite lease */
723 } else
724 lease->leasetime = ~0U; /* Default to infinite lease */
725 if (get_option_uint32(&lease->renewaltime, dhcp, DHO_RENEWALTIME) != 0)
726 lease->renewaltime = 0;
727 if (get_option_uint32(&lease->rebindtime, dhcp, DHO_REBINDTIME) != 0)
728 lease->rebindtime = 0;
729 if (get_option_addr(&lease->server, dhcp, DHO_SERVERID) != 0)
730 lease->server.s_addr = INADDR_ANY;
731 }
732