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