Syncdiff -r1.12 -r1.13 src/external/bsd/dhcpcd/dist/src/bpf.c
(roy)
--- 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 | ||||
414 | static const struct bpf_insn bpf_arp_ether [] = { | 413 | static 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 | |
562 | static const struct bpf_insn bpf_bootp_none[] = { | 550 | static 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 | |||
570 | static const struct bpf_insn bpf_bootp_ether[] = { | 555 | static 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 | ||||
584 | static const struct bpf_insn bpf_bootp_filter[] = { | 570 | static 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 | |||
662 | int | 607 | int | |
663 | bpf_bootp(struct interface *ifp, int fd) | 608 | bpf_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 | } |
--- 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) |
--- 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 | |||
2004 | static void | 2016 | static bool | |
2005 | dhcp_addr_duplicated(struct interface *ifp, struct in_addr *ia) | 2017 | dhcp_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)) | |
2032 | static void | 2058 | static void | |
2033 | dhcp_arp_not_found(struct arp_state *astate) | 2059 | dhcp_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 | |||
3230 | static void * | 3261 | static void * | |
3231 | get_udp_data(void *packet, size_t *len) | 3262 | get_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 | |||
3242 | static int | 3273 | static bool | |
3243 | valid_udp_packet(void *packet, size_t plen, struct in_addr *from, | 3274 | is_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. */ | |||
3304 | static bool | |||
3305 | checksums_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 | |||
3318 | static void | 3345 | static void | |
3319 | dhcp_handlebootp(struct interface *ifp, struct bootp *bootp, size_t len, | 3346 | dhcp_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 | |||
3342 | static void | 3368 | static void | |
3343 | dhcp_handlepacket(struct interface *ifp, uint8_t *data, size_t len) | 3369 | dhcp_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 | |||
3372 | static void | 3401 | static void | |
3373 | dhcp_readpacket(void *arg) | 3402 | dhcp_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 | |||
3404 | static void | 3433 | static void | |
3405 | dhcp_readudp(struct dhcpcd_ctx *ctx, struct interface *ifp) | 3434 | dhcp_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 | |||
3512 | int | 3541 | int | |
3513 | dhcp_dump(struct interface *ifp) | 3542 | dhcp_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 | |||
3940 | void | 3969 | struct ipv4_addr * | |
3941 | dhcp_handleifa(int cmd, struct ipv4_addr *ia, pid_t pid) | 3970 | dhcp_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 | } |
--- 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 | |||
193 | interface will imply Master mode which this is not. | 193 | interface will imply Master mode which this is not. | |
194 | To force starting in Master mode with only one interface, the | 194 | To force starting in Master mode with only one interface, the | |
195 | .Fl M , Fl Fl master | 195 | .Fl M , Fl Fl master | |
196 | option can be used. | 196 | option can be used. | |
197 | .Pp | 197 | .Pp | |
198 | Interfaces are preferred by carrier, DHCP lease/IPv4LL and then lowest metric. | 198 | Interfaces are preferred by carrier, DHCP lease/IPv4LL and then lowest metric. | |
199 | For systems that support route metrics, each route will be tagged with the | 199 | For systems that support route metrics, each route will be tagged with the | |
200 | metric, otherwise | 200 | metric, otherwise | |
201 | .Nm | 201 | .Nm | |
202 | changes the routes to use the interface with the same route and the lowest | 202 | changes the routes to use the interface with the same route and the lowest | |
203 | metric. | 203 | metric. | |
204 | See options below for controlling which interfaces we allow and deny through | 204 | See options below for controlling which interfaces we allow and deny through | |
205 | the use of patterns. | 205 | the use of patterns. | |
206 | .Pp | |||
207 | Non-ethernet interfaces and some virtual ethernet interfaces | |||
208 | such as TAP and bridge are ignored by default, | |||
209 | as is the FireWire interface. | |||
210 | To work with these devices they either need to be specified on the command line, | |||
211 | be listed in | |||
212 | .Fl Fl allowinterfaces | |||
213 | or have an interface directive in | |||
214 | .Pa @SYSCONFDIR@/dhcpcd.conf . | |||
206 | .Ss Hooking into events | 215 | .Ss Hooking into events | |
207 | .Nm | 216 | .Nm | |
208 | runs | 217 | runs | |
209 | .Pa @SCRIPT@ , | 218 | .Pa @SCRIPT@ , | |
210 | or the script specified by the | 219 | or the script specified by the | |
211 | .Fl c , Fl Fl script | 220 | .Fl c , Fl Fl script | |
212 | option. | 221 | option. | |
213 | This script runs each script found in | 222 | This script runs each script found in | |
214 | .Pa @HOOKDIR@ | 223 | .Pa @HOOKDIR@ | |
215 | in a lexical order. | 224 | in a lexical order. | |
216 | The default installation supplies the scripts | 225 | The default installation supplies the scripts | |
217 | .Pa 01-test , | 226 | .Pa 01-test , | |
218 | .Pa 02-dump , | 227 | .Pa 02-dump , |
--- 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 | |||
1093 | static void | 1093 | static void | |
1094 | dhcpcd_checkcarrier(void *arg) | 1094 | dhcpcd_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 | |
1102 | static void | 1107 | static void | |
1103 | dhcpcd_setlinkrcvbuf(struct dhcpcd_ctx *ctx) | 1108 | dhcpcd_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, |
--- 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. */ | |||
105 | static const char * const ifnames_ignore[] = { | |||
106 | "bridge", | |||
107 | "fwe", /* Firewire */ | |||
108 | "tap", | |||
109 | NULL | |||
110 | }; | |||
111 | ||||
104 | #ifdef INET6 | 112 | #ifdef INET6 | |
105 | static void ifa_setscope(struct sockaddr_in6 *, unsigned int); | 113 | static void ifa_setscope(struct sockaddr_in6 *, unsigned int); | |
106 | static unsigned int ifa_getscope(const struct sockaddr_in6 *); | 114 | static unsigned int ifa_getscope(const struct sockaddr_in6 *); | |
107 | #endif | 115 | #endif | |
108 | 116 | |||
109 | struct priv { | 117 | struct priv { | |
110 | int pf_inet6_fd; | 118 | int pf_inet6_fd; | |
111 | }; | 119 | }; | |
112 | 120 | |||
113 | struct rtm | 121 | struct 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 | |||
201 | void | 209 | void | |
202 | if_closesockets_os(struct dhcpcd_ctx *ctx) | 210 | if_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 | |||
219 | static bool | |||
220 | if_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 | ||||
231 | bool | |||
232 | if_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 | ||||
211 | int | 274 | int | |
212 | if_carrier(struct interface *ifp) | 275 | if_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 |
--- 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 | |
513 | static int | 513 | static int | |
514 | parse_addr(__unused struct in_addr *addr, __unused struct in_addr *net, | 514 | parse_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 | |||
523 | static const char * | 523 | static void | |
524 | set_option_space(struct dhcpcd_ctx *ctx, | 524 | set_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 | |||
582 | void | 581 | void | |
583 | free_dhcp_opt_embenc(struct dhcp_opt *opt) | 582 | free_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: |