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 { 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 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 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 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 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 * 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 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 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 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 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 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 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 * 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 * 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 * 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 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 * 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 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 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 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 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 * 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 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 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 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 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 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