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 <syslog.h>
34 #include <unistd.h>
35
36 #include "config.h"
37 #include "common.h"
38 #include "dhcp.h"
39
40 #define REQUEST (1 << 0)
41 #define UINT8 (1 << 1)
42 #define UINT16 (1 << 2)
43 #define SINT16 (1 << 3)
44 #define UINT32 (1 << 4)
45 #define SINT32 (1 << 5)
46 #define IPV4 (1 << 6)
47 #define STRING (1 << 7)
48 #define PAIR (1 << 8)
49 #define ARRAY (1 << 9)
50 #define RFC3361 (1 << 10)
51 #define RFC3397 (1 << 11)
52 #define RFC3442 (1 << 12)
53
54 #define IPV4R IPV4 | REQUEST
55
56 #define DAD "Duplicate address detected"
57
58 /* Our aggregate option buffer.
59 * We ONLY use this when options are split, which for most purposes is
60 * practically never. See RFC3396 for details. */
61 static uint8_t *opt_buffer;
62
63 struct dhcp_opt {
64 uint8_t option;
65 int type;
66 const char *var;
67 };
68
69 static const struct dhcp_opt const dhcp_opts[] = {
70 { 1, IPV4 | REQUEST, "subnet_mask" },
71 /* RFC 3442 states that the CSR has to come before all other
72 * routes. For completeness, we also specify static routes,
73 * then routers. */
74 { 121, RFC3442, "classless_static_routes" },
75 { 249, RFC3442, "ms_classless_static_routes" },
76 { 33, IPV4 | ARRAY | REQUEST, "static_routes" },
77 { 3, IPV4 | ARRAY | REQUEST, "routers" },
78 { 2, UINT32, "time_offset" },
79 { 4, IPV4 | ARRAY, "time_servers" },
80 { 5, IPV4 | ARRAY, "ien116_name_servers" },
81 { 6, IPV4 | ARRAY, "domain_name_servers" },
82 { 7, IPV4 | ARRAY, "log_servers" },
83 { 8, IPV4 | ARRAY, "cookie_servers" },
84 { 9, IPV4 | ARRAY, "lpr_servers" },
85 { 10, IPV4 | ARRAY, "impress_servers" },
86 { 11, IPV4 | ARRAY, "resource_location_servers" },
87 { 12, STRING, "host_name" },
88 { 13, UINT16, "boot_size" },
89 { 14, STRING, "merit_dump" },
90 { 15, STRING, "domain_name" },
91 { 16, IPV4, "swap_server" },
92 { 17, STRING, "root_path" },
93 { 18, STRING, "extensions_path" },
94 { 19, UINT8, "ip_forwarding" },
95 { 20, UINT8, "non_local_source_routing" },
96 { 21, IPV4 | ARRAY, "policy_filter" },
97 { 22, SINT16, "max_dgram_reassembly" },
98 { 23, UINT16, "default_ip_ttl" },
99 { 24, UINT32, "path_mtu_aging_timeout" },
100 { 25, UINT16 | ARRAY, "path_mtu_plateau_table" },
101 { 26, UINT16, "interface_mtu" },
102 { 27, UINT8, "all_subnets_local" },
103 { 28, IPV4 | REQUEST, "broadcast_address" },
104 { 29, UINT8, "perform_mask_discovery" },
105 { 30, UINT8, "mask_supplier" },
106 { 31, UINT8, "router_discovery" },
107 { 32, IPV4, "router_solicitation_address" },
108 { 34, UINT8, "trailer_encapsulation" },
109 { 35, UINT32, "arp_cache_timeout" },
110 { 36, UINT16, "ieee802_3_encapsulation" },
111 { 37, UINT8, "default_tcp_ttl" },
112 { 38, UINT32, "tcp_keepalive_interval" },
113 { 39, UINT8, "tcp_keepalive_garbage" },
114 { 40, STRING, "nis_domain" },
115 { 41, IPV4 | ARRAY, "nis_servers" },
116 { 42, IPV4 | ARRAY, "ntp_servers" },
117 { 43, STRING, "vendor_encapsulated_options" },
118 { 44, IPV4 | ARRAY, "netbios_name_servers" },
119 { 45, IPV4, "netbios_dd_server" },
120 { 46, UINT8, "netbios_node_type" },
121 { 47, STRING, "netbios_scope" },
122 { 48, IPV4 | ARRAY, "font_servers" },
123 { 49, IPV4 | ARRAY, "x_display_manager" },
124 { 50, IPV4, "dhcp_requested_address" },
125 { 51, UINT32 | REQUEST, "dhcp_lease_time" },
126 { 52, UINT8, "dhcp_option_overload" },
127 { 53, UINT8, "dhcp_message_type" },
128 { 54, IPV4, "dhcp_server_identifier" },
129 { 55, UINT8 | ARRAY, "dhcp_parameter_request_list" },
130 { 56, STRING, "dhcp_message" },
131 { 57, UINT16, "dhcp_max_message_size" },
132 { 58, UINT32 | REQUEST, "dhcp_renewal_time" },
133 { 59, UINT32 | REQUEST, "dhcp_rebinding_time" },
134 { 64, STRING, "nisplus_domain" },
135 { 65, IPV4 | ARRAY, "nisplus_servers" },
136 { 66, STRING, "tftp_server_name" },
137 { 67, STRING, "bootfile_name" },
138 { 68, IPV4 | ARRAY, "mobile_ip_home_agent" },
139 { 69, IPV4 | ARRAY, "smtp_server" },
140 { 70, IPV4 | ARRAY, "pop_server" },
141 { 71, IPV4 | ARRAY, "nntp_server" },
142 { 72, IPV4 | ARRAY, "www_server" },
143 { 73, IPV4 | ARRAY, "finger_server" },
144 { 74, IPV4 | ARRAY, "irc_server" },
145 { 75, IPV4 | ARRAY, "streettalk_server" },
146 { 76, IPV4 | ARRAY, "streettalk_directory_assistance_server" },
147 { 77, STRING, "user_class" },
148 { 81, STRING | RFC3397, "fqdn_name" },
149 { 85, IPV4 | ARRAY, "nds_servers" },
150 { 86, STRING, "nds_tree_name" },
151 { 87, STRING, "nds_context" },
152 { 88, STRING | RFC3397, "bcms_controller_names" },
153 { 89, IPV4 | ARRAY, "bcms_controller_address" },
154 { 91, UINT32, "client_last_transaction_time" },
155 { 92, IPV4 | ARRAY, "associated_ip" },
156 { 98, STRING, "uap_servers" },
157 { 112, IPV4 | ARRAY, "netinfo_server_address" },
158 { 113, STRING, "netinfo_server_tag" },
159 { 114, STRING, "default_url" },
160 { 118, IPV4, "subnet_selection" },
161 { 119, STRING | RFC3397, "domain_search" },
162 { 0, 0, NULL }
163 };
164
165 static const char *if_params[] = {
166 "interface",
167 "reason",
168 "pid",
169 "ifmetric",
170 "ifwireless",
171 "ifflags",
172 "profile",
173 "interface_order",
174 NULL
175 };
176
177 static const char *dhcp_params[] = {
178 "ip_address",
179 "subnet_cidr",
180 "network_number",
181 "ssid",
182 "filename",
183 "server_name",
184 NULL
185 };
186
187 void
print_options(void)188 print_options(void)
189 {
190 const struct dhcp_opt *opt;
191 const char **p;
192
193 for (p = if_params; *p; p++)
194 printf(" - %s\n", *p);
195
196 for (p = dhcp_params; *p; p++)
197 printf(" %s\n", *p);
198
199 for (opt = dhcp_opts; opt->option; opt++)
200 if (opt->var)
201 printf("%03d %s\n", opt->option, opt->var);
202 }
203
make_option_mask(uint8_t * mask,const char * opts,int add)204 int make_option_mask(uint8_t *mask, const char *opts, int add)
205 {
206 char *token, *o, *p, *t;
207 const struct dhcp_opt *opt;
208 int match, n;
209
210 o = p = xstrdup(opts);
211 while ((token = strsep(&p, ", "))) {
212 if (*token == '\0')
213 continue;
214 for (opt = dhcp_opts; opt->option; opt++) {
215 if (!opt->var)
216 continue;
217 match = 0;
218 if (strcmp(opt->var, token) == 0)
219 match = 1;
220 else {
221 errno = 0;
222 n = strtol(token, &t, 0);
223 if (errno == 0 && !*t)
224 if (opt->option == n)
225 match = 1;
226 }
227 if (match) {
228 if (add == 2 && !(opt->type & IPV4)) {
229 free(o);
230 errno = EINVAL;
231 return -1;
232 }
233 if (add == 1 || add == 2)
234 add_option_mask(mask,
235 opt->option);
236 else
237 del_option_mask(mask,
238 opt->option);
239 break;
240 }
241 }
242 if (!opt->option) {
243 free(o);
244 errno = ENOENT;
245 return -1;
246 }
247 }
248 free(o);
249 return 0;
250 }
251
252 static int
valid_length(uint8_t option,int dl,int * type)253 valid_length(uint8_t option, int dl, int *type)
254 {
255 const struct dhcp_opt *opt;
256 ssize_t sz;
257
258 if (dl == 0)
259 return -1;
260
261 for (opt = dhcp_opts; opt->option; opt++) {
262 if (opt->option != option)
263 continue;
264
265 if (type)
266 *type = opt->type;
267
268 if (opt->type == 0 ||
269 opt->type & STRING ||
270 opt->type & RFC3442)
271 return 0;
272
273 sz = 0;
274 if (opt->type & UINT32 || opt->type & IPV4)
275 sz = sizeof(uint32_t);
276 if (opt->type & UINT16)
277 sz = sizeof(uint16_t);
278 if (opt->type & UINT8)
279 sz = sizeof(uint8_t);
280 if (opt->type & IPV4 || opt->type & ARRAY)
281 return dl % sz;
282 return (dl == sz ? 0 : -1);
283 }
284
285 /* unknown option, so let it pass */
286 return 0;
287 }
288
289 #ifdef DEBUG_MEMORY
290 static void
free_option_buffer(void)291 free_option_buffer(void)
292 {
293 free(opt_buffer);
294 }
295 #endif
296
297 #define get_option_raw(dhcp, opt) get_option(dhcp, opt, NULL, NULL)
298 static const uint8_t *
get_option(const struct dhcp_message * dhcp,uint8_t opt,int * len,int * type)299 get_option(const struct dhcp_message *dhcp, uint8_t opt, int *len, int *type)
300 {
301 const uint8_t *p = dhcp->options;
302 const uint8_t *e = p + sizeof(dhcp->options);
303 uint8_t l, ol = 0;
304 uint8_t o = 0;
305 uint8_t overl = 0;
306 uint8_t *bp = NULL;
307 const uint8_t *op = NULL;
308 int bl = 0;
309
310 while (p < e) {
311 o = *p++;
312 if (o == opt) {
313 if (op) {
314 if (!opt_buffer) {
315 opt_buffer = xmalloc(sizeof(*dhcp));
316 #ifdef DEBUG_MEMORY
317 atexit(free_option_buffer);
318 #endif
319 }
320 if (!bp)
321 bp = opt_buffer;
322 memcpy(bp, op, ol);
323 bp += ol;
324 }
325 ol = *p;
326 op = p + 1;
327 bl += ol;
328 }
329 switch (o) {
330 case DHO_PAD:
331 continue;
332 case DHO_END:
333 if (overl & 1) {
334 /* bit 1 set means parse boot file */
335 overl &= ~1;
336 p = dhcp->bootfile;
337 e = p + sizeof(dhcp->bootfile);
338 } else if (overl & 2) {
339 /* bit 2 set means parse server name */
340 overl &= ~2;
341 p = dhcp->servername;
342 e = p + sizeof(dhcp->servername);
343 } else
344 goto exit;
345 break;
346 case DHO_OPTIONSOVERLOADED:
347 /* Ensure we only get this option once */
348 if (!overl)
349 overl = p[1];
350 break;
351 }
352 l = *p++;
353 p += l;
354 }
355
356 exit:
357 if (valid_length(opt, bl, type) == -1) {
358 errno = EINVAL;
359 return NULL;
360 }
361 if (len)
362 *len = bl;
363 if (bp) {
364 memcpy(bp, op, ol);
365 return (const uint8_t *)opt_buffer;
366 }
367 if (op)
368 return op;
369 errno = ENOENT;
370 return NULL;
371 }
372
373 int
get_option_addr(struct in_addr * a,const struct dhcp_message * dhcp,uint8_t option)374 get_option_addr(struct in_addr *a, const struct dhcp_message *dhcp,
375 uint8_t option)
376 {
377 const uint8_t *p = get_option_raw(dhcp, option);
378
379 if (!p)
380 return -1;
381 memcpy(&a->s_addr, p, sizeof(a->s_addr));
382 return 0;
383 }
384
385 int
get_option_uint32(uint32_t * i,const struct dhcp_message * dhcp,uint8_t option)386 get_option_uint32(uint32_t *i, const struct dhcp_message *dhcp, uint8_t option)
387 {
388 const uint8_t *p = get_option_raw(dhcp, option);
389 uint32_t d;
390
391 if (!p)
392 return -1;
393 memcpy(&d, p, sizeof(d));
394 *i = ntohl(d);
395 return 0;
396 }
397
398 int
get_option_uint16(uint16_t * i,const struct dhcp_message * dhcp,uint8_t option)399 get_option_uint16(uint16_t *i, const struct dhcp_message *dhcp, uint8_t option)
400 {
401 const uint8_t *p = get_option_raw(dhcp, option);
402 uint16_t d;
403
404 if (!p)
405 return -1;
406 memcpy(&d, p, sizeof(d));
407 *i = ntohs(d);
408 return 0;
409 }
410
411 int
get_option_uint8(uint8_t * i,const struct dhcp_message * dhcp,uint8_t option)412 get_option_uint8(uint8_t *i, const struct dhcp_message *dhcp, uint8_t option)
413 {
414 const uint8_t *p = get_option_raw(dhcp, option);
415
416 if (!p)
417 return -1;
418 if (i)
419 *i = *(p);
420 return 0;
421 }
422
423 /* Decode an RFC3397 DNS search order option into a space
424 * separated string. Returns length of string (including
425 * terminating zero) or zero on error. out may be NULL
426 * to just determine output length. */
427 static ssize_t
decode_rfc3397(char * out,ssize_t len,int pl,const uint8_t * p)428 decode_rfc3397(char *out, ssize_t len, int pl, const uint8_t *p)
429 {
430 const uint8_t *r, *q = p;
431 int count = 0, l, hops;
432 uint8_t ltype;
433
434 while (q - p < pl) {
435 r = NULL;
436 hops = 0;
437 /* We check we are inside our length again incase
438 * the data is NOT terminated correctly. */
439 while ((l = *q++) && q - p < pl) {
440 ltype = l & 0xc0;
441 if (ltype == 0x80 || ltype == 0x40)
442 return 0;
443 else if (ltype == 0xc0) { /* pointer */
444 l = (l & 0x3f) << 8;
445 l |= *q++;
446 /* save source of first jump. */
447 if (!r)
448 r = q;
449 hops++;
450 if (hops > 255)
451 return 0;
452 q = p + l;
453 if (q - p >= pl)
454 return 0;
455 } else {
456 /* straightforward name segment, add with '.' */
457 count += l + 1;
458 if (out) {
459 if ((ssize_t)l + 1 > len) {
460 errno = ENOBUFS;
461 return -1;
462 }
463 memcpy(out, q, l);
464 out += l;
465 *out++ = '.';
466 len -= l;
467 len--;
468 }
469 q += l;
470 }
471 }
472 /* change last dot to space */
473 if (out)
474 *(out - 1) = ' ';
475 if (r)
476 q = r;
477 }
478
479 /* change last space to zero terminator */
480 if (out)
481 *(out - 1) = 0;
482
483 return count;
484 }
485
486 static ssize_t
decode_rfc3442(char * out,ssize_t len,int pl,const uint8_t * p)487 decode_rfc3442(char *out, ssize_t len, int pl, const uint8_t *p)
488 {
489 const uint8_t *e;
490 ssize_t b, bytes = 0, ocets;
491 uint8_t cidr;
492 struct in_addr addr;
493 char *o = out;
494
495 /* Minimum is 5 -first is CIDR and a router length of 4 */
496 if (pl < 5) {
497 errno = EINVAL;
498 return -1;
499 }
500
501 e = p + pl;
502 while (p < e) {
503 cidr = *p++;
504 if (cidr > 32) {
505 errno = EINVAL;
506 return -1;
507 }
508 ocets = (cidr + 7) / 8;
509 if (!out) {
510 p += 4 + ocets;
511 bytes += ((4 * 4) * 2) + 4;
512 continue;
513 }
514 if ((((4 * 4) * 2) + 4) > len) {
515 errno = ENOBUFS;
516 return -1;
517 }
518 if (o != out) {
519 *o++ = ' ';
520 len--;
521 }
522 /* If we have ocets then we have a destination and netmask */
523 if (ocets > 0) {
524 addr.s_addr = 0;
525 memcpy(&addr.s_addr, p, ocets);
526 b = snprintf(o, len, "%s/%d", inet_ntoa(addr), cidr);
527 p += ocets;
528 } else
529 b = snprintf(o, len, "0.0.0.0/0");
530 o += b;
531 len -= b;
532
533 /* Finally, snag the router */
534 memcpy(&addr.s_addr, p, 4);
535 p += 4;
536 b = snprintf(o, len, " %s", inet_ntoa(addr));
537 o += b;
538 len -= b;
539 }
540
541 if (out)
542 return o - out;
543 return bytes;
544 }
545
546 static struct rt *
decode_rfc3442_rt(int dl,const uint8_t * data)547 decode_rfc3442_rt(int dl, const uint8_t *data)
548 {
549 const uint8_t *p = data;
550 const uint8_t *e;
551 uint8_t cidr;
552 size_t ocets;
553 struct rt *routes = NULL;
554 struct rt *rt = NULL;
555
556 /* Minimum is 5 -first is CIDR and a router length of 4 */
557 if (dl < 5)
558 return NULL;
559
560 e = p + dl;
561 while (p < e) {
562 cidr = *p++;
563 if (cidr > 32) {
564 free_routes(routes);
565 errno = EINVAL;
566 return NULL;
567 }
568
569 if (rt) {
570 rt->next = xzalloc(sizeof(*rt));
571 rt = rt->next;
572 } else {
573 routes = rt = xzalloc(sizeof(*routes));
574 }
575 rt->next = NULL;
576
577 ocets = (cidr + 7) / 8;
578 /* If we have ocets then we have a destination and netmask */
579 if (ocets > 0) {
580 memcpy(&rt->dest.s_addr, p, ocets);
581 p += ocets;
582 rt->net.s_addr = htonl(~0U << (32 - cidr));
583 }
584
585 /* Finally, snag the router */
586 memcpy(&rt->gate.s_addr, p, 4);
587 p += 4;
588 }
589 return routes;
590 }
591
592 static char *
decode_rfc3361(int dl,const uint8_t * data)593 decode_rfc3361(int dl, const uint8_t *data)
594 {
595 uint8_t enc;
596 unsigned int l;
597 char *sip = NULL;
598 struct in_addr addr;
599 char *p;
600
601 if (dl < 2) {
602 errno = EINVAL;
603 return 0;
604 }
605
606 enc = *data++;
607 dl--;
608 switch (enc) {
609 case 0:
610 if ((l = decode_rfc3397(NULL, 0, dl, data)) > 0) {
611 sip = xmalloc(l);
612 decode_rfc3397(sip, l, dl, data);
613 }
614 break;
615 case 1:
616 if (dl == 0 || dl % 4 != 0) {
617 errno = EINVAL;
618 break;
619 }
620 addr.s_addr = INADDR_BROADCAST;
621 l = ((dl / sizeof(addr.s_addr)) * ((4 * 4) + 1)) + 1;
622 sip = p = xmalloc(l);
623 while (l != 0) {
624 memcpy(&addr.s_addr, data, sizeof(addr.s_addr));
625 data += sizeof(addr.s_addr);
626 p += snprintf(p, l - (p - sip), "%s ", inet_ntoa(addr));
627 l -= sizeof(addr.s_addr);
628 }
629 *--p = '\0';
630 break;
631 default:
632 errno = EINVAL;
633 return 0;
634 }
635
636 return sip;
637 }
638
639 char *
get_option_string(const struct dhcp_message * dhcp,uint8_t option)640 get_option_string(const struct dhcp_message *dhcp, uint8_t option)
641 {
642 int type = 0;
643 int len;
644 const uint8_t *p;
645 char *s;
646
647 p = get_option(dhcp, option, &len, &type);
648 if (!p || *p == '\0')
649 return NULL;
650
651 if (type & RFC3397) {
652 type = decode_rfc3397(NULL, 0, len, p);
653 if (!type) {
654 errno = EINVAL;
655 return NULL;
656 }
657 s = xmalloc(sizeof(char) * type);
658 decode_rfc3397(s, type, len, p);
659 return s;
660 }
661
662 if (type & RFC3361)
663 return decode_rfc3361(len, p);
664
665 s = xmalloc(sizeof(char) * (len + 1));
666 memcpy(s, p, len);
667 s[len] = '\0';
668 return s;
669 }
670
671 /* This calculates the netmask that we should use for static routes.
672 * This IS different from the calculation used to calculate the netmask
673 * for an interface address. */
674 static uint32_t
route_netmask(uint32_t ip_in)675 route_netmask(uint32_t ip_in)
676 {
677 /* used to be unsigned long - check if error */
678 uint32_t p = ntohl(ip_in);
679 uint32_t t;
680
681 if (IN_CLASSA(p))
682 t = ~IN_CLASSA_NET;
683 else {
684 if (IN_CLASSB(p))
685 t = ~IN_CLASSB_NET;
686 else {
687 if (IN_CLASSC(p))
688 t = ~IN_CLASSC_NET;
689 else
690 t = 0;
691 }
692 }
693
694 while (t & p)
695 t >>= 1;
696
697 return (htonl(~t));
698 }
699
700 /* We need to obey routing options.
701 * If we have a CSR then we only use that.
702 * Otherwise we add static routes and then routers. */
703 struct rt *
get_option_routes(const struct dhcp_message * dhcp,const char * ifname,int * opts)704 get_option_routes(const struct dhcp_message *dhcp,
705 const char *ifname, int *opts)
706 {
707 const uint8_t *p;
708 const uint8_t *e;
709 struct rt *routes = NULL;
710 struct rt *route = NULL;
711 int len;
712
713 /* If we have CSR's then we MUST use these only */
714 p = get_option(dhcp, DHO_CSR, &len, NULL);
715 /* Check for crappy MS option */
716 if (!p)
717 p = get_option(dhcp, DHO_MSCSR, &len, NULL);
718 if (p) {
719 routes = decode_rfc3442_rt(len, p);
720 if (routes && !(*opts & DHCPCD_CSR_WARNED)) {
721 syslog(LOG_DEBUG,
722 "%s: using Classless Static Routes (RFC3442)",
723 ifname);
724 *opts |= DHCPCD_CSR_WARNED;
725 return routes;
726 }
727 }
728
729 /* OK, get our static routes first. */
730 p = get_option(dhcp, DHO_STATICROUTE, &len, NULL);
731 if (p) {
732 e = p + len;
733 while (p < e) {
734 if (route) {
735 route->next = xmalloc(sizeof(*route));
736 route = route->next;
737 } else
738 routes = route = xmalloc(sizeof(*routes));
739 route->next = NULL;
740 memcpy(&route->dest.s_addr, p, 4);
741 p += 4;
742 memcpy(&route->gate.s_addr, p, 4);
743 p += 4;
744 route->net.s_addr = route_netmask(route->dest.s_addr);
745 }
746 }
747
748 /* Now grab our routers */
749 p = get_option(dhcp, DHO_ROUTER, &len, NULL);
750 if (p) {
751 e = p + len;
752 while (p < e) {
753 if (route) {
754 route->next = xzalloc(sizeof(*route));
755 route = route->next;
756 } else
757 routes = route = xzalloc(sizeof(*route));
758 memcpy(&route->gate.s_addr, p, 4);
759 p += 4;
760 }
761 }
762
763 return routes;
764 }
765
766 static size_t
encode_rfc1035(const char * src,uint8_t * dst)767 encode_rfc1035(const char *src, uint8_t *dst)
768 {
769 uint8_t *p = dst;
770 uint8_t *lp = p++;
771
772 if (*src == '\0')
773 return 0;
774 for (; *src; src++) {
775 if (*src == '\0')
776 break;
777 if (*src == '.') {
778 /* Skip the trailing . */
779 if (src[1] == '\0')
780 break;
781 *lp = p - lp - 1;
782 if (*lp == '\0')
783 return p - dst;
784 lp = p++;
785 } else
786 *p++ = (uint8_t)*src;
787 }
788 *lp = p - lp - 1;
789 *p++ = '\0';
790 return p - dst;
791 }
792
793 #define PUTADDR(_type, _val) \
794 { \
795 *p++ = _type; \
796 *p++ = 4; \
797 memcpy(p, &_val.s_addr, 4); \
798 p += 4; \
799 }
800
801 int
dhcp_message_add_addr(struct dhcp_message * dhcp,uint8_t type,struct in_addr addr)802 dhcp_message_add_addr(struct dhcp_message *dhcp,
803 uint8_t type, struct in_addr addr)
804 {
805 uint8_t *p;
806 size_t len;
807
808 p = dhcp->options;
809 while (*p != DHO_END) {
810 p++;
811 p += *p + 1;
812 }
813
814 len = p - (uint8_t *)dhcp;
815 if (len + 6 > sizeof(*dhcp)) {
816 errno = ENOMEM;
817 return -1;
818 }
819
820 PUTADDR(type, addr);
821 *p = DHO_END;
822 return 0;
823 }
824
825 ssize_t
make_message(struct dhcp_message ** message,const struct interface * iface,uint8_t type)826 make_message(struct dhcp_message **message,
827 const struct interface *iface,
828 uint8_t type)
829 {
830 struct dhcp_message *dhcp;
831 uint8_t *m, *lp, *p;
832 uint8_t *n_params = NULL;
833 time_t up = uptime() - iface->start_uptime;
834 uint32_t ul;
835 uint16_t sz;
836 size_t len;
837 const char *hp;
838 const struct dhcp_opt *opt;
839 const struct if_options *ifo = iface->state->options;
840 const struct dhcp_lease *lease = &iface->state->lease;
841
842 dhcp = xzalloc(sizeof (*dhcp));
843 m = (uint8_t *)dhcp;
844 p = dhcp->options;
845
846 if ((type == DHCP_INFORM || type == DHCP_RELEASE ||
847 (type == DHCP_REQUEST &&
848 iface->net.s_addr == lease->net.s_addr &&
849 (iface->state->new == NULL ||
850 iface->state->new->cookie == htonl(MAGIC_COOKIE)))))
851 {
852 dhcp->ciaddr = iface->addr.s_addr;
853 /* In-case we haven't actually configured the address yet */
854 if (type == DHCP_INFORM && iface->addr.s_addr == 0)
855 dhcp->ciaddr = lease->addr.s_addr;
856 }
857
858 dhcp->op = DHCP_BOOTREQUEST;
859 dhcp->hwtype = iface->family;
860 switch (iface->family) {
861 case ARPHRD_ETHER:
862 case ARPHRD_IEEE802:
863 dhcp->hwlen = iface->hwlen;
864 memcpy(&dhcp->chaddr, &iface->hwaddr, iface->hwlen);
865 break;
866 }
867
868 if (ifo->options & DHCPCD_BROADCAST &&
869 dhcp->ciaddr == 0 &&
870 type != DHCP_DECLINE &&
871 type != DHCP_RELEASE)
872 dhcp->flags = htons(BROADCAST_FLAG);
873
874 if (type != DHCP_DECLINE && type != DHCP_RELEASE) {
875 if (up < 0 || up > (time_t)UINT16_MAX)
876 dhcp->secs = htons((uint16_t)UINT16_MAX);
877 else
878 dhcp->secs = htons(up);
879 }
880 dhcp->xid = iface->state->xid;
881 dhcp->cookie = htonl(MAGIC_COOKIE);
882
883 *p++ = DHO_MESSAGETYPE;
884 *p++ = 1;
885 *p++ = type;
886
887 if (iface->clientid) {
888 *p++ = DHO_CLIENTID;
889 memcpy(p, iface->clientid, iface->clientid[0] + 1);
890 p += iface->clientid[0] + 1;
891 }
892
893 if (lease->addr.s_addr && lease->cookie == htonl(MAGIC_COOKIE)) {
894 if (type == DHCP_DECLINE ||
895 (type == DHCP_REQUEST &&
896 lease->addr.s_addr != iface->addr.s_addr))
897 {
898 PUTADDR(DHO_IPADDRESS, lease->addr);
899 if (lease->server.s_addr)
900 PUTADDR(DHO_SERVERID, lease->server);
901 }
902
903 if (type == DHCP_RELEASE) {
904 if (lease->server.s_addr)
905 PUTADDR(DHO_SERVERID, lease->server);
906 }
907 }
908
909 if (type == DHCP_DECLINE) {
910 *p++ = DHO_MESSAGE;
911 len = strlen(DAD);
912 *p++ = len;
913 memcpy(p, DAD, len);
914 p += len;
915 }
916
917 if (type == DHCP_DISCOVER && ifo->options & DHCPCD_REQUEST)
918 PUTADDR(DHO_IPADDRESS, ifo->req_addr);
919
920 if (type == DHCP_DISCOVER ||
921 type == DHCP_INFORM ||
922 type == DHCP_REQUEST)
923 {
924 *p++ = DHO_MAXMESSAGESIZE;
925 *p++ = 2;
926 sz = get_mtu(iface->name);
927 if (sz < MTU_MIN) {
928 if (set_mtu(iface->name, MTU_MIN) == 0)
929 sz = MTU_MIN;
930 } else if (sz > MTU_MAX) {
931 /* Even though our MTU could be greater than
932 * MTU_MAX (1500) dhcpcd does not presently
933 * handle DHCP packets any bigger. */
934 sz = MTU_MAX;
935 }
936 sz = htons(sz);
937 memcpy(p, &sz, 2);
938 p += 2;
939
940 if (ifo->userclass[0]) {
941 *p++ = DHO_USERCLASS;
942 memcpy(p, ifo->userclass, ifo->userclass[0] + 1);
943 p += ifo->userclass[0] + 1;
944 }
945
946 if (ifo->vendorclassid[0]) {
947 *p++ = DHO_VENDORCLASSID;
948 memcpy(p, ifo->vendorclassid,
949 ifo->vendorclassid[0] + 1);
950 p += ifo->vendorclassid[0] + 1;
951 }
952
953
954 if (type != DHCP_INFORM) {
955 if (ifo->leasetime != 0) {
956 *p++ = DHO_LEASETIME;
957 *p++ = 4;
958 ul = htonl(ifo->leasetime);
959 memcpy(p, &ul, 4);
960 p += 4;
961 }
962 }
963
964 /* Regardless of RFC2132, we should always send a hostname
965 * upto the first dot (the short hostname) as otherwise
966 * confuses some DHCP servers when updating DNS.
967 * The FQDN option should be used if a FQDN is required. */
968 if (ifo->options & DHCPCD_HOSTNAME && ifo->hostname[0]) {
969 *p++ = DHO_HOSTNAME;
970 hp = strchr(ifo->hostname, '.');
971 if (hp)
972 len = hp - ifo->hostname;
973 else
974 len = strlen(ifo->hostname);
975 *p++ = len;
976 memcpy(p, ifo->hostname, len);
977 p += len;
978 }
979 if (ifo->fqdn != FQDN_DISABLE && ifo->hostname[0]) {
980 /* IETF DHC-FQDN option (81), RFC4702 */
981 *p++ = DHO_FQDN;
982 lp = p;
983 *p++ = 3;
984 /*
985 * Flags: 0000NEOS
986 * S: 1 => Client requests Server to update
987 * a RR in DNS as well as PTR
988 * O: 1 => Server indicates to client that
989 * DNS has been updated
990 * E: 1 => Name data is DNS format
991 * N: 1 => Client requests Server to not
992 * update DNS
993 */
994 *p++ = (ifo->fqdn & 0x09) | 0x04;
995 *p++ = 0; /* from server for PTR RR */
996 *p++ = 0; /* from server for A RR if S=1 */
997 ul = encode_rfc1035(ifo->hostname, p);
998 *lp += ul;
999 p += ul;
1000 }
1001
1002 /* vendor is already encoded correctly, so just add it */
1003 if (ifo->vendor[0]) {
1004 *p++ = DHO_VENDOR;
1005 memcpy(p, ifo->vendor, ifo->vendor[0] + 1);
1006 p += ifo->vendor[0] + 1;
1007 }
1008
1009 *p++ = DHO_PARAMETERREQUESTLIST;
1010 n_params = p;
1011 *p++ = 0;
1012 for (opt = dhcp_opts; opt->option; opt++) {
1013 if (!(opt->type & REQUEST ||
1014 has_option_mask(ifo->requestmask, opt->option)))
1015 continue;
1016 if (type == DHCP_INFORM &&
1017 (opt->option == DHO_RENEWALTIME ||
1018 opt->option == DHO_REBINDTIME))
1019 continue;
1020 *p++ = opt->option;
1021 }
1022 *n_params = p - n_params - 1;
1023 }
1024 *p++ = DHO_END;
1025
1026 #ifdef BOOTP_MESSAGE_LENTH_MIN
1027 /* Some crappy DHCP servers think they have to obey the BOOTP minimum
1028 * message length.
1029 * They are wrong, but we should still cater for them. */
1030 while (p - m < BOOTP_MESSAGE_LENTH_MIN)
1031 *p++ = DHO_PAD;
1032 #endif
1033
1034 *message = dhcp;
1035 return p - m;
1036 }
1037
1038 ssize_t
write_lease(const struct interface * iface,const struct dhcp_message * dhcp)1039 write_lease(const struct interface *iface, const struct dhcp_message *dhcp)
1040 {
1041 int fd;
1042 ssize_t bytes = sizeof(*dhcp);
1043 const uint8_t *p = dhcp->options;
1044 const uint8_t *e = p + sizeof(dhcp->options);
1045 uint8_t l;
1046 uint8_t o = 0;
1047
1048 /* We don't write BOOTP leases */
1049 if (is_bootp(dhcp)) {
1050 unlink(iface->leasefile);
1051 return 0;
1052 }
1053
1054 syslog(LOG_DEBUG, "%s: writing lease `%s'",
1055 iface->name, iface->leasefile);
1056
1057 fd = open(iface->leasefile, O_WRONLY | O_CREAT | O_TRUNC, 0444);
1058 #ifdef ANDROID
1059 if (fd == -1 && errno == EACCES) {
1060 /* the lease file might have been created when dhcpcd was running as root */
1061 unlink(iface->leasefile);
1062 fd = open(iface->leasefile, O_WRONLY | O_CREAT | O_TRUNC, 0444);
1063 }
1064 #endif
1065 if (fd == -1) {
1066 syslog(LOG_ERR, "%s: open: %m", iface->name);
1067 return -1;
1068 }
1069
1070 /* Only write as much as we need */
1071 while (p < e) {
1072 o = *p;
1073 if (o == DHO_END) {
1074 bytes = p - (const uint8_t *)dhcp;
1075 break;
1076 }
1077 p++;
1078 if (o != DHO_PAD) {
1079 l = *p++;
1080 p += l;
1081 }
1082 }
1083 bytes = write(fd, dhcp, bytes);
1084 close(fd);
1085 return bytes;
1086 }
1087
1088 struct dhcp_message *
read_lease(const struct interface * iface)1089 read_lease(const struct interface *iface)
1090 {
1091 int fd;
1092 struct dhcp_message *dhcp;
1093 ssize_t bytes;
1094
1095 fd = open(iface->leasefile, O_RDONLY);
1096 if (fd == -1) {
1097 if (errno != ENOENT)
1098 syslog(LOG_ERR, "%s: open `%s': %m",
1099 iface->name, iface->leasefile);
1100 return NULL;
1101 }
1102 syslog(LOG_DEBUG, "%s: reading lease `%s'",
1103 iface->name, iface->leasefile);
1104 dhcp = xmalloc(sizeof(*dhcp));
1105 memset(dhcp, 0, sizeof(*dhcp));
1106 bytes = read(fd, dhcp, sizeof(*dhcp));
1107 close(fd);
1108 if (bytes < 0) {
1109 free(dhcp);
1110 dhcp = NULL;
1111 }
1112 return dhcp;
1113 }
1114
1115 static ssize_t
print_string(char * s,ssize_t len,int dl,const uint8_t * data)1116 print_string(char *s, ssize_t len, int dl, const uint8_t *data)
1117 {
1118 uint8_t c;
1119 const uint8_t *e, *p;
1120 ssize_t bytes = 0;
1121 ssize_t r;
1122
1123 e = data + dl;
1124 while (data < e) {
1125 c = *data++;
1126 if (c == '\0') {
1127 /* If rest is all NULL, skip it. */
1128 for (p = data; p < e; p++)
1129 if (*p != '\0')
1130 break;
1131 if (p == e)
1132 break;
1133 }
1134 if (!isascii(c) || !isprint(c)) {
1135 if (s) {
1136 if (len < 5) {
1137 errno = ENOBUFS;
1138 return -1;
1139 }
1140 r = snprintf(s, len, "\\%03o", c);
1141 len -= r;
1142 bytes += r;
1143 s += r;
1144 } else
1145 bytes += 4;
1146 continue;
1147 }
1148 switch (c) {
1149 case '"': /* FALLTHROUGH */
1150 case '\'': /* FALLTHROUGH */
1151 case '$': /* FALLTHROUGH */
1152 case '`': /* FALLTHROUGH */
1153 case '\\':
1154 if (s) {
1155 if (len < 3) {
1156 errno = ENOBUFS;
1157 return -1;
1158 }
1159 *s++ = '\\';
1160 len--;
1161 }
1162 bytes++;
1163 break;
1164 }
1165 if (s) {
1166 *s++ = c;
1167 len--;
1168 }
1169 bytes++;
1170 }
1171
1172 /* NULL */
1173 if (s)
1174 *s = '\0';
1175 bytes++;
1176 return bytes;
1177 }
1178
1179 static ssize_t
print_option(char * s,ssize_t len,int type,int dl,const uint8_t * data)1180 print_option(char *s, ssize_t len, int type, int dl, const uint8_t *data)
1181 {
1182 const uint8_t *e, *t;
1183 uint16_t u16;
1184 int16_t s16;
1185 uint32_t u32;
1186 int32_t s32;
1187 struct in_addr addr;
1188 ssize_t bytes = 0;
1189 ssize_t l;
1190 char *tmp;
1191
1192 if (type & RFC3397) {
1193 l = decode_rfc3397(NULL, 0, dl, data);
1194 if (l < 1)
1195 return l;
1196 tmp = xmalloc(l);
1197 decode_rfc3397(tmp, l, dl, data);
1198 l = print_string(s, len, l - 1, (uint8_t *)tmp);
1199 free(tmp);
1200 return l;
1201 }
1202
1203 if (type & RFC3442)
1204 return decode_rfc3442(s, len, dl, data);
1205
1206 if (type & STRING) {
1207 /* Some DHCP servers return NULL strings */
1208 if (*data == '\0')
1209 return 0;
1210 return print_string(s, len, dl, data);
1211 }
1212
1213 if (!s) {
1214 if (type & UINT8)
1215 l = 3;
1216 else if (type & UINT16) {
1217 l = 5;
1218 dl /= 2;
1219 } else if (type & SINT16) {
1220 l = 6;
1221 dl /= 2;
1222 } else if (type & UINT32) {
1223 l = 10;
1224 dl /= 4;
1225 } else if (type & SINT32) {
1226 l = 11;
1227 dl /= 4;
1228 } else if (type & IPV4) {
1229 l = 16;
1230 dl /= 4;
1231 } else {
1232 errno = EINVAL;
1233 return -1;
1234 }
1235 return (l + 1) * dl;
1236 }
1237
1238 t = data;
1239 e = data + dl;
1240 while (data < e) {
1241 if (data != t) {
1242 *s++ = ' ';
1243 bytes++;
1244 len--;
1245 }
1246 if (type & UINT8) {
1247 l = snprintf(s, len, "%d", *data);
1248 data++;
1249 } else if (type & UINT16) {
1250 memcpy(&u16, data, sizeof(u16));
1251 u16 = ntohs(u16);
1252 l = snprintf(s, len, "%d", u16);
1253 data += sizeof(u16);
1254 } else if (type & SINT16) {
1255 memcpy(&s16, data, sizeof(s16));
1256 s16 = ntohs(s16);
1257 l = snprintf(s, len, "%d", s16);
1258 data += sizeof(s16);
1259 } else if (type & UINT32) {
1260 memcpy(&u32, data, sizeof(u32));
1261 u32 = ntohl(u32);
1262 l = snprintf(s, len, "%d", u32);
1263 data += sizeof(u32);
1264 } else if (type & SINT32) {
1265 memcpy(&s32, data, sizeof(s32));
1266 s32 = ntohl(s32);
1267 l = snprintf(s, len, "%d", s32);
1268 data += sizeof(s32);
1269 } else if (type & IPV4) {
1270 memcpy(&addr.s_addr, data, sizeof(addr.s_addr));
1271 l = snprintf(s, len, "%s", inet_ntoa(addr));
1272 data += sizeof(addr.s_addr);
1273 } else
1274 l = 0;
1275 len -= l;
1276 bytes += l;
1277 s += l;
1278 }
1279
1280 return bytes;
1281 }
1282
1283 static void
setvar(char *** e,const char * prefix,const char * var,const char * value)1284 setvar(char ***e, const char *prefix, const char *var, const char *value)
1285 {
1286 size_t len = strlen(prefix) + strlen(var) + strlen(value) + 4;
1287
1288 **e = xmalloc(len);
1289 snprintf(**e, len, "%s_%s=%s", prefix, var, value);
1290 (*e)++;
1291 }
1292
1293 ssize_t
configure_env(char ** env,const char * prefix,const struct dhcp_message * dhcp,const struct if_options * ifo)1294 configure_env(char **env, const char *prefix, const struct dhcp_message *dhcp,
1295 const struct if_options *ifo)
1296 {
1297 unsigned int i;
1298 const uint8_t *p;
1299 int pl;
1300 struct in_addr addr;
1301 struct in_addr net;
1302 struct in_addr brd;
1303 char *val, *v;
1304 const struct dhcp_opt *opt;
1305 ssize_t len, e = 0;
1306 char **ep;
1307 char cidr[4];
1308 uint8_t overl = 0;
1309
1310 get_option_uint8(&overl, dhcp, DHO_OPTIONSOVERLOADED);
1311
1312 if (!env) {
1313 for (opt = dhcp_opts; opt->option; opt++) {
1314 if (!opt->var)
1315 continue;
1316 if (has_option_mask(ifo->nomask, opt->option))
1317 continue;
1318 if (get_option_raw(dhcp, opt->option))
1319 e++;
1320 }
1321 if (dhcp->yiaddr || dhcp->ciaddr)
1322 e += 5;
1323 if (*dhcp->bootfile && !(overl & 1))
1324 e++;
1325 if (*dhcp->servername && !(overl & 2))
1326 e++;
1327 return e;
1328 }
1329
1330 ep = env;
1331 if (dhcp->yiaddr || dhcp->ciaddr) {
1332 /* Set some useful variables that we derive from the DHCP
1333 * message but are not necessarily in the options */
1334 addr.s_addr = dhcp->yiaddr ? dhcp->yiaddr : dhcp->ciaddr;
1335 setvar(&ep, prefix, "ip_address", inet_ntoa(addr));
1336 if (get_option_addr(&net, dhcp, DHO_SUBNETMASK) == -1) {
1337 net.s_addr = get_netmask(addr.s_addr);
1338 setvar(&ep, prefix, "subnet_mask", inet_ntoa(net));
1339 }
1340 i = inet_ntocidr(net);
1341 snprintf(cidr, sizeof(cidr), "%d", inet_ntocidr(net));
1342 setvar(&ep, prefix, "subnet_cidr", cidr);
1343 if (get_option_addr(&brd, dhcp, DHO_BROADCAST) == -1) {
1344 brd.s_addr = addr.s_addr | ~net.s_addr;
1345 setvar(&ep, prefix, "broadcast_address", inet_ntoa(brd));
1346 }
1347 addr.s_addr = dhcp->yiaddr & net.s_addr;
1348 setvar(&ep, prefix, "network_number", inet_ntoa(addr));
1349 }
1350
1351 if (*dhcp->bootfile && !(overl & 1))
1352 setvar(&ep, prefix, "filename", (const char *)dhcp->bootfile);
1353 if (*dhcp->servername && !(overl & 2))
1354 setvar(&ep, prefix, "server_name", (const char *)dhcp->servername);
1355
1356 for (opt = dhcp_opts; opt->option; opt++) {
1357 if (!opt->var)
1358 continue;
1359 if (has_option_mask(ifo->nomask, opt->option))
1360 continue;
1361 val = NULL;
1362 p = get_option(dhcp, opt->option, &pl, NULL);
1363 if (!p)
1364 continue;
1365 /* We only want the FQDN name */
1366 if (opt->option == DHO_FQDN) {
1367 p += 3;
1368 pl -= 3;
1369 }
1370 len = print_option(NULL, 0, opt->type, pl, p);
1371 if (len < 0)
1372 return -1;
1373 e = strlen(prefix) + strlen(opt->var) + len + 4;
1374 v = val = *ep++ = xmalloc(e);
1375 v += snprintf(val, e, "%s_%s=", prefix, opt->var);
1376 if (len != 0)
1377 print_option(v, len, opt->type, pl, p);
1378 }
1379
1380 return ep - env;
1381 }
1382
1383 void
get_lease(struct dhcp_lease * lease,const struct dhcp_message * dhcp)1384 get_lease(struct dhcp_lease *lease, const struct dhcp_message *dhcp)
1385 {
1386 struct timeval now;
1387
1388 lease->cookie = dhcp->cookie;
1389 /* BOOTP does not set yiaddr for replies when ciaddr is set. */
1390 if (dhcp->yiaddr)
1391 lease->addr.s_addr = dhcp->yiaddr;
1392 else
1393 lease->addr.s_addr = dhcp->ciaddr;
1394 if (get_option_addr(&lease->net, dhcp, DHO_SUBNETMASK) == -1)
1395 lease->net.s_addr = get_netmask(lease->addr.s_addr);
1396 if (get_option_addr(&lease->brd, dhcp, DHO_BROADCAST) == -1)
1397 lease->brd.s_addr = lease->addr.s_addr | ~lease->net.s_addr;
1398 if (get_option_uint32(&lease->leasetime, dhcp, DHO_LEASETIME) == 0) {
1399 /* Ensure that we can use the lease */
1400 get_monotonic(&now);
1401 if (now.tv_sec + (time_t)lease->leasetime < now.tv_sec)
1402 lease->leasetime = ~0U; /* Infinite lease */
1403 } else
1404 lease->leasetime = ~0U; /* Default to infinite lease */
1405 if (get_option_uint32(&lease->renewaltime, dhcp, DHO_RENEWALTIME) != 0)
1406 lease->renewaltime = 0;
1407 if (get_option_uint32(&lease->rebindtime, dhcp, DHO_REBINDTIME) != 0)
1408 lease->rebindtime = 0;
1409 if (get_option_addr(&lease->server, dhcp, DHO_SERVERID) != 0)
1410 lease->server.s_addr = INADDR_ANY;
1411 }
1412