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