Fri Oct 11 11:03:59 2019 UTC ()
Sync


(roy)
diff -r1.12 -r1.13 src/external/bsd/dhcpcd/dist/src/bpf.c
diff -r1.12 -r1.13 src/external/bsd/dhcpcd/dist/src/dhcp6.c
diff -r1.27 -r1.28 src/external/bsd/dhcpcd/dist/src/dhcp.c
diff -r1.3 -r1.4 src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in
diff -r1.26 -r1.27 src/external/bsd/dhcpcd/dist/src/dhcpcd.c
diff -r1.13 -r1.14 src/external/bsd/dhcpcd/dist/src/if-bsd.c
diff -r1.17 -r1.18 src/external/bsd/dhcpcd/dist/src/if-options.c

cvs diff -r1.12 -r1.13 src/external/bsd/dhcpcd/dist/src/bpf.c (expand / switch to unified diff)

--- src/external/bsd/dhcpcd/dist/src/bpf.c 2019/08/21 17:12:19 1.12
+++ src/external/bsd/dhcpcd/dist/src/bpf.c 2019/10/11 11:03:59 1.13
@@ -400,33 +400,27 @@ bpf_cmp_hwaddr(struct bpf_insn *bpf, siz @@ -400,33 +400,27 @@ bpf_cmp_hwaddr(struct bpf_insn *bpf, siz
400 bp++; 400 bp++;
401 } 401 }
402 402
403 /* Last step is always return failure. 403 /* Last step is always return failure.
404 * Next step is a positive finish. */ 404 * Next step is a positive finish. */
405 BPF_SET_STMT(bp, BPF_RET + BPF_K, 0); 405 BPF_SET_STMT(bp, BPF_RET + BPF_K, 0);
406 bp++; 406 bp++;
407 407
408 return (unsigned int)(bp - bpf); 408 return (unsigned int)(bp - bpf);
409} 409}
410#endif 410#endif
411 411
412#ifdef ARP 412#ifdef ARP
413 
414static const struct bpf_insn bpf_arp_ether [] = { 413static const struct bpf_insn bpf_arp_ether [] = {
415 /* Ensure packet is at least correct size. */ 
416 BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0), 
417 BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(struct ether_arp), 1, 0), 
418 BPF_STMT(BPF_RET + BPF_K, 0), 
419 
420 /* Check this is an ARP packet. */ 414 /* Check this is an ARP packet. */
421 BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 415 BPF_STMT(BPF_LD + BPF_H + BPF_ABS,
422 offsetof(struct ether_header, ether_type)), 416 offsetof(struct ether_header, ether_type)),
423 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_ARP, 1, 0), 417 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_ARP, 1, 0),
424 BPF_STMT(BPF_RET + BPF_K, 0), 418 BPF_STMT(BPF_RET + BPF_K, 0),
425 419
426 /* Load frame header length into X */ 420 /* Load frame header length into X */
427 BPF_STMT(BPF_LDX + BPF_W + BPF_IMM, sizeof(struct ether_header)), 421 BPF_STMT(BPF_LDX + BPF_W + BPF_IMM, sizeof(struct ether_header)),
428 422
429 /* Make sure the hardware family matches. */ 423 /* Make sure the hardware family matches. */
430 BPF_STMT(BPF_LD + BPF_H + BPF_IND, offsetof(struct arphdr, ar_hrd)), 424 BPF_STMT(BPF_LD + BPF_H + BPF_IND, offsetof(struct arphdr, ar_hrd)),
431 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPHRD_ETHER, 1, 0), 425 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPHRD_ETHER, 1, 0),
432 BPF_STMT(BPF_RET + BPF_K, 0), 426 BPF_STMT(BPF_RET + BPF_K, 0),
@@ -542,124 +536,75 @@ bpf_arp(struct interface *ifp, int fd) @@ -542,124 +536,75 @@ bpf_arp(struct interface *ifp, int fd)
542 BPF_SET_STMT(bp, BPF_RET + BPF_K, arp_len); 536 BPF_SET_STMT(bp, BPF_RET + BPF_K, arp_len);
543 bp++; 537 bp++;
544 } 538 }
545 539
546 /* Return nothing, no protocol address match. */ 540 /* Return nothing, no protocol address match. */
547 BPF_SET_STMT(bp, BPF_RET + BPF_K, 0); 541 BPF_SET_STMT(bp, BPF_RET + BPF_K, 0);
548 bp++; 542 bp++;
549 } 543 }
550 544
551 return bpf_attach(fd, bpf, (unsigned int)(bp - bpf)); 545 return bpf_attach(fd, bpf, (unsigned int)(bp - bpf));
552} 546}
553#endif 547#endif
554 548
555#define BPF_M_FHLEN 0 
556#define BPF_M_IPHLEN 1 
557#define BPF_M_IPLEN 2 
558#define BPF_M_UDP 3 
559#define BPF_M_UDPLEN 4 
560 
561#ifdef ARPHRD_NONE 549#ifdef ARPHRD_NONE
562static const struct bpf_insn bpf_bootp_none[] = { 550static const struct bpf_insn bpf_bootp_none[] = {
563 /* Set the frame header length to zero. */ 
564 BPF_STMT(BPF_LD + BPF_IMM, 0), 
565 BPF_STMT(BPF_ST, BPF_M_FHLEN), 
566}; 551};
567#define BPF_BOOTP_NONE_LEN __arraycount(bpf_bootp_none) 552#define BPF_BOOTP_NONE_LEN __arraycount(bpf_bootp_none)
568#endif 553#endif
569 554
570static const struct bpf_insn bpf_bootp_ether[] = { 555static const struct bpf_insn bpf_bootp_ether[] = {
571 /* Make sure this is an IP packet. */ 556 /* Make sure this is an IP packet. */
572 BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 557 BPF_STMT(BPF_LD + BPF_H + BPF_ABS,
573 offsetof(struct ether_header, ether_type)), 558 offsetof(struct ether_header, ether_type)),
574 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 1, 0), 559 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 1, 0),
575 BPF_STMT(BPF_RET + BPF_K, 0), 560 BPF_STMT(BPF_RET + BPF_K, 0),
576 561
577 /* Load frame header length into X. */ 562 /* Advance to the IP header. */
578 BPF_STMT(BPF_LDX + BPF_W + BPF_IMM, sizeof(struct ether_header)), 563 BPF_STMT(BPF_LDX + BPF_K, sizeof(struct ether_header)),
579 /* Copy frame header length to memory */ 
580 BPF_STMT(BPF_STX, BPF_M_FHLEN), 
581}; 564};
582#define BPF_BOOTP_ETHER_LEN __arraycount(bpf_bootp_ether) 565#define BPF_BOOTP_ETHER_LEN __arraycount(bpf_bootp_ether)
583 566
 567#define BOOTP_MIN_SIZE sizeof(struct ip) + sizeof(struct udphdr) + \
 568 sizeof(struct bootp)
 569
584static const struct bpf_insn bpf_bootp_filter[] = { 570static const struct bpf_insn bpf_bootp_filter[] = {
585 /* Make sure it's an IPv4 packet. */ 571 /* Make sure it's an IPv4 packet. */
586 BPF_STMT(BPF_LD + BPF_B + BPF_IND, 0), 572 BPF_STMT(BPF_LD + BPF_B + BPF_IND, 0),
587 BPF_STMT(BPF_ALU + BPF_AND + BPF_K, 0xf0), 573 BPF_STMT(BPF_ALU + BPF_AND + BPF_K, 0xf0),
588 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x40, 1, 0), 574 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x40, 1, 0),
589 BPF_STMT(BPF_RET + BPF_K, 0), 575 BPF_STMT(BPF_RET + BPF_K, 0),
590 576
591 /* Ensure IP header length is big enough and 
592 * store the IP header length in memory. */ 
593 BPF_STMT(BPF_LD + BPF_B + BPF_IND, 0), 
594 BPF_STMT(BPF_ALU + BPF_AND + BPF_K, 0x0f), 
595 BPF_STMT(BPF_ALU + BPF_MUL + BPF_K, 4), 
596 BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(struct ip), 1, 0), 
597 BPF_STMT(BPF_RET + BPF_K, 0), 
598 BPF_STMT(BPF_ST, BPF_M_IPHLEN), 
599 
600 /* Make sure it's a UDP packet. */ 577 /* Make sure it's a UDP packet. */
601 BPF_STMT(BPF_LD + BPF_B + BPF_IND, offsetof(struct ip, ip_p)), 578 BPF_STMT(BPF_LD + BPF_B + BPF_IND, offsetof(struct ip, ip_p)),
602 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 1, 0), 579 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 1, 0),
603 BPF_STMT(BPF_RET + BPF_K, 0), 580 BPF_STMT(BPF_RET + BPF_K, 0),
604 581
605 /* Make sure this isn't a fragment. */ 582 /* Make sure this isn't a fragment. */
606 BPF_STMT(BPF_LD + BPF_H + BPF_IND, offsetof(struct ip, ip_off)), 583 BPF_STMT(BPF_LD + BPF_H + BPF_IND, offsetof(struct ip, ip_off)),
607 BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 0, 1), 584 BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 0, 1),
608 BPF_STMT(BPF_RET + BPF_K, 0), 585 BPF_STMT(BPF_RET + BPF_K, 0),
609 586
610 /* Store IP length. */ 
611 BPF_STMT(BPF_LD + BPF_H + BPF_IND, offsetof(struct ip, ip_len)), 
612 BPF_STMT(BPF_ST, BPF_M_IPLEN), 
613 
614 /* Advance to the UDP header. */ 587 /* Advance to the UDP header. */
615 BPF_STMT(BPF_LD + BPF_MEM, BPF_M_IPHLEN), 588 BPF_STMT(BPF_LD + BPF_B + BPF_IND, 0),
 589 BPF_STMT(BPF_ALU + BPF_AND + BPF_K, 0x0f),
 590 BPF_STMT(BPF_ALU + BPF_MUL + BPF_K, 4),
616 BPF_STMT(BPF_ALU + BPF_ADD + BPF_X, 0), 591 BPF_STMT(BPF_ALU + BPF_ADD + BPF_X, 0),
617 BPF_STMT(BPF_MISC + BPF_TAX, 0), 592 BPF_STMT(BPF_MISC + BPF_TAX, 0),
618 593
619 /* Store UDP location */ 
620 BPF_STMT(BPF_STX, BPF_M_UDP), 
621 
622 /* Make sure it's from and to the right port. */ 594 /* Make sure it's from and to the right port. */
623 BPF_STMT(BPF_LD + BPF_W + BPF_IND, 0), 595 BPF_STMT(BPF_LD + BPF_W + BPF_IND, 0),
624 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, (BOOTPS << 16) + BOOTPC, 1, 0), 596 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, (BOOTPS << 16) + BOOTPC, 1, 0),
625 BPF_STMT(BPF_RET + BPF_K, 0), 597 BPF_STMT(BPF_RET + BPF_K, 0),
626 
627 /* Store UDP length. */ 
628 BPF_STMT(BPF_LD + BPF_H + BPF_IND, offsetof(struct udphdr, uh_ulen)), 
629 BPF_STMT(BPF_ST, BPF_M_UDPLEN), 
630 
631 /* Ensure that UDP length + IP header length == IP length */ 
632 /* Copy IP header length to X. */ 
633 BPF_STMT(BPF_LDX + BPF_MEM, BPF_M_IPHLEN), 
634 /* Add UDP length (A) to IP header length (X). */ 
635 BPF_STMT(BPF_ALU + BPF_ADD + BPF_X, 0), 
636 /* Store result in X. */ 
637 BPF_STMT(BPF_MISC + BPF_TAX, 0), 
638 /* Copy IP length to A. */ 
639 BPF_STMT(BPF_LD + BPF_MEM, BPF_M_IPLEN), 
640 /* Ensure X == A. */ 
641 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_X, 0, 1, 0), 
642 BPF_STMT(BPF_RET + BPF_K, 0), 
643 
644 /* Advance to the BOOTP packet. */ 
645 BPF_STMT(BPF_LD + BPF_MEM, BPF_M_UDP), 
646 BPF_STMT(BPF_ALU + BPF_ADD + BPF_K, sizeof(struct udphdr)), 
647 BPF_STMT(BPF_MISC + BPF_TAX, 0), 
648 
649 /* Make sure it's BOOTREPLY. */ 
650 BPF_STMT(BPF_LD + BPF_B + BPF_IND, offsetof(struct bootp, op)), 
651 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, BOOTREPLY, 1, 0), 
652 BPF_STMT(BPF_RET + BPF_K, 0), 
653}; 598};
654 599
655#define BPF_BOOTP_FILTER_LEN __arraycount(bpf_bootp_filter) 600#define BPF_BOOTP_FILTER_LEN __arraycount(bpf_bootp_filter)
656#define BPF_BOOTP_CHADDR_LEN ((BOOTP_CHADDR_LEN / 4) * 3) 601#define BPF_BOOTP_CHADDR_LEN ((BOOTP_CHADDR_LEN / 4) * 3)
657#define BPF_BOOTP_XID_LEN 4 /* BOUND check is 4 instructions */ 602#define BPF_BOOTP_XID_LEN 4 /* BOUND check is 4 instructions */
658 603
659#define BPF_BOOTP_LEN BPF_BOOTP_ETHER_LEN + BPF_BOOTP_FILTER_LEN \ 604#define BPF_BOOTP_LEN BPF_BOOTP_ETHER_LEN + BPF_BOOTP_FILTER_LEN \
660 + BPF_BOOTP_XID_LEN + BPF_BOOTP_CHADDR_LEN + 4 605 + BPF_BOOTP_XID_LEN + BPF_BOOTP_CHADDR_LEN + 4
661 606
662int 607int
663bpf_bootp(struct interface *ifp, int fd) 608bpf_bootp(struct interface *ifp, int fd)
664{ 609{
665#if 0 610#if 0
@@ -719,25 +664,19 @@ bpf_bootp(struct interface *ifp, int fd) @@ -719,25 +664,19 @@ bpf_bootp(struct interface *ifp, int fd)
719 /* As we're not bound, we need to check xid to ensure 664 /* As we're not bound, we need to check xid to ensure
720 * it's a reply to our transaction. */ 665 * it's a reply to our transaction. */
721 BPF_SET_STMT(bp, BPF_LD + BPF_W + BPF_IND, 666 BPF_SET_STMT(bp, BPF_LD + BPF_W + BPF_IND,
722 offsetof(struct bootp, xid)); 667 offsetof(struct bootp, xid));
723 bp++; 668 bp++;
724 BPF_SET_JUMP(bp, BPF_JMP + BPF_JEQ + BPF_K, 669 BPF_SET_JUMP(bp, BPF_JMP + BPF_JEQ + BPF_K,
725 state->xid, 1, 0); 670 state->xid, 1, 0);
726 bp++; 671 bp++;
727 BPF_SET_STMT(bp, BPF_RET + BPF_K, 0); 672 BPF_SET_STMT(bp, BPF_RET + BPF_K, 0);
728 bp++; 673 bp++;
729 } 674 }
730#endif 675#endif
731 676
732 /* All passed, return the packet - frame length + ip length */ 677 /* All passed, return the packet. */
733 BPF_SET_STMT(bp, BPF_LD + BPF_MEM, BPF_M_FHLEN); 678 BPF_SET_STMT(bp, BPF_RET + BPF_K, BPF_WHOLEPACKET);
734 bp++; 
735 BPF_SET_STMT(bp, BPF_LDX + BPF_MEM, BPF_M_IPLEN); 
736 bp++; 
737 BPF_SET_STMT(bp, BPF_ALU + BPF_ADD + BPF_X, 0); 
738 bp++; 
739 BPF_SET_STMT(bp, BPF_RET + BPF_A, 0); 
740 bp++; 679 bp++;
741 680
742 return bpf_attach(fd, bpf, (unsigned int)(bp - bpf)); 681 return bpf_attach(fd, bpf, (unsigned int)(bp - bpf));
743} 682}

cvs diff -r1.12 -r1.13 src/external/bsd/dhcpcd/dist/src/dhcp6.c (expand / switch to unified diff)

--- src/external/bsd/dhcpcd/dist/src/dhcp6.c 2019/09/04 13:28:56 1.12
+++ src/external/bsd/dhcpcd/dist/src/dhcp6.c 2019/10/11 11:03:59 1.13
@@ -522,33 +522,26 @@ dhcp6_delegateaddr(struct in6_addr *addr @@ -522,33 +522,26 @@ dhcp6_delegateaddr(struct in6_addr *addr
522 522
523 TAILQ_INIT(&state->addrs); 523 TAILQ_INIT(&state->addrs);
524 state->state = DH6S_DELEGATED; 524 state->state = DH6S_DELEGATED;
525 state->reason = "DELEGATED6"; 525 state->reason = "DELEGATED6";
526 } 526 }
527 527
528 if (sla == NULL || sla->sla_set == 0) { 528 if (sla == NULL || sla->sla_set == 0) {
529 /* No SLA set, so make an assumption of 529 /* No SLA set, so make an assumption of
530 * desired SLA and prefix length. */ 530 * desired SLA and prefix length. */
531 asla.sla = ifp->index; 531 asla.sla = ifp->index;
532 asla.prefix_len = 0; 532 asla.prefix_len = 0;
533 asla.sla_set = 0; 533 asla.sla_set = 0;
534 sla = &asla; 534 sla = &asla;
535 } else if (sla->sla == 0 && sla->prefix_len == 0) { 
536 /* An SLA of 0 was set with no prefix length specified. 
537 * This means we delegate the whole prefix. */ 
538 asla.sla = sla->sla; 
539 asla.prefix_len = prefix->prefix_len; 
540 asla.sla_set = 0; 
541 sla = &asla; 
542 } else if (sla->prefix_len == 0) { 535 } else if (sla->prefix_len == 0) {
543 /* An SLA was given, but prefix length was not. 536 /* An SLA was given, but prefix length was not.
544 * We need to work out a suitable prefix length for 537 * We need to work out a suitable prefix length for
545 * potentially more than one interface. */ 538 * potentially more than one interface. */
546 asla.sla = sla->sla; 539 asla.sla = sla->sla;
547 asla.prefix_len = 0; 540 asla.prefix_len = 0;
548 asla.sla_set = 0; 541 asla.sla_set = 0;
549 sla = &asla; 542 sla = &asla;
550 } 543 }
551 544
552 if (sla->prefix_len == 0) { 545 if (sla->prefix_len == 0) {
553 uint32_t sla_max; 546 uint32_t sla_max;
554 int bits; 547 int bits;
@@ -670,47 +663,41 @@ dhcp6_makemessage(struct interface *ifp) @@ -670,47 +663,41 @@ dhcp6_makemessage(struct interface *ifp)
670 if (state->state != DH6S_RELEASE) { 663 if (state->state != DH6S_RELEASE) {
671 for (l = 0, opt = ifp->ctx->dhcp6_opts; 664 for (l = 0, opt = ifp->ctx->dhcp6_opts;
672 l < ifp->ctx->dhcp6_opts_len; 665 l < ifp->ctx->dhcp6_opts_len;
673 l++, opt++) 666 l++, opt++)
674 { 667 {
675 for (n = 0, opt2 = ifo->dhcp6_override; 668 for (n = 0, opt2 = ifo->dhcp6_override;
676 n < ifo->dhcp6_override_len; 669 n < ifo->dhcp6_override_len;
677 n++, opt2++) 670 n++, opt2++)
678 { 671 {
679 if (opt->option == opt2->option) 672 if (opt->option == opt2->option)
680 break; 673 break;
681 } 674 }
682 if (n < ifo->dhcp6_override_len) 675 if (n < ifo->dhcp6_override_len)
683 continue; 676 continue;
684 if (!(opt->type & OT_NOREQ) && 677 if (!DHC_REQOPT(opt, ifo->requestmask6, ifo->nomask6))
685 (opt->type & OT_REQUEST || 678 continue;
686 has_option_mask(ifo->requestmask6, opt->option))) 679 n_options++;
687 { 680 len += sizeof(o.len);
688 n_options++; 
689 len += sizeof(o.len); 
690 } 
691 } 681 }
692#ifndef SMALL 682#ifndef SMALL
693 for (l = 0, opt = ifo->dhcp6_override; 683 for (l = 0, opt = ifo->dhcp6_override;
694 l < ifo->dhcp6_override_len; 684 l < ifo->dhcp6_override_len;
695 l++, opt++) 685 l++, opt++)
696 { 686 {
697 if (!(opt->type & OT_NOREQ) && 687 if (!DHC_REQOPT(opt, ifo->requestmask6, ifo->nomask6))
698 (opt->type & OT_REQUEST || 688 continue;
699 has_option_mask(ifo->requestmask6, opt->option))) 689 n_options++;
700 { 690 len += sizeof(o.len);
701 n_options++; 
702 len += sizeof(o.len); 
703 } 
704 } 691 }
705 if (dhcp6_findselfsla(ifp)) { 692 if (dhcp6_findselfsla(ifp)) {
706 n_options++; 693 n_options++;
707 len += sizeof(o.len); 694 len += sizeof(o.len);
708 } 695 }
709#endif 696#endif
710 if (len) 697 if (len)
711 len += sizeof(o); 698 len += sizeof(o);
712 699
713 if (fqdn != FQDN_DISABLE) { 700 if (fqdn != FQDN_DISABLE) {
714 hl = encode_rfc1035(hostname, NULL); 701 hl = encode_rfc1035(hostname, NULL);
715 len += sizeof(o) + 1 + hl; 702 len += sizeof(o) + 1 + hl;
716 } 703 }
@@ -1027,77 +1014,70 @@ dhcp6_makemessage(struct interface *ifp) @@ -1027,77 +1014,70 @@ dhcp6_makemessage(struct interface *ifp)
1027 p++; 1014 p++;
1028 encode_rfc1035(hostname, p); 1015 encode_rfc1035(hostname, p);
1029 p += hl; 1016 p += hl;
1030 o.len = htons((uint16_t)(hl + 1)); 1017 o.len = htons((uint16_t)(hl + 1));
1031 memcpy(o_lenp, &o.len, sizeof(o.len)); 1018 memcpy(o_lenp, &o.len, sizeof(o.len));
1032 } 1019 }
1033 1020
1034 if (ifo->mudurl[0]) 1021 if (ifo->mudurl[0])
1035 COPYIN(D6_OPTION_MUDURL, 1022 COPYIN(D6_OPTION_MUDURL,
1036 ifo->mudurl + 1, ifo->mudurl[0]); 1023 ifo->mudurl + 1, ifo->mudurl[0]);
1037 1024
1038#ifdef AUTH 1025#ifdef AUTH
1039 if ((ifo->auth.options & DHCPCD_AUTH_SENDREQUIRE) != 1026 if ((ifo->auth.options & DHCPCD_AUTH_SENDREQUIRE) !=
1040 DHCPCD_AUTH_SENDREQUIRE) 1027 DHCPCD_AUTH_SENDREQUIRE &&
 1028 !has_option_mask(ifo->nomask6, D6_OPTION_RECONF_ACCEPT))
1041 COPYIN1(D6_OPTION_RECONF_ACCEPT, 0); 1029 COPYIN1(D6_OPTION_RECONF_ACCEPT, 0);
1042#endif 1030#endif
1043 1031
1044 if (n_options) { 1032 if (n_options) {
1045 o_lenp = NEXTLEN; 1033 o_lenp = NEXTLEN;
1046 o.len = 0; 1034 o.len = 0;
1047 COPYIN1(D6_OPTION_ORO, 0); 1035 COPYIN1(D6_OPTION_ORO, 0);
1048 for (l = 0, opt = ifp->ctx->dhcp6_opts; 1036 for (l = 0, opt = ifp->ctx->dhcp6_opts;
1049 l < ifp->ctx->dhcp6_opts_len; 1037 l < ifp->ctx->dhcp6_opts_len;
1050 l++, opt++) 1038 l++, opt++)
1051 { 1039 {
1052#ifndef SMALL 1040#ifndef SMALL
1053 for (n = 0, opt2 = ifo->dhcp6_override; 1041 for (n = 0, opt2 = ifo->dhcp6_override;
1054 n < ifo->dhcp6_override_len; 1042 n < ifo->dhcp6_override_len;
1055 n++, opt2++) 1043 n++, opt2++)
1056 { 1044 {
1057 if (opt->option == opt2->option) 1045 if (opt->option == opt2->option)
1058 break; 1046 break;
1059 } 1047 }
1060 if (n < ifo->dhcp6_override_len) 1048 if (n < ifo->dhcp6_override_len)
1061 continue; 1049 continue;
1062#endif 1050#endif
1063 if (!(opt->type & OT_NOREQ) && 1051 if (!DHC_REQOPT(opt, ifo->requestmask6,
1064 (opt->type & OT_REQUEST || 1052 ifo->nomask6))
1065 has_option_mask(ifo->requestmask6, 1053 continue;
1066 opt->option))) 1054 o.code = htons((uint16_t)opt->option);
1067 { 1055 memcpy(p, &o.code, sizeof(o.code));
1068 o.code = htons((uint16_t)opt->option); 1056 p += sizeof(o.code);
1069 memcpy(p, &o.code, sizeof(o.code)); 1057 o.len = (uint16_t)(o.len + sizeof(o.code));
1070 p += sizeof(o.code); 
1071 o.len = (uint16_t) 
1072 (o.len + sizeof(o.code)); 
1073 } 
1074 } 1058 }
1075#ifndef SMALL 1059#ifndef SMALL
1076 for (l = 0, opt = ifo->dhcp6_override; 1060 for (l = 0, opt = ifo->dhcp6_override;
1077 l < ifo->dhcp6_override_len; 1061 l < ifo->dhcp6_override_len;
1078 l++, opt++) 1062 l++, opt++)
1079 { 1063 {
1080 if (!(opt->type & OT_NOREQ) && 1064 if (!DHC_REQOPT(opt, ifo->requestmask6,
1081 (opt->type & OT_REQUEST || 1065 ifo->nomask6))
1082 has_option_mask(ifo->requestmask6, 1066 continue;
1083 opt->option))) 1067 o.code = htons((uint16_t)opt->option);
1084 { 1068 memcpy(p, &o.code, sizeof(o.code));
1085 o.code = htons((uint16_t)opt->option); 1069 p += sizeof(o.code);
1086 memcpy(p, &o.code, sizeof(o.code)); 1070 o.len = (uint16_t)(o.len + sizeof(o.code));
1087 p += sizeof(o.code); 
1088 o.len = (uint16_t) 
1089 (o.len + sizeof(o.code)); 
1090 } 
1091 } 1071 }
1092 if (dhcp6_findselfsla(ifp)) { 1072 if (dhcp6_findselfsla(ifp)) {
1093 o.code = htons(D6_OPTION_PD_EXCLUDE); 1073 o.code = htons(D6_OPTION_PD_EXCLUDE);
1094 memcpy(p, &o.code, sizeof(o.code)); 1074 memcpy(p, &o.code, sizeof(o.code));
1095 p += sizeof(o.code); 1075 p += sizeof(o.code);
1096 o.len = (uint16_t)(o.len + sizeof(o.code)); 1076 o.len = (uint16_t)(o.len + sizeof(o.code));
1097 } 1077 }
1098#endif 1078#endif
1099 o.len = htons(o.len); 1079 o.len = htons(o.len);
1100 memcpy(o_lenp, &o.len, sizeof(o.len)); 1080 memcpy(o_lenp, &o.len, sizeof(o.len));
1101 } 1081 }
1102 } 1082 }
1103 1083
@@ -2998,27 +2978,29 @@ dhcp6_bind(struct interface *ifp, const  @@ -2998,27 +2978,29 @@ dhcp6_bind(struct interface *ifp, const
2998 case DH6S_CONFIRM: 2978 case DH6S_CONFIRM:
2999 if (state->reason == NULL) 2979 if (state->reason == NULL)
3000 state->reason = "REBOOT6"; 2980 state->reason = "REBOOT6";
3001 /* FALLTHROUGH */ 2981 /* FALLTHROUGH */
3002 case DH6S_TIMEDOUT: 2982 case DH6S_TIMEDOUT:
3003 if (state->reason == NULL) 2983 if (state->reason == NULL)
3004 state->reason = "TIMEOUT6"; 2984 state->reason = "TIMEOUT6";
3005 if (state->renew != 0) { 2985 if (state->renew != 0) {
3006 bool all_expired = true; 2986 bool all_expired = true;
3007 2987
3008 TAILQ_FOREACH(ia, &state->addrs, next) { 2988 TAILQ_FOREACH(ia, &state->addrs, next) {
3009 if (ia->flags & IPV6_AF_STALE) 2989 if (ia->flags & IPV6_AF_STALE)
3010 continue; 2990 continue;
3011 if (ia->prefix_vltime <= state->renew) 2991 if (!(state->renew == ND6_INFINITE_LIFETIME &&
 2992 ia->prefix_vltime == ND6_INFINITE_LIFETIME)
 2993 && ia->prefix_vltime <= state->renew)
3012 logwarnx( 2994 logwarnx(
3013 "%s: %s will expire before renewal", 2995 "%s: %s will expire before renewal",
3014 ifp->name, ia->saddr); 2996 ifp->name, ia->saddr);
3015 else 2997 else
3016 all_expired = false; 2998 all_expired = false;
3017 } 2999 }
3018 if (all_expired) { 3000 if (all_expired) {
3019 /* All address's vltime happens at or before 3001 /* All address's vltime happens at or before
3020 * the configured T1 in the IA. 3002 * the configured T1 in the IA.
3021 * This is a badly configured server and we 3003 * This is a badly configured server and we
3022 * have to use our own notion of what 3004 * have to use our own notion of what
3023 * T1 and T2 should be as a result. 3005 * T1 and T2 should be as a result.
3024 * 3006 *
@@ -3142,26 +3124,28 @@ dhcp6_bind(struct interface *ifp, const  @@ -3142,26 +3124,28 @@ dhcp6_bind(struct interface *ifp, const
3142 if (state->expire != ND6_INFINITE_LIFETIME) 3124 if (state->expire != ND6_INFINITE_LIFETIME)
3143 eloop_timeout_add_sec(ifp->ctx->eloop, 3125 eloop_timeout_add_sec(ifp->ctx->eloop,
3144 (time_t)state->expire, dhcp6_startexpire, ifp); 3126 (time_t)state->expire, dhcp6_startexpire, ifp);
3145 else if (timed_out) 3127 else if (timed_out)
3146 eloop_timeout_add_sec(ifp->ctx->eloop, 3128 eloop_timeout_add_sec(ifp->ctx->eloop,
3147 (time_t)state->expire, dhcp6_startdiscover, ifp); 3129 (time_t)state->expire, dhcp6_startdiscover, ifp);
3148 3130
3149 ipv6_addaddrs(&state->addrs); 3131 ipv6_addaddrs(&state->addrs);
3150 dhcp6_deprecateaddrs(&state->addrs); 3132 dhcp6_deprecateaddrs(&state->addrs);
3151 3133
3152 if (state->state == DH6S_INFORMED) 3134 if (state->state == DH6S_INFORMED)
3153 lognewinfo("%s: refresh in %"PRIu32" seconds", 3135 lognewinfo("%s: refresh in %"PRIu32" seconds",
3154 ifp->name, state->renew); 3136 ifp->name, state->renew);
 3137 else if (state->renew == ND6_INFINITE_LIFETIME)
 3138 lognewinfo("%s: leased for infinity", ifp->name);
3155 else if (state->renew || state->rebind) 3139 else if (state->renew || state->rebind)
3156 lognewinfo("%s: renew in %"PRIu32", " 3140 lognewinfo("%s: renew in %"PRIu32", "
3157 "rebind in %"PRIu32", " 3141 "rebind in %"PRIu32", "
3158 "expire in %"PRIu32" seconds", 3142 "expire in %"PRIu32" seconds",
3159 ifp->name, 3143 ifp->name,
3160 state->renew, state->rebind, state->expire); 3144 state->renew, state->rebind, state->expire);
3161 else if (state->expire == 0) 3145 else if (state->expire == 0)
3162 lognewinfo("%s: will expire", ifp->name); 3146 lognewinfo("%s: will expire", ifp->name);
3163 else 3147 else
3164 lognewinfo("%s: expire in %"PRIu32" seconds", 3148 lognewinfo("%s: expire in %"PRIu32" seconds",
3165 ifp->name, state->expire); 3149 ifp->name, state->expire);
3166 rt_build(ifp->ctx, AF_INET6); 3150 rt_build(ifp->ctx, AF_INET6);
3167 if (!timed_out) 3151 if (!timed_out)

cvs diff -r1.27 -r1.28 src/external/bsd/dhcpcd/dist/src/dhcp.c (expand / switch to unified diff)

--- src/external/bsd/dhcpcd/dist/src/dhcp.c 2019/09/13 11:54:03 1.27
+++ src/external/bsd/dhcpcd/dist/src/dhcp.c 2019/10/11 11:03:59 1.28
@@ -978,27 +978,28 @@ make_message(struct bootp **bootpm, cons @@ -978,27 +978,28 @@ make_message(struct bootp **bootpm, cons
978 p += len; 978 p += len;
979 } 979 }
980 980
981 /* vendor is already encoded correctly, so just add it */ 981 /* vendor is already encoded correctly, so just add it */
982 if (ifo->vendor[0]) { 982 if (ifo->vendor[0]) {
983 AREA_CHECK(ifo->vendor[0]); 983 AREA_CHECK(ifo->vendor[0]);
984 *p++ = DHO_VENDOR; 984 *p++ = DHO_VENDOR;
985 memcpy(p, ifo->vendor, (size_t)ifo->vendor[0] + 1); 985 memcpy(p, ifo->vendor, (size_t)ifo->vendor[0] + 1);
986 p += ifo->vendor[0] + 1; 986 p += ifo->vendor[0] + 1;
987 } 987 }
988 988
989#ifdef AUTH 989#ifdef AUTH
990 if ((ifo->auth.options & DHCPCD_AUTH_SENDREQUIRE) != 990 if ((ifo->auth.options & DHCPCD_AUTH_SENDREQUIRE) !=
991 DHCPCD_AUTH_SENDREQUIRE) 991 DHCPCD_AUTH_SENDREQUIRE &&
 992 !has_option_mask(ifo->nomask, DHO_FORCERENEW_NONCE))
992 { 993 {
993 /* We support HMAC-MD5 */ 994 /* We support HMAC-MD5 */
994 AREA_CHECK(1); 995 AREA_CHECK(1);
995 *p++ = DHO_FORCERENEW_NONCE; 996 *p++ = DHO_FORCERENEW_NONCE;
996 *p++ = 1; 997 *p++ = 1;
997 *p++ = AUTH_ALG_HMAC_MD5; 998 *p++ = AUTH_ALG_HMAC_MD5;
998 } 999 }
999#endif 1000#endif
1000 1001
1001 if (ifo->vivco_len) { 1002 if (ifo->vivco_len) {
1002 AREA_CHECK(sizeof(ul)); 1003 AREA_CHECK(sizeof(ul));
1003 *p++ = DHO_VIVCO; 1004 *p++ = DHO_VIVCO;
1004 lp = p++; 1005 lp = p++;
@@ -1022,52 +1023,46 @@ make_message(struct bootp **bootpm, cons @@ -1022,52 +1023,46 @@ make_message(struct bootp **bootpm, cons
1022 p += vivco->len; 1023 p += vivco->len;
1023 *lp = (uint8_t)(*lp + vivco->len + 1); 1024 *lp = (uint8_t)(*lp + vivco->len + 1);
1024 } 1025 }
1025 } 1026 }
1026 1027
1027 AREA_CHECK(0); 1028 AREA_CHECK(0);
1028 *p++ = DHO_PARAMETERREQUESTLIST; 1029 *p++ = DHO_PARAMETERREQUESTLIST;
1029 n_params = p; 1030 n_params = p;
1030 *p++ = 0; 1031 *p++ = 0;
1031 for (i = 0, opt = ifp->ctx->dhcp_opts; 1032 for (i = 0, opt = ifp->ctx->dhcp_opts;
1032 i < ifp->ctx->dhcp_opts_len; 1033 i < ifp->ctx->dhcp_opts_len;
1033 i++, opt++) 1034 i++, opt++)
1034 { 1035 {
1035 if (!(opt->type & OT_REQUEST || 1036 if (!DHC_REQOPT(opt, ifo->requestmask, ifo->nomask))
1036 has_option_mask(ifo->requestmask, opt->option))) 
1037 continue; 
1038 if (opt->type & OT_NOREQ) 
1039 continue; 1037 continue;
1040 if (type == DHCP_INFORM && 1038 if (type == DHCP_INFORM &&
1041 (opt->option == DHO_RENEWALTIME || 1039 (opt->option == DHO_RENEWALTIME ||
1042 opt->option == DHO_REBINDTIME)) 1040 opt->option == DHO_REBINDTIME))
1043 continue; 1041 continue;
1044 AREA_FIT(1); 1042 AREA_FIT(1);
1045 *p++ = (uint8_t)opt->option; 1043 *p++ = (uint8_t)opt->option;
1046 } 1044 }
1047 for (i = 0, opt = ifo->dhcp_override; 1045 for (i = 0, opt = ifo->dhcp_override;
1048 i < ifo->dhcp_override_len; 1046 i < ifo->dhcp_override_len;
1049 i++, opt++) 1047 i++, opt++)
1050 { 1048 {
1051 /* Check if added above */ 1049 /* Check if added above */
1052 for (lp = n_params + 1; lp < p; lp++) 1050 for (lp = n_params + 1; lp < p; lp++)
1053 if (*lp == (uint8_t)opt->option) 1051 if (*lp == (uint8_t)opt->option)
1054 break; 1052 break;
1055 if (lp < p) 1053 if (lp < p)
1056 continue; 1054 continue;
1057 if (!(opt->type & OT_REQUEST || 1055 if (!DHC_REQOPT(opt, ifo->requestmask, ifo->nomask))
1058 has_option_mask(ifo->requestmask, opt->option))) 
1059 continue; 
1060 if (opt->type & OT_NOREQ) 
1061 continue; 1056 continue;
1062 if (type == DHCP_INFORM && 1057 if (type == DHCP_INFORM &&
1063 (opt->option == DHO_RENEWALTIME || 1058 (opt->option == DHO_RENEWALTIME ||
1064 opt->option == DHO_REBINDTIME)) 1059 opt->option == DHO_REBINDTIME))
1065 continue; 1060 continue;
1066 AREA_FIT(1); 1061 AREA_FIT(1);
1067 *p++ = (uint8_t)opt->option; 1062 *p++ = (uint8_t)opt->option;
1068 } 1063 }
1069 *n_params = (uint8_t)(p - n_params - 1); 1064 *n_params = (uint8_t)(p - n_params - 1);
1070 } 1065 }
1071 1066
1072#ifdef AUTH 1067#ifdef AUTH
1073 auth = NULL; /* appease GCC */ 1068 auth = NULL; /* appease GCC */
@@ -1728,35 +1723,52 @@ send_message(struct interface *ifp, uint @@ -1728,35 +1723,52 @@ send_message(struct interface *ifp, uint
1728 if (ifp->carrier <= LINK_DOWN) 1723 if (ifp->carrier <= LINK_DOWN)
1729 goto fail; 1724 goto fail;
1730 logdebugx("%s: sending %s (xid 0x%x), next in %0.1f seconds", 1725 logdebugx("%s: sending %s (xid 0x%x), next in %0.1f seconds",
1731 ifp->name, 1726 ifp->name,
1732 ifo->options & DHCPCD_BOOTP ? "BOOTP" : get_dhcp_op(type), 1727 ifo->options & DHCPCD_BOOTP ? "BOOTP" : get_dhcp_op(type),
1733 state->xid, 1728 state->xid,
1734 timespec_to_double(&tv)); 1729 timespec_to_double(&tv));
1735 } 1730 }
1736 1731
1737 r = make_message(&bootp, ifp, type); 1732 r = make_message(&bootp, ifp, type);
1738 if (r == -1) 1733 if (r == -1)
1739 goto fail; 1734 goto fail;
1740 len = (size_t)r; 1735 len = (size_t)r;
1741 from.s_addr = bootp->ciaddr; 1736
1742 if (from.s_addr != INADDR_ANY) 1737 if (ipv4_iffindaddr(ifp, &state->lease.addr, NULL) != NULL)
 1738 from.s_addr = state->lease.addr.s_addr;
 1739 else
 1740 from.s_addr = INADDR_ANY;
 1741 if (from.s_addr != INADDR_ANY &&
 1742 state->lease.server.s_addr != INADDR_ANY)
1743 to.s_addr = state->lease.server.s_addr; 1743 to.s_addr = state->lease.server.s_addr;
1744 else 1744 else
1745 to.s_addr = INADDR_ANY; 1745 to.s_addr = INADDR_BROADCAST;
1746 1746
1747 /* If unicasting, try and avoid sending by BPF so we don't 1747 /*
1748 * use a L2 broadcast. */ 1748 * If not listening on the unspecified address we can
1749 if (to.s_addr != INADDR_ANY && to.s_addr != INADDR_BROADCAST) { 1749 * only receive broadcast messages via BPF.
 1750 * Sockets bound to an address cannot receive broadcast messages
 1751 * even if they are setup to send them.
 1752 * Broadcasting from UDP is only an optimisation for rebinding
 1753 * and on BSD, at least, is reliant on the subnet route being
 1754 * correctly configured to recieve the unicast reply.
 1755 * As such, we always broadcast and receive the reply to it via BPF.
 1756 * This also guarantees we have a DHCP server attached to the
 1757 * interface we want to configure because we can't dictate the
 1758 * interface via IP_PKTINFO unlike for IPv6.
 1759 */
 1760 if (to.s_addr != INADDR_BROADCAST)
 1761 {
1750 if (dhcp_sendudp(ifp, &to, bootp, len) != -1) 1762 if (dhcp_sendudp(ifp, &to, bootp, len) != -1)
1751 goto out; 1763 goto out;
1752 logerr("%s: dhcp_sendudp", ifp->name); 1764 logerr("%s: dhcp_sendudp", ifp->name);
1753 } 1765 }
1754 1766
1755 if (dhcp_openbpf(ifp) == -1) 1767 if (dhcp_openbpf(ifp) == -1)
1756 goto out; 1768 goto out;
1757 1769
1758 udp = dhcp_makeudppacket(&ulen, (uint8_t *)bootp, len, from, to); 1770 udp = dhcp_makeudppacket(&ulen, (uint8_t *)bootp, len, from, to);
1759 if (udp == NULL) { 1771 if (udp == NULL) {
1760 logerr("%s: dhcp_makeudppacket", ifp->name); 1772 logerr("%s: dhcp_makeudppacket", ifp->name);
1761 r = 0; 1773 r = 0;
1762 } else { 1774 } else {
@@ -1991,50 +2003,64 @@ dhcp_finish_dad(struct interface *ifp, s @@ -1991,50 +2003,64 @@ dhcp_finish_dad(struct interface *ifp, s
1991 if (ifp->ctx->options & DHCPCD_FORKED) 2003 if (ifp->ctx->options & DHCPCD_FORKED)
1992 return; 2004 return;
1993 2005
1994#ifdef IPV4LL 2006#ifdef IPV4LL
1995 /* Stop IPv4LL now we have a working DHCP address */ 2007 /* Stop IPv4LL now we have a working DHCP address */
1996 ipv4ll_drop(ifp); 2008 ipv4ll_drop(ifp);
1997#endif 2009#endif
1998 2010
1999 if (ifp->options->options & DHCPCD_INFORM) 2011 if (ifp->options->options & DHCPCD_INFORM)
2000 dhcp_inform(ifp); 2012 dhcp_inform(ifp);
2001} 2013}
2002 2014
2003 2015
2004static void 2016static bool
2005dhcp_addr_duplicated(struct interface *ifp, struct in_addr *ia) 2017dhcp_addr_duplicated(struct interface *ifp, struct in_addr *ia)
2006{ 2018{
2007 struct dhcp_state *state = D_STATE(ifp); 2019 struct dhcp_state *state = D_STATE(ifp);
 2020 unsigned long long opts = ifp->options->options;
 2021 struct dhcpcd_ctx *ctx = ifp->ctx;
 2022 bool deleted = false;
2008#ifdef IN_IFF_DUPLICATED 2023#ifdef IN_IFF_DUPLICATED
2009 struct ipv4_addr *iap; 2024 struct ipv4_addr *iap;
2010#endif 2025#endif
2011 2026
2012 if ((state->offer == NULL || state->offer->yiaddr != ia->s_addr) && 2027 if ((state->offer == NULL || state->offer->yiaddr != ia->s_addr) &&
2013 !IN_ARE_ADDR_EQUAL(ia, &state->lease.addr)) 2028 !IN_ARE_ADDR_EQUAL(ia, &state->lease.addr))
2014 return; 2029 return deleted;
2015 2030
2016 /* RFC 2131 3.1.5, Client-server interaction */ 2031 /* RFC 2131 3.1.5, Client-server interaction */
2017 logerrx("%s: DAD detected %s", ifp->name, inet_ntoa(*ia)); 2032 logerrx("%s: DAD detected %s", ifp->name, inet_ntoa(*ia));
2018 unlink(state->leasefile); 2033 unlink(state->leasefile);
2019 if (!(ifp->options->options & DHCPCD_STATIC) && !state->lease.frominfo) 2034 if (!(opts & DHCPCD_STATIC) && !state->lease.frominfo)
2020 dhcp_decline(ifp); 2035 dhcp_decline(ifp);
2021#ifdef IN_IFF_DUPLICATED 2036#ifdef IN_IFF_DUPLICATED
2022 if ((iap = ipv4_iffindaddr(ifp, ia, NULL)) != NULL) 2037 if ((iap = ipv4_iffindaddr(ifp, ia, NULL)) != NULL) {
2023 ipv4_deladdr(iap, 0); 2038 ipv4_deladdr(iap, 0);
 2039 deleted = true;
 2040 }
2024#endif 2041#endif
2025 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); 2042 eloop_timeout_delete(ctx->eloop, NULL, ifp);
 2043 if (opts & (DHCPCD_STATIC | DHCPCD_INFORM)) {
 2044 state->reason = "EXPIRE";
 2045 script_runreason(ifp, state->reason);
 2046#define NOT_ONLY_SELF (DHCPCD_MASTER | DHCPCD_IPV6RS | DHCPCD_DHCP6)
 2047 if (!(ctx->options & NOT_ONLY_SELF))
 2048 eloop_exit(ifp->ctx->eloop, EXIT_FAILURE);
 2049 return deleted;
 2050 }
2026 eloop_timeout_add_sec(ifp->ctx->eloop, 2051 eloop_timeout_add_sec(ifp->ctx->eloop,
2027 DHCP_RAND_MAX, dhcp_discover, ifp); 2052 DHCP_RAND_MAX, dhcp_discover, ifp);
 2053 return deleted;
2028} 2054}
2029#endif 2055#endif
2030 2056
2031#if defined(ARP) && (!defined(KERNEL_RFC5227) || defined(ARPING)) 2057#if defined(ARP) && (!defined(KERNEL_RFC5227) || defined(ARPING))
2032static void 2058static void
2033dhcp_arp_not_found(struct arp_state *astate) 2059dhcp_arp_not_found(struct arp_state *astate)
2034{ 2060{
2035 struct interface *ifp; 2061 struct interface *ifp;
2036#ifdef ARPING 2062#ifdef ARPING
2037 struct dhcp_state *state; 2063 struct dhcp_state *state;
2038 struct if_options *ifo; 2064 struct if_options *ifo;
2039#endif 2065#endif
2040 2066
@@ -2352,27 +2378,29 @@ dhcp_arp_address(struct interface *ifp) @@ -2352,27 +2378,29 @@ dhcp_arp_address(struct interface *ifp)
2352 /* If the interface already has the address configured 2378 /* If the interface already has the address configured
2353 * then we can't ARP for duplicate detection. */ 2379 * then we can't ARP for duplicate detection. */
2354 ia = ipv4_iffindaddr(ifp, &addr, NULL); 2380 ia = ipv4_iffindaddr(ifp, &addr, NULL);
2355#ifdef IN_IFF_NOTUSEABLE 2381#ifdef IN_IFF_NOTUSEABLE
2356 if (ia == NULL || ia->addr_flags & IN_IFF_NOTUSEABLE) { 2382 if (ia == NULL || ia->addr_flags & IN_IFF_NOTUSEABLE) {
2357 state->state = DHS_PROBE; 2383 state->state = DHS_PROBE;
2358 if (ia == NULL) { 2384 if (ia == NULL) {
2359 struct dhcp_lease l; 2385 struct dhcp_lease l;
2360 2386
2361 get_lease(ifp, &l, state->offer, state->offer_len); 2387 get_lease(ifp, &l, state->offer, state->offer_len);
2362 /* Add the address now, let the kernel handle DAD. */ 2388 /* Add the address now, let the kernel handle DAD. */
2363 ipv4_addaddr(ifp, &l.addr, &l.mask, &l.brd, 2389 ipv4_addaddr(ifp, &l.addr, &l.mask, &l.brd,
2364 l.leasetime, l.rebindtime); 2390 l.leasetime, l.rebindtime);
2365 } else 2391 } else if (ia->addr_flags & IN_IFF_DUPLICATED)
 2392 dhcp_addr_duplicated(ifp, &ia->addr);
 2393 else
2366 loginfox("%s: waiting for DAD on %s", 2394 loginfox("%s: waiting for DAD on %s",
2367 ifp->name, inet_ntoa(addr)); 2395 ifp->name, inet_ntoa(addr));
2368 return 0; 2396 return 0;
2369 } 2397 }
2370#else 2398#else
2371 if (!(ifp->flags & IFF_NOARP) && 2399 if (!(ifp->flags & IFF_NOARP) &&
2372 ifp->options->options & DHCPCD_ARP && 2400 ifp->options->options & DHCPCD_ARP &&
2373 ia == NULL) 2401 ia == NULL)
2374 { 2402 {
2375 struct arp_state *astate; 2403 struct arp_state *astate;
2376 struct dhcp_lease l; 2404 struct dhcp_lease l;
2377 2405
2378 astate = dhcp_arp_new(ifp, &addr); 2406 astate = dhcp_arp_new(ifp, &addr);
@@ -2831,50 +2859,56 @@ dhcp_handledhcp(struct interface *ifp, s @@ -2831,50 +2859,56 @@ dhcp_handledhcp(struct interface *ifp, s
2831#ifdef AUTH 2859#ifdef AUTH
2832 const uint8_t *auth; 2860 const uint8_t *auth;
2833 size_t auth_len; 2861 size_t auth_len;
2834#endif 2862#endif
2835#ifdef IN_IFF_DUPLICATED 2863#ifdef IN_IFF_DUPLICATED
2836 struct ipv4_addr *ia; 2864 struct ipv4_addr *ia;
2837#endif 2865#endif
2838 2866
2839#define LOGDHCP0(l, m) \ 2867#define LOGDHCP0(l, m) \
2840 log_dhcp((l), (m), ifp, bootp, bootp_len, from, 0) 2868 log_dhcp((l), (m), ifp, bootp, bootp_len, from, 0)
2841#define LOGDHCP(l, m) \ 2869#define LOGDHCP(l, m) \
2842 log_dhcp((l), (m), ifp, bootp, bootp_len, from, 1) 2870 log_dhcp((l), (m), ifp, bootp, bootp_len, from, 1)
2843 2871
 2872#define IS_STATE_ACTIVE(s) ((s)-state != DHS_NONE && \
 2873 (s)->state != DHS_INIT && (s)->state != DHS_BOUND)
 2874
2844 if (bootp->op != BOOTREPLY) { 2875 if (bootp->op != BOOTREPLY) {
2845 logdebugx("%s: op (%d) is not BOOTREPLY", 2876 if (IS_STATE_ACTIVE(state))
2846 ifp->name, bootp->op); 2877 logdebugx("%s: op (%d) is not BOOTREPLY",
 2878 ifp->name, bootp->op);
2847 return; 2879 return;
2848 } 2880 }
2849 2881
2850 if (state->xid != ntohl(bootp->xid)) { 2882 if (state->xid != ntohl(bootp->xid)) {
2851 if (state->state != DHS_BOUND && state->state != DHS_NONE) 2883 if (IS_STATE_ACTIVE(state))
2852 logdebugx("%s: wrong xid 0x%x (expecting 0x%x) from %s", 2884 logdebugx("%s: wrong xid 0x%x (expecting 0x%x) from %s",
2853 ifp->name, ntohl(bootp->xid), state->xid, 2885 ifp->name, ntohl(bootp->xid), state->xid,
2854 inet_ntoa(*from)); 2886 inet_ntoa(*from));
2855 dhcp_redirect_dhcp(ifp, bootp, bootp_len, from); 2887 dhcp_redirect_dhcp(ifp, bootp, bootp_len, from);
2856 return; 2888 return;
2857 } 2889 }
2858 2890
2859 if (ifp->hwlen <= sizeof(bootp->chaddr) && 2891 if (ifp->hwlen <= sizeof(bootp->chaddr) &&
2860 memcmp(bootp->chaddr, ifp->hwaddr, ifp->hwlen)) 2892 memcmp(bootp->chaddr, ifp->hwaddr, ifp->hwlen))
2861 { 2893 {
2862 char buf[sizeof(bootp->chaddr) * 3]; 2894 if (IS_STATE_ACTIVE(state)) {
 2895 char buf[sizeof(bootp->chaddr) * 3];
2863 2896
2864 logdebugx("%s: xid 0x%x is for hwaddr %s", 2897 logdebugx("%s: xid 0x%x is for hwaddr %s",
2865 ifp->name, ntohl(bootp->xid), 2898 ifp->name, ntohl(bootp->xid),
2866 hwaddr_ntoa(bootp->chaddr, sizeof(bootp->chaddr), 2899 hwaddr_ntoa(bootp->chaddr, sizeof(bootp->chaddr),
2867 buf, sizeof(buf))); 2900 buf, sizeof(buf)));
 2901 }
2868 dhcp_redirect_dhcp(ifp, bootp, bootp_len, from); 2902 dhcp_redirect_dhcp(ifp, bootp, bootp_len, from);
2869 return; 2903 return;
2870 } 2904 }
2871 2905
2872 if (!ifp->active) 2906 if (!ifp->active)
2873 return; 2907 return;
2874 2908
2875 i = whitelisted_ip(ifp->options, from->s_addr); 2909 i = whitelisted_ip(ifp->options, from->s_addr);
2876 switch (i) { 2910 switch (i) {
2877 case WHTLST_NOMATCH: 2911 case WHTLST_NOMATCH:
2878 logwarnx("%s: non whitelisted DHCP packet from %s", 2912 logwarnx("%s: non whitelisted DHCP packet from %s",
2879 ifp->name, inet_ntoa(*from)); 2913 ifp->name, inet_ntoa(*from));
2880 return; 2914 return;
@@ -2949,30 +2983,27 @@ dhcp_handledhcp(struct interface *ifp, s @@ -2949,30 +2983,27 @@ dhcp_handledhcp(struct interface *ifp, s
2949 dhcp_renew(ifp); 2983 dhcp_renew(ifp);
2950 else { 2984 else {
2951 eloop_timeout_delete(ifp->ctx->eloop, 2985 eloop_timeout_delete(ifp->ctx->eloop,
2952 send_inform, ifp); 2986 send_inform, ifp);
2953 dhcp_inform(ifp); 2987 dhcp_inform(ifp);
2954 } 2988 }
2955#else 2989#else
2956 LOGDHCP(logerrx, "unauthenticated Force Renew"); 2990 LOGDHCP(logerrx, "unauthenticated Force Renew");
2957#endif 2991#endif
2958 return; 2992 return;
2959 } 2993 }
2960 2994
2961 if (state->state == DHS_BOUND) { 2995 if (state->state == DHS_BOUND) {
2962 /* Before we supported FORCERENEW we closed off the raw 2996 LOGDHCP(logdebugx, "bound, ignoring");
2963 * port so we effectively ignored all messages. 
2964 * As such we'll not log by default here. */ 
2965 //LOGDHCP(logdebugx, "bound, ignoring"); 
2966 return; 2997 return;
2967 } 2998 }
2968 2999
2969 if (state->state == DHS_PROBE) { 3000 if (state->state == DHS_PROBE) {
2970 /* Ignore any DHCP messages whilst probing a lease to bind. */ 3001 /* Ignore any DHCP messages whilst probing a lease to bind. */
2971 LOGDHCP(logdebugx, "probing, ignoring"); 3002 LOGDHCP(logdebugx, "probing, ignoring");
2972 return; 3003 return;
2973 } 3004 }
2974 3005
2975 /* reset the message counter */ 3006 /* reset the message counter */
2976 state->interval = 0; 3007 state->interval = 0;
2977 3008
2978 /* Ensure that no reject options are present */ 3009 /* Ensure that no reject options are present */
@@ -3229,180 +3260,178 @@ rapidcommit: @@ -3229,180 +3260,178 @@ rapidcommit:
3229 3260
3230static void * 3261static void *
3231get_udp_data(void *packet, size_t *len) 3262get_udp_data(void *packet, size_t *len)
3232{ 3263{
3233 const struct ip *ip = packet; 3264 const struct ip *ip = packet;
3234 size_t ip_hl = (size_t)ip->ip_hl * 4; 3265 size_t ip_hl = (size_t)ip->ip_hl * 4;
3235 char *p = packet; 3266 char *p = packet;
3236 3267
3237 p += ip_hl + sizeof(struct udphdr); 3268 p += ip_hl + sizeof(struct udphdr);
3238 *len = (size_t)ntohs(ip->ip_len) - sizeof(struct udphdr) - ip_hl; 3269 *len = (size_t)ntohs(ip->ip_len) - sizeof(struct udphdr) - ip_hl;
3239 return p; 3270 return p;
3240} 3271}
3241 3272
3242static int 3273static bool
3243valid_udp_packet(void *packet, size_t plen, struct in_addr *from, 3274is_packet_udp_bootp(void *packet, size_t plen)
3244 unsigned int flags) 3275{
 3276 struct ip *ip = packet;
 3277 size_t ip_hlen;
 3278 struct udphdr *udp;
 3279
 3280 if (sizeof(*ip) > plen)
 3281 return false;
 3282
 3283 if (ip->ip_v != IPVERSION || ip->ip_p != IPPROTO_UDP)
 3284 return false;
 3285
 3286 /* Sanity. */
 3287 if (ntohs(ip->ip_len) != plen)
 3288 return false;
 3289
 3290 ip_hlen = (size_t)ip->ip_hl * 4;
 3291 /* Check we have a UDP header and BOOTP. */
 3292 if (ip_hlen + sizeof(*udp) + offsetof(struct bootp, vend) > plen)
 3293 return false;
 3294
 3295 /* Check it's to and from the right ports. */
 3296 udp = (struct udphdr *)(void *)((char *)ip + ip_hlen);
 3297 if (udp->uh_dport != htons(BOOTPC) || udp->uh_sport != htons(BOOTPS))
 3298 return false;
 3299
 3300 return true;
 3301}
 3302
 3303/* Lengths have already been checked. */
 3304static bool
 3305checksums_valid(void *packet,
 3306 struct in_addr *from, unsigned int flags)
3245{ 3307{
3246 struct ip *ip = packet; 3308 struct ip *ip = packet;
3247 struct ip pseudo_ip = { 3309 struct ip pseudo_ip = {
3248 .ip_p = IPPROTO_UDP, 3310 .ip_p = IPPROTO_UDP,
3249 .ip_src = ip->ip_src, 3311 .ip_src = ip->ip_src,
3250 .ip_dst = ip->ip_dst 3312 .ip_dst = ip->ip_dst
3251 }; 3313 };
3252 size_t ip_hlen; 3314 size_t ip_hlen;
3253 uint16_t ip_len, udp_len, uh_sum; 3315 uint16_t udp_len, uh_sum;
3254 struct udphdr *udp; 3316 struct udphdr *udp;
3255 uint32_t csum; 3317 uint32_t csum;
3256 3318
3257 if (plen < sizeof(*ip)) { 
3258 if (from != NULL) 
3259 from->s_addr = INADDR_ANY; 
3260 errno = ERANGE; 
3261 return -1; 
3262 } 
3263 
3264 if (from != NULL) 3319 if (from != NULL)
3265 from->s_addr = ip->ip_src.s_addr; 3320 from->s_addr = ip->ip_src.s_addr;
3266 3321
3267 /* Check we have the IP header */ 
3268 ip_hlen = (size_t)ip->ip_hl * 4; 3322 ip_hlen = (size_t)ip->ip_hl * 4;
3269 if (ip_hlen > plen) { 3323 if (in_cksum(ip, ip_hlen, NULL) != 0)
3270 errno = ENOBUFS; 3324 return false;
3271 return -1; 
3272 } 
3273 3325
3274 if (in_cksum(ip, ip_hlen, NULL) != 0) { 3326 if (flags & BPF_PARTIALCSUM)
3275 errno = EINVAL; 3327 return 0;
3276 return -1; 
3277 } 
3278 
3279 /* Check we have a payload */ 
3280 ip_len = ntohs(ip->ip_len); 
3281 if (ip_len <= ip_hlen + sizeof(*udp)) { 
3282 errno = ERANGE; 
3283 return -1; 
3284 } 
3285 /* Check IP doesn't go beyond the payload */ 
3286 if (ip_len > plen) { 
3287 errno = ENOBUFS; 
3288 return -1; 
3289 } 
3290 3328
3291 /* Check UDP doesn't go beyond the payload */ 
3292 udp = (struct udphdr *)(void *)((char *)ip + ip_hlen); 3329 udp = (struct udphdr *)(void *)((char *)ip + ip_hlen);
3293 udp_len = ntohs(udp->uh_ulen); 3330 if (udp->uh_sum == 0)
3294 if (udp_len > plen - ip_hlen) { 
3295 errno = ENOBUFS; 
3296 return -1; 
3297 } 
3298 
3299 if (udp->uh_sum == 0 || flags & BPF_PARTIALCSUM) 
3300 return 0; 3331 return 0;
3301 3332
3302 /* UDP checksum is based on a pseudo IP header alongside 3333 /* UDP checksum is based on a pseudo IP header alongside
3303 * the UDP header and payload. */ 3334 * the UDP header and payload. */
 3335 udp_len = ntohs(udp->uh_ulen);
3304 uh_sum = udp->uh_sum; 3336 uh_sum = udp->uh_sum;
3305 udp->uh_sum = 0; 3337 udp->uh_sum = 0;
3306 pseudo_ip.ip_len = udp->uh_ulen; 3338 pseudo_ip.ip_len = udp->uh_ulen;
3307 csum = 0; 3339 csum = 0;
3308 in_cksum(&pseudo_ip, sizeof(pseudo_ip), &csum); 3340 in_cksum(&pseudo_ip, sizeof(pseudo_ip), &csum);
3309 csum = in_cksum(udp, udp_len, &csum); 3341 csum = in_cksum(udp, udp_len, &csum);
3310 if (csum != uh_sum) { 3342 return csum == uh_sum;
3311 errno = EINVAL; 
3312 return -1; 
3313 } 
3314 
3315 return 0; 
3316} 3343}
3317 3344
3318static void 3345static void
3319dhcp_handlebootp(struct interface *ifp, struct bootp *bootp, size_t len, 3346dhcp_handlebootp(struct interface *ifp, struct bootp *bootp, size_t len,
3320 struct in_addr *from) 3347 struct in_addr *from)
3321{ 3348{
3322 size_t v; 3349 size_t v;
3323 3350
3324 /* udp_len must be correct because the values are checked in 
3325 * valid_udp_packet(). */ 
3326 if (len < offsetof(struct bootp, vend)) { 3351 if (len < offsetof(struct bootp, vend)) {
3327 logerrx("%s: truncated packet (%zu) from %s", 3352 logerrx("%s: truncated packet (%zu) from %s",
3328 ifp->name, len, inet_ntoa(*from)); 3353 ifp->name, len, inet_ntoa(*from));
3329 return; 3354 return;
3330 } 3355 }
 3356
3331 /* To make our IS_DHCP macro easy, ensure the vendor 3357 /* To make our IS_DHCP macro easy, ensure the vendor
3332 * area has at least 4 octets. */ 3358 * area has at least 4 octets. */
3333 v = len - offsetof(struct bootp, vend); 3359 v = len - offsetof(struct bootp, vend);
3334 while (v < 4) { 3360 while (v < 4) {
3335 bootp->vend[v++] = '\0'; 3361 bootp->vend[v++] = '\0';
3336 len++; 3362 len++;
3337 } 3363 }
3338 3364
3339 dhcp_handledhcp(ifp, bootp, len, from); 3365 dhcp_handledhcp(ifp, bootp, len, from);
3340} 3366}
3341 3367
3342static void 3368static void
3343dhcp_handlepacket(struct interface *ifp, uint8_t *data, size_t len) 3369dhcp_handlebpf(struct interface *ifp, uint8_t *data, size_t len)
3344{ 3370{
3345 struct bootp *bootp; 3371 struct bootp *bootp;
3346 struct in_addr from; 3372 struct in_addr from;
3347 size_t udp_len; 3373 size_t udp_len;
3348 const struct dhcp_state *state = D_CSTATE(ifp); 3374 const struct dhcp_state *state = D_CSTATE(ifp);
3349 3375
3350 if (valid_udp_packet(data, len, &from, state->bpf_flags) == -1) { 3376 /* Validate filter. */
3351 const char *errstr; 3377 if (!is_packet_udp_bootp(data, len)) {
 3378#ifdef BPF_DEBUG
 3379 logerrx("%s: DHCP BPF validation failure", ifp->name);
 3380#endif
 3381 return;
 3382 }
3352 3383
3353 if (errno == EINVAL) 3384 if (!checksums_valid(data, &from, state->bpf_flags)) {
3354 errstr = "checksum failure"; 3385 logerrx("%s: checksum failure from %s",
3355 else 3386 ifp->name, inet_ntoa(from));
3356 errstr = "invalid UDP packet"; 
3357 logerrx("%s: %s from %s", errstr, ifp->name, inet_ntoa(from)); 
3358 return; 3387 return;
3359 } 3388 }
3360 3389
3361 /* 3390 /*
3362 * DHCP has a variable option area rather than a fixed vendor area. 3391 * DHCP has a variable option area rather than a fixed vendor area.
3363 * Because DHCP uses the BOOTP protocol it should still send BOOTP 3392 * Because DHCP uses the BOOTP protocol it should still send BOOTP
3364 * sized packets to be RFC compliant. 3393 * sized packets to be RFC compliant.
3365 * However some servers send a truncated vendor area. 3394 * However some servers send a truncated vendor area.
3366 * dhcpcd can work fine without the vendor area being sent. 3395 * dhcpcd can work fine without the vendor area being sent.
3367 */ 3396 */
3368 bootp = get_udp_data(data, &udp_len); 3397 bootp = get_udp_data(data, &udp_len);
3369 dhcp_handlebootp(ifp, bootp, udp_len, &from); 3398 dhcp_handlebootp(ifp, bootp, udp_len, &from);
3370} 3399}
3371 3400
3372static void 3401static void
3373dhcp_readpacket(void *arg) 3402dhcp_readbpf(void *arg)
3374{ 3403{
3375 struct interface *ifp = arg; 3404 struct interface *ifp = arg;
3376 uint8_t buf[MTU_MAX]; 3405 uint8_t buf[MTU_MAX];
3377 ssize_t bytes; 3406 ssize_t bytes;
3378 struct dhcp_state *state = D_STATE(ifp); 3407 struct dhcp_state *state = D_STATE(ifp);
3379 3408
3380 /* Some RAW mechanisms are generic file descriptors, not sockets. 3409 /* Some RAW mechanisms are generic file descriptors, not sockets.
3381 * This means we have no kernel call to just get one packet, 3410 * This means we have no kernel call to just get one packet,
3382 * so we have to process the entire buffer. */ 3411 * so we have to process the entire buffer. */
3383 state->bpf_flags &= ~BPF_EOF; 3412 state->bpf_flags &= ~BPF_EOF;
3384 state->bpf_flags |= BPF_READING; 3413 state->bpf_flags |= BPF_READING;
3385 while (!(state->bpf_flags & BPF_EOF)) { 3414 while (!(state->bpf_flags & BPF_EOF)) {
3386 bytes = bpf_read(ifp, state->bpf_fd, buf, sizeof(buf), 3415 bytes = bpf_read(ifp, state->bpf_fd, buf, sizeof(buf),
3387 &state->bpf_flags); 3416 &state->bpf_flags);
3388 if (bytes == -1) { 3417 if (bytes == -1) {
3389 if (state->state != DHS_NONE) { 3418 if (state->state != DHS_NONE) {
3390 logerr("%s: %s", __func__, ifp->name); 3419 logerr("%s: %s", __func__, ifp->name);
3391 dhcp_close(ifp); 3420 dhcp_close(ifp);
3392 } 3421 }
3393 break; 3422 break;
3394 } 3423 }
3395 dhcp_handlepacket(ifp, buf, (size_t)bytes); 3424 dhcp_handlebpf(ifp, buf, (size_t)bytes);
3396 /* Check we still have a state after processing. */ 3425 /* Check we still have a state after processing. */
3397 if ((state = D_STATE(ifp)) == NULL) 3426 if ((state = D_STATE(ifp)) == NULL)
3398 break; 3427 break;
3399 } 3428 }
3400 if (state != NULL) 3429 if (state != NULL)
3401 state->bpf_flags &= ~BPF_READING; 3430 state->bpf_flags &= ~BPF_READING;
3402} 3431}
3403 3432
3404static void 3433static void
3405dhcp_readudp(struct dhcpcd_ctx *ctx, struct interface *ifp) 3434dhcp_readudp(struct dhcpcd_ctx *ctx, struct interface *ifp)
3406{ 3435{
3407 const struct dhcp_state *state; 3436 const struct dhcp_state *state;
3408 struct sockaddr_in from; 3437 struct sockaddr_in from;
@@ -3495,27 +3524,27 @@ dhcp_openbpf(struct interface *ifp) @@ -3495,27 +3524,27 @@ dhcp_openbpf(struct interface *ifp)
3495 state->bpf_fd = bpf_open(ifp, bpf_bootp); 3524 state->bpf_fd = bpf_open(ifp, bpf_bootp);
3496 if (state->bpf_fd == -1) { 3525 if (state->bpf_fd == -1) {
3497 if (errno == ENOENT) { 3526 if (errno == ENOENT) {
3498 logerrx("%s not found", bpf_name); 3527 logerrx("%s not found", bpf_name);
3499 /* May as well disable IPv4 entirely at 3528 /* May as well disable IPv4 entirely at
3500 * this point as we really need it. */ 3529 * this point as we really need it. */
3501 ifp->options->options &= ~DHCPCD_IPV4; 3530 ifp->options->options &= ~DHCPCD_IPV4;
3502 } else 3531 } else
3503 logerr("%s: %s", __func__, ifp->name); 3532 logerr("%s: %s", __func__, ifp->name);
3504 return -1; 3533 return -1;
3505 } 3534 }
3506 3535
3507 eloop_event_add(ifp->ctx->eloop, 3536 eloop_event_add(ifp->ctx->eloop,
3508 state->bpf_fd, dhcp_readpacket, ifp); 3537 state->bpf_fd, dhcp_readbpf, ifp);
3509 return 0; 3538 return 0;
3510} 3539}
3511 3540
3512int 3541int
3513dhcp_dump(struct interface *ifp) 3542dhcp_dump(struct interface *ifp)
3514{ 3543{
3515 struct dhcp_state *state; 3544 struct dhcp_state *state;
3516 3545
3517 ifp->if_data[IF_DATA_DHCP] = state = calloc(1, sizeof(*state)); 3546 ifp->if_data[IF_DATA_DHCP] = state = calloc(1, sizeof(*state));
3518 if (state == NULL) 3547 if (state == NULL)
3519 goto eexit; 3548 goto eexit;
3520 state->bpf_fd = -1; 3549 state->bpf_fd = -1;
3521 dhcp_set_leasefile(state->leasefile, sizeof(state->leasefile), 3550 dhcp_set_leasefile(state->leasefile, sizeof(state->leasefile),
@@ -3927,82 +3956,84 @@ dhcp_abort(struct interface *ifp) @@ -3927,82 +3956,84 @@ dhcp_abort(struct interface *ifp)
3927 state->arping_index = -1; 3956 state->arping_index = -1;
3928#endif 3957#endif
3929 3958
3930 eloop_timeout_delete(ifp->ctx->eloop, dhcp_start1, ifp); 3959 eloop_timeout_delete(ifp->ctx->eloop, dhcp_start1, ifp);
3931 3960
3932 if (state != NULL && state->added) { 3961 if (state != NULL && state->added) {
3933 rt_build(ifp->ctx, AF_INET); 3962 rt_build(ifp->ctx, AF_INET);
3934#ifdef ARP 3963#ifdef ARP
3935 arp_announceaddr(ifp->ctx, &state->addr->addr); 3964 arp_announceaddr(ifp->ctx, &state->addr->addr);
3936#endif 3965#endif
3937 } 3966 }
3938} 3967}
3939 3968
3940void 3969struct ipv4_addr *
3941dhcp_handleifa(int cmd, struct ipv4_addr *ia, pid_t pid) 3970dhcp_handleifa(int cmd, struct ipv4_addr *ia, pid_t pid)
3942{ 3971{
3943 struct interface *ifp; 3972 struct interface *ifp;
3944 struct dhcp_state *state; 3973 struct dhcp_state *state;
3945 struct if_options *ifo; 3974 struct if_options *ifo;
3946 uint8_t i; 3975 uint8_t i;
3947 3976
3948 ifp = ia->iface; 3977 ifp = ia->iface;
3949 state = D_STATE(ifp); 3978 state = D_STATE(ifp);
3950 if (state == NULL || state->state == DHS_NONE) 3979 if (state == NULL || state->state == DHS_NONE)
3951 return; 3980 return ia;
3952 3981
3953 if (cmd == RTM_DELADDR) { 3982 if (cmd == RTM_DELADDR) {
3954 if (state->addr == ia) { 3983 if (state->addr == ia) {
3955 loginfox("%s: pid %d deleted IP address %s", 3984 loginfox("%s: pid %d deleted IP address %s",
3956 ifp->name, pid, ia->saddr); 3985 ifp->name, pid, ia->saddr);
3957 state->addr = NULL; 3986 state->addr = NULL;
3958 /* Don't clear the added state as we need 3987 /* Don't clear the added state as we need
3959 * to drop the lease. */ 3988 * to drop the lease. */
3960 dhcp_drop(ifp, "EXPIRE"); 3989 dhcp_drop(ifp, "EXPIRE");
3961 dhcp_start1(ifp); 3990 dhcp_start1(ifp);
 3991 return NULL;
3962 } 3992 }
3963 return; 
3964 } 3993 }
3965 3994
3966 if (cmd != RTM_NEWADDR) 3995 if (cmd != RTM_NEWADDR)
3967 return; 3996 return ia;
3968 3997
3969#ifdef IN_IFF_NOTUSEABLE 3998#ifdef IN_IFF_NOTUSEABLE
3970 if (!(ia->addr_flags & IN_IFF_NOTUSEABLE)) 3999 if (!(ia->addr_flags & IN_IFF_NOTUSEABLE))
3971 dhcp_finish_dad(ifp, &ia->addr); 4000 dhcp_finish_dad(ifp, &ia->addr);
3972 else if (ia->addr_flags & IN_IFF_DUPLICATED) 4001 else if (ia->addr_flags & IN_IFF_DUPLICATED)
3973 dhcp_addr_duplicated(ifp, &ia->addr); 4002 return dhcp_addr_duplicated(ifp, &ia->addr) ? NULL : ia;
3974#endif 4003#endif
3975 4004
3976 ifo = ifp->options; 4005 ifo = ifp->options;
3977 if (ifo->options & DHCPCD_INFORM) { 4006 if (ifo->options & DHCPCD_INFORM) {
3978 if (state->state != DHS_INFORM) 4007 if (state->state != DHS_INFORM)
3979 dhcp_inform(ifp); 4008 dhcp_inform(ifp);
3980 return; 4009 return ia;
3981 } 4010 }
3982 4011
3983 if (!(ifo->options & DHCPCD_STATIC)) 4012 if (!(ifo->options & DHCPCD_STATIC))
3984 return; 4013 return ia;
3985 if (ifo->req_addr.s_addr != INADDR_ANY) 4014 if (ifo->req_addr.s_addr != INADDR_ANY)
3986 return; 4015 return ia;
3987 4016
3988 free(state->old); 4017 free(state->old);
3989 state->old = state->new; 4018 state->old = state->new;
3990 state->new_len = dhcp_message_new(&state->new, &ia->addr, &ia->mask); 4019 state->new_len = dhcp_message_new(&state->new, &ia->addr, &ia->mask);
3991 if (state->new == NULL) 4020 if (state->new == NULL)
3992 return; 4021 return ia;
3993 if (ifp->flags & IFF_POINTOPOINT) { 4022 if (ifp->flags & IFF_POINTOPOINT) {
3994 for (i = 1; i < 255; i++) 4023 for (i = 1; i < 255; i++)
3995 if (i != DHO_ROUTER && has_option_mask(ifo->dstmask,i)) 4024 if (i != DHO_ROUTER && has_option_mask(ifo->dstmask,i))
3996 dhcp_message_add_addr(state->new, i, ia->brd); 4025 dhcp_message_add_addr(state->new, i, ia->brd);
3997 } 4026 }
3998 state->reason = "STATIC"; 4027 state->reason = "STATIC";
3999 rt_build(ifp->ctx, AF_INET); 4028 rt_build(ifp->ctx, AF_INET);
4000 script_runreason(ifp, state->reason); 4029 script_runreason(ifp, state->reason);
4001 if (ifo->options & DHCPCD_INFORM) { 4030 if (ifo->options & DHCPCD_INFORM) {
4002 state->state = DHS_INFORM; 4031 state->state = DHS_INFORM;
4003 dhcp_new_xid(ifp); 4032 dhcp_new_xid(ifp);
4004 state->lease.server.s_addr = INADDR_ANY; 4033 state->lease.server.s_addr = INADDR_ANY;
4005 state->addr = ia; 4034 state->addr = ia;
4006 dhcp_inform(ifp); 4035 dhcp_inform(ifp);
4007 } 4036 }
 4037
 4038 return ia;
4008} 4039}

cvs diff -r1.3 -r1.4 src/external/bsd/dhcpcd/dist/src/Attic/dhcpcd.8.in (expand / switch to unified diff)

--- src/external/bsd/dhcpcd/dist/src/Attic/dhcpcd.8.in 2019/09/04 13:28:56 1.3
+++ src/external/bsd/dhcpcd/dist/src/Attic/dhcpcd.8.in 2019/10/11 11:03:59 1.4
@@ -14,27 +14,27 @@ @@ -14,27 +14,27 @@
14.\" 14.\"
15.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 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 16.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 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 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 24.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25.\" SUCH DAMAGE. 25.\" SUCH DAMAGE.
26.\" 26.\"
27.Dd August 28, 2019 27.Dd October 9, 2019
28.Dt DHCPCD 8 28.Dt DHCPCD 8
29.Os 29.Os
30.Sh NAME 30.Sh NAME
31.Nm dhcpcd 31.Nm dhcpcd
32.Nd a DHCP client 32.Nd a DHCP client
33.Sh SYNOPSIS 33.Sh SYNOPSIS
34.Nm 34.Nm
35.Op Fl 146ABbDdEGgHJKLMNPpqTV 35.Op Fl 146ABbDdEGgHJKLMNPpqTV
36.Op Fl C , Fl Fl nohook Ar hook 36.Op Fl C , Fl Fl nohook Ar hook
37.Op Fl c , Fl Fl script Ar script 37.Op Fl c , Fl Fl script Ar script
38.Op Fl e , Fl Fl env Ar value 38.Op Fl e , Fl Fl env Ar value
39.Op Fl F , Fl Fl fqdn Ar FQDN 39.Op Fl F , Fl Fl fqdn Ar FQDN
40.Op Fl f , Fl Fl config Ar file 40.Op Fl f , Fl Fl config Ar file
@@ -193,26 +193,35 @@ options, where the same interface will n @@ -193,26 +193,35 @@ options, where the same interface will n
193interface will imply Master mode which this is not. 193interface will imply Master mode which this is not.
194To force starting in Master mode with only one interface, the 194To force starting in Master mode with only one interface, the
195.Fl M , Fl Fl master 195.Fl M , Fl Fl master
196option can be used. 196option can be used.
197.Pp 197.Pp
198Interfaces are preferred by carrier, DHCP lease/IPv4LL and then lowest metric. 198Interfaces are preferred by carrier, DHCP lease/IPv4LL and then lowest metric.
199For systems that support route metrics, each route will be tagged with the 199For systems that support route metrics, each route will be tagged with the
200metric, otherwise 200metric, otherwise
201.Nm 201.Nm
202changes the routes to use the interface with the same route and the lowest 202changes the routes to use the interface with the same route and the lowest
203metric. 203metric.
204See options below for controlling which interfaces we allow and deny through 204See options below for controlling which interfaces we allow and deny through
205the use of patterns. 205the use of patterns.
 206.Pp
 207Non-ethernet interfaces and some virtual ethernet interfaces
 208such as TAP and bridge are ignored by default,
 209as is the FireWire interface.
 210To work with these devices they either need to be specified on the command line,
 211be listed in
 212.Fl Fl allowinterfaces
 213or have an interface directive in
 214.Pa @SYSCONFDIR@/dhcpcd.conf .
206.Ss Hooking into events 215.Ss Hooking into events
207.Nm 216.Nm
208runs 217runs
209.Pa @SCRIPT@ , 218.Pa @SCRIPT@ ,
210or the script specified by the 219or the script specified by the
211.Fl c , Fl Fl script 220.Fl c , Fl Fl script
212option. 221option.
213This script runs each script found in 222This script runs each script found in
214.Pa @HOOKDIR@ 223.Pa @HOOKDIR@
215in a lexical order. 224in a lexical order.
216The default installation supplies the scripts 225The default installation supplies the scripts
217.Pa 01-test , 226.Pa 01-test ,
218.Pa 02-dump , 227.Pa 02-dump ,

cvs diff -r1.26 -r1.27 src/external/bsd/dhcpcd/dist/src/dhcpcd.c (expand / switch to unified diff)

--- src/external/bsd/dhcpcd/dist/src/dhcpcd.c 2019/09/13 11:01:50 1.26
+++ src/external/bsd/dhcpcd/dist/src/dhcpcd.c 2019/10/11 11:03:59 1.27
@@ -1084,28 +1084,33 @@ dhcpcd_handlelink(void *arg) @@ -1084,28 +1084,33 @@ dhcpcd_handlelink(void *arg)
1084 if (errno == ENOBUFS || errno == ENOMEM) { 1084 if (errno == ENOBUFS || errno == ENOMEM) {
1085 dhcpcd_linkoverflow(ctx); 1085 dhcpcd_linkoverflow(ctx);
1086 return; 1086 return;
1087 } 1087 }
1088 if (errno != ENOTSUP) 1088 if (errno != ENOTSUP)
1089 logerr(__func__); 1089 logerr(__func__);
1090 } 1090 }
1091} 1091}
1092 1092
1093static void 1093static void
1094dhcpcd_checkcarrier(void *arg) 1094dhcpcd_checkcarrier(void *arg)
1095{ 1095{
1096 struct interface *ifp = arg; 1096 struct interface *ifp = arg;
 1097 int carrier;
1097 1098
1098 dhcpcd_handlecarrier(ifp->ctx, LINK_UNKNOWN, ifp->flags, ifp->name); 1099 /* Check carrier here rather than setting LINK_UNKNOWN.
 1100 * This is because we force LINK_UNKNOWN as down for wireless which
 1101 * we do not want when dealing with a route socket overflow. */
 1102 carrier = if_carrier(ifp);
 1103 dhcpcd_handlecarrier(ifp->ctx, carrier, ifp->flags, ifp->name);
1099} 1104}
1100 1105
1101#ifndef SMALL 1106#ifndef SMALL
1102static void 1107static void
1103dhcpcd_setlinkrcvbuf(struct dhcpcd_ctx *ctx) 1108dhcpcd_setlinkrcvbuf(struct dhcpcd_ctx *ctx)
1104{ 1109{
1105 socklen_t socklen; 1110 socklen_t socklen;
1106 1111
1107 if (ctx->link_rcvbuf == 0) 1112 if (ctx->link_rcvbuf == 0)
1108 return; 1113 return;
1109 1114
1110 socklen = sizeof(ctx->link_rcvbuf); 1115 socklen = sizeof(ctx->link_rcvbuf);
1111 if (setsockopt(ctx->link_fd, SOL_SOCKET, 1116 if (setsockopt(ctx->link_fd, SOL_SOCKET,

cvs diff -r1.13 -r1.14 src/external/bsd/dhcpcd/dist/src/if-bsd.c (expand / switch to unified diff)

--- src/external/bsd/dhcpcd/dist/src/if-bsd.c 2019/09/13 11:01:50 1.13
+++ src/external/bsd/dhcpcd/dist/src/if-bsd.c 2019/10/11 11:03:59 1.14
@@ -91,26 +91,34 @@ @@ -91,26 +91,34 @@
91#include "ipv4ll.h" 91#include "ipv4ll.h"
92#include "ipv6.h" 92#include "ipv6.h"
93#include "ipv6nd.h" 93#include "ipv6nd.h"
94#include "logerr.h" 94#include "logerr.h"
95#include "route.h" 95#include "route.h"
96#include "sa.h" 96#include "sa.h"
97 97
98#ifndef RT_ROUNDUP 98#ifndef RT_ROUNDUP
99#define RT_ROUNDUP(a) \ 99#define RT_ROUNDUP(a) \
100 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) 100 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
101#define RT_ADVANCE(x, n) (x += RT_ROUNDUP((n)->sa_len)) 101#define RT_ADVANCE(x, n) (x += RT_ROUNDUP((n)->sa_len))
102#endif 102#endif
103 103
 104/* Ignore these interface names which look like ethernet but are virtual. */
 105static const char * const ifnames_ignore[] = {
 106 "bridge",
 107 "fwe", /* Firewire */
 108 "tap",
 109 NULL
 110};
 111
104#ifdef INET6 112#ifdef INET6
105static void ifa_setscope(struct sockaddr_in6 *, unsigned int); 113static void ifa_setscope(struct sockaddr_in6 *, unsigned int);
106static unsigned int ifa_getscope(const struct sockaddr_in6 *); 114static unsigned int ifa_getscope(const struct sockaddr_in6 *);
107#endif 115#endif
108 116
109struct priv { 117struct priv {
110 int pf_inet6_fd; 118 int pf_inet6_fd;
111}; 119};
112 120
113struct rtm 121struct rtm
114{ 122{
115 struct rt_msghdr hdr; 123 struct rt_msghdr hdr;
116 char buffer[sizeof(struct sockaddr_storage) * RTAX_MAX]; 124 char buffer[sizeof(struct sockaddr_storage) * RTAX_MAX];
@@ -198,26 +206,81 @@ if_opensockets_os(struct dhcpcd_ctx *ctx @@ -198,26 +206,81 @@ if_opensockets_os(struct dhcpcd_ctx *ctx
198 return 0; 206 return 0;
199} 207}
200 208
201void 209void
202if_closesockets_os(struct dhcpcd_ctx *ctx) 210if_closesockets_os(struct dhcpcd_ctx *ctx)
203{ 211{
204 struct priv *priv; 212 struct priv *priv;
205 213
206 priv = (struct priv *)ctx->priv; 214 priv = (struct priv *)ctx->priv;
207 if (priv->pf_inet6_fd != -1) 215 if (priv->pf_inet6_fd != -1)
208 close(priv->pf_inet6_fd); 216 close(priv->pf_inet6_fd);
209} 217}
210 218
 219static bool
 220if_ignore1(const char *drvname)
 221{
 222 const char * const *p;
 223
 224 for (p = ifnames_ignore; *p; p++) {
 225 if (strcmp(*p, drvname) == 0)
 226 return true;
 227 }
 228 return false;
 229}
 230
 231bool
 232if_ignore(struct dhcpcd_ctx *ctx, const char *ifname)
 233{
 234 struct if_spec spec;
 235
 236 if (if_nametospec(ifname, &spec) != 0)
 237 return false;
 238
 239 if (if_ignore1(spec.drvname))
 240 return true;
 241
 242#ifdef SIOCGIFGROUP
 243 struct ifgroupreq ifgr = { .ifgr_len = 0 };
 244 struct ifg_req *ifg;
 245 size_t ifg_len;
 246
 247 /* Sadly it is possible to remove the device name
 248 * from the interface groups, but hopefully this
 249 * will be very unlikely.... */
 250
 251 strlcpy(ifgr.ifgr_name, ifname, sizeof(ifgr.ifgr_name));
 252 if (ioctl(ctx->pf_inet_fd, SIOCGIFGROUP, &ifgr) == -1 ||
 253 (ifgr.ifgr_groups = malloc(ifgr.ifgr_len)) == NULL ||
 254 ioctl(ctx->pf_inet_fd, SIOCGIFGROUP, &ifgr) == -1)
 255 {
 256 logerr(__func__);
 257 return false;
 258 }
 259
 260 for (ifg = ifgr.ifgr_groups, ifg_len = ifgr.ifgr_len;
 261 ifg && ifg_len >= sizeof(*ifg);
 262 ifg++, ifg_len -= sizeof(*ifg))
 263 {
 264 if (if_ignore1(ifg->ifgrq_group))
 265 return true;
 266 }
 267#else
 268 UNUSED(ctx);
 269#endif
 270
 271 return false;
 272}
 273
211int 274int
212if_carrier(struct interface *ifp) 275if_carrier(struct interface *ifp)
213{ 276{
214 struct ifmediareq ifmr = { .ifm_status = 0 }; 277 struct ifmediareq ifmr = { .ifm_status = 0 };
215 278
216 strlcpy(ifmr.ifm_name, ifp->name, sizeof(ifmr.ifm_name)); 279 strlcpy(ifmr.ifm_name, ifp->name, sizeof(ifmr.ifm_name));
217 if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFMEDIA, &ifmr) == -1 || 280 if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFMEDIA, &ifmr) == -1 ||
218 !(ifmr.ifm_status & IFM_AVALID)) 281 !(ifmr.ifm_status & IFM_AVALID))
219 return LINK_UNKNOWN; 282 return LINK_UNKNOWN;
220 283
221 return (ifmr.ifm_status & IFM_ACTIVE) ? LINK_UP : LINK_DOWN; 284 return (ifmr.ifm_status & IFM_ACTIVE) ? LINK_UP : LINK_DOWN;
222} 285}
223 286

cvs diff -r1.17 -r1.18 src/external/bsd/dhcpcd/dist/src/if-options.c (expand / switch to unified diff)

--- src/external/bsd/dhcpcd/dist/src/if-options.c 2019/08/21 17:12:19 1.17
+++ src/external/bsd/dhcpcd/dist/src/if-options.c 2019/10/11 11:03:59 1.18
@@ -510,83 +510,82 @@ parse_addr(struct in_addr *addr, struct  @@ -510,83 +510,82 @@ parse_addr(struct in_addr *addr, struct
510 return 0; 510 return 0;
511} 511}
512#else 512#else
513static int 513static int
514parse_addr(__unused struct in_addr *addr, __unused struct in_addr *net, 514parse_addr(__unused struct in_addr *addr, __unused struct in_addr *net,
515 __unused const char *arg) 515 __unused const char *arg)
516{ 516{
517 517
518 logerrx("No IPv4 support"); 518 logerrx("No IPv4 support");
519 return -1; 519 return -1;
520} 520}
521#endif 521#endif
522 522
523static const char * 523static void
524set_option_space(struct dhcpcd_ctx *ctx, 524set_option_space(struct dhcpcd_ctx *ctx,
525 const char *arg, 525 const char *arg,
526 const struct dhcp_opt **d, size_t *dl, 526 const struct dhcp_opt **d, size_t *dl,
527 const struct dhcp_opt **od, size_t *odl, 527 const struct dhcp_opt **od, size_t *odl,
528 struct if_options *ifo, 528 struct if_options *ifo,
529 uint8_t *request[], uint8_t *require[], uint8_t *no[], uint8_t *reject[]) 529 uint8_t *request[], uint8_t *require[], uint8_t *no[], uint8_t *reject[])
530{ 530{
531 531
532#if !defined(INET) && !defined(INET6) 532#if !defined(INET) && !defined(INET6)
533 UNUSED(ctx); 533 UNUSED(ctx);
534#endif 534#endif
535 535
536#ifdef INET6 536#ifdef INET6
537 if (strncmp(arg, "nd_", strlen("nd_")) == 0) { 537 if (strncmp(arg, "nd_", strlen("nd_")) == 0) {
538 *d = ctx->nd_opts; 538 *d = ctx->nd_opts;
539 *dl = ctx->nd_opts_len; 539 *dl = ctx->nd_opts_len;
540 *od = ifo->nd_override; 540 *od = ifo->nd_override;
541 *odl = ifo->nd_override_len; 541 *odl = ifo->nd_override_len;
542 *request = ifo->requestmasknd; 542 *request = ifo->requestmasknd;
543 *require = ifo->requiremasknd; 543 *require = ifo->requiremasknd;
544 *no = ifo->nomasknd; 544 *no = ifo->nomasknd;
545 *reject = ifo->rejectmasknd; 545 *reject = ifo->rejectmasknd;
546 return arg + strlen("nd_"); 546 return;
547 } 547 }
548 548
549#ifdef DHCP6 549#ifdef DHCP6
550 if (strncmp(arg, "dhcp6_", strlen("dhcp6_")) == 0) { 550 if (strncmp(arg, "dhcp6_", strlen("dhcp6_")) == 0) {
551 *d = ctx->dhcp6_opts; 551 *d = ctx->dhcp6_opts;
552 *dl = ctx->dhcp6_opts_len; 552 *dl = ctx->dhcp6_opts_len;
553 *od = ifo->dhcp6_override; 553 *od = ifo->dhcp6_override;
554 *odl = ifo->dhcp6_override_len; 554 *odl = ifo->dhcp6_override_len;
555 *request = ifo->requestmask6; 555 *request = ifo->requestmask6;
556 *require = ifo->requiremask6; 556 *require = ifo->requiremask6;
557 *no = ifo->nomask6; 557 *no = ifo->nomask6;
558 *reject = ifo->rejectmask6; 558 *reject = ifo->rejectmask6;
559 return arg + strlen("dhcp6_"); 559 return;
560 } 560 }
561#endif 561#endif
562#endif 562#endif
563 563
564#ifdef INET 564#ifdef INET
565 *d = ctx->dhcp_opts; 565 *d = ctx->dhcp_opts;
566 *dl = ctx->dhcp_opts_len; 566 *dl = ctx->dhcp_opts_len;
567 *od = ifo->dhcp_override; 567 *od = ifo->dhcp_override;
568 *odl = ifo->dhcp_override_len; 568 *odl = ifo->dhcp_override_len;
569#else 569#else
570 *d = NULL; 570 *d = NULL;
571 *dl = 0; 571 *dl = 0;
572 *od = NULL; 572 *od = NULL;
573 *odl = 0; 573 *odl = 0;
574#endif 574#endif
575 *request = ifo->requestmask; 575 *request = ifo->requestmask;
576 *require = ifo->requiremask; 576 *require = ifo->requiremask;
577 *no = ifo->nomask; 577 *no = ifo->nomask;
578 *reject = ifo->rejectmask; 578 *reject = ifo->rejectmask;
579 return arg; 
580} 579}
581 580
582void 581void
583free_dhcp_opt_embenc(struct dhcp_opt *opt) 582free_dhcp_opt_embenc(struct dhcp_opt *opt)
584{ 583{
585 size_t i; 584 size_t i;
586 struct dhcp_opt *o; 585 struct dhcp_opt *o;
587 586
588 free(opt->var); 587 free(opt->var);
589 588
590 for (i = 0, o = opt->embopts; i < opt->embopts_len; i++, o++) 589 for (i = 0, o = opt->embopts; i < opt->embopts_len; i++, o++)
591 free_dhcp_opt_embenc(o); 590 free_dhcp_opt_embenc(o);
592 free(opt->embopts); 591 free(opt->embopts);
@@ -796,39 +795,39 @@ parse_option(struct dhcpcd_ctx *ctx, con @@ -796,39 +795,39 @@ parse_option(struct dhcpcd_ctx *ctx, con
796 return -1; 795 return -1;
797 } 796 }
798 break; 797 break;
799 case 'm': 798 case 'm':
800 ARG_REQUIRED; 799 ARG_REQUIRED;
801 ifo->metric = (int)strtoi(arg, NULL, 0, 0, INT32_MAX, &e); 800 ifo->metric = (int)strtoi(arg, NULL, 0, 0, INT32_MAX, &e);
802 if (e) { 801 if (e) {
803 logerrx("failed to convert metric %s", arg); 802 logerrx("failed to convert metric %s", arg);
804 return -1; 803 return -1;
805 } 804 }
806 break; 805 break;
807 case 'o': 806 case 'o':
808 ARG_REQUIRED; 807 ARG_REQUIRED;
809 arg = set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo, 808 set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo,
810 &request, &require, &no, &reject); 809 &request, &require, &no, &reject);
811 if (make_option_mask(d, dl, od, odl, request, arg, 1) != 0 || 810 if (make_option_mask(d, dl, od, odl, request, arg, 1) != 0 ||
812 make_option_mask(d, dl, od, odl, no, arg, -1) != 0 || 811 make_option_mask(d, dl, od, odl, no, arg, -1) != 0 ||
813 make_option_mask(d, dl, od, odl, reject, arg, -1) != 0) 812 make_option_mask(d, dl, od, odl, reject, arg, -1) != 0)
814 { 813 {
815 logerrx("unknown option `%s'", arg); 814 logerrx("unknown option `%s'", arg);
816 return -1; 815 return -1;
817 } 816 }
818 break; 817 break;
819 case O_REJECT: 818 case O_REJECT:
820 ARG_REQUIRED; 819 ARG_REQUIRED;
821 arg = set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo, 820 set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo,
822 &request, &require, &no, &reject); 821 &request, &require, &no, &reject);
823 if (make_option_mask(d, dl, od, odl, reject, arg, 1) != 0 || 822 if (make_option_mask(d, dl, od, odl, reject, arg, 1) != 0 ||
824 make_option_mask(d, dl, od, odl, request, arg, -1) != 0 || 823 make_option_mask(d, dl, od, odl, request, arg, -1) != 0 ||
825 make_option_mask(d, dl, od, odl, require, arg, -1) != 0) 824 make_option_mask(d, dl, od, odl, require, arg, -1) != 0)
826 { 825 {
827 logerrx("unknown option `%s'", arg); 826 logerrx("unknown option `%s'", arg);
828 return -1; 827 return -1;
829 } 828 }
830 break; 829 break;
831 case 'p': 830 case 'p':
832 ifo->options |= DHCPCD_PERSISTENT; 831 ifo->options |= DHCPCD_PERSISTENT;
833 break; 832 break;
834 case 'r': 833 case 'r':
@@ -1043,39 +1042,39 @@ parse_option(struct dhcpcd_ctx *ctx, con @@ -1043,39 +1042,39 @@ parse_option(struct dhcpcd_ctx *ctx, con
1043 ifo->options |= DHCPCD_BROADCAST; 1042 ifo->options |= DHCPCD_BROADCAST;
1044 break; 1043 break;
1045 case 'K': 1044 case 'K':
1046 ifo->options &= ~DHCPCD_LINK; 1045 ifo->options &= ~DHCPCD_LINK;
1047 break; 1046 break;
1048 case 'L': 1047 case 'L':
1049 ifo->options &= ~DHCPCD_IPV4LL; 1048 ifo->options &= ~DHCPCD_IPV4LL;
1050 break; 1049 break;
1051 case 'M': 1050 case 'M':
1052 ifo->options |= DHCPCD_MASTER; 1051 ifo->options |= DHCPCD_MASTER;
1053 break; 1052 break;
1054 case 'O': 1053 case 'O':
1055 ARG_REQUIRED; 1054 ARG_REQUIRED;
1056 arg = set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo, 1055 set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo,
1057 &request, &require, &no, &reject); 1056 &request, &require, &no, &reject);
1058 if (make_option_mask(d, dl, od, odl, request, arg, -1) != 0 || 1057 if (make_option_mask(d, dl, od, odl, request, arg, -1) != 0 ||
1059 make_option_mask(d, dl, od, odl, require, arg, -1) != 0 || 1058 make_option_mask(d, dl, od, odl, require, arg, -1) != 0 ||
1060 make_option_mask(d, dl, od, odl, no, arg, 1) != 0) 1059 make_option_mask(d, dl, od, odl, no, arg, 1) != 0)
1061 { 1060 {
1062 logerrx("unknown option `%s'", arg); 1061 logerrx("unknown option `%s'", arg);
1063 return -1; 1062 return -1;
1064 } 1063 }
1065 break; 1064 break;
1066 case 'Q': 1065 case 'Q':
1067 ARG_REQUIRED; 1066 ARG_REQUIRED;
1068 arg = set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo, 1067 set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo,
1069 &request, &require, &no, &reject); 1068 &request, &require, &no, &reject);
1070 if (make_option_mask(d, dl, od, odl, require, arg, 1) != 0 || 1069 if (make_option_mask(d, dl, od, odl, require, arg, 1) != 0 ||
1071 make_option_mask(d, dl, od, odl, request, arg, 1) != 0 || 1070 make_option_mask(d, dl, od, odl, request, arg, 1) != 0 ||
1072 make_option_mask(d, dl, od, odl, no, arg, -1) != 0 || 1071 make_option_mask(d, dl, od, odl, no, arg, -1) != 0 ||
1073 make_option_mask(d, dl, od, odl, reject, arg, -1) != 0) 1072 make_option_mask(d, dl, od, odl, reject, arg, -1) != 0)
1074 { 1073 {
1075 logerrx("unknown option `%s'", arg); 1074 logerrx("unknown option `%s'", arg);
1076 return -1; 1075 return -1;
1077 } 1076 }
1078 break; 1077 break;
1079 case 'S': 1078 case 'S':
1080 ARG_REQUIRED; 1079 ARG_REQUIRED;
1081 p = strchr(arg, '='); 1080 p = strchr(arg, '=');
@@ -1243,27 +1242,27 @@ parse_option(struct dhcpcd_ctx *ctx, con @@ -1243,27 +1242,27 @@ parse_option(struct dhcpcd_ctx *ctx, con
1243 naddr = reallocarray(ifo->arping, 1242 naddr = reallocarray(ifo->arping,
1244 (size_t)ifo->arping_len + 1, sizeof(in_addr_t)); 1243 (size_t)ifo->arping_len + 1, sizeof(in_addr_t));
1245 if (naddr == NULL) { 1244 if (naddr == NULL) {
1246 logerr(__func__); 1245 logerr(__func__);
1247 return -1; 1246 return -1;
1248 } 1247 }
1249 ifo->arping = naddr; 1248 ifo->arping = naddr;
1250 ifo->arping[ifo->arping_len++] = addr.s_addr; 1249 ifo->arping[ifo->arping_len++] = addr.s_addr;
1251 arg = strskipwhite(fp); 1250 arg = strskipwhite(fp);
1252 } 1251 }
1253 break; 1252 break;
1254 case O_DESTINATION: 1253 case O_DESTINATION:
1255 ARG_REQUIRED; 1254 ARG_REQUIRED;
1256 arg = set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo, 1255 set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo,
1257 &request, &require, &no, &reject); 1256 &request, &require, &no, &reject);
1258 if (make_option_mask(d, dl, od, odl, 1257 if (make_option_mask(d, dl, od, odl,
1259 ifo->dstmask, arg, 2) != 0) 1258 ifo->dstmask, arg, 2) != 0)
1260 { 1259 {
1261 if (errno == EINVAL) 1260 if (errno == EINVAL)
1262 logerrx("option `%s' does not take" 1261 logerrx("option `%s' does not take"
1263 " an IPv4 address", arg); 1262 " an IPv4 address", arg);
1264 else 1263 else
1265 logerrx("unknown option `%s'", arg); 1264 logerrx("unknown option `%s'", arg);
1266 return -1; 1265 return -1;
1267 } 1266 }
1268 break; 1267 break;
1269 case O_FALLBACK: 1268 case O_FALLBACK: