Sun Nov 1 14:24:01 2020 UTC ()
Sync with dhcpcd-9.3.2


(roy)
diff -r1.41 -r1.42 src/external/bsd/dhcpcd/dist/src/dhcp.c
diff -r1.8 -r1.9 src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in
diff -r1.44 -r1.45 src/external/bsd/dhcpcd/dist/src/dhcpcd.c
diff -r1.10 -r1.11 src/external/bsd/dhcpcd/dist/src/logerr.c
diff -r1.9 -r1.10 src/external/bsd/dhcpcd/dist/src/privsep.c

cvs diff -r1.41 -r1.42 src/external/bsd/dhcpcd/dist/src/dhcp.c (switch to unified diff)

--- src/external/bsd/dhcpcd/dist/src/dhcp.c 2020/10/12 14:09:03 1.41
+++ src/external/bsd/dhcpcd/dist/src/dhcp.c 2020/11/01 14:24:01 1.42
@@ -524,3661 +524,3714 @@ get_option_string(struct dhcpcd_ctx *ctx @@ -524,3661 +524,3714 @@ get_option_string(struct dhcpcd_ctx *ctx
524{ 524{
525 size_t len; 525 size_t len;
526 const uint8_t *p; 526 const uint8_t *p;
527 char *s; 527 char *s;
528 528
529 p = get_option(ctx, bootp, bootp_len, option, &len); 529 p = get_option(ctx, bootp, bootp_len, option, &len);
530 if (!p || len == 0 || *p == '\0') 530 if (!p || len == 0 || *p == '\0')
531 return NULL; 531 return NULL;
532 532
533 s = malloc(sizeof(char) * (len + 1)); 533 s = malloc(sizeof(char) * (len + 1));
534 if (s) { 534 if (s) {
535 memcpy(s, p, len); 535 memcpy(s, p, len);
536 s[len] = '\0'; 536 s[len] = '\0';
537 } 537 }
538 return s; 538 return s;
539} 539}
540 540
541/* This calculates the netmask that we should use for static routes. 541/* This calculates the netmask that we should use for static routes.
542 * This IS different from the calculation used to calculate the netmask 542 * This IS different from the calculation used to calculate the netmask
543 * for an interface address. */ 543 * for an interface address. */
544static uint32_t 544static uint32_t
545route_netmask(uint32_t ip_in) 545route_netmask(uint32_t ip_in)
546{ 546{
547 /* used to be unsigned long - check if error */ 547 /* used to be unsigned long - check if error */
548 uint32_t p = ntohl(ip_in); 548 uint32_t p = ntohl(ip_in);
549 uint32_t t; 549 uint32_t t;
550 550
551 if (IN_CLASSA(p)) 551 if (IN_CLASSA(p))
552 t = ~IN_CLASSA_NET; 552 t = ~IN_CLASSA_NET;
553 else { 553 else {
554 if (IN_CLASSB(p)) 554 if (IN_CLASSB(p))
555 t = ~IN_CLASSB_NET; 555 t = ~IN_CLASSB_NET;
556 else { 556 else {
557 if (IN_CLASSC(p)) 557 if (IN_CLASSC(p))
558 t = ~IN_CLASSC_NET; 558 t = ~IN_CLASSC_NET;
559 else 559 else
560 t = 0; 560 t = 0;
561 } 561 }
562 } 562 }
563 563
564 while (t & p) 564 while (t & p)
565 t >>= 1; 565 t >>= 1;
566 566
567 return (htonl(~t)); 567 return (htonl(~t));
568} 568}
569 569
570/* We need to obey routing options. 570/* We need to obey routing options.
571 * If we have a CSR then we only use that. 571 * If we have a CSR then we only use that.
572 * Otherwise we add static routes and then routers. */ 572 * Otherwise we add static routes and then routers. */
573static int 573static int
574get_option_routes(rb_tree_t *routes, struct interface *ifp, 574get_option_routes(rb_tree_t *routes, struct interface *ifp,
575 const struct bootp *bootp, size_t bootp_len) 575 const struct bootp *bootp, size_t bootp_len)
576{ 576{
577 struct if_options *ifo = ifp->options; 577 struct if_options *ifo = ifp->options;
578 const uint8_t *p; 578 const uint8_t *p;
579 const uint8_t *e; 579 const uint8_t *e;
580 struct rt *rt = NULL; 580 struct rt *rt = NULL;
581 struct in_addr dest, netmask, gateway; 581 struct in_addr dest, netmask, gateway;
582 size_t len; 582 size_t len;
583 const char *csr = ""; 583 const char *csr = "";
584 int n; 584 int n;
585 585
586 /* If we have CSR's then we MUST use these only */ 586 /* If we have CSR's then we MUST use these only */
587 if (!has_option_mask(ifo->nomask, DHO_CSR)) 587 if (!has_option_mask(ifo->nomask, DHO_CSR))
588 p = get_option(ifp->ctx, bootp, bootp_len, DHO_CSR, &len); 588 p = get_option(ifp->ctx, bootp, bootp_len, DHO_CSR, &len);
589 else 589 else
590 p = NULL; 590 p = NULL;
591 /* Check for crappy MS option */ 591 /* Check for crappy MS option */
592 if (!p && !has_option_mask(ifo->nomask, DHO_MSCSR)) { 592 if (!p && !has_option_mask(ifo->nomask, DHO_MSCSR)) {
593 p = get_option(ifp->ctx, bootp, bootp_len, DHO_MSCSR, &len); 593 p = get_option(ifp->ctx, bootp, bootp_len, DHO_MSCSR, &len);
594 if (p) 594 if (p)
595 csr = "MS "; 595 csr = "MS ";
596 } 596 }
597 if (p && (n = decode_rfc3442_rt(routes, ifp, p, len, bootp)) != -1) { 597 if (p && (n = decode_rfc3442_rt(routes, ifp, p, len, bootp)) != -1) {
598 const struct dhcp_state *state; 598 const struct dhcp_state *state;
599 599
600 state = D_CSTATE(ifp); 600 state = D_CSTATE(ifp);
601 if (!(ifo->options & DHCPCD_CSR_WARNED) && 601 if (!(ifo->options & DHCPCD_CSR_WARNED) &&
602 !(state->added & STATE_FAKE)) 602 !(state->added & STATE_FAKE))
603 { 603 {
604 logdebugx("%s: using %sClassless Static Routes", 604 logdebugx("%s: using %sClassless Static Routes",
605 ifp->name, csr); 605 ifp->name, csr);
606 ifo->options |= DHCPCD_CSR_WARNED; 606 ifo->options |= DHCPCD_CSR_WARNED;
607 } 607 }
608 return n; 608 return n;
609 } 609 }
610 610
611 n = 0; 611 n = 0;
612 /* OK, get our static routes first. */ 612 /* OK, get our static routes first. */
613 if (!has_option_mask(ifo->nomask, DHO_STATICROUTE)) 613 if (!has_option_mask(ifo->nomask, DHO_STATICROUTE))
614 p = get_option(ifp->ctx, bootp, bootp_len, 614 p = get_option(ifp->ctx, bootp, bootp_len,
615 DHO_STATICROUTE, &len); 615 DHO_STATICROUTE, &len);
616 else 616 else
617 p = NULL; 617 p = NULL;
618 /* RFC 2131 Section 5.8 states length MUST be in multiples of 8 */ 618 /* RFC 2131 Section 5.8 states length MUST be in multiples of 8 */
619 if (p && len % 8 == 0) { 619 if (p && len % 8 == 0) {
620 e = p + len; 620 e = p + len;
621 while (p < e) { 621 while (p < e) {
622 memcpy(&dest.s_addr, p, sizeof(dest.s_addr)); 622 memcpy(&dest.s_addr, p, sizeof(dest.s_addr));
623 p += 4; 623 p += 4;
624 memcpy(&gateway.s_addr, p, sizeof(gateway.s_addr)); 624 memcpy(&gateway.s_addr, p, sizeof(gateway.s_addr));
625 p += 4; 625 p += 4;
626 /* RFC 2131 Section 5.8 states default route is 626 /* RFC 2131 Section 5.8 states default route is
627 * illegal */ 627 * illegal */
628 if (gateway.s_addr == INADDR_ANY) 628 if (gateway.s_addr == INADDR_ANY)
629 continue; 629 continue;
630 if ((rt = rt_new(ifp)) == NULL) 630 if ((rt = rt_new(ifp)) == NULL)
631 return -1; 631 return -1;
632 632
633 /* A on-link host route is normally set by having the 633 /* A on-link host route is normally set by having the
634 * gateway match the destination or assigned address */ 634 * gateway match the destination or assigned address */
635 if (gateway.s_addr == dest.s_addr || 635 if (gateway.s_addr == dest.s_addr ||
636 (gateway.s_addr == bootp->yiaddr || 636 (gateway.s_addr == bootp->yiaddr ||
637 gateway.s_addr == bootp->ciaddr)) 637 gateway.s_addr == bootp->ciaddr))
638 { 638 {
639 gateway.s_addr = INADDR_ANY; 639 gateway.s_addr = INADDR_ANY;
640 netmask.s_addr = INADDR_BROADCAST; 640 netmask.s_addr = INADDR_BROADCAST;
641 } else 641 } else
642 netmask.s_addr = route_netmask(dest.s_addr); 642 netmask.s_addr = route_netmask(dest.s_addr);
643 if (netmask.s_addr == INADDR_BROADCAST) 643 if (netmask.s_addr == INADDR_BROADCAST)
644 rt->rt_flags = RTF_HOST; 644 rt->rt_flags = RTF_HOST;
645 645
646 sa_in_init(&rt->rt_dest, &dest); 646 sa_in_init(&rt->rt_dest, &dest);
647 sa_in_init(&rt->rt_netmask, &netmask); 647 sa_in_init(&rt->rt_netmask, &netmask);
648 sa_in_init(&rt->rt_gateway, &gateway); 648 sa_in_init(&rt->rt_gateway, &gateway);
649 if (rt_proto_add(routes, rt)) 649 if (rt_proto_add(routes, rt))
650 n++; 650 n++;
651 } 651 }
652 } 652 }
653 653
654 /* Now grab our routers */ 654 /* Now grab our routers */
655 if (!has_option_mask(ifo->nomask, DHO_ROUTER)) 655 if (!has_option_mask(ifo->nomask, DHO_ROUTER))
656 p = get_option(ifp->ctx, bootp, bootp_len, DHO_ROUTER, &len); 656 p = get_option(ifp->ctx, bootp, bootp_len, DHO_ROUTER, &len);
657 else 657 else
658 p = NULL; 658 p = NULL;
659 if (p && len % 4 == 0) { 659 if (p && len % 4 == 0) {
660 e = p + len; 660 e = p + len;
661 dest.s_addr = INADDR_ANY; 661 dest.s_addr = INADDR_ANY;
662 netmask.s_addr = INADDR_ANY; 662 netmask.s_addr = INADDR_ANY;
663 while (p < e) { 663 while (p < e) {
664 if ((rt = rt_new(ifp)) == NULL) 664 if ((rt = rt_new(ifp)) == NULL)
665 return -1; 665 return -1;
666 memcpy(&gateway.s_addr, p, sizeof(gateway.s_addr)); 666 memcpy(&gateway.s_addr, p, sizeof(gateway.s_addr));
667 p += 4; 667 p += 4;
668 sa_in_init(&rt->rt_dest, &dest); 668 sa_in_init(&rt->rt_dest, &dest);
669 sa_in_init(&rt->rt_netmask, &netmask); 669 sa_in_init(&rt->rt_netmask, &netmask);
670 sa_in_init(&rt->rt_gateway, &gateway); 670 sa_in_init(&rt->rt_gateway, &gateway);
671 if (rt_proto_add(routes, rt)) 671 if (rt_proto_add(routes, rt))
672 n++; 672 n++;
673 } 673 }
674 } 674 }
675 675
676 return n; 676 return n;
677} 677}
678 678
679uint16_t 679uint16_t
680dhcp_get_mtu(const struct interface *ifp) 680dhcp_get_mtu(const struct interface *ifp)
681{ 681{
682 const struct dhcp_state *state; 682 const struct dhcp_state *state;
683 uint16_t mtu; 683 uint16_t mtu;
684 684
685 if (ifp->options->mtu) 685 if (ifp->options->mtu)
686 return (uint16_t)ifp->options->mtu; 686 return (uint16_t)ifp->options->mtu;
687 mtu = 0; /* bogus gcc warning */ 687 mtu = 0; /* bogus gcc warning */
688 if ((state = D_CSTATE(ifp)) == NULL || 688 if ((state = D_CSTATE(ifp)) == NULL ||
689 has_option_mask(ifp->options->nomask, DHO_MTU) || 689 has_option_mask(ifp->options->nomask, DHO_MTU) ||
690 get_option_uint16(ifp->ctx, &mtu, 690 get_option_uint16(ifp->ctx, &mtu,
691 state->new, state->new_len, DHO_MTU) == -1) 691 state->new, state->new_len, DHO_MTU) == -1)
692 return 0; 692 return 0;
693 return mtu; 693 return mtu;
694} 694}
695 695
696/* Grab our routers from the DHCP message and apply any MTU value 696/* Grab our routers from the DHCP message and apply any MTU value
697 * the message contains */ 697 * the message contains */
698int 698int
699dhcp_get_routes(rb_tree_t *routes, struct interface *ifp) 699dhcp_get_routes(rb_tree_t *routes, struct interface *ifp)
700{ 700{
701 const struct dhcp_state *state; 701 const struct dhcp_state *state;
702 702
703 if ((state = D_CSTATE(ifp)) == NULL || !(state->added & STATE_ADDED)) 703 if ((state = D_CSTATE(ifp)) == NULL || !(state->added & STATE_ADDED))
704 return 0; 704 return 0;
705 return get_option_routes(routes, ifp, state->new, state->new_len); 705 return get_option_routes(routes, ifp, state->new, state->new_len);
706} 706}
707 707
708/* Assumes DHCP options */ 708/* Assumes DHCP options */
709static int 709static int
710dhcp_message_add_addr(struct bootp *bootp, 710dhcp_message_add_addr(struct bootp *bootp,
711 uint8_t type, struct in_addr addr) 711 uint8_t type, struct in_addr addr)
712{ 712{
713 uint8_t *p; 713 uint8_t *p;
714 size_t len; 714 size_t len;
715 715
716 p = bootp->vend; 716 p = bootp->vend;
717 while (*p != DHO_END) { 717 while (*p != DHO_END) {
718 p++; 718 p++;
719 p += *p + 1; 719 p += *p + 1;
720 } 720 }
721 721
722 len = (size_t)(p - bootp->vend); 722 len = (size_t)(p - bootp->vend);
723 if (len + 6 > sizeof(bootp->vend)) { 723 if (len + 6 > sizeof(bootp->vend)) {
724 errno = ENOMEM; 724 errno = ENOMEM;
725 return -1; 725 return -1;
726 } 726 }
727 727
728 *p++ = type; 728 *p++ = type;
729 *p++ = 4; 729 *p++ = 4;
730 memcpy(p, &addr.s_addr, 4); 730 memcpy(p, &addr.s_addr, 4);
731 p += 4; 731 p += 4;
732 *p = DHO_END; 732 *p = DHO_END;
733 return 0; 733 return 0;
734} 734}
735 735
736static ssize_t 736static ssize_t
737make_message(struct bootp **bootpm, const struct interface *ifp, uint8_t type) 737make_message(struct bootp **bootpm, const struct interface *ifp, uint8_t type)
738{ 738{
739 struct bootp *bootp; 739 struct bootp *bootp;
740 uint8_t *lp, *p, *e; 740 uint8_t *lp, *p, *e;
741 uint8_t *n_params = NULL; 741 uint8_t *n_params = NULL;
742 uint32_t ul; 742 uint32_t ul;
743 uint16_t sz; 743 uint16_t sz;
744 size_t len, i; 744 size_t len, i;
745 const struct dhcp_opt *opt; 745 const struct dhcp_opt *opt;
746 struct if_options *ifo = ifp->options; 746 struct if_options *ifo = ifp->options;
747 const struct dhcp_state *state = D_CSTATE(ifp); 747 const struct dhcp_state *state = D_CSTATE(ifp);
748 const struct dhcp_lease *lease = &state->lease; 748 const struct dhcp_lease *lease = &state->lease;
749 char hbuf[HOSTNAME_MAX_LEN + 1]; 749 char hbuf[HOSTNAME_MAX_LEN + 1];
750 const char *hostname; 750 const char *hostname;
751 const struct vivco *vivco; 751 const struct vivco *vivco;
752 int mtu; 752 int mtu;
753#ifdef AUTH 753#ifdef AUTH
754 uint8_t *auth, auth_len; 754 uint8_t *auth, auth_len;
755#endif 755#endif
756 756
757 if ((mtu = if_getmtu(ifp)) == -1) 757 if ((mtu = if_getmtu(ifp)) == -1)
758 logerr("%s: if_getmtu", ifp->name); 758 logerr("%s: if_getmtu", ifp->name);
759 else if (mtu < MTU_MIN) { 759 else if (mtu < MTU_MIN) {
760 if (if_setmtu(ifp, MTU_MIN) == -1) 760 if (if_setmtu(ifp, MTU_MIN) == -1)
761 logerr("%s: if_setmtu", ifp->name); 761 logerr("%s: if_setmtu", ifp->name);
762 mtu = MTU_MIN; 762 mtu = MTU_MIN;
763 } 763 }
764 764
765 if (ifo->options & DHCPCD_BOOTP) 765 if (ifo->options & DHCPCD_BOOTP)
766 bootp = calloc(1, sizeof (*bootp)); 766 bootp = calloc(1, sizeof (*bootp));
767 else 767 else
768 /* Make the maximal message we could send */ 768 /* Make the maximal message we could send */
769 bootp = calloc(1, (size_t)(mtu - IP_UDP_SIZE)); 769 bootp = calloc(1, (size_t)(mtu - IP_UDP_SIZE));
770 770
771 if (bootp == NULL) 771 if (bootp == NULL)
772 return -1; 772 return -1;
773 *bootpm = bootp; 773 *bootpm = bootp;
774 774
775 if (state->addr != NULL && 775 if (state->addr != NULL &&
776 (type == DHCP_INFORM || type == DHCP_RELEASE || 776 (type == DHCP_INFORM || type == DHCP_RELEASE ||
777 (type == DHCP_REQUEST && 777 (type == DHCP_REQUEST &&
778 state->addr->mask.s_addr == lease->mask.s_addr && 778 state->addr->mask.s_addr == lease->mask.s_addr &&
779 (state->new == NULL || IS_DHCP(state->new)) && 779 (state->new == NULL || IS_DHCP(state->new)) &&
780 !(state->added & (STATE_FAKE | STATE_EXPIRED))))) 780 !(state->added & (STATE_FAKE | STATE_EXPIRED)))))
781 bootp->ciaddr = state->addr->addr.s_addr; 781 bootp->ciaddr = state->addr->addr.s_addr;
782 782
783 bootp->op = BOOTREQUEST; 783 bootp->op = BOOTREQUEST;
784 bootp->htype = (uint8_t)ifp->hwtype; 784 bootp->htype = (uint8_t)ifp->hwtype;
785 if (ifp->hwlen != 0 && ifp->hwlen < sizeof(bootp->chaddr)) { 785 if (ifp->hwlen != 0 && ifp->hwlen < sizeof(bootp->chaddr)) {
786 bootp->hlen = (uint8_t)ifp->hwlen; 786 bootp->hlen = (uint8_t)ifp->hwlen;
787 memcpy(&bootp->chaddr, &ifp->hwaddr, ifp->hwlen); 787 memcpy(&bootp->chaddr, &ifp->hwaddr, ifp->hwlen);
788 } 788 }
789 789
790 if (ifo->options & DHCPCD_BROADCAST && 790 if (ifo->options & DHCPCD_BROADCAST &&
791 bootp->ciaddr == 0 && 791 bootp->ciaddr == 0 &&
792 type != DHCP_DECLINE && 792 type != DHCP_DECLINE &&
793 type != DHCP_RELEASE) 793 type != DHCP_RELEASE)
794 bootp->flags = htons(BROADCAST_FLAG); 794 bootp->flags = htons(BROADCAST_FLAG);
795 795
796 if (type != DHCP_DECLINE && type != DHCP_RELEASE) { 796 if (type != DHCP_DECLINE && type != DHCP_RELEASE) {
797 struct timespec tv; 797 struct timespec tv;
798 unsigned long long secs; 798 unsigned long long secs;
799 799
800 clock_gettime(CLOCK_MONOTONIC, &tv); 800 clock_gettime(CLOCK_MONOTONIC, &tv);
801 secs = eloop_timespec_diff(&tv, &state->started, NULL); 801 secs = eloop_timespec_diff(&tv, &state->started, NULL);
802 if (secs > UINT16_MAX) 802 if (secs > UINT16_MAX)
803 bootp->secs = htons((uint16_t)UINT16_MAX); 803 bootp->secs = htons((uint16_t)UINT16_MAX);
804 else 804 else
805 bootp->secs = htons((uint16_t)secs); 805 bootp->secs = htons((uint16_t)secs);
806 } 806 }
807 807
808 bootp->xid = htonl(state->xid); 808 bootp->xid = htonl(state->xid);
809 809
810 if (ifo->options & DHCPCD_BOOTP) 810 if (ifo->options & DHCPCD_BOOTP)
811 return sizeof(*bootp); 811 return sizeof(*bootp);
812 812
813 p = bootp->vend; 813 p = bootp->vend;
814 e = (uint8_t *)bootp + (mtu - IP_UDP_SIZE) - 1; /* -1 for DHO_END */ 814 e = (uint8_t *)bootp + (mtu - IP_UDP_SIZE) - 1; /* -1 for DHO_END */
815 815
816 ul = htonl(MAGIC_COOKIE); 816 ul = htonl(MAGIC_COOKIE);
817 memcpy(p, &ul, sizeof(ul)); 817 memcpy(p, &ul, sizeof(ul));
818 p += sizeof(ul); 818 p += sizeof(ul);
819 819
820#define AREA_LEFT (size_t)(e - p) 820#define AREA_LEFT (size_t)(e - p)
821#define AREA_FIT(s) if ((s) > AREA_LEFT) goto toobig 821#define AREA_FIT(s) if ((s) > AREA_LEFT) goto toobig
822#define AREA_CHECK(s) if ((s) + 2UL > AREA_LEFT) goto toobig 822#define AREA_CHECK(s) if ((s) + 2UL > AREA_LEFT) goto toobig
823#define PUT_ADDR(o, a) do { \ 823#define PUT_ADDR(o, a) do { \
824 AREA_CHECK(4); \ 824 AREA_CHECK(4); \
825 *p++ = (o); \ 825 *p++ = (o); \
826 *p++ = 4; \ 826 *p++ = 4; \
827 memcpy(p, &(a)->s_addr, 4); \ 827 memcpy(p, &(a)->s_addr, 4); \
828 p += 4; \ 828 p += 4; \
829} while (0 /* CONSTCOND */) 829} while (0 /* CONSTCOND */)
830 830
831 /* Options are listed in numerical order as per RFC 7844 Section 3.1 831 /* Options are listed in numerical order as per RFC 7844 Section 3.1
832 * XXX: They should be randomised. */ 832 * XXX: They should be randomised. */
833 833
834 bool putip = false; 834 bool putip = false;
835 if (lease->addr.s_addr && lease->cookie == htonl(MAGIC_COOKIE)) { 835 if (lease->addr.s_addr && lease->cookie == htonl(MAGIC_COOKIE)) {
836 if (type == DHCP_DECLINE || 836 if (type == DHCP_DECLINE ||
837 (type == DHCP_REQUEST && 837 (type == DHCP_REQUEST &&
838 (state->addr == NULL || 838 (state->addr == NULL ||
839 state->added & (STATE_FAKE | STATE_EXPIRED) || 839 state->added & (STATE_FAKE | STATE_EXPIRED) ||
840 lease->addr.s_addr != state->addr->addr.s_addr))) 840 lease->addr.s_addr != state->addr->addr.s_addr)))
841 { 841 {
842 putip = true; 842 putip = true;
843 PUT_ADDR(DHO_IPADDRESS, &lease->addr); 843 PUT_ADDR(DHO_IPADDRESS, &lease->addr);
844 } 844 }
845 } 845 }
846 846
847 AREA_CHECK(3); 847 AREA_CHECK(3);
848 *p++ = DHO_MESSAGETYPE; 848 *p++ = DHO_MESSAGETYPE;
849 *p++ = 1; 849 *p++ = 1;
850 *p++ = type; 850 *p++ = type;
851 851
852 if (lease->addr.s_addr && lease->cookie == htonl(MAGIC_COOKIE)) { 852 if (lease->addr.s_addr && lease->cookie == htonl(MAGIC_COOKIE)) {
853 if (type == DHCP_RELEASE || putip) { 853 if (type == DHCP_RELEASE || putip) {
854 if (lease->server.s_addr) 854 if (lease->server.s_addr)
855 PUT_ADDR(DHO_SERVERID, &lease->server); 855 PUT_ADDR(DHO_SERVERID, &lease->server);
856 } 856 }
857 } 857 }
858 858
859 if (type == DHCP_DECLINE) { 859 if (type == DHCP_DECLINE) {
860 len = strlen(DAD); 860 len = strlen(DAD);
861 if (len > AREA_LEFT) { 861 if (len > AREA_LEFT) {
862 *p++ = DHO_MESSAGE; 862 *p++ = DHO_MESSAGE;
863 *p++ = (uint8_t)len; 863 *p++ = (uint8_t)len;
864 memcpy(p, DAD, len); 864 memcpy(p, DAD, len);
865 p += len; 865 p += len;
866 } 866 }
867 } 867 }
868 868
869#define DHCP_DIR(type) ((type) == DHCP_DISCOVER || (type) == DHCP_INFORM || \ 869#define DHCP_DIR(type) ((type) == DHCP_DISCOVER || (type) == DHCP_INFORM || \
870 (type) == DHCP_REQUEST) 870 (type) == DHCP_REQUEST)
871 871
872 if (DHCP_DIR(type)) { 872 if (DHCP_DIR(type)) {
873 /* vendor is already encoded correctly, so just add it */ 873 /* vendor is already encoded correctly, so just add it */
874 if (ifo->vendor[0]) { 874 if (ifo->vendor[0]) {
875 AREA_CHECK(ifo->vendor[0]); 875 AREA_CHECK(ifo->vendor[0]);
876 *p++ = DHO_VENDOR; 876 *p++ = DHO_VENDOR;
877 memcpy(p, ifo->vendor, (size_t)ifo->vendor[0] + 1); 877 memcpy(p, ifo->vendor, (size_t)ifo->vendor[0] + 1);
878 p += ifo->vendor[0] + 1; 878 p += ifo->vendor[0] + 1;
879 } 879 }
880 } 880 }
881 881
882 if (type == DHCP_DISCOVER && ifo->options & DHCPCD_REQUEST) 882 if (type == DHCP_DISCOVER && ifo->options & DHCPCD_REQUEST)
883 PUT_ADDR(DHO_IPADDRESS, &ifo->req_addr); 883 PUT_ADDR(DHO_IPADDRESS, &ifo->req_addr);
884 884
885 if (DHCP_DIR(type)) { 885 if (DHCP_DIR(type)) {
886 if (type != DHCP_INFORM) { 886 if (type != DHCP_INFORM) {
887 if (ifo->leasetime != 0) { 887 if (ifo->leasetime != 0) {
888 AREA_CHECK(4); 888 AREA_CHECK(4);
889 *p++ = DHO_LEASETIME; 889 *p++ = DHO_LEASETIME;
890 *p++ = 4; 890 *p++ = 4;
891 ul = htonl(ifo->leasetime); 891 ul = htonl(ifo->leasetime);
892 memcpy(p, &ul, 4); 892 memcpy(p, &ul, 4);
893 p += 4; 893 p += 4;
894 } 894 }
895 } 895 }
896 896
897 AREA_CHECK(0); 897 AREA_CHECK(0);
898 *p++ = DHO_PARAMETERREQUESTLIST; 898 *p++ = DHO_PARAMETERREQUESTLIST;
899 n_params = p; 899 n_params = p;
900 *p++ = 0; 900 *p++ = 0;
901 for (i = 0, opt = ifp->ctx->dhcp_opts; 901 for (i = 0, opt = ifp->ctx->dhcp_opts;
902 i < ifp->ctx->dhcp_opts_len; 902 i < ifp->ctx->dhcp_opts_len;
903 i++, opt++) 903 i++, opt++)
904 { 904 {
905 if (!DHC_REQOPT(opt, ifo->requestmask, ifo->nomask)) 905 if (!DHC_REQOPT(opt, ifo->requestmask, ifo->nomask))
906 continue; 906 continue;
907 if (type == DHCP_INFORM && 907 if (type == DHCP_INFORM &&
908 (opt->option == DHO_RENEWALTIME || 908 (opt->option == DHO_RENEWALTIME ||
909 opt->option == DHO_REBINDTIME)) 909 opt->option == DHO_REBINDTIME))
910 continue; 910 continue;
911 AREA_FIT(1); 911 AREA_FIT(1);
912 *p++ = (uint8_t)opt->option; 912 *p++ = (uint8_t)opt->option;
913 } 913 }
914 for (i = 0, opt = ifo->dhcp_override; 914 for (i = 0, opt = ifo->dhcp_override;
915 i < ifo->dhcp_override_len; 915 i < ifo->dhcp_override_len;
916 i++, opt++) 916 i++, opt++)
917 { 917 {
918 /* Check if added above */ 918 /* Check if added above */
919 for (lp = n_params + 1; lp < p; lp++) 919 for (lp = n_params + 1; lp < p; lp++)
920 if (*lp == (uint8_t)opt->option) 920 if (*lp == (uint8_t)opt->option)
921 break; 921 break;
922 if (lp < p) 922 if (lp < p)
923 continue; 923 continue;
924 if (!DHC_REQOPT(opt, ifo->requestmask, ifo->nomask)) 924 if (!DHC_REQOPT(opt, ifo->requestmask, ifo->nomask))
925 continue; 925 continue;
926 if (type == DHCP_INFORM && 926 if (type == DHCP_INFORM &&
927 (opt->option == DHO_RENEWALTIME || 927 (opt->option == DHO_RENEWALTIME ||
928 opt->option == DHO_REBINDTIME)) 928 opt->option == DHO_REBINDTIME))
929 continue; 929 continue;
930 AREA_FIT(1); 930 AREA_FIT(1);
931 *p++ = (uint8_t)opt->option; 931 *p++ = (uint8_t)opt->option;
932 } 932 }
933 *n_params = (uint8_t)(p - n_params - 1); 933 *n_params = (uint8_t)(p - n_params - 1);
934 934
935 if (mtu != -1 && 935 if (mtu != -1 &&
936 !(has_option_mask(ifo->nomask, DHO_MAXMESSAGESIZE))) 936 !(has_option_mask(ifo->nomask, DHO_MAXMESSAGESIZE)))
937 { 937 {
938 AREA_CHECK(2); 938 AREA_CHECK(2);
939 *p++ = DHO_MAXMESSAGESIZE; 939 *p++ = DHO_MAXMESSAGESIZE;
940 *p++ = 2; 940 *p++ = 2;
941 sz = htons((uint16_t)(mtu - IP_UDP_SIZE)); 941 sz = htons((uint16_t)(mtu - IP_UDP_SIZE));
942 memcpy(p, &sz, 2); 942 memcpy(p, &sz, 2);
943 p += 2; 943 p += 2;
944 } 944 }
945 945
946 if (ifo->userclass[0] && 946 if (ifo->userclass[0] &&
947 !has_option_mask(ifo->nomask, DHO_USERCLASS)) 947 !has_option_mask(ifo->nomask, DHO_USERCLASS))
948 { 948 {
949 AREA_CHECK(ifo->userclass[0]); 949 AREA_CHECK(ifo->userclass[0]);
950 *p++ = DHO_USERCLASS; 950 *p++ = DHO_USERCLASS;
951 memcpy(p, ifo->userclass, 951 memcpy(p, ifo->userclass,
952 (size_t)ifo->userclass[0] + 1); 952 (size_t)ifo->userclass[0] + 1);
953 p += ifo->userclass[0] + 1; 953 p += ifo->userclass[0] + 1;
954 } 954 }
955 } 955 }
956 956
957 if (state->clientid) { 957 if (state->clientid) {
958 AREA_CHECK(state->clientid[0]); 958 AREA_CHECK(state->clientid[0]);
959 *p++ = DHO_CLIENTID; 959 *p++ = DHO_CLIENTID;
960 memcpy(p, state->clientid, (size_t)state->clientid[0] + 1); 960 memcpy(p, state->clientid, (size_t)state->clientid[0] + 1);
961 p += state->clientid[0] + 1; 961 p += state->clientid[0] + 1;
962 } 962 }
963 963
964 if (DHCP_DIR(type) && 964 if (DHCP_DIR(type) &&
965 !has_option_mask(ifo->nomask, DHO_VENDORCLASSID) && 965 !has_option_mask(ifo->nomask, DHO_VENDORCLASSID) &&
966 ifo->vendorclassid[0]) 966 ifo->vendorclassid[0])
967 { 967 {
968 AREA_CHECK(ifo->vendorclassid[0]); 968 AREA_CHECK(ifo->vendorclassid[0]);
969 *p++ = DHO_VENDORCLASSID; 969 *p++ = DHO_VENDORCLASSID;
970 memcpy(p, ifo->vendorclassid, (size_t)ifo->vendorclassid[0]+1); 970 memcpy(p, ifo->vendorclassid, (size_t)ifo->vendorclassid[0]+1);
971 p += ifo->vendorclassid[0] + 1; 971 p += ifo->vendorclassid[0] + 1;
972 } 972 }
973 973
974 if (type == DHCP_DISCOVER && 974 if (type == DHCP_DISCOVER &&
975 !(ifp->ctx->options & DHCPCD_TEST) && 975 !(ifp->ctx->options & DHCPCD_TEST) &&
976 DHC_REQ(ifo->requestmask, ifo->nomask, DHO_RAPIDCOMMIT)) 976 DHC_REQ(ifo->requestmask, ifo->nomask, DHO_RAPIDCOMMIT))
977 { 977 {
978 /* RFC 4039 Section 3 */ 978 /* RFC 4039 Section 3 */
979 AREA_CHECK(0); 979 AREA_CHECK(0);
980 *p++ = DHO_RAPIDCOMMIT; 980 *p++ = DHO_RAPIDCOMMIT;
981 *p++ = 0; 981 *p++ = 0;
982 } 982 }
983 983
984 if (DHCP_DIR(type)) { 984 if (DHCP_DIR(type)) {
985 hostname = dhcp_get_hostname(hbuf, sizeof(hbuf), ifo); 985 hostname = dhcp_get_hostname(hbuf, sizeof(hbuf), ifo);
986 986
987 /* 987 /*
988 * RFC4702 3.1 States that if we send the Client FQDN option 988 * RFC4702 3.1 States that if we send the Client FQDN option
989 * then we MUST NOT also send the Host Name option. 989 * then we MUST NOT also send the Host Name option.
990 * Technically we could, but that is not RFC conformant and 990 * Technically we could, but that is not RFC conformant and
991 * also seems to break some DHCP server implemetations such as 991 * also seems to break some DHCP server implemetations such as
992 * Windows. On the other hand, ISC dhcpd is just as non RFC 992 * Windows. On the other hand, ISC dhcpd is just as non RFC
993 * conformant by not accepting a partially qualified FQDN. 993 * conformant by not accepting a partially qualified FQDN.
994 */ 994 */
995 if (ifo->fqdn != FQDN_DISABLE) { 995 if (ifo->fqdn != FQDN_DISABLE) {
996 /* IETF DHC-FQDN option (81), RFC4702 */ 996 /* IETF DHC-FQDN option (81), RFC4702 */
997 i = 3; 997 i = 3;
998 if (hostname) 998 if (hostname)
999 i += encode_rfc1035(hostname, NULL); 999 i += encode_rfc1035(hostname, NULL);
1000 AREA_CHECK(i); 1000 AREA_CHECK(i);
1001 *p++ = DHO_FQDN; 1001 *p++ = DHO_FQDN;
1002 *p++ = (uint8_t)i; 1002 *p++ = (uint8_t)i;
1003 /* 1003 /*
1004 * Flags: 0000NEOS 1004 * Flags: 0000NEOS
1005 * S: 1 => Client requests Server to update 1005 * S: 1 => Client requests Server to update
1006 * a RR in DNS as well as PTR 1006 * a RR in DNS as well as PTR
1007 * O: 1 => Server indicates to client that 1007 * O: 1 => Server indicates to client that
1008 * DNS has been updated 1008 * DNS has been updated
1009 * E: 1 => Name data is DNS format 1009 * E: 1 => Name data is DNS format
1010 * N: 1 => Client requests Server to not 1010 * N: 1 => Client requests Server to not
1011 * update DNS 1011 * update DNS
1012 */ 1012 */
1013 if (hostname) 1013 if (hostname)
1014 *p++ = (uint8_t)((ifo->fqdn & 0x09) | 0x04); 1014 *p++ = (uint8_t)((ifo->fqdn & 0x09) | 0x04);
1015 else 1015 else
1016 *p++ = (FQDN_NONE & 0x09) | 0x04; 1016 *p++ = (FQDN_NONE & 0x09) | 0x04;
1017 *p++ = 0; /* from server for PTR RR */ 1017 *p++ = 0; /* from server for PTR RR */
1018 *p++ = 0; /* from server for A RR if S=1 */ 1018 *p++ = 0; /* from server for A RR if S=1 */
1019 if (hostname) { 1019 if (hostname) {
1020 i = encode_rfc1035(hostname, p); 1020 i = encode_rfc1035(hostname, p);
1021 p += i; 1021 p += i;
1022 } 1022 }
1023 } else if (ifo->options & DHCPCD_HOSTNAME && hostname) { 1023 } else if (ifo->options & DHCPCD_HOSTNAME && hostname) {
1024 len = strlen(hostname); 1024 len = strlen(hostname);
1025 AREA_CHECK(len); 1025 AREA_CHECK(len);
1026 *p++ = DHO_HOSTNAME; 1026 *p++ = DHO_HOSTNAME;
1027 *p++ = (uint8_t)len; 1027 *p++ = (uint8_t)len;
1028 memcpy(p, hostname, len); 1028 memcpy(p, hostname, len);
1029 p += len; 1029 p += len;
1030 } 1030 }
1031 } 1031 }
1032 1032
1033#ifdef AUTH 1033#ifdef AUTH
1034 auth = NULL; /* appease GCC */ 1034 auth = NULL; /* appease GCC */
1035 auth_len = 0; 1035 auth_len = 0;
1036 if (ifo->auth.options & DHCPCD_AUTH_SEND) { 1036 if (ifo->auth.options & DHCPCD_AUTH_SEND) {
1037 ssize_t alen = dhcp_auth_encode(ifp->ctx, &ifo->auth, 1037 ssize_t alen = dhcp_auth_encode(ifp->ctx, &ifo->auth,
1038 state->auth.token, 1038 state->auth.token,
1039 NULL, 0, 4, type, NULL, 0); 1039 NULL, 0, 4, type, NULL, 0);
1040 if (alen != -1 && alen > UINT8_MAX) { 1040 if (alen != -1 && alen > UINT8_MAX) {
1041 errno = ERANGE; 1041 errno = ERANGE;
1042 alen = -1; 1042 alen = -1;
1043 } 1043 }
1044 if (alen == -1) 1044 if (alen == -1)
1045 logerr("%s: dhcp_auth_encode", ifp->name); 1045 logerr("%s: dhcp_auth_encode", ifp->name);
1046 else if (alen != 0) { 1046 else if (alen != 0) {
1047 auth_len = (uint8_t)alen; 1047 auth_len = (uint8_t)alen;
1048 AREA_CHECK(auth_len); 1048 AREA_CHECK(auth_len);
1049 *p++ = DHO_AUTHENTICATION; 1049 *p++ = DHO_AUTHENTICATION;
1050 *p++ = auth_len; 1050 *p++ = auth_len;
1051 auth = p; 1051 auth = p;
1052 p += auth_len; 1052 p += auth_len;
1053 } 1053 }
1054 } 1054 }
1055#endif 1055#endif
1056 1056
1057 /* RFC 2563 Auto Configure */ 1057 /* RFC 2563 Auto Configure */
1058 if (type == DHCP_DISCOVER && ifo->options & DHCPCD_IPV4LL && 1058 if (type == DHCP_DISCOVER && ifo->options & DHCPCD_IPV4LL &&
1059 !(has_option_mask(ifo->nomask, DHO_AUTOCONFIGURE))) 1059 !(has_option_mask(ifo->nomask, DHO_AUTOCONFIGURE)))
1060 { 1060 {
1061 AREA_CHECK(1); 1061 AREA_CHECK(1);
1062 *p++ = DHO_AUTOCONFIGURE; 1062 *p++ = DHO_AUTOCONFIGURE;
1063 *p++ = 1; 1063 *p++ = 1;
1064 *p++ = 1; 1064 *p++ = 1;
1065 } 1065 }
1066 1066
1067 if (DHCP_DIR(type)) { 1067 if (DHCP_DIR(type)) {
1068 if (ifo->mudurl[0]) { 1068 if (ifo->mudurl[0]) {
1069 AREA_CHECK(ifo->mudurl[0]); 1069 AREA_CHECK(ifo->mudurl[0]);
1070 *p++ = DHO_MUDURL; 1070 *p++ = DHO_MUDURL;
1071 memcpy(p, ifo->mudurl, (size_t)ifo->mudurl[0] + 1); 1071 memcpy(p, ifo->mudurl, (size_t)ifo->mudurl[0] + 1);
1072 p += ifo->mudurl[0] + 1; 1072 p += ifo->mudurl[0] + 1;
1073 } 1073 }
1074 1074
1075 if (ifo->vivco_len && 1075 if (ifo->vivco_len &&
1076 !has_option_mask(ifo->nomask, DHO_VIVCO)) 1076 !has_option_mask(ifo->nomask, DHO_VIVCO))
1077 { 1077 {
1078 AREA_CHECK(sizeof(ul)); 1078 AREA_CHECK(sizeof(ul));
1079 *p++ = DHO_VIVCO; 1079 *p++ = DHO_VIVCO;
1080 lp = p++; 1080 lp = p++;
1081 *lp = sizeof(ul); 1081 *lp = sizeof(ul);
1082 ul = htonl(ifo->vivco_en); 1082 ul = htonl(ifo->vivco_en);
1083 memcpy(p, &ul, sizeof(ul)); 1083 memcpy(p, &ul, sizeof(ul));
1084 p += sizeof(ul); 1084 p += sizeof(ul);
1085 for (i = 0, vivco = ifo->vivco; 1085 for (i = 0, vivco = ifo->vivco;
1086 i < ifo->vivco_len; 1086 i < ifo->vivco_len;
1087 i++, vivco++) 1087 i++, vivco++)
1088 { 1088 {
1089 AREA_FIT(vivco->len); 1089 AREA_FIT(vivco->len);
1090 if (vivco->len + 2 + *lp > 255) { 1090 if (vivco->len + 2 + *lp > 255) {
1091 logerrx("%s: VIVCO option too big", 1091 logerrx("%s: VIVCO option too big",
1092 ifp->name); 1092 ifp->name);
1093 free(bootp); 1093 free(bootp);
1094 return -1; 1094 return -1;
1095 } 1095 }
1096 *p++ = (uint8_t)vivco->len; 1096 *p++ = (uint8_t)vivco->len;
1097 memcpy(p, vivco->data, vivco->len); 1097 memcpy(p, vivco->data, vivco->len);
1098 p += vivco->len; 1098 p += vivco->len;
1099 *lp = (uint8_t)(*lp + vivco->len + 1); 1099 *lp = (uint8_t)(*lp + vivco->len + 1);
1100 } 1100 }
1101 } 1101 }
1102 1102
1103#ifdef AUTH 1103#ifdef AUTH
1104 if ((ifo->auth.options & DHCPCD_AUTH_SENDREQUIRE) != 1104 if ((ifo->auth.options & DHCPCD_AUTH_SENDREQUIRE) !=
1105 DHCPCD_AUTH_SENDREQUIRE && 1105 DHCPCD_AUTH_SENDREQUIRE &&
1106 !has_option_mask(ifo->nomask, DHO_FORCERENEW_NONCE)) 1106 !has_option_mask(ifo->nomask, DHO_FORCERENEW_NONCE))
1107 { 1107 {
1108 /* We support HMAC-MD5 */ 1108 /* We support HMAC-MD5 */
1109 AREA_CHECK(1); 1109 AREA_CHECK(1);
1110 *p++ = DHO_FORCERENEW_NONCE; 1110 *p++ = DHO_FORCERENEW_NONCE;
1111 *p++ = 1; 1111 *p++ = 1;
1112 *p++ = AUTH_ALG_HMAC_MD5; 1112 *p++ = AUTH_ALG_HMAC_MD5;
1113 } 1113 }
1114#endif 1114#endif
1115 } 1115 }
1116 1116
1117 *p++ = DHO_END; 1117 *p++ = DHO_END;
1118 len = (size_t)(p - (uint8_t *)bootp); 1118 len = (size_t)(p - (uint8_t *)bootp);
1119 1119
1120 /* Pad out to the BOOTP message length. 1120 /* Pad out to the BOOTP message length.
1121 * Even if we send a DHCP packet with a variable length vendor area, 1121 * Even if we send a DHCP packet with a variable length vendor area,
1122 * some servers / relay agents don't like packets smaller than 1122 * some servers / relay agents don't like packets smaller than
1123 * a BOOTP message which is fine because that's stipulated 1123 * a BOOTP message which is fine because that's stipulated
1124 * in RFC1542 section 2.1. */ 1124 * in RFC1542 section 2.1. */
1125 while (len < sizeof(*bootp)) { 1125 while (len < sizeof(*bootp)) {
1126 *p++ = DHO_PAD; 1126 *p++ = DHO_PAD;
1127 len++; 1127 len++;
1128 } 1128 }
1129 1129
1130#ifdef AUTH 1130#ifdef AUTH
1131 if (ifo->auth.options & DHCPCD_AUTH_SEND && auth_len != 0) 1131 if (ifo->auth.options & DHCPCD_AUTH_SEND && auth_len != 0)
1132 dhcp_auth_encode(ifp->ctx, &ifo->auth, state->auth.token, 1132 dhcp_auth_encode(ifp->ctx, &ifo->auth, state->auth.token,
1133 (uint8_t *)bootp, len, 4, type, auth, auth_len); 1133 (uint8_t *)bootp, len, 4, type, auth, auth_len);
1134#endif 1134#endif
1135 1135
1136 return (ssize_t)len; 1136 return (ssize_t)len;
1137 1137
1138toobig: 1138toobig:
1139 logerrx("%s: DHCP message too big", ifp->name); 1139 logerrx("%s: DHCP message too big", ifp->name);
1140 free(bootp); 1140 free(bootp);
1141 return -1; 1141 return -1;
1142} 1142}
1143 1143
1144static size_t 1144static size_t
1145read_lease(struct interface *ifp, struct bootp **bootp) 1145read_lease(struct interface *ifp, struct bootp **bootp)
1146{ 1146{
1147 union { 1147 union {
1148 struct bootp bootp; 1148 struct bootp bootp;
1149 uint8_t buf[FRAMELEN_MAX]; 1149 uint8_t buf[FRAMELEN_MAX];
1150 } buf; 1150 } buf;
1151 struct dhcp_state *state = D_STATE(ifp); 1151 struct dhcp_state *state = D_STATE(ifp);
1152 ssize_t sbytes; 1152 ssize_t sbytes;
1153 size_t bytes; 1153 size_t bytes;
1154 uint8_t type; 1154 uint8_t type;
1155#ifdef AUTH 1155#ifdef AUTH
1156 const uint8_t *auth; 1156 const uint8_t *auth;
1157 size_t auth_len; 1157 size_t auth_len;
1158#endif 1158#endif
1159 1159
1160 /* Safety */ 1160 /* Safety */
1161 *bootp = NULL; 1161 *bootp = NULL;
1162 1162
1163 if (state->leasefile[0] == '\0') { 1163 if (state->leasefile[0] == '\0') {
1164 logdebugx("reading standard input"); 1164 logdebugx("reading standard input");
1165 sbytes = read(fileno(stdin), buf.buf, sizeof(buf.buf)); 1165 sbytes = read(fileno(stdin), buf.buf, sizeof(buf.buf));
1166 } else { 1166 } else {
1167 logdebugx("%s: reading lease: %s", 1167 logdebugx("%s: reading lease: %s",
1168 ifp->name, state->leasefile); 1168 ifp->name, state->leasefile);
1169 sbytes = dhcp_readfile(ifp->ctx, state->leasefile, 1169 sbytes = dhcp_readfile(ifp->ctx, state->leasefile,
1170 buf.buf, sizeof(buf.buf)); 1170 buf.buf, sizeof(buf.buf));
1171 } 1171 }
1172 if (sbytes == -1) { 1172 if (sbytes == -1) {
1173 if (errno != ENOENT) 1173 if (errno != ENOENT)
1174 logerr("%s: %s", ifp->name, state->leasefile); 1174 logerr("%s: %s", ifp->name, state->leasefile);
1175 return 0; 1175 return 0;
1176 } 1176 }
1177 bytes = (size_t)sbytes; 1177 bytes = (size_t)sbytes;
1178 1178
1179 /* Ensure the packet is at lease BOOTP sized 1179 /* Ensure the packet is at lease BOOTP sized
1180 * with a vendor area of 4 octets 1180 * with a vendor area of 4 octets
1181 * (it should be more, and our read packet enforces this so this 1181 * (it should be more, and our read packet enforces this so this
1182 * code should not be needed, but of course people could 1182 * code should not be needed, but of course people could
1183 * scribble whatever in the stored lease file. */ 1183 * scribble whatever in the stored lease file. */
1184 if (bytes < DHCP_MIN_LEN) { 1184 if (bytes < DHCP_MIN_LEN) {
1185 logerrx("%s: %s: truncated lease", ifp->name, __func__); 1185 logerrx("%s: %s: truncated lease", ifp->name, __func__);
1186 return 0; 1186 return 0;
1187 } 1187 }
1188 1188
1189 if (ifp->ctx->options & DHCPCD_DUMPLEASE) 1189 if (ifp->ctx->options & DHCPCD_DUMPLEASE)
1190 goto out; 1190 goto out;
1191 1191
1192 /* We may have found a BOOTP server */ 1192 /* We may have found a BOOTP server */
1193 if (get_option_uint8(ifp->ctx, &type, &buf.bootp, bytes, 1193 if (get_option_uint8(ifp->ctx, &type, &buf.bootp, bytes,
1194 DHO_MESSAGETYPE) == -1) 1194 DHO_MESSAGETYPE) == -1)
1195 type = 0; 1195 type = 0;
1196 1196
1197#ifdef AUTH 1197#ifdef AUTH
1198 /* Authenticate the message */ 1198 /* Authenticate the message */
1199 auth = get_option(ifp->ctx, &buf.bootp, bytes, 1199 auth = get_option(ifp->ctx, &buf.bootp, bytes,
1200 DHO_AUTHENTICATION, &auth_len); 1200 DHO_AUTHENTICATION, &auth_len);
1201 if (auth) { 1201 if (auth) {
1202 if (dhcp_auth_validate(&state->auth, &ifp->options->auth, 1202 if (dhcp_auth_validate(&state->auth, &ifp->options->auth,
1203 &buf.bootp, bytes, 4, type, auth, auth_len) == NULL) 1203 &buf.bootp, bytes, 4, type, auth, auth_len) == NULL)
1204 { 1204 {
1205 logerr("%s: authentication failed", ifp->name); 1205 logerr("%s: authentication failed", ifp->name);
1206 return 0; 1206 return 0;
1207 } 1207 }
1208 if (state->auth.token) 1208 if (state->auth.token)
1209 logdebugx("%s: validated using 0x%08" PRIu32, 1209 logdebugx("%s: validated using 0x%08" PRIu32,
1210 ifp->name, state->auth.token->secretid); 1210 ifp->name, state->auth.token->secretid);
1211 else 1211 else
1212 logdebugx("%s: accepted reconfigure key", ifp->name); 1212 logdebugx("%s: accepted reconfigure key", ifp->name);
1213 } else if ((ifp->options->auth.options & DHCPCD_AUTH_SENDREQUIRE) == 1213 } else if ((ifp->options->auth.options & DHCPCD_AUTH_SENDREQUIRE) ==
1214 DHCPCD_AUTH_SENDREQUIRE) 1214 DHCPCD_AUTH_SENDREQUIRE)
1215 { 1215 {
1216 logerrx("%s: authentication now required", ifp->name); 1216 logerrx("%s: authentication now required", ifp->name);
1217 return 0; 1217 return 0;
1218 } 1218 }
1219#endif 1219#endif
1220 1220
1221out: 1221out:
1222 *bootp = malloc(bytes); 1222 *bootp = malloc(bytes);
1223 if (*bootp == NULL) { 1223 if (*bootp == NULL) {
1224 logerr(__func__); 1224 logerr(__func__);
1225 return 0; 1225 return 0;
1226 } 1226 }
1227 memcpy(*bootp, buf.buf, bytes); 1227 memcpy(*bootp, buf.buf, bytes);
1228 return bytes; 1228 return bytes;
1229} 1229}
1230 1230
1231static const struct dhcp_opt * 1231static const struct dhcp_opt *
1232dhcp_getoverride(const struct if_options *ifo, unsigned int o) 1232dhcp_getoverride(const struct if_options *ifo, unsigned int o)
1233{ 1233{
1234 size_t i; 1234 size_t i;
1235 const struct dhcp_opt *opt; 1235 const struct dhcp_opt *opt;
1236 1236
1237 for (i = 0, opt = ifo->dhcp_override; 1237 for (i = 0, opt = ifo->dhcp_override;
1238 i < ifo->dhcp_override_len; 1238 i < ifo->dhcp_override_len;
1239 i++, opt++) 1239 i++, opt++)
1240 { 1240 {
1241 if (opt->option == o) 1241 if (opt->option == o)
1242 return opt; 1242 return opt;
1243 } 1243 }
1244 return NULL; 1244 return NULL;
1245} 1245}
1246 1246
1247static const uint8_t * 1247static const uint8_t *
1248dhcp_getoption(struct dhcpcd_ctx *ctx, 1248dhcp_getoption(struct dhcpcd_ctx *ctx,
1249 size_t *os, unsigned int *code, size_t *len, 1249 size_t *os, unsigned int *code, size_t *len,
1250 const uint8_t *od, size_t ol, struct dhcp_opt **oopt) 1250 const uint8_t *od, size_t ol, struct dhcp_opt **oopt)
1251{ 1251{
1252 size_t i; 1252 size_t i;
1253 struct dhcp_opt *opt; 1253 struct dhcp_opt *opt;
1254 1254
1255 if (od) { 1255 if (od) {
1256 if (ol < 2) { 1256 if (ol < 2) {
1257 errno = EINVAL; 1257 errno = EINVAL;
1258 return NULL; 1258 return NULL;
1259 } 1259 }
1260 *os = 2; /* code + len */ 1260 *os = 2; /* code + len */
1261 *code = (unsigned int)*od++; 1261 *code = (unsigned int)*od++;
1262 *len = (size_t)*od++; 1262 *len = (size_t)*od++;
1263 if (*len > ol - *os) { 1263 if (*len > ol - *os) {
1264 errno = ERANGE; 1264 errno = ERANGE;
1265 return NULL; 1265 return NULL;
1266 } 1266 }
1267 } 1267 }
1268 1268
1269 *oopt = NULL; 1269 *oopt = NULL;
1270 for (i = 0, opt = ctx->dhcp_opts; i < ctx->dhcp_opts_len; i++, opt++) { 1270 for (i = 0, opt = ctx->dhcp_opts; i < ctx->dhcp_opts_len; i++, opt++) {
1271 if (opt->option == *code) { 1271 if (opt->option == *code) {
1272 *oopt = opt; 1272 *oopt = opt;
1273 break; 1273 break;
1274 } 1274 }
1275 } 1275 }
1276 1276
1277 return od; 1277 return od;
1278} 1278}
1279 1279
1280ssize_t 1280ssize_t
1281dhcp_env(FILE *fenv, const char *prefix, const struct interface *ifp, 1281dhcp_env(FILE *fenv, const char *prefix, const struct interface *ifp,
1282 const struct bootp *bootp, size_t bootp_len) 1282 const struct bootp *bootp, size_t bootp_len)
1283{ 1283{
1284 const struct if_options *ifo; 1284 const struct if_options *ifo;
1285 const uint8_t *p; 1285 const uint8_t *p;
1286 struct in_addr addr; 1286 struct in_addr addr;
1287 struct in_addr net; 1287 struct in_addr net;
1288 struct in_addr brd; 1288 struct in_addr brd;
1289 struct dhcp_opt *opt, *vo; 1289 struct dhcp_opt *opt, *vo;
1290 size_t i, pl; 1290 size_t i, pl;
1291 char safe[(BOOTP_FILE_LEN * 4) + 1]; 1291 char safe[(BOOTP_FILE_LEN * 4) + 1];
1292 uint8_t overl = 0; 1292 uint8_t overl = 0;
1293 uint32_t en; 1293 uint32_t en;
1294 1294
1295 ifo = ifp->options; 1295 ifo = ifp->options;
1296 if (get_option_uint8(ifp->ctx, &overl, bootp, bootp_len, 1296 if (get_option_uint8(ifp->ctx, &overl, bootp, bootp_len,
1297 DHO_OPTSOVERLOADED) == -1) 1297 DHO_OPTSOVERLOADED) == -1)
1298 overl = 0; 1298 overl = 0;
1299 1299
1300 if (bootp->yiaddr || bootp->ciaddr) { 1300 if (bootp->yiaddr || bootp->ciaddr) {
1301 /* Set some useful variables that we derive from the DHCP 1301 /* Set some useful variables that we derive from the DHCP
1302 * message but are not necessarily in the options */ 1302 * message but are not necessarily in the options */
1303 addr.s_addr = bootp->yiaddr ? bootp->yiaddr : bootp->ciaddr; 1303 addr.s_addr = bootp->yiaddr ? bootp->yiaddr : bootp->ciaddr;
1304 if (efprintf(fenv, "%s_ip_address=%s", 1304 if (efprintf(fenv, "%s_ip_address=%s",
1305 prefix, inet_ntoa(addr)) == -1) 1305 prefix, inet_ntoa(addr)) == -1)
1306 return -1; 1306 return -1;
1307 if (get_option_addr(ifp->ctx, &net, 1307 if (get_option_addr(ifp->ctx, &net,
1308 bootp, bootp_len, DHO_SUBNETMASK) == -1) { 1308 bootp, bootp_len, DHO_SUBNETMASK) == -1) {
1309 net.s_addr = ipv4_getnetmask(addr.s_addr); 1309 net.s_addr = ipv4_getnetmask(addr.s_addr);
1310 if (efprintf(fenv, "%s_subnet_mask=%s", 1310 if (efprintf(fenv, "%s_subnet_mask=%s",
1311 prefix, inet_ntoa(net)) == -1) 1311 prefix, inet_ntoa(net)) == -1)
1312 return -1; 1312 return -1;
1313 } 1313 }
1314 if (efprintf(fenv, "%s_subnet_cidr=%d", 1314 if (efprintf(fenv, "%s_subnet_cidr=%d",
1315 prefix, inet_ntocidr(net))== -1) 1315 prefix, inet_ntocidr(net))== -1)
1316 return -1; 1316 return -1;
1317 if (get_option_addr(ifp->ctx, &brd, 1317 if (get_option_addr(ifp->ctx, &brd,
1318 bootp, bootp_len, DHO_BROADCAST) == -1) 1318 bootp, bootp_len, DHO_BROADCAST) == -1)
1319 { 1319 {
1320 brd.s_addr = addr.s_addr | ~net.s_addr; 1320 brd.s_addr = addr.s_addr | ~net.s_addr;
1321 if (efprintf(fenv, "%s_broadcast_address=%s", 1321 if (efprintf(fenv, "%s_broadcast_address=%s",
1322 prefix, inet_ntoa(brd)) == -1) 1322 prefix, inet_ntoa(brd)) == -1)
1323 return -1; 1323 return -1;
1324 } 1324 }
1325 addr.s_addr = bootp->yiaddr & net.s_addr; 1325 addr.s_addr = bootp->yiaddr & net.s_addr;
1326 if (efprintf(fenv, "%s_network_number=%s", 1326 if (efprintf(fenv, "%s_network_number=%s",
1327 prefix, inet_ntoa(addr)) == -1) 1327 prefix, inet_ntoa(addr)) == -1)
1328 return -1; 1328 return -1;
1329 } 1329 }
1330 1330
1331 if (*bootp->file && !(overl & 1)) { 1331 if (*bootp->file && !(overl & 1)) {
1332 print_string(safe, sizeof(safe), OT_STRING, 1332 print_string(safe, sizeof(safe), OT_STRING,
1333 bootp->file, sizeof(bootp->file)); 1333 bootp->file, sizeof(bootp->file));
1334 if (efprintf(fenv, "%s_filename=%s", prefix, safe) == -1) 1334 if (efprintf(fenv, "%s_filename=%s", prefix, safe) == -1)
1335 return -1; 1335 return -1;
1336 } 1336 }
1337 if (*bootp->sname && !(overl & 2)) { 1337 if (*bootp->sname && !(overl & 2)) {
1338 print_string(safe, sizeof(safe), OT_STRING | OT_DOMAIN, 1338 print_string(safe, sizeof(safe), OT_STRING | OT_DOMAIN,
1339 bootp->sname, sizeof(bootp->sname)); 1339 bootp->sname, sizeof(bootp->sname));
1340 if (efprintf(fenv, "%s_server_name=%s", prefix, safe) == -1) 1340 if (efprintf(fenv, "%s_server_name=%s", prefix, safe) == -1)
1341 return -1; 1341 return -1;
1342 } 1342 }
1343 1343
1344 /* Zero our indexes */ 1344 /* Zero our indexes */
1345 for (i = 0, opt = ifp->ctx->dhcp_opts; 1345 for (i = 0, opt = ifp->ctx->dhcp_opts;
1346 i < ifp->ctx->dhcp_opts_len; 1346 i < ifp->ctx->dhcp_opts_len;
1347 i++, opt++) 1347 i++, opt++)
1348 dhcp_zero_index(opt); 1348 dhcp_zero_index(opt);
1349 for (i = 0, opt = ifp->options->dhcp_override; 1349 for (i = 0, opt = ifp->options->dhcp_override;
1350 i < ifp->options->dhcp_override_len; 1350 i < ifp->options->dhcp_override_len;
1351 i++, opt++) 1351 i++, opt++)
1352 dhcp_zero_index(opt); 1352 dhcp_zero_index(opt);
1353 for (i = 0, opt = ifp->ctx->vivso; 1353 for (i = 0, opt = ifp->ctx->vivso;
1354 i < ifp->ctx->vivso_len; 1354 i < ifp->ctx->vivso_len;
1355 i++, opt++) 1355 i++, opt++)
1356 dhcp_zero_index(opt); 1356 dhcp_zero_index(opt);
1357 1357
1358 for (i = 0, opt = ifp->ctx->dhcp_opts; 1358 for (i = 0, opt = ifp->ctx->dhcp_opts;
1359 i < ifp->ctx->dhcp_opts_len; 1359 i < ifp->ctx->dhcp_opts_len;
1360 i++, opt++) 1360 i++, opt++)
1361 { 1361 {
1362 if (has_option_mask(ifo->nomask, opt->option)) 1362 if (has_option_mask(ifo->nomask, opt->option))
1363 continue; 1363 continue;
1364 if (dhcp_getoverride(ifo, opt->option)) 1364 if (dhcp_getoverride(ifo, opt->option))
1365 continue; 1365 continue;
1366 p = get_option(ifp->ctx, bootp, bootp_len, opt->option, &pl); 1366 p = get_option(ifp->ctx, bootp, bootp_len, opt->option, &pl);
1367 if (p == NULL) 1367 if (p == NULL)
1368 continue; 1368 continue;
1369 dhcp_envoption(ifp->ctx, fenv, prefix, ifp->name, 1369 dhcp_envoption(ifp->ctx, fenv, prefix, ifp->name,
1370 opt, dhcp_getoption, p, pl); 1370 opt, dhcp_getoption, p, pl);
1371 1371
1372 if (opt->option != DHO_VIVSO || pl <= (int)sizeof(uint32_t)) 1372 if (opt->option != DHO_VIVSO || pl <= (int)sizeof(uint32_t))
1373 continue; 1373 continue;
1374 memcpy(&en, p, sizeof(en)); 1374 memcpy(&en, p, sizeof(en));
1375 en = ntohl(en); 1375 en = ntohl(en);
1376 vo = vivso_find(en, ifp); 1376 vo = vivso_find(en, ifp);
1377 if (vo == NULL) 1377 if (vo == NULL)
1378 continue; 1378 continue;
1379 /* Skip over en + total size */ 1379 /* Skip over en + total size */
1380 p += sizeof(en) + 1; 1380 p += sizeof(en) + 1;
1381 pl -= sizeof(en) + 1; 1381 pl -= sizeof(en) + 1;
1382 dhcp_envoption(ifp->ctx, fenv, prefix, ifp->name, 1382 dhcp_envoption(ifp->ctx, fenv, prefix, ifp->name,
1383 vo, dhcp_getoption, p, pl); 1383 vo, dhcp_getoption, p, pl);
1384 } 1384 }
1385 1385
1386 for (i = 0, opt = ifo->dhcp_override; 1386 for (i = 0, opt = ifo->dhcp_override;
1387 i < ifo->dhcp_override_len; 1387 i < ifo->dhcp_override_len;
1388 i++, opt++) 1388 i++, opt++)
1389 { 1389 {
1390 if (has_option_mask(ifo->nomask, opt->option)) 1390 if (has_option_mask(ifo->nomask, opt->option))
1391 continue; 1391 continue;
1392 p = get_option(ifp->ctx, bootp, bootp_len, opt->option, &pl); 1392 p = get_option(ifp->ctx, bootp, bootp_len, opt->option, &pl);
1393 if (p == NULL) 1393 if (p == NULL)
1394 continue; 1394 continue;
1395 dhcp_envoption(ifp->ctx, fenv, prefix, ifp->name, 1395 dhcp_envoption(ifp->ctx, fenv, prefix, ifp->name,
1396 opt, dhcp_getoption, p, pl); 1396 opt, dhcp_getoption, p, pl);
1397 } 1397 }
1398 1398
1399 return 1; 1399 return 1;
1400} 1400}
1401 1401
1402static void 1402static void
1403get_lease(struct interface *ifp, 1403get_lease(struct interface *ifp,
1404 struct dhcp_lease *lease, const struct bootp *bootp, size_t len) 1404 struct dhcp_lease *lease, const struct bootp *bootp, size_t len)
1405{ 1405{
1406 struct dhcpcd_ctx *ctx; 1406 struct dhcpcd_ctx *ctx;
1407 1407
1408 assert(bootp != NULL); 1408 assert(bootp != NULL);
1409 1409
1410 memcpy(&lease->cookie, bootp->vend, sizeof(lease->cookie)); 1410 memcpy(&lease->cookie, bootp->vend, sizeof(lease->cookie));
1411 /* BOOTP does not set yiaddr for replies when ciaddr is set. */ 1411 /* BOOTP does not set yiaddr for replies when ciaddr is set. */
1412 lease->addr.s_addr = bootp->yiaddr ? bootp->yiaddr : bootp->ciaddr; 1412 lease->addr.s_addr = bootp->yiaddr ? bootp->yiaddr : bootp->ciaddr;
1413 ctx = ifp->ctx; 1413 ctx = ifp->ctx;
1414 if (ifp->options->options & (DHCPCD_STATIC | DHCPCD_INFORM)) { 1414 if (ifp->options->options & (DHCPCD_STATIC | DHCPCD_INFORM)) {
1415 if (ifp->options->req_addr.s_addr != INADDR_ANY) { 1415 if (ifp->options->req_addr.s_addr != INADDR_ANY) {
1416 lease->mask = ifp->options->req_mask; 1416 lease->mask = ifp->options->req_mask;
1417 if (ifp->options->req_brd.s_addr != INADDR_ANY) 1417 if (ifp->options->req_brd.s_addr != INADDR_ANY)
1418 lease->brd = ifp->options->req_brd; 1418 lease->brd = ifp->options->req_brd;
1419 else 1419 else
1420 lease->brd.s_addr = 1420 lease->brd.s_addr =
1421 lease->addr.s_addr | ~lease->mask.s_addr; 1421 lease->addr.s_addr | ~lease->mask.s_addr;
1422 } else { 1422 } else {
1423 const struct ipv4_addr *ia; 1423 const struct ipv4_addr *ia;
1424 1424
1425 ia = ipv4_iffindaddr(ifp, &lease->addr, NULL); 1425 ia = ipv4_iffindaddr(ifp, &lease->addr, NULL);
1426 assert(ia != NULL); 1426 assert(ia != NULL);
1427 lease->mask = ia->mask; 1427 lease->mask = ia->mask;
1428 lease->brd = ia->brd; 1428 lease->brd = ia->brd;
1429 } 1429 }
1430 } else { 1430 } else {
1431 if (get_option_addr(ctx, &lease->mask, bootp, len, 1431 if (get_option_addr(ctx, &lease->mask, bootp, len,
1432 DHO_SUBNETMASK) == -1) 1432 DHO_SUBNETMASK) == -1)
1433 lease->mask.s_addr = 1433 lease->mask.s_addr =
1434 ipv4_getnetmask(lease->addr.s_addr); 1434 ipv4_getnetmask(lease->addr.s_addr);
1435 if (get_option_addr(ctx, &lease->brd, bootp, len, 1435 if (get_option_addr(ctx, &lease->brd, bootp, len,
1436 DHO_BROADCAST) == -1) 1436 DHO_BROADCAST) == -1)
1437 lease->brd.s_addr = 1437 lease->brd.s_addr =
1438 lease->addr.s_addr | ~lease->mask.s_addr; 1438 lease->addr.s_addr | ~lease->mask.s_addr;
1439 } 1439 }
1440 if (get_option_uint32(ctx, &lease->leasetime, 1440 if (get_option_uint32(ctx, &lease->leasetime,
1441 bootp, len, DHO_LEASETIME) != 0) 1441 bootp, len, DHO_LEASETIME) != 0)
1442 lease->leasetime = DHCP_INFINITE_LIFETIME; 1442 lease->leasetime = DHCP_INFINITE_LIFETIME;
1443 if (get_option_uint32(ctx, &lease->renewaltime, 1443 if (get_option_uint32(ctx, &lease->renewaltime,
1444 bootp, len, DHO_RENEWALTIME) != 0) 1444 bootp, len, DHO_RENEWALTIME) != 0)
1445 lease->renewaltime = 0; 1445 lease->renewaltime = 0;
1446 if (get_option_uint32(ctx, &lease->rebindtime, 1446 if (get_option_uint32(ctx, &lease->rebindtime,
1447 bootp, len, DHO_REBINDTIME) != 0) 1447 bootp, len, DHO_REBINDTIME) != 0)
1448 lease->rebindtime = 0; 1448 lease->rebindtime = 0;
1449 if (get_option_addr(ctx, &lease->server, bootp, len, DHO_SERVERID) != 0) 1449 if (get_option_addr(ctx, &lease->server, bootp, len, DHO_SERVERID) != 0)
1450 lease->server.s_addr = INADDR_ANY; 1450 lease->server.s_addr = INADDR_ANY;
1451} 1451}
1452 1452
1453static const char * 1453static const char *
1454get_dhcp_op(uint8_t type) 1454get_dhcp_op(uint8_t type)
1455{ 1455{
1456 const struct dhcp_op *d; 1456 const struct dhcp_op *d;
1457 1457
1458 for (d = dhcp_ops; d->name; d++) 1458 for (d = dhcp_ops; d->name; d++)
1459 if (d->value == type) 1459 if (d->value == type)
1460 return d->name; 1460 return d->name;
1461 return NULL; 1461 return NULL;
1462} 1462}
1463 1463
1464static void 1464static void
1465dhcp_fallback(void *arg) 1465dhcp_fallback(void *arg)
1466{ 1466{
1467 struct interface *iface; 1467 struct interface *iface;
1468 1468
1469 iface = (struct interface *)arg; 1469 iface = (struct interface *)arg;
1470 dhcpcd_selectprofile(iface, iface->options->fallback); 1470 dhcpcd_selectprofile(iface, iface->options->fallback);
1471 dhcpcd_startinterface(iface); 1471 dhcpcd_startinterface(iface);
1472} 1472}
1473 1473
1474static void 1474static void
1475dhcp_new_xid(struct interface *ifp) 1475dhcp_new_xid(struct interface *ifp)
1476{ 1476{
1477 struct dhcp_state *state; 1477 struct dhcp_state *state;
1478 const struct interface *ifp1; 1478 const struct interface *ifp1;
1479 const struct dhcp_state *state1; 1479 const struct dhcp_state *state1;
1480 1480
1481 state = D_STATE(ifp); 1481 state = D_STATE(ifp);
1482 if (ifp->options->options & DHCPCD_XID_HWADDR && 1482 if (ifp->options->options & DHCPCD_XID_HWADDR &&
1483 ifp->hwlen >= sizeof(state->xid)) 1483 ifp->hwlen >= sizeof(state->xid))
1484 /* The lower bits are probably more unique on the network */ 1484 /* The lower bits are probably more unique on the network */
1485 memcpy(&state->xid, 1485 memcpy(&state->xid,
1486 (ifp->hwaddr + ifp->hwlen) - sizeof(state->xid), 1486 (ifp->hwaddr + ifp->hwlen) - sizeof(state->xid),
1487 sizeof(state->xid)); 1487 sizeof(state->xid));
1488 else { 1488 else {
1489again: 1489again:
1490 state->xid = arc4random(); 1490 state->xid = arc4random();
1491 } 1491 }
1492 1492
1493 /* Ensure it's unique */ 1493 /* Ensure it's unique */
1494 TAILQ_FOREACH(ifp1, ifp->ctx->ifaces, next) { 1494 TAILQ_FOREACH(ifp1, ifp->ctx->ifaces, next) {
1495 if (ifp == ifp1) 1495 if (ifp == ifp1)
1496 continue; 1496 continue;
1497 if ((state1 = D_CSTATE(ifp1)) == NULL) 1497 if ((state1 = D_CSTATE(ifp1)) == NULL)
1498 continue; 1498 continue;
1499 if (state1->xid == state->xid) 1499 if (state1->xid == state->xid)
1500 break; 1500 break;
1501 } 1501 }
1502 if (ifp1 != NULL) { 1502 if (ifp1 != NULL) {
1503 if (ifp->options->options & DHCPCD_XID_HWADDR && 1503 if (ifp->options->options & DHCPCD_XID_HWADDR &&
1504 ifp->hwlen >= sizeof(state->xid)) 1504 ifp->hwlen >= sizeof(state->xid))
1505 { 1505 {
1506 logerrx("%s: duplicate xid on %s", 1506 logerrx("%s: duplicate xid on %s",
1507 ifp->name, ifp1->name); 1507 ifp->name, ifp1->name);
1508 return; 1508 return;
1509 } 1509 }
1510 goto again; 1510 goto again;
1511 } 1511 }
1512 1512
1513 /* We can't do this when sharing leases across interfaes */ 1513 /* We can't do this when sharing leases across interfaes */
1514#if 0 1514#if 0
1515 /* As the XID changes, re-apply the filter. */ 1515 /* As the XID changes, re-apply the filter. */
1516 if (state->bpf_fd != -1) { 1516 if (state->bpf_fd != -1) {
1517 if (bpf_bootp(ifp, state->bpf_fd) == -1) 1517 if (bpf_bootp(ifp, state->bpf_fd) == -1)
1518 logerr(__func__); /* try to continue */ 1518 logerr(__func__); /* try to continue */
1519 } 1519 }
1520#endif 1520#endif
1521} 1521}
1522 1522
1523void 1523static void
1524dhcp_close(struct interface *ifp) 1524dhcp_closebpf(struct interface *ifp)
1525{ 1525{
1526 struct dhcpcd_ctx *ctx = ifp->ctx; 1526 struct dhcpcd_ctx *ctx = ifp->ctx;
1527 struct dhcp_state *state = D_STATE(ifp); 1527 struct dhcp_state *state = D_STATE(ifp);
1528 1528
1529 if (state == NULL) 
1530 return; 
1531 
1532#ifdef PRIVSEP 1529#ifdef PRIVSEP
1533 if (IN_PRIVSEP_SE(ctx)) { 1530 if (IN_PRIVSEP_SE(ctx))
1534 ps_bpf_closebootp(ifp); 1531 ps_bpf_closebootp(ifp);
1535 if (state->addr != NULL) 
1536 ps_inet_closebootp(state->addr); 
1537 } 
1538#endif 1532#endif
1539 1533
1540 if (state->bpf != NULL) { 1534 if (state->bpf != NULL) {
1541 eloop_event_delete(ctx->eloop, state->bpf->bpf_fd); 1535 eloop_event_delete(ctx->eloop, state->bpf->bpf_fd);
1542 bpf_close(state->bpf); 1536 bpf_close(state->bpf);
1543 state->bpf = NULL; 1537 state->bpf = NULL;
1544 } 1538 }
 1539}
 1540
 1541static void
 1542dhcp_closeinet(struct interface *ifp)
 1543{
 1544 struct dhcpcd_ctx *ctx = ifp->ctx;
 1545 struct dhcp_state *state = D_STATE(ifp);
 1546
 1547#ifdef PRIVSEP
 1548 if (IN_PRIVSEP_SE(ctx)) {
 1549 if (state->addr != NULL)
 1550 ps_inet_closebootp(state->addr);
 1551 }
 1552#endif
 1553
1545 if (state->udp_rfd != -1) { 1554 if (state->udp_rfd != -1) {
1546 eloop_event_delete(ctx->eloop, state->udp_rfd); 1555 eloop_event_delete(ctx->eloop, state->udp_rfd);
1547 close(state->udp_rfd); 1556 close(state->udp_rfd);
1548 state->udp_rfd = -1; 1557 state->udp_rfd = -1;
1549 } 1558 }
 1559}
 1560
 1561void
 1562dhcp_close(struct interface *ifp)
 1563{
 1564 struct dhcp_state *state = D_STATE(ifp);
 1565
 1566 if (state == NULL)
 1567 return;
 1568
 1569 dhcp_closebpf(ifp);
 1570 dhcp_closeinet(ifp);
1550 1571
1551 state->interval = 0; 1572 state->interval = 0;
1552} 1573}
1553 1574
1554int 1575int
1555dhcp_openudp(struct in_addr *ia) 1576dhcp_openudp(struct in_addr *ia)
1556{ 1577{
1557 int s; 1578 int s;
1558 struct sockaddr_in sin; 1579 struct sockaddr_in sin;
1559 int n; 1580 int n;
1560 1581
1561 if ((s = xsocket(PF_INET, SOCK_DGRAM | SOCK_CXNB, IPPROTO_UDP)) == -1) 1582 if ((s = xsocket(PF_INET, SOCK_DGRAM | SOCK_CXNB, IPPROTO_UDP)) == -1)
1562 return -1; 1583 return -1;
1563 1584
1564 n = 1; 1585 n = 1;
1565 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) == -1) 1586 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) == -1)
1566 goto errexit; 1587 goto errexit;
1567#ifdef IP_RECVIF 1588#ifdef IP_RECVIF
1568 if (setsockopt(s, IPPROTO_IP, IP_RECVIF, &n, sizeof(n)) == -1) 1589 if (setsockopt(s, IPPROTO_IP, IP_RECVIF, &n, sizeof(n)) == -1)
1569 goto errexit; 1590 goto errexit;
1570#else 1591#else
1571 if (setsockopt(s, IPPROTO_IP, IP_RECVPKTINFO, &n, sizeof(n)) == -1) 1592 if (setsockopt(s, IPPROTO_IP, IP_RECVPKTINFO, &n, sizeof(n)) == -1)
1572 goto errexit; 1593 goto errexit;
1573#endif 1594#endif
1574#ifdef SO_RERROR 1595#ifdef SO_RERROR
1575 if (setsockopt(s, SOL_SOCKET, SO_RERROR, &n, sizeof(n)) == -1) 1596 if (setsockopt(s, SOL_SOCKET, SO_RERROR, &n, sizeof(n)) == -1)
1576 goto errexit; 1597 goto errexit;
1577#endif 1598#endif
1578 1599
1579 memset(&sin, 0, sizeof(sin)); 1600 memset(&sin, 0, sizeof(sin));
1580 sin.sin_family = AF_INET; 1601 sin.sin_family = AF_INET;
1581 sin.sin_port = htons(BOOTPC); 1602 sin.sin_port = htons(BOOTPC);
1582 if (ia != NULL) 1603 if (ia != NULL)
1583 sin.sin_addr = *ia; 1604 sin.sin_addr = *ia;
1584 if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == -1) 1605 if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == -1)
1585 goto errexit; 1606 goto errexit;
1586 1607
1587 return s; 1608 return s;
1588 1609
1589errexit: 1610errexit:
1590 close(s); 1611 close(s);
1591 return -1; 1612 return -1;
1592} 1613}
1593 1614
1594static uint16_t 1615static uint16_t
1595in_cksum(const void *data, size_t len, uint32_t *isum) 1616in_cksum(const void *data, size_t len, uint32_t *isum)
1596{ 1617{
1597 const uint16_t *word = data; 1618 const uint16_t *word = data;
1598 uint32_t sum = isum != NULL ? *isum : 0; 1619 uint32_t sum = isum != NULL ? *isum : 0;
1599 1620
1600 for (; len > 1; len -= sizeof(*word)) 1621 for (; len > 1; len -= sizeof(*word))
1601 sum += *word++; 1622 sum += *word++;
1602 1623
1603 if (len == 1) 1624 if (len == 1)
1604 sum += htons((uint16_t)(*(const uint8_t *)word << 8)); 1625 sum += htons((uint16_t)(*(const uint8_t *)word << 8));
1605 1626
1606 if (isum != NULL) 1627 if (isum != NULL)
1607 *isum = sum; 1628 *isum = sum;
1608 1629
1609 sum = (sum >> 16) + (sum & 0xffff); 1630 sum = (sum >> 16) + (sum & 0xffff);
1610 sum += (sum >> 16); 1631 sum += (sum >> 16);
1611 1632
1612 return (uint16_t)~sum; 1633 return (uint16_t)~sum;
1613} 1634}
1614 1635
1615static struct bootp_pkt * 1636static struct bootp_pkt *
1616dhcp_makeudppacket(size_t *sz, const uint8_t *data, size_t length, 1637dhcp_makeudppacket(size_t *sz, const uint8_t *data, size_t length,
1617 struct in_addr source, struct in_addr dest) 1638 struct in_addr source, struct in_addr dest)
1618{ 1639{
1619 struct bootp_pkt *udpp; 1640 struct bootp_pkt *udpp;
1620 struct ip *ip; 1641 struct ip *ip;
1621 struct udphdr *udp; 1642 struct udphdr *udp;
1622 1643
1623 if ((udpp = calloc(1, sizeof(*ip) + sizeof(*udp) + length)) == NULL) 1644 if ((udpp = calloc(1, sizeof(*ip) + sizeof(*udp) + length)) == NULL)
1624 return NULL; 1645 return NULL;
1625 ip = &udpp->ip; 1646 ip = &udpp->ip;
1626 udp = &udpp->udp; 1647 udp = &udpp->udp;
1627 1648
1628 /* OK, this is important :) 1649 /* OK, this is important :)
1629 * We copy the data to our packet and then create a small part of the 1650 * We copy the data to our packet and then create a small part of the
1630 * ip structure and an invalid ip_len (basically udp length). 1651 * ip structure and an invalid ip_len (basically udp length).
1631 * We then fill the udp structure and put the checksum 1652 * We then fill the udp structure and put the checksum
1632 * of the whole packet into the udp checksum. 1653 * of the whole packet into the udp checksum.
1633 * Finally we complete the ip structure and ip checksum. 1654 * Finally we complete the ip structure and ip checksum.
1634 * If we don't do the ordering like so then the udp checksum will be 1655 * If we don't do the ordering like so then the udp checksum will be
1635 * broken, so find another way of doing it! */ 1656 * broken, so find another way of doing it! */
1636 1657
1637 memcpy(&udpp->bootp, data, length); 1658 memcpy(&udpp->bootp, data, length);
1638 1659
1639 ip->ip_p = IPPROTO_UDP; 1660 ip->ip_p = IPPROTO_UDP;
1640 ip->ip_src.s_addr = source.s_addr; 1661 ip->ip_src.s_addr = source.s_addr;
1641 if (dest.s_addr == 0) 1662 if (dest.s_addr == 0)
1642 ip->ip_dst.s_addr = INADDR_BROADCAST; 1663 ip->ip_dst.s_addr = INADDR_BROADCAST;
1643 else 1664 else
1644 ip->ip_dst.s_addr = dest.s_addr; 1665 ip->ip_dst.s_addr = dest.s_addr;
1645 1666
1646 udp->uh_sport = htons(BOOTPC); 1667 udp->uh_sport = htons(BOOTPC);
1647 udp->uh_dport = htons(BOOTPS); 1668 udp->uh_dport = htons(BOOTPS);
1648 udp->uh_ulen = htons((uint16_t)(sizeof(*udp) + length)); 1669 udp->uh_ulen = htons((uint16_t)(sizeof(*udp) + length));
1649 ip->ip_len = udp->uh_ulen; 1670 ip->ip_len = udp->uh_ulen;
1650 udp->uh_sum = in_cksum(udpp, sizeof(*ip) + sizeof(*udp) + length, NULL); 1671 udp->uh_sum = in_cksum(udpp, sizeof(*ip) + sizeof(*udp) + length, NULL);
1651 1672
1652 ip->ip_v = IPVERSION; 1673 ip->ip_v = IPVERSION;
1653 ip->ip_hl = sizeof(*ip) >> 2; 1674 ip->ip_hl = sizeof(*ip) >> 2;
1654 ip->ip_id = (uint16_t)arc4random_uniform(UINT16_MAX); 1675 ip->ip_id = (uint16_t)arc4random_uniform(UINT16_MAX);
1655 ip->ip_ttl = IPDEFTTL; 1676 ip->ip_ttl = IPDEFTTL;
1656 ip->ip_len = htons((uint16_t)(sizeof(*ip) + sizeof(*udp) + length)); 1677 ip->ip_len = htons((uint16_t)(sizeof(*ip) + sizeof(*udp) + length));
1657 ip->ip_sum = in_cksum(ip, sizeof(*ip), NULL); 1678 ip->ip_sum = in_cksum(ip, sizeof(*ip), NULL);
1658 if (ip->ip_sum == 0) 1679 if (ip->ip_sum == 0)
1659 ip->ip_sum = 0xffff; /* RFC 768 */ 1680 ip->ip_sum = 0xffff; /* RFC 768 */
1660 1681
1661 *sz = sizeof(*ip) + sizeof(*udp) + length; 1682 *sz = sizeof(*ip) + sizeof(*udp) + length;
1662 return udpp; 1683 return udpp;
1663} 1684}
1664 1685
1665static ssize_t 1686static ssize_t
1666dhcp_sendudp(struct interface *ifp, struct in_addr *to, void *data, size_t len) 1687dhcp_sendudp(struct interface *ifp, struct in_addr *to, void *data, size_t len)
1667{ 1688{
1668 struct sockaddr_in sin = { 1689 struct sockaddr_in sin = {
1669 .sin_family = AF_INET, 1690 .sin_family = AF_INET,
1670 .sin_addr = *to, 1691 .sin_addr = *to,
1671 .sin_port = htons(BOOTPS), 1692 .sin_port = htons(BOOTPS),
1672#ifdef HAVE_SA_LEN 1693#ifdef HAVE_SA_LEN
1673 .sin_len = sizeof(sin), 1694 .sin_len = sizeof(sin),
1674#endif 1695#endif
1675 }; 1696 };
1676 struct udphdr udp = { 1697 struct udphdr udp = {
1677 .uh_sport = htons(BOOTPC), 1698 .uh_sport = htons(BOOTPC),
1678 .uh_dport = htons(BOOTPS), 1699 .uh_dport = htons(BOOTPS),
1679 .uh_ulen = htons((uint16_t)(sizeof(udp) + len)), 1700 .uh_ulen = htons((uint16_t)(sizeof(udp) + len)),
1680 }; 1701 };
1681 struct iovec iov[] = { 1702 struct iovec iov[] = {
1682 { .iov_base = &udp, .iov_len = sizeof(udp), }, 1703 { .iov_base = &udp, .iov_len = sizeof(udp), },
1683 { .iov_base = data, .iov_len = len, }, 1704 { .iov_base = data, .iov_len = len, },
1684 }; 1705 };
1685 struct msghdr msg = { 1706 struct msghdr msg = {
1686 .msg_name = (void *)&sin, 1707 .msg_name = (void *)&sin,
1687 .msg_namelen = sizeof(sin), 1708 .msg_namelen = sizeof(sin),
1688 .msg_iov = iov, 1709 .msg_iov = iov,
1689 .msg_iovlen = __arraycount(iov), 1710 .msg_iovlen = __arraycount(iov),
1690 }; 1711 };
1691 struct dhcpcd_ctx *ctx = ifp->ctx; 1712 struct dhcpcd_ctx *ctx = ifp->ctx;
1692 1713
1693#ifdef PRIVSEP 1714#ifdef PRIVSEP
1694 if (ctx->options & DHCPCD_PRIVSEP) 1715 if (ctx->options & DHCPCD_PRIVSEP)
1695 return ps_inet_sendbootp(ifp, &msg); 1716 return ps_inet_sendbootp(ifp, &msg);
1696#endif 1717#endif
1697 return sendmsg(ctx->udp_wfd, &msg, 0); 1718 return sendmsg(ctx->udp_wfd, &msg, 0);
1698} 1719}
1699 1720
1700static void 1721static void
1701send_message(struct interface *ifp, uint8_t type, 1722send_message(struct interface *ifp, uint8_t type,
1702 void (*callback)(void *)) 1723 void (*callback)(void *))
1703{ 1724{
1704 struct dhcp_state *state = D_STATE(ifp); 1725 struct dhcp_state *state = D_STATE(ifp);
1705 struct if_options *ifo = ifp->options; 1726 struct if_options *ifo = ifp->options;
1706 struct bootp *bootp; 1727 struct bootp *bootp;
1707 struct bootp_pkt *udp; 1728 struct bootp_pkt *udp;
1708 size_t len, ulen; 1729 size_t len, ulen;
1709 ssize_t r; 1730 ssize_t r;
1710 struct in_addr from, to; 1731 struct in_addr from, to;
1711 unsigned int RT; 1732 unsigned int RT;
1712 1733
1713 if (callback == NULL) { 1734 if (callback == NULL) {
1714 /* No carrier? Don't bother sending the packet. */ 1735 /* No carrier? Don't bother sending the packet. */
1715 if (!if_is_link_up(ifp)) 1736 if (!if_is_link_up(ifp))
1716 return; 1737 return;
1717 logdebugx("%s: sending %s with xid 0x%x", 1738 logdebugx("%s: sending %s with xid 0x%x",
1718 ifp->name, 1739 ifp->name,
1719 ifo->options & DHCPCD_BOOTP ? "BOOTP" : get_dhcp_op(type), 1740 ifo->options & DHCPCD_BOOTP ? "BOOTP" : get_dhcp_op(type),
1720 state->xid); 1741 state->xid);
1721 RT = 0; /* bogus gcc warning */ 1742 RT = 0; /* bogus gcc warning */
1722 } else { 1743 } else {
1723 if (state->interval == 0) 1744 if (state->interval == 0)
1724 state->interval = 4; 1745 state->interval = 4;
1725 else { 1746 else {
1726 state->interval *= 2; 1747 state->interval *= 2;
1727 if (state->interval > 64) 1748 if (state->interval > 64)
1728 state->interval = 64; 1749 state->interval = 64;
1729 } 1750 }
1730 RT = (state->interval * MSEC_PER_SEC) + 1751 RT = (state->interval * MSEC_PER_SEC) +
1731 (arc4random_uniform(MSEC_PER_SEC * 2) - MSEC_PER_SEC); 1752 (arc4random_uniform(MSEC_PER_SEC * 2) - MSEC_PER_SEC);
1732 /* No carrier? Don't bother sending the packet. 1753 /* No carrier? Don't bother sending the packet.
1733 * However, we do need to advance the timeout. */ 1754 * However, we do need to advance the timeout. */
1734 if (!if_is_link_up(ifp)) 1755 if (!if_is_link_up(ifp))
1735 goto fail; 1756 goto fail;
1736 logdebugx("%s: sending %s (xid 0x%x), next in %0.1f seconds", 1757 logdebugx("%s: sending %s (xid 0x%x), next in %0.1f seconds",
1737 ifp->name, 1758 ifp->name,
1738 ifo->options & DHCPCD_BOOTP ? "BOOTP" : get_dhcp_op(type), 1759 ifo->options & DHCPCD_BOOTP ? "BOOTP" : get_dhcp_op(type),
1739 state->xid, 1760 state->xid,
1740 (float)RT / MSEC_PER_SEC); 1761 (float)RT / MSEC_PER_SEC);
1741 } 1762 }
1742 1763
1743 r = make_message(&bootp, ifp, type); 1764 r = make_message(&bootp, ifp, type);
1744 if (r == -1) 1765 if (r == -1)
1745 goto fail; 1766 goto fail;
1746 len = (size_t)r; 1767 len = (size_t)r;
1747 1768
1748 if (!(state->added & (STATE_FAKE | STATE_EXPIRED)) && 1769 if (!(state->added & (STATE_FAKE | STATE_EXPIRED)) &&
1749 state->addr != NULL && 1770 state->addr != NULL &&
1750 ipv4_iffindaddr(ifp, &state->lease.addr, NULL) != NULL) 1771 ipv4_iffindaddr(ifp, &state->lease.addr, NULL) != NULL)
1751 from.s_addr = state->lease.addr.s_addr; 1772 from.s_addr = state->lease.addr.s_addr;
1752 else 1773 else
1753 from.s_addr = INADDR_ANY; 1774 from.s_addr = INADDR_ANY;
1754 if (from.s_addr != INADDR_ANY && 1775 if (from.s_addr != INADDR_ANY &&
1755 state->lease.server.s_addr != INADDR_ANY) 1776 state->lease.server.s_addr != INADDR_ANY)
1756 to.s_addr = state->lease.server.s_addr; 1777 to.s_addr = state->lease.server.s_addr;
1757 else 1778 else
1758 to.s_addr = INADDR_BROADCAST; 1779 to.s_addr = INADDR_BROADCAST;
1759 1780
1760 /* 1781 /*
1761 * If not listening on the unspecified address we can 1782 * If not listening on the unspecified address we can
1762 * only receive broadcast messages via BPF. 1783 * only receive broadcast messages via BPF.
1763 * Sockets bound to an address cannot receive broadcast messages 1784 * Sockets bound to an address cannot receive broadcast messages
1764 * even if they are setup to send them. 1785 * even if they are setup to send them.
1765 * Broadcasting from UDP is only an optimisation for rebinding 1786 * Broadcasting from UDP is only an optimisation for rebinding
1766 * and on BSD, at least, is reliant on the subnet route being 1787 * and on BSD, at least, is reliant on the subnet route being
1767 * correctly configured to receive the unicast reply. 1788 * correctly configured to receive the unicast reply.
1768 * As such, we always broadcast and receive the reply to it via BPF. 1789 * As such, we always broadcast and receive the reply to it via BPF.
1769 * This also guarantees we have a DHCP server attached to the 1790 * This also guarantees we have a DHCP server attached to the
1770 * interface we want to configure because we can't dictate the 1791 * interface we want to configure because we can't dictate the
1771 * interface via IP_PKTINFO unlike for IPv6. 1792 * interface via IP_PKTINFO unlike for IPv6.
1772 */ 1793 */
1773 if (to.s_addr != INADDR_BROADCAST) { 1794 if (to.s_addr != INADDR_BROADCAST) {
1774 if (dhcp_sendudp(ifp, &to, bootp, len) != -1) 1795 if (dhcp_sendudp(ifp, &to, bootp, len) != -1)
1775 goto out; 1796 goto out;
1776 logerr("%s: dhcp_sendudp", ifp->name); 1797 logerr("%s: dhcp_sendudp", ifp->name);
1777 } 1798 }
1778 1799
1779 if (dhcp_openbpf(ifp) == -1) 1800 if (dhcp_openbpf(ifp) == -1)
1780 goto out; 1801 goto out;
1781 1802
1782 udp = dhcp_makeudppacket(&ulen, (uint8_t *)bootp, len, from, to); 1803 udp = dhcp_makeudppacket(&ulen, (uint8_t *)bootp, len, from, to);
1783 if (udp == NULL) { 1804 if (udp == NULL) {
1784 logerr("%s: dhcp_makeudppacket", ifp->name); 1805 logerr("%s: dhcp_makeudppacket", ifp->name);
1785 r = 0; 1806 r = 0;
1786#ifdef PRIVSEP 1807#ifdef PRIVSEP
1787 } else if (ifp->ctx->options & DHCPCD_PRIVSEP) { 1808 } else if (ifp->ctx->options & DHCPCD_PRIVSEP) {
1788 r = ps_bpf_sendbootp(ifp, udp, ulen); 1809 r = ps_bpf_sendbootp(ifp, udp, ulen);
1789 free(udp); 1810 free(udp);
1790#endif 1811#endif
1791 } else { 1812 } else {
1792 r = bpf_send(state->bpf, ETHERTYPE_IP, udp, ulen); 1813 r = bpf_send(state->bpf, ETHERTYPE_IP, udp, ulen);
1793 free(udp); 1814 free(udp);
1794 } 1815 }
1795 /* If we failed to send a raw packet this normally means 1816 /* If we failed to send a raw packet this normally means
1796 * we don't have the ability to work beneath the IP layer 1817 * we don't have the ability to work beneath the IP layer
1797 * for this interface. 1818 * for this interface.
1798 * As such we remove it from consideration without actually 1819 * As such we remove it from consideration without actually
1799 * stopping the interface. */ 1820 * stopping the interface. */
1800 if (r == -1) { 1821 if (r == -1) {
1801 logerr("%s: bpf_send", ifp->name); 1822 logerr("%s: bpf_send", ifp->name);
1802 switch(errno) { 1823 switch(errno) {
1803 case ENETDOWN: 1824 case ENETDOWN:
1804 case ENETRESET: 1825 case ENETRESET:
1805 case ENETUNREACH: 1826 case ENETUNREACH:
1806 case ENOBUFS: 1827 case ENOBUFS:
1807 break; 1828 break;
1808 default: 1829 default:
1809 if (!(ifp->ctx->options & DHCPCD_TEST)) 1830 if (!(ifp->ctx->options & DHCPCD_TEST))
1810 dhcp_drop(ifp, "FAIL"); 1831 dhcp_drop(ifp, "FAIL");
1811 eloop_timeout_delete(ifp->ctx->eloop, 1832 eloop_timeout_delete(ifp->ctx->eloop,
1812 NULL, ifp); 1833 NULL, ifp);
1813 callback = NULL; 1834 callback = NULL;
1814 } 1835 }
1815 } 1836 }
1816 1837
1817out: 1838out:
1818 free(bootp); 1839 free(bootp);
1819 1840
1820fail: 1841fail:
1821 /* Even if we fail to send a packet we should continue as we are 1842 /* Even if we fail to send a packet we should continue as we are
1822 * as our failure timeouts will change out codepath when needed. */ 1843 * as our failure timeouts will change out codepath when needed. */
1823 if (callback != NULL) 1844 if (callback != NULL)
1824 eloop_timeout_add_msec(ifp->ctx->eloop, RT, callback, ifp); 1845 eloop_timeout_add_msec(ifp->ctx->eloop, RT, callback, ifp);
1825} 1846}
1826 1847
1827static void 1848static void
1828send_inform(void *arg) 1849send_inform(void *arg)
1829{ 1850{
1830 1851
1831 send_message((struct interface *)arg, DHCP_INFORM, send_inform); 1852 send_message((struct interface *)arg, DHCP_INFORM, send_inform);
1832} 1853}
1833 1854
1834static void 1855static void
1835send_discover(void *arg) 1856send_discover(void *arg)
1836{ 1857{
1837 1858
1838 send_message((struct interface *)arg, DHCP_DISCOVER, send_discover); 1859 send_message((struct interface *)arg, DHCP_DISCOVER, send_discover);
1839} 1860}
1840 1861
1841static void 1862static void
1842send_request(void *arg) 1863send_request(void *arg)
1843{ 1864{
1844 1865
1845 send_message((struct interface *)arg, DHCP_REQUEST, send_request); 1866 send_message((struct interface *)arg, DHCP_REQUEST, send_request);
1846} 1867}
1847 1868
1848static void 1869static void
1849send_renew(void *arg) 1870send_renew(void *arg)
1850{ 1871{
1851 1872
1852 send_message((struct interface *)arg, DHCP_REQUEST, send_renew); 1873 send_message((struct interface *)arg, DHCP_REQUEST, send_renew);
1853} 1874}
1854 1875
1855static void 1876static void
1856send_rebind(void *arg) 1877send_rebind(void *arg)
1857{ 1878{
1858 1879
1859 send_message((struct interface *)arg, DHCP_REQUEST, send_rebind); 1880 send_message((struct interface *)arg, DHCP_REQUEST, send_rebind);
1860} 1881}
1861 1882
1862void 1883void
1863dhcp_discover(void *arg) 1884dhcp_discover(void *arg)
1864{ 1885{
1865 struct interface *ifp = arg; 1886 struct interface *ifp = arg;
1866 struct dhcp_state *state = D_STATE(ifp); 1887 struct dhcp_state *state = D_STATE(ifp);
1867 struct if_options *ifo = ifp->options; 1888 struct if_options *ifo = ifp->options;
1868 1889
1869 state->state = DHS_DISCOVER; 1890 state->state = DHS_DISCOVER;
1870 dhcp_new_xid(ifp); 1891 dhcp_new_xid(ifp);
1871 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); 1892 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
1872 if (!(state->added & STATE_EXPIRED)) { 1893 if (!(state->added & STATE_EXPIRED)) {
1873 if (ifo->fallback) 1894 if (ifo->fallback)
1874 eloop_timeout_add_sec(ifp->ctx->eloop, 1895 eloop_timeout_add_sec(ifp->ctx->eloop,
1875 ifo->reboot, dhcp_fallback, ifp); 1896 ifo->reboot, dhcp_fallback, ifp);
1876#ifdef IPV4LL 1897#ifdef IPV4LL
1877 else if (ifo->options & DHCPCD_IPV4LL) 1898 else if (ifo->options & DHCPCD_IPV4LL)
1878 eloop_timeout_add_sec(ifp->ctx->eloop, 1899 eloop_timeout_add_sec(ifp->ctx->eloop,
1879 ifo->reboot, ipv4ll_start, ifp); 1900 ifo->reboot, ipv4ll_start, ifp);
1880#endif 1901#endif
1881 } 1902 }
1882 if (ifo->options & DHCPCD_REQUEST) 1903 if (ifo->options & DHCPCD_REQUEST)
1883 loginfox("%s: soliciting a DHCP lease (requesting %s)", 1904 loginfox("%s: soliciting a DHCP lease (requesting %s)",
1884 ifp->name, inet_ntoa(ifo->req_addr)); 1905 ifp->name, inet_ntoa(ifo->req_addr));
1885 else 1906 else
1886 loginfox("%s: soliciting a %s lease", 1907 loginfox("%s: soliciting a %s lease",
1887 ifp->name, ifo->options & DHCPCD_BOOTP ? "BOOTP" : "DHCP"); 1908 ifp->name, ifo->options & DHCPCD_BOOTP ? "BOOTP" : "DHCP");
1888 send_discover(ifp); 1909 send_discover(ifp);
1889} 1910}
1890 1911
1891static void 1912static void
1892dhcp_request(void *arg) 1913dhcp_request(void *arg)
1893{ 1914{
1894 struct interface *ifp = arg; 1915 struct interface *ifp = arg;
1895 struct dhcp_state *state = D_STATE(ifp); 1916 struct dhcp_state *state = D_STATE(ifp);
1896 1917
1897 state->state = DHS_REQUEST; 1918 state->state = DHS_REQUEST;
1898 send_request(ifp); 1919 send_request(ifp);
1899} 1920}
1900 1921
1901static void 1922static void
1902dhcp_expire(void *arg) 1923dhcp_expire(void *arg)
1903{ 1924{
1904 struct interface *ifp = arg; 1925 struct interface *ifp = arg;
1905 struct dhcp_state *state = D_STATE(ifp); 1926 struct dhcp_state *state = D_STATE(ifp);
1906 1927
1907 if (ifp->options->options & DHCPCD_LASTLEASE_EXTEND) { 1928 if (ifp->options->options & DHCPCD_LASTLEASE_EXTEND) {
1908 logwarnx("%s: DHCP lease expired, extending lease", ifp->name); 1929 logwarnx("%s: DHCP lease expired, extending lease", ifp->name);
1909 state->added |= STATE_EXPIRED; 1930 state->added |= STATE_EXPIRED;
1910 } else { 1931 } else {
1911 logerrx("%s: DHCP lease expired", ifp->name); 1932 logerrx("%s: DHCP lease expired", ifp->name);
1912 dhcp_drop(ifp, "EXPIRE"); 1933 dhcp_drop(ifp, "EXPIRE");
1913 dhcp_unlink(ifp->ctx, state->leasefile); 1934 dhcp_unlink(ifp->ctx, state->leasefile);
1914 } 1935 }
1915 state->interval = 0; 1936 state->interval = 0;
1916 dhcp_discover(ifp); 1937 dhcp_discover(ifp);
1917} 1938}
1918 1939
1919#if defined(ARP) || defined(IN_IFF_DUPLICATED) 1940#if defined(ARP) || defined(IN_IFF_DUPLICATED)
1920static void 1941static void
1921dhcp_decline(struct interface *ifp) 1942dhcp_decline(struct interface *ifp)
1922{ 1943{
1923 1944
1924 send_message(ifp, DHCP_DECLINE, NULL); 1945 send_message(ifp, DHCP_DECLINE, NULL);
1925} 1946}
1926#endif 1947#endif
1927 1948
1928static void 1949static void
1929dhcp_startrenew(void *arg) 1950dhcp_startrenew(void *arg)
1930{ 1951{
1931 struct interface *ifp = arg; 1952 struct interface *ifp = arg;
1932 struct dhcp_state *state; 1953 struct dhcp_state *state;
1933 struct dhcp_lease *lease; 1954 struct dhcp_lease *lease;
1934 1955
1935 if ((state = D_STATE(ifp)) == NULL) 1956 if ((state = D_STATE(ifp)) == NULL)
1936 return; 1957 return;
1937 1958
1938 /* Only renew in the bound or renew states */ 1959 /* Only renew in the bound or renew states */
1939 if (state->state != DHS_BOUND && 1960 if (state->state != DHS_BOUND &&
1940 state->state != DHS_RENEW) 1961 state->state != DHS_RENEW)
1941 return; 1962 return;
1942 1963
1943 /* Remove the timeout as the renew may have been forced. */ 1964 /* Remove the timeout as the renew may have been forced. */
1944 eloop_timeout_delete(ifp->ctx->eloop, dhcp_startrenew, ifp); 1965 eloop_timeout_delete(ifp->ctx->eloop, dhcp_startrenew, ifp);
1945 1966
1946 lease = &state->lease; 1967 lease = &state->lease;
1947 logdebugx("%s: renewing lease of %s", ifp->name, 1968 logdebugx("%s: renewing lease of %s", ifp->name,
1948 inet_ntoa(lease->addr)); 1969 inet_ntoa(lease->addr));
1949 state->state = DHS_RENEW; 1970 state->state = DHS_RENEW;
1950 dhcp_new_xid(ifp); 1971 dhcp_new_xid(ifp);
1951 state->interval = 0; 1972 state->interval = 0;
1952 send_renew(ifp); 1973 send_renew(ifp);
1953} 1974}
1954 1975
1955void 1976void
1956dhcp_renew(struct interface *ifp) 1977dhcp_renew(struct interface *ifp)
1957{ 1978{
1958 1979
1959 dhcp_startrenew(ifp); 1980 dhcp_startrenew(ifp);
1960} 1981}
1961 1982
1962static void 1983static void
1963dhcp_rebind(void *arg) 1984dhcp_rebind(void *arg)
1964{ 1985{
1965 struct interface *ifp = arg; 1986 struct interface *ifp = arg;
1966 struct dhcp_state *state = D_STATE(ifp); 1987 struct dhcp_state *state = D_STATE(ifp);
1967 struct dhcp_lease *lease = &state->lease; 1988 struct dhcp_lease *lease = &state->lease;
1968 1989
1969 logwarnx("%s: failed to renew DHCP, rebinding", ifp->name); 1990 logwarnx("%s: failed to renew DHCP, rebinding", ifp->name);
1970 logdebugx("%s: expire in %"PRIu32" seconds", 1991 logdebugx("%s: expire in %"PRIu32" seconds",
1971 ifp->name, lease->leasetime - lease->rebindtime); 1992 ifp->name, lease->leasetime - lease->rebindtime);
1972 state->state = DHS_REBIND; 1993 state->state = DHS_REBIND;
1973 eloop_timeout_delete(ifp->ctx->eloop, send_renew, ifp); 1994 eloop_timeout_delete(ifp->ctx->eloop, send_renew, ifp);
1974 state->lease.server.s_addr = INADDR_ANY; 1995 state->lease.server.s_addr = INADDR_ANY;
1975 state->interval = 0; 1996 state->interval = 0;
1976 ifp->options->options &= ~(DHCPCD_CSR_WARNED | 1997 ifp->options->options &= ~(DHCPCD_CSR_WARNED |
1977 DHCPCD_ROUTER_HOST_ROUTE_WARNED); 1998 DHCPCD_ROUTER_HOST_ROUTE_WARNED);
1978 send_rebind(ifp); 1999 send_rebind(ifp);
1979} 2000}
1980 2001
1981#if defined(ARP) || defined(IN_IFF_DUPLICATED) 2002#if defined(ARP) || defined(IN_IFF_DUPLICATED)
1982static void 2003static void
1983dhcp_finish_dad(struct interface *ifp, struct in_addr *ia) 2004dhcp_finish_dad(struct interface *ifp, struct in_addr *ia)
1984{ 2005{
1985 struct dhcp_state *state = D_STATE(ifp); 2006 struct dhcp_state *state = D_STATE(ifp);
1986 2007
1987 if (state->state != DHS_PROBE) 2008 if (state->state != DHS_PROBE)
1988 return; 2009 return;
1989 if (state->offer == NULL || state->offer->yiaddr != ia->s_addr) 2010 if (state->offer == NULL || state->offer->yiaddr != ia->s_addr)
1990 return; 2011 return;
1991 2012
1992 logdebugx("%s: DAD completed for %s", ifp->name, inet_ntoa(*ia)); 2013 logdebugx("%s: DAD completed for %s", ifp->name, inet_ntoa(*ia));
1993 if (!(ifp->options->options & DHCPCD_INFORM)) 2014 if (!(ifp->options->options & DHCPCD_INFORM))
1994 dhcp_bind(ifp); 2015 dhcp_bind(ifp);
1995#ifndef IN_IFF_DUPLICATED 2016#ifndef IN_IFF_DUPLICATED
1996 else { 2017 else {
1997 struct bootp *bootp; 2018 struct bootp *bootp;
1998 size_t len; 2019 size_t len;
1999 2020
2000 bootp = state->new; 2021 bootp = state->new;
2001 len = state->new_len; 2022 len = state->new_len;
2002 state->new = state->offer; 2023 state->new = state->offer;
2003 state->new_len = state->offer_len; 2024 state->new_len = state->offer_len;
2004 get_lease(ifp, &state->lease, state->new, state->new_len); 2025 get_lease(ifp, &state->lease, state->new, state->new_len);
2005 ipv4_applyaddr(ifp); 2026 ipv4_applyaddr(ifp);
2006 state->new = bootp; 2027 state->new = bootp;
2007 state->new_len = len; 2028 state->new_len = len;
2008 } 2029 }
2009#endif 2030#endif
2010 2031
2011#ifdef IPV4LL 2032#ifdef IPV4LL
2012 /* Stop IPv4LL now we have a working DHCP address */ 2033 /* Stop IPv4LL now we have a working DHCP address */
2013 ipv4ll_drop(ifp); 2034 ipv4ll_drop(ifp);
2014#endif 2035#endif
2015 2036
2016 if (ifp->options->options & DHCPCD_INFORM) 2037 if (ifp->options->options & DHCPCD_INFORM)
2017 dhcp_inform(ifp); 2038 dhcp_inform(ifp);
2018} 2039}
2019 2040
2020 2041
2021static bool 2042static bool
2022dhcp_addr_duplicated(struct interface *ifp, struct in_addr *ia) 2043dhcp_addr_duplicated(struct interface *ifp, struct in_addr *ia)
2023{ 2044{
2024 struct dhcp_state *state = D_STATE(ifp); 2045 struct dhcp_state *state = D_STATE(ifp);
2025 unsigned long long opts = ifp->options->options; 2046 unsigned long long opts = ifp->options->options;
2026 struct dhcpcd_ctx *ctx = ifp->ctx; 2047 struct dhcpcd_ctx *ctx = ifp->ctx;
2027 bool deleted = false; 2048 bool deleted = false;
2028#ifdef IN_IFF_DUPLICATED 2049#ifdef IN_IFF_DUPLICATED
2029 struct ipv4_addr *iap; 2050 struct ipv4_addr *iap;
2030#endif 2051#endif
2031 2052
2032 if ((state->offer == NULL || state->offer->yiaddr != ia->s_addr) && 2053 if ((state->offer == NULL || state->offer->yiaddr != ia->s_addr) &&
2033 !IN_ARE_ADDR_EQUAL(ia, &state->lease.addr)) 2054 !IN_ARE_ADDR_EQUAL(ia, &state->lease.addr))
2034 return deleted; 2055 return deleted;
2035 2056
2036 /* RFC 2131 3.1.5, Client-server interaction */ 2057 /* RFC 2131 3.1.5, Client-server interaction */
2037 logerrx("%s: DAD detected %s", ifp->name, inet_ntoa(*ia)); 2058 logerrx("%s: DAD detected %s", ifp->name, inet_ntoa(*ia));
2038 dhcp_unlink(ifp->ctx, state->leasefile); 2059 dhcp_unlink(ifp->ctx, state->leasefile);
2039 if (!(opts & DHCPCD_STATIC) && !state->lease.frominfo) 2060 if (!(opts & DHCPCD_STATIC) && !state->lease.frominfo)
2040 dhcp_decline(ifp); 2061 dhcp_decline(ifp);
2041#ifdef IN_IFF_DUPLICATED 2062#ifdef IN_IFF_DUPLICATED
2042 if ((iap = ipv4_iffindaddr(ifp, ia, NULL)) != NULL) { 2063 if ((iap = ipv4_iffindaddr(ifp, ia, NULL)) != NULL) {
2043 ipv4_deladdr(iap, 0); 2064 ipv4_deladdr(iap, 0);
2044 deleted = true; 2065 deleted = true;
2045 } 2066 }
2046#endif 2067#endif
2047 eloop_timeout_delete(ctx->eloop, NULL, ifp); 2068 eloop_timeout_delete(ctx->eloop, NULL, ifp);
2048 if (opts & (DHCPCD_STATIC | DHCPCD_INFORM)) { 2069 if (opts & (DHCPCD_STATIC | DHCPCD_INFORM)) {
2049 state->reason = "EXPIRE"; 2070 state->reason = "EXPIRE";
2050 script_runreason(ifp, state->reason); 2071 script_runreason(ifp, state->reason);
2051#define NOT_ONLY_SELF (DHCPCD_MASTER | DHCPCD_IPV6RS | DHCPCD_DHCP6) 2072#define NOT_ONLY_SELF (DHCPCD_MASTER | DHCPCD_IPV6RS | DHCPCD_DHCP6)
2052 if (!(ctx->options & NOT_ONLY_SELF)) 2073 if (!(ctx->options & NOT_ONLY_SELF))
2053 eloop_exit(ifp->ctx->eloop, EXIT_FAILURE); 2074 eloop_exit(ifp->ctx->eloop, EXIT_FAILURE);
2054 return deleted; 2075 return deleted;
2055 } 2076 }
2056 eloop_timeout_add_sec(ifp->ctx->eloop, 2077 eloop_timeout_add_sec(ifp->ctx->eloop,
2057 DHCP_RAND_MAX, dhcp_discover, ifp); 2078 DHCP_RAND_MAX, dhcp_discover, ifp);
2058 return deleted; 2079 return deleted;
2059} 2080}
2060#endif 2081#endif
2061 2082
2062#ifdef ARP 2083#ifdef ARP
2063#ifdef KERNEL_RFC5227 2084#ifdef KERNEL_RFC5227
 2085#ifdef ARPING
2064static void 2086static void
2065dhcp_arp_announced(struct arp_state *state) 2087dhcp_arp_announced(struct arp_state *state)
2066{ 2088{
2067 2089
2068 arp_free(state); 2090 arp_free(state);
2069} 2091}
 2092#endif
2070#else 2093#else
2071static void 2094static void
2072dhcp_arp_defend_failed(struct arp_state *astate) 2095dhcp_arp_defend_failed(struct arp_state *astate)
2073{ 2096{
2074 struct interface *ifp = astate->iface; 2097 struct interface *ifp = astate->iface;
2075 2098
2076 dhcp_drop(ifp, "EXPIRED"); 2099 dhcp_drop(ifp, "EXPIRED");
2077 dhcp_start1(ifp); 2100 dhcp_start1(ifp);
2078} 2101}
2079#endif 2102#endif
2080 2103
2081#if !defined(KERNEL_RFC5227) || defined(ARPING) 2104#if !defined(KERNEL_RFC5227) || defined(ARPING)
2082static void dhcp_arp_not_found(struct arp_state *); 2105static void dhcp_arp_not_found(struct arp_state *);
2083 2106
2084static struct arp_state * 2107static struct arp_state *
2085dhcp_arp_new(struct interface *ifp, struct in_addr *addr) 2108dhcp_arp_new(struct interface *ifp, struct in_addr *addr)
2086{ 2109{
2087 struct arp_state *astate; 2110 struct arp_state *astate;
2088 2111
2089 astate = arp_new(ifp, addr); 2112 astate = arp_new(ifp, addr);
2090 if (astate == NULL) 2113 if (astate == NULL)
2091 return NULL; 2114 return NULL;
2092 2115
2093 astate->found_cb = dhcp_arp_found; 2116 astate->found_cb = dhcp_arp_found;
2094 astate->not_found_cb = dhcp_arp_not_found; 2117 astate->not_found_cb = dhcp_arp_not_found;
2095#ifdef KERNEL_RFC5227 2118#ifdef KERNEL_RFC5227
2096 astate->announced_cb = dhcp_arp_announced; 2119 astate->announced_cb = dhcp_arp_announced;
2097#else 2120#else
2098 astate->announced_cb = NULL; 2121 astate->announced_cb = NULL;
2099 astate->defend_failed_cb = dhcp_arp_defend_failed; 2122 astate->defend_failed_cb = dhcp_arp_defend_failed;
2100#endif 2123#endif
2101 return astate; 2124 return astate;
2102} 2125}
2103#endif 2126#endif
2104 2127
2105#ifdef ARPING 2128#ifdef ARPING
2106static int 2129static int
2107dhcp_arping(struct interface *ifp) 2130dhcp_arping(struct interface *ifp)
2108{ 2131{
2109 struct dhcp_state *state; 2132 struct dhcp_state *state;
2110 struct if_options *ifo; 2133 struct if_options *ifo;
2111 struct arp_state *astate; 2134 struct arp_state *astate;
2112 struct in_addr addr; 2135 struct in_addr addr;
2113 2136
2114 state = D_STATE(ifp); 2137 state = D_STATE(ifp);
2115 ifo = ifp->options; 2138 ifo = ifp->options;
2116 2139
2117 if (ifo->arping_len == 0 || state->arping_index > ifo->arping_len) 2140 if (ifo->arping_len == 0 || state->arping_index > ifo->arping_len)
2118 return 0; 2141 return 0;
2119 2142
2120 if (state->arping_index + 1 == ifo->arping_len) { 2143 if (state->arping_index + 1 == ifo->arping_len) {
2121 state->arping_index++; 2144 state->arping_index++;
2122 dhcpcd_startinterface(ifp); 2145 dhcpcd_startinterface(ifp);
2123 return 1; 2146 return 1;
2124 } 2147 }
2125 2148
2126 addr.s_addr = ifo->arping[++state->arping_index]; 2149 addr.s_addr = ifo->arping[++state->arping_index];
2127 astate = dhcp_arp_new(ifp, &addr); 2150 astate = dhcp_arp_new(ifp, &addr);
2128 if (astate == NULL) { 2151 if (astate == NULL) {
2129 logerr(__func__); 2152 logerr(__func__);
2130 return -1; 2153 return -1;
2131 } 2154 }
2132 arp_probe(astate); 2155 arp_probe(astate);
2133 return 1; 2156 return 1;
2134} 2157}
2135#endif 2158#endif
2136 2159
2137#if !defined(KERNEL_RFC5227) || defined(ARPING) 2160#if !defined(KERNEL_RFC5227) || defined(ARPING)
2138static void 2161static void
2139dhcp_arp_not_found(struct arp_state *astate) 2162dhcp_arp_not_found(struct arp_state *astate)
2140{ 2163{
2141 struct interface *ifp; 2164 struct interface *ifp;
2142 2165
2143 ifp = astate->iface; 2166 ifp = astate->iface;
2144#ifdef ARPING 2167#ifdef ARPING
2145 if (dhcp_arping(ifp) == 1) { 2168 if (dhcp_arping(ifp) == 1) {
2146 arp_free(astate); 2169 arp_free(astate);
2147 return; 2170 return;
2148 } 2171 }
2149#endif 2172#endif
2150 2173
2151 dhcp_finish_dad(ifp, &astate->addr); 2174 dhcp_finish_dad(ifp, &astate->addr);
2152} 2175}
2153 2176
2154static void 2177static void
2155dhcp_arp_found(struct arp_state *astate, const struct arp_msg *amsg) 2178dhcp_arp_found(struct arp_state *astate, const struct arp_msg *amsg)
2156{ 2179{
2157 struct in_addr addr; 2180 struct in_addr addr;
2158 struct interface *ifp = astate->iface; 2181 struct interface *ifp = astate->iface;
2159#ifdef ARPING 2182#ifdef ARPING
2160 struct dhcp_state *state; 2183 struct dhcp_state *state;
2161 struct if_options *ifo; 2184 struct if_options *ifo;
2162 2185
2163 state = D_STATE(ifp); 2186 state = D_STATE(ifp);
2164 2187
2165 ifo = ifp->options; 2188 ifo = ifp->options;
2166 if (state->arping_index != -1 && 2189 if (state->arping_index != -1 &&
2167 state->arping_index < ifo->arping_len && 2190 state->arping_index < ifo->arping_len &&
2168 amsg && 2191 amsg &&
2169 amsg->sip.s_addr == ifo->arping[state->arping_index]) 2192 amsg->sip.s_addr == ifo->arping[state->arping_index])
2170 { 2193 {
2171 char buf[HWADDR_LEN * 3]; 2194 char buf[HWADDR_LEN * 3];
2172 2195
2173 hwaddr_ntoa(amsg->sha, ifp->hwlen, buf, sizeof(buf)); 2196 hwaddr_ntoa(amsg->sha, ifp->hwlen, buf, sizeof(buf));
2174 if (dhcpcd_selectprofile(ifp, buf) == -1 && 2197 if (dhcpcd_selectprofile(ifp, buf) == -1 &&
2175 dhcpcd_selectprofile(ifp, inet_ntoa(amsg->sip)) == -1) 2198 dhcpcd_selectprofile(ifp, inet_ntoa(amsg->sip)) == -1)
2176 { 2199 {
2177 /* We didn't find a profile for this 2200 /* We didn't find a profile for this
2178 * address or hwaddr, so move to the next 2201 * address or hwaddr, so move to the next
2179 * arping profile */ 2202 * arping profile */
2180 dhcp_arp_not_found(astate); 2203 dhcp_arp_not_found(astate);
2181 return; 2204 return;
2182 } 2205 }
2183 arp_free(astate); 2206 arp_free(astate);
2184 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); 2207 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
2185 dhcpcd_startinterface(ifp); 2208 dhcpcd_startinterface(ifp);
2186 return; 2209 return;
2187 } 2210 }
2188#else 2211#else
2189 UNUSED(amsg); 2212 UNUSED(amsg);
2190#endif 2213#endif
2191 2214
2192 addr = astate->addr; 2215 addr = astate->addr;
2193 arp_free(astate); 2216 arp_free(astate);
2194 dhcp_addr_duplicated(ifp, &addr); 2217 dhcp_addr_duplicated(ifp, &addr);
2195} 2218}
2196#endif 2219#endif
2197 2220
2198#endif /* ARP */ 2221#endif /* ARP */
2199 2222
2200void 2223void
2201dhcp_bind(struct interface *ifp) 2224dhcp_bind(struct interface *ifp)
2202{ 2225{
2203 struct dhcpcd_ctx *ctx = ifp->ctx; 2226 struct dhcpcd_ctx *ctx = ifp->ctx;
2204 struct dhcp_state *state = D_STATE(ifp); 2227 struct dhcp_state *state = D_STATE(ifp);
2205 struct if_options *ifo = ifp->options; 2228 struct if_options *ifo = ifp->options;
2206 struct dhcp_lease *lease = &state->lease; 2229 struct dhcp_lease *lease = &state->lease;
2207 uint8_t old_state; 2230 uint8_t old_state;
2208 2231
2209 state->reason = NULL; 2232 state->reason = NULL;
2210 /* If we don't have an offer, we are re-binding a lease on preference, 2233 /* If we don't have an offer, we are re-binding a lease on preference,
2211 * normally when two interfaces have a lease matching IP addresses. */ 2234 * normally when two interfaces have a lease matching IP addresses. */
2212 if (state->offer) { 2235 if (state->offer) {
2213 free(state->old); 2236 free(state->old);
2214 state->old = state->new; 2237 state->old = state->new;
2215 state->old_len = state->new_len; 2238 state->old_len = state->new_len;
2216 state->new = state->offer; 2239 state->new = state->offer;
2217 state->new_len = state->offer_len; 2240 state->new_len = state->offer_len;
2218 state->offer = NULL; 2241 state->offer = NULL;
2219 state->offer_len = 0; 2242 state->offer_len = 0;
2220 } 2243 }
2221 get_lease(ifp, lease, state->new, state->new_len); 2244 get_lease(ifp, lease, state->new, state->new_len);
2222 if (ifo->options & DHCPCD_STATIC) { 2245 if (ifo->options & DHCPCD_STATIC) {
2223 loginfox("%s: using static address %s/%d", 2246 loginfox("%s: using static address %s/%d",
2224 ifp->name, inet_ntoa(lease->addr), 2247 ifp->name, inet_ntoa(lease->addr),
2225 inet_ntocidr(lease->mask)); 2248 inet_ntocidr(lease->mask));
2226 lease->leasetime = DHCP_INFINITE_LIFETIME; 2249 lease->leasetime = DHCP_INFINITE_LIFETIME;
2227 state->reason = "STATIC"; 2250 state->reason = "STATIC";
2228 } else if (ifo->options & DHCPCD_INFORM) { 2251 } else if (ifo->options & DHCPCD_INFORM) {
2229 loginfox("%s: received approval for %s", 2252 loginfox("%s: received approval for %s",
2230 ifp->name, inet_ntoa(lease->addr)); 2253 ifp->name, inet_ntoa(lease->addr));
2231 lease->leasetime = DHCP_INFINITE_LIFETIME; 2254 lease->leasetime = DHCP_INFINITE_LIFETIME;
2232 state->reason = "INFORM"; 2255 state->reason = "INFORM";
2233 } else { 2256 } else {
2234 if (lease->frominfo) 2257 if (lease->frominfo)
2235 state->reason = "TIMEOUT"; 2258 state->reason = "TIMEOUT";
2236 if (lease->leasetime == DHCP_INFINITE_LIFETIME) { 2259 if (lease->leasetime == DHCP_INFINITE_LIFETIME) {
2237 lease->renewaltime = 2260 lease->renewaltime =
2238 lease->rebindtime = 2261 lease->rebindtime =
2239 lease->leasetime; 2262 lease->leasetime;
2240 loginfox("%s: leased %s for infinity", 2263 loginfox("%s: leased %s for infinity",
2241 ifp->name, inet_ntoa(lease->addr)); 2264 ifp->name, inet_ntoa(lease->addr));
2242 } else { 2265 } else {
2243 if (lease->leasetime < DHCP_MIN_LEASE) { 2266 if (lease->leasetime < DHCP_MIN_LEASE) {
2244 logwarnx("%s: minimum lease is %d seconds", 2267 logwarnx("%s: minimum lease is %d seconds",
2245 ifp->name, DHCP_MIN_LEASE); 2268 ifp->name, DHCP_MIN_LEASE);
2246 lease->leasetime = DHCP_MIN_LEASE; 2269 lease->leasetime = DHCP_MIN_LEASE;
2247 } 2270 }
2248 if (lease->rebindtime == 0) 2271 if (lease->rebindtime == 0)
2249 lease->rebindtime = 2272 lease->rebindtime =
2250 (uint32_t)(lease->leasetime * T2); 2273 (uint32_t)(lease->leasetime * T2);
2251 else if (lease->rebindtime >= lease->leasetime) { 2274 else if (lease->rebindtime >= lease->leasetime) {
2252 lease->rebindtime = 2275 lease->rebindtime =
2253 (uint32_t)(lease->leasetime * T2); 2276 (uint32_t)(lease->leasetime * T2);
2254 logwarnx("%s: rebind time greater than lease " 2277 logwarnx("%s: rebind time greater than lease "
2255 "time, forcing to %"PRIu32" seconds", 2278 "time, forcing to %"PRIu32" seconds",
2256 ifp->name, lease->rebindtime); 2279 ifp->name, lease->rebindtime);
2257 } 2280 }
2258 if (lease->renewaltime == 0) 2281 if (lease->renewaltime == 0)
2259 lease->renewaltime = 2282 lease->renewaltime =
2260 (uint32_t)(lease->leasetime * T1); 2283 (uint32_t)(lease->leasetime * T1);
2261 else if (lease->renewaltime > lease->rebindtime) { 2284 else if (lease->renewaltime > lease->rebindtime) {
2262 lease->renewaltime = 2285 lease->renewaltime =
2263 (uint32_t)(lease->leasetime * T1); 2286 (uint32_t)(lease->leasetime * T1);
2264 logwarnx("%s: renewal time greater than " 2287 logwarnx("%s: renewal time greater than "
2265 "rebind time, forcing to %"PRIu32" seconds", 2288 "rebind time, forcing to %"PRIu32" seconds",
2266 ifp->name, lease->renewaltime); 2289 ifp->name, lease->renewaltime);
2267 } 2290 }
2268 if (state->state == DHS_RENEW && state->addr && 2291 if (state->state == DHS_RENEW && state->addr &&
2269 lease->addr.s_addr == state->addr->addr.s_addr && 2292 lease->addr.s_addr == state->addr->addr.s_addr &&
2270 !(state->added & STATE_FAKE)) 2293 !(state->added & STATE_FAKE))
2271 logdebugx("%s: leased %s for %"PRIu32" seconds", 2294 logdebugx("%s: leased %s for %"PRIu32" seconds",
2272 ifp->name, inet_ntoa(lease->addr), 2295 ifp->name, inet_ntoa(lease->addr),
2273 lease->leasetime); 2296 lease->leasetime);
2274 else 2297 else
2275 loginfox("%s: leased %s for %"PRIu32" seconds", 2298 loginfox("%s: leased %s for %"PRIu32" seconds",
2276 ifp->name, inet_ntoa(lease->addr), 2299 ifp->name, inet_ntoa(lease->addr),
2277 lease->leasetime); 2300 lease->leasetime);
2278 } 2301 }
2279 } 2302 }
2280 if (ctx->options & DHCPCD_TEST) { 2303 if (ctx->options & DHCPCD_TEST) {
2281 state->reason = "TEST"; 2304 state->reason = "TEST";
2282 script_runreason(ifp, state->reason); 2305 script_runreason(ifp, state->reason);
2283 eloop_exit(ctx->eloop, EXIT_SUCCESS); 2306 eloop_exit(ctx->eloop, EXIT_SUCCESS);
2284 return; 2307 return;
2285 } 2308 }
2286 if (state->reason == NULL) { 2309 if (state->reason == NULL) {
2287 if (state->old && 2310 if (state->old &&
2288 !(state->added & (STATE_FAKE | STATE_EXPIRED))) 2311 !(state->added & (STATE_FAKE | STATE_EXPIRED)))
2289 { 2312 {
2290 if (state->old->yiaddr == state->new->yiaddr && 2313 if (state->old->yiaddr == state->new->yiaddr &&
2291 lease->server.s_addr && 2314 lease->server.s_addr &&
2292 state->state != DHS_REBIND) 2315 state->state != DHS_REBIND)
2293 state->reason = "RENEW"; 2316 state->reason = "RENEW";
2294 else 2317 else
2295 state->reason = "REBIND"; 2318 state->reason = "REBIND";
2296 } else if (state->state == DHS_REBOOT) 2319 } else if (state->state == DHS_REBOOT)
2297 state->reason = "REBOOT"; 2320 state->reason = "REBOOT";
2298 else 2321 else
2299 state->reason = "BOUND"; 2322 state->reason = "BOUND";
2300 } 2323 }
2301 if (lease->leasetime == DHCP_INFINITE_LIFETIME) 2324 if (lease->leasetime == DHCP_INFINITE_LIFETIME)
2302 lease->renewaltime = lease->rebindtime = lease->leasetime; 2325 lease->renewaltime = lease->rebindtime = lease->leasetime;
2303 else { 2326 else {
2304 eloop_timeout_add_sec(ctx->eloop, 2327 eloop_timeout_add_sec(ctx->eloop,
2305 lease->renewaltime, dhcp_startrenew, ifp); 2328 lease->renewaltime, dhcp_startrenew, ifp);
2306 eloop_timeout_add_sec(ctx->eloop, 2329 eloop_timeout_add_sec(ctx->eloop,
2307 lease->rebindtime, dhcp_rebind, ifp); 2330 lease->rebindtime, dhcp_rebind, ifp);
2308 eloop_timeout_add_sec(ctx->eloop, 2331 eloop_timeout_add_sec(ctx->eloop,
2309 lease->leasetime, dhcp_expire, ifp); 2332 lease->leasetime, dhcp_expire, ifp);
2310 logdebugx("%s: renew in %"PRIu32" seconds, rebind in %"PRIu32 2333 logdebugx("%s: renew in %"PRIu32" seconds, rebind in %"PRIu32
2311 " seconds", 2334 " seconds",
2312 ifp->name, lease->renewaltime, lease->rebindtime); 2335 ifp->name, lease->renewaltime, lease->rebindtime);
2313 } 2336 }
2314 state->state = DHS_BOUND; 2337 state->state = DHS_BOUND;
2315 if (!state->lease.frominfo && 2338 if (!state->lease.frominfo &&
2316 !(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC))) { 2339 !(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC))) {
2317 logdebugx("%s: writing lease: %s", 2340 logdebugx("%s: writing lease: %s",
2318 ifp->name, state->leasefile); 2341 ifp->name, state->leasefile);
2319 if (dhcp_writefile(ifp->ctx, state->leasefile, 0640, 2342 if (dhcp_writefile(ifp->ctx, state->leasefile, 0640,
2320 state->new, state->new_len) == -1) 2343 state->new, state->new_len) == -1)
2321 logerr("dhcp_writefile: %s", state->leasefile); 2344 logerr("dhcp_writefile: %s", state->leasefile);
2322 } 2345 }
2323 2346
 2347 old_state = state->added;
 2348
2324 /* Close the BPF filter as we can now receive DHCP messages 2349 /* Close the BPF filter as we can now receive DHCP messages
2325 * on a UDP socket. */ 2350 * on a UDP socket. */
2326 old_state = state->added; 2351 dhcp_closebpf(ifp);
2327 if (ctx->options & DHCPCD_MASTER || 
2328 state->old == NULL || 
2329 state->old->yiaddr != state->new->yiaddr || old_state & STATE_FAKE) 
2330 dhcp_close(ifp); 
2331 2352
 2353 /* Add the address */
2332 ipv4_applyaddr(ifp); 2354 ipv4_applyaddr(ifp);
2333 2355
2334 /* If not in master mode, open an address specific socket. */ 2356 /* If not in master mode, open an address specific socket. */
2335 if (ctx->options & DHCPCD_MASTER || 2357 if (ctx->options & DHCPCD_MASTER ||
2336 (state->old != NULL && 2358 (state->old != NULL &&
2337 state->old->yiaddr == state->new->yiaddr && 2359 state->old->yiaddr == state->new->yiaddr &&
2338 old_state & STATE_ADDED && !(old_state & STATE_FAKE))) 2360 old_state & STATE_ADDED && !(old_state & STATE_FAKE)))
2339 return; 2361 return;
2340 2362
 2363 dhcp_closeinet(ifp);
 2364
2341#ifdef PRIVSEP 2365#ifdef PRIVSEP
2342 if (IN_PRIVSEP_SE(ctx)) { 2366 if (IN_PRIVSEP_SE(ctx)) {
2343 if (ps_inet_openbootp(state->addr) == -1) 2367 if (ps_inet_openbootp(state->addr) == -1)
2344 logerr(__func__); 2368 logerr(__func__);
2345 return; 2369 return;
2346 } 2370 }
2347#endif 2371#endif
2348 2372
2349 state->udp_rfd = dhcp_openudp(&state->addr->addr); 2373 state->udp_rfd = dhcp_openudp(&state->addr->addr);
2350 if (state->udp_rfd == -1) { 2374 if (state->udp_rfd == -1) {
2351 logerr(__func__); 2375 logerr(__func__);
2352 /* Address sharing without master mode is not supported. 2376 /* Address sharing without master mode is not supported.
2353 * It's also possible another DHCP client could be running, 2377 * It's also possible another DHCP client could be running,
2354 * which is even worse. 2378 * which is even worse.
2355 * We still need to work, so re-open BPF. */ 2379 * We still need to work, so re-open BPF. */
2356 dhcp_openbpf(ifp); 2380 dhcp_openbpf(ifp);
2357 return; 2381 return;
2358 } 2382 }
2359 eloop_event_add(ctx->eloop, state->udp_rfd, dhcp_handleifudp, ifp); 2383 eloop_event_add(ctx->eloop, state->udp_rfd, dhcp_handleifudp, ifp);
2360} 2384}
2361 2385
2362static size_t 2386static size_t
2363dhcp_message_new(struct bootp **bootp, 2387dhcp_message_new(struct bootp **bootp,
2364 const struct in_addr *addr, const struct in_addr *mask) 2388 const struct in_addr *addr, const struct in_addr *mask)
2365{ 2389{
2366 uint8_t *p; 2390 uint8_t *p;
2367 uint32_t cookie; 2391 uint32_t cookie;
2368 2392
2369 if ((*bootp = calloc(1, sizeof(**bootp))) == NULL) 2393 if ((*bootp = calloc(1, sizeof(**bootp))) == NULL)
2370 return 0; 2394 return 0;
2371 2395
2372 (*bootp)->yiaddr = addr->s_addr; 2396 (*bootp)->yiaddr = addr->s_addr;
2373 p = (*bootp)->vend; 2397 p = (*bootp)->vend;
2374 2398
2375 cookie = htonl(MAGIC_COOKIE); 2399 cookie = htonl(MAGIC_COOKIE);
2376 memcpy(p, &cookie, sizeof(cookie)); 2400 memcpy(p, &cookie, sizeof(cookie));
2377 p += sizeof(cookie); 2401 p += sizeof(cookie);
2378 2402
2379 if (mask->s_addr != INADDR_ANY) { 2403 if (mask->s_addr != INADDR_ANY) {
2380 *p++ = DHO_SUBNETMASK; 2404 *p++ = DHO_SUBNETMASK;
2381 *p++ = sizeof(mask->s_addr); 2405 *p++ = sizeof(mask->s_addr);
2382 memcpy(p, &mask->s_addr, sizeof(mask->s_addr)); 2406 memcpy(p, &mask->s_addr, sizeof(mask->s_addr));
2383 p+= sizeof(mask->s_addr); 2407 p+= sizeof(mask->s_addr);
2384 } 2408 }
2385 2409
2386 *p = DHO_END; 2410 *p = DHO_END;
2387 return sizeof(**bootp); 2411 return sizeof(**bootp);
2388} 2412}
2389 2413
2390#if defined(ARP) || defined(KERNEL_RFC5227) 2414#if defined(ARP) || defined(KERNEL_RFC5227)
2391static int 2415static int
2392dhcp_arp_address(struct interface *ifp) 2416dhcp_arp_address(struct interface *ifp)
2393{ 2417{
2394 struct dhcp_state *state; 2418 struct dhcp_state *state;
2395 struct in_addr addr; 2419 struct in_addr addr;
2396 struct ipv4_addr *ia; 2420 struct ipv4_addr *ia;
2397 2421
2398 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); 2422 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
2399 2423
2400 state = D_STATE(ifp); 2424 state = D_STATE(ifp);
2401 addr.s_addr = state->offer->yiaddr == INADDR_ANY ? 2425 addr.s_addr = state->offer->yiaddr == INADDR_ANY ?
2402 state->offer->ciaddr : state->offer->yiaddr; 2426 state->offer->ciaddr : state->offer->yiaddr;
2403 /* If the interface already has the address configured 2427 /* If the interface already has the address configured
2404 * then we can't ARP for duplicate detection. */ 2428 * then we can't ARP for duplicate detection. */
2405 ia = ipv4_iffindaddr(ifp, &addr, NULL); 2429 ia = ipv4_iffindaddr(ifp, &addr, NULL);
2406#ifdef IN_IFF_NOTUSEABLE 2430#ifdef IN_IFF_NOTUSEABLE
2407 if (ia == NULL || ia->addr_flags & IN_IFF_NOTUSEABLE) { 2431 if (ia == NULL || ia->addr_flags & IN_IFF_NOTUSEABLE) {
2408 state->state = DHS_PROBE; 2432 state->state = DHS_PROBE;
2409 if (ia == NULL) { 2433 if (ia == NULL) {
2410 struct dhcp_lease l; 2434 struct dhcp_lease l;
2411 2435
2412 get_lease(ifp, &l, state->offer, state->offer_len); 2436 get_lease(ifp, &l, state->offer, state->offer_len);
2413 /* Add the address now, let the kernel handle DAD. */ 2437 /* Add the address now, let the kernel handle DAD. */
2414 ipv4_addaddr(ifp, &l.addr, &l.mask, &l.brd, 2438 ipv4_addaddr(ifp, &l.addr, &l.mask, &l.brd,
2415 l.leasetime, l.rebindtime); 2439 l.leasetime, l.rebindtime);
2416 } else if (ia->addr_flags & IN_IFF_DUPLICATED) 2440 } else if (ia->addr_flags & IN_IFF_DUPLICATED)
2417 dhcp_addr_duplicated(ifp, &ia->addr); 2441 dhcp_addr_duplicated(ifp, &ia->addr);
2418 else 2442 else
2419 loginfox("%s: waiting for DAD on %s", 2443 loginfox("%s: waiting for DAD on %s",
2420 ifp->name, inet_ntoa(addr)); 2444 ifp->name, inet_ntoa(addr));
2421 return 0; 2445 return 0;
2422 } 2446 }
2423#else 2447#else
2424 if (!(ifp->flags & IFF_NOARP) && 2448 if (!(ifp->flags & IFF_NOARP) &&
2425 ifp->options->options & DHCPCD_ARP) 2449 ifp->options->options & DHCPCD_ARP)
2426 { 2450 {
2427 struct arp_state *astate; 2451 struct arp_state *astate;
2428 struct dhcp_lease l; 2452 struct dhcp_lease l;
2429 2453
2430 /* Even if the address exists, we need to defend it. */ 2454 /* Even if the address exists, we need to defend it. */
2431 astate = dhcp_arp_new(ifp, &addr); 2455 astate = dhcp_arp_new(ifp, &addr);
2432 if (astate == NULL) 2456 if (astate == NULL)
2433 return -1; 2457 return -1;
2434 2458
2435 if (ia == NULL) { 2459 if (ia == NULL) {
2436 state->state = DHS_PROBE; 2460 state->state = DHS_PROBE;
2437 get_lease(ifp, &l, state->offer, state->offer_len); 2461 get_lease(ifp, &l, state->offer, state->offer_len);
2438 loginfox("%s: probing address %s/%d", 2462 loginfox("%s: probing address %s/%d",
2439 ifp->name, inet_ntoa(l.addr), inet_ntocidr(l.mask)); 2463 ifp->name, inet_ntoa(l.addr), inet_ntocidr(l.mask));
2440 /* We need to handle DAD. */ 2464 /* We need to handle DAD. */
2441 arp_probe(astate); 2465 arp_probe(astate);
2442 return 0; 2466 return 0;
2443 } 2467 }
2444 } 2468 }
2445#endif 2469#endif
2446 2470
2447 return 1; 2471 return 1;
2448} 2472}
2449 2473
2450static void 2474static void
2451dhcp_arp_bind(struct interface *ifp) 2475dhcp_arp_bind(struct interface *ifp)
2452{ 2476{
2453 2477
2454 if (ifp->ctx->options & DHCPCD_TEST || 2478 if (ifp->ctx->options & DHCPCD_TEST ||
2455 dhcp_arp_address(ifp) == 1) 2479 dhcp_arp_address(ifp) == 1)
2456 dhcp_bind(ifp); 2480 dhcp_bind(ifp);
2457} 2481}
2458#endif 2482#endif
2459 2483
2460static void 2484static void
2461dhcp_lastlease(void *arg) 2485dhcp_lastlease(void *arg)
2462{ 2486{
2463 struct interface *ifp = arg; 2487 struct interface *ifp = arg;
2464 struct dhcp_state *state = D_STATE(ifp); 2488 struct dhcp_state *state = D_STATE(ifp);
2465 2489
2466 loginfox("%s: timed out contacting a DHCP server, using last lease", 2490 loginfox("%s: timed out contacting a DHCP server, using last lease",
2467 ifp->name); 2491 ifp->name);
2468#if defined(ARP) || defined(KERNEL_RFC5227) 2492#if defined(ARP) || defined(KERNEL_RFC5227)
2469 dhcp_arp_bind(ifp); 2493 dhcp_arp_bind(ifp);
2470#else 2494#else
2471 dhcp_bind(ifp); 2495 dhcp_bind(ifp);
2472#endif 2496#endif
2473 /* Set expired here because dhcp_bind() -> ipv4_addaddr() will reset 2497 /* Set expired here because dhcp_bind() -> ipv4_addaddr() will reset
2474 * state */ 2498 * state */
2475 state->added |= STATE_EXPIRED; 2499 state->added |= STATE_EXPIRED;
2476 state->interval = 0; 2500 state->interval = 0;
2477 dhcp_discover(ifp); 2501 dhcp_discover(ifp);
2478} 2502}
2479 2503
2480static void 2504static void
2481dhcp_static(struct interface *ifp) 2505dhcp_static(struct interface *ifp)
2482{ 2506{
2483 struct if_options *ifo; 2507 struct if_options *ifo;
2484 struct dhcp_state *state; 2508 struct dhcp_state *state;
2485 struct ipv4_addr *ia; 2509 struct ipv4_addr *ia;
2486 2510
2487 state = D_STATE(ifp); 2511 state = D_STATE(ifp);
2488 ifo = ifp->options; 2512 ifo = ifp->options;
2489 2513
2490 ia = NULL; 2514 ia = NULL;
2491 if (ifo->req_addr.s_addr == INADDR_ANY && 2515 if (ifo->req_addr.s_addr == INADDR_ANY &&
2492 (ia = ipv4_iffindaddr(ifp, NULL, NULL)) == NULL) 2516 (ia = ipv4_iffindaddr(ifp, NULL, NULL)) == NULL)
2493 { 2517 {
2494 loginfox("%s: waiting for 3rd party to " 2518 loginfox("%s: waiting for 3rd party to "
2495 "configure IP address", ifp->name); 2519 "configure IP address", ifp->name);
2496 state->reason = "3RDPARTY"; 2520 state->reason = "3RDPARTY";
2497 script_runreason(ifp, state->reason); 2521 script_runreason(ifp, state->reason);
2498 return; 2522 return;
2499 } 2523 }
2500 2524
2501 state->offer_len = dhcp_message_new(&state->offer, 2525 state->offer_len = dhcp_message_new(&state->offer,
2502 ia ? &ia->addr : &ifo->req_addr, 2526 ia ? &ia->addr : &ifo->req_addr,
2503 ia ? &ia->mask : &ifo->req_mask); 2527 ia ? &ia->mask : &ifo->req_mask);
2504 if (state->offer_len) 2528 if (state->offer_len)
2505#if defined(ARP) || defined(KERNEL_RFC5227) 2529#if defined(ARP) || defined(KERNEL_RFC5227)
2506 dhcp_arp_bind(ifp); 2530 dhcp_arp_bind(ifp);
2507#else 2531#else
2508 dhcp_bind(ifp); 2532 dhcp_bind(ifp);
2509#endif 2533#endif
2510} 2534}
2511 2535
2512void 2536void
2513dhcp_inform(struct interface *ifp) 2537dhcp_inform(struct interface *ifp)
2514{ 2538{
2515 struct dhcp_state *state; 2539 struct dhcp_state *state;
2516 struct if_options *ifo; 2540 struct if_options *ifo;
2517 struct ipv4_addr *ia; 2541 struct ipv4_addr *ia;
2518 2542
2519 state = D_STATE(ifp); 2543 state = D_STATE(ifp);
2520 ifo = ifp->options; 2544 ifo = ifp->options;
2521 2545
2522 state->state = DHS_INFORM; 2546 state->state = DHS_INFORM;
2523 free(state->offer); 2547 free(state->offer);
2524 state->offer = NULL; 2548 state->offer = NULL;
2525 state->offer_len = 0; 2549 state->offer_len = 0;
2526 2550
2527 if (ifo->req_addr.s_addr == INADDR_ANY) { 2551 if (ifo->req_addr.s_addr == INADDR_ANY) {
2528 ia = ipv4_iffindaddr(ifp, NULL, NULL); 2552 ia = ipv4_iffindaddr(ifp, NULL, NULL);
2529 if (ia == NULL) { 2553 if (ia == NULL) {
2530 loginfox("%s: waiting for 3rd party to " 2554 loginfox("%s: waiting for 3rd party to "
2531 "configure IP address", 2555 "configure IP address",
2532 ifp->name); 2556 ifp->name);
2533 if (!(ifp->ctx->options & DHCPCD_TEST)) { 2557 if (!(ifp->ctx->options & DHCPCD_TEST)) {
2534 state->reason = "3RDPARTY"; 2558 state->reason = "3RDPARTY";
2535 script_runreason(ifp, state->reason); 2559 script_runreason(ifp, state->reason);
2536 } 2560 }
2537 return; 2561 return;
2538 } 2562 }
2539 } else { 2563 } else {
2540 ia = ipv4_iffindaddr(ifp, &ifo->req_addr, &ifo->req_mask); 2564 ia = ipv4_iffindaddr(ifp, &ifo->req_addr, &ifo->req_mask);
2541 if (ia == NULL) { 2565 if (ia == NULL) {
2542 if (ifp->ctx->options & DHCPCD_TEST) { 2566 if (ifp->ctx->options & DHCPCD_TEST) {
2543 logerrx("%s: cannot add IP address in test mode", 2567 logerrx("%s: cannot add IP address in test mode",
2544 ifp->name); 2568 ifp->name);
2545 return; 2569 return;
2546 } 2570 }
2547 ia = ipv4_iffindaddr(ifp, &ifo->req_addr, NULL); 2571 ia = ipv4_iffindaddr(ifp, &ifo->req_addr, NULL);
2548 if (ia != NULL) 2572 if (ia != NULL)
2549 /* Netmask must be different, delete it. */ 2573 /* Netmask must be different, delete it. */
2550 ipv4_deladdr(ia, 1); 2574 ipv4_deladdr(ia, 1);
2551 state->offer_len = dhcp_message_new(&state->offer, 2575 state->offer_len = dhcp_message_new(&state->offer,
2552 &ifo->req_addr, &ifo->req_mask); 2576 &ifo->req_addr, &ifo->req_mask);
2553#ifdef ARP 2577#ifdef ARP
2554 if (dhcp_arp_address(ifp) != 1) 2578 if (dhcp_arp_address(ifp) != 1)
2555 return; 2579 return;
2556#endif 2580#endif
2557 ia = ipv4_iffindaddr(ifp, 2581 ia = ipv4_iffindaddr(ifp,
2558 &ifo->req_addr, &ifo->req_mask); 2582 &ifo->req_addr, &ifo->req_mask);
2559 assert(ia != NULL); 2583 assert(ia != NULL);
2560 } 2584 }
2561 } 2585 }
2562 2586
2563 state->addr = ia; 2587 state->addr = ia;
2564 state->offer_len = dhcp_message_new(&state->offer, 2588 state->offer_len = dhcp_message_new(&state->offer,
2565 &ia->addr, &ia->mask); 2589 &ia->addr, &ia->mask);
2566 if (state->offer_len) { 2590 if (state->offer_len) {
2567 dhcp_new_xid(ifp); 2591 dhcp_new_xid(ifp);
2568 get_lease(ifp, &state->lease, state->offer, state->offer_len); 2592 get_lease(ifp, &state->lease, state->offer, state->offer_len);
2569 send_inform(ifp); 2593 send_inform(ifp);
2570 } 2594 }
2571} 2595}
2572 2596
2573void 2597void
2574dhcp_reboot_newopts(struct interface *ifp, unsigned long long oldopts) 2598dhcp_reboot_newopts(struct interface *ifp, unsigned long long oldopts)
2575{ 2599{
2576 struct if_options *ifo; 2600 struct if_options *ifo;
2577 struct dhcp_state *state = D_STATE(ifp); 2601 struct dhcp_state *state = D_STATE(ifp);
2578 2602
2579 if (state == NULL || state->state == DHS_NONE) 2603 if (state == NULL || state->state == DHS_NONE)
2580 return; 2604 return;
2581 ifo = ifp->options; 2605 ifo = ifp->options;
2582 if ((ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC) && 2606 if ((ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC) &&
2583 (state->addr == NULL || 2607 (state->addr == NULL ||
2584 state->addr->addr.s_addr != ifo->req_addr.s_addr)) || 2608 state->addr->addr.s_addr != ifo->req_addr.s_addr)) ||
2585 (oldopts & (DHCPCD_INFORM | DHCPCD_STATIC) && 2609 (oldopts & (DHCPCD_INFORM | DHCPCD_STATIC) &&
2586 !(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC)))) 2610 !(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC))))
2587 { 2611 {
2588 dhcp_drop(ifp, "EXPIRE"); 2612 dhcp_drop(ifp, "EXPIRE");
2589 } 2613 }
2590} 2614}
2591 2615
2592#ifdef ARP 2616#ifdef ARP
2593static int 2617static int
2594dhcp_activeaddr(const struct interface *ifp, const struct in_addr *addr) 2618dhcp_activeaddr(const struct interface *ifp, const struct in_addr *addr)
2595{ 2619{
2596 const struct interface *ifp1; 2620 const struct interface *ifp1;
2597 const struct dhcp_state *state; 2621 const struct dhcp_state *state;
2598 2622
2599 TAILQ_FOREACH(ifp1, ifp->ctx->ifaces, next) { 2623 TAILQ_FOREACH(ifp1, ifp->ctx->ifaces, next) {
2600 if (ifp1 == ifp) 2624 if (ifp1 == ifp)
2601 continue; 2625 continue;
2602 if ((state = D_CSTATE(ifp1)) == NULL) 2626 if ((state = D_CSTATE(ifp1)) == NULL)
2603 continue; 2627 continue;
2604 switch(state->state) { 2628 switch(state->state) {
2605 case DHS_REBOOT: 2629 case DHS_REBOOT:
2606 case DHS_RENEW: 2630 case DHS_RENEW:
2607 case DHS_REBIND: 2631 case DHS_REBIND:
2608 case DHS_BOUND: 2632 case DHS_BOUND:
2609 case DHS_INFORM: 2633 case DHS_INFORM:
2610 break; 2634 break;
2611 default: 2635 default:
2612 continue; 2636 continue;
2613 } 2637 }
2614 if (state->lease.addr.s_addr == addr->s_addr) 2638 if (state->lease.addr.s_addr == addr->s_addr)
2615 return 1; 2639 return 1;
2616 } 2640 }
2617 return 0; 2641 return 0;
2618} 2642}
2619#endif 2643#endif
2620 2644
2621static void 2645static void
2622dhcp_reboot(struct interface *ifp) 2646dhcp_reboot(struct interface *ifp)
2623{ 2647{
2624 struct if_options *ifo; 2648 struct if_options *ifo;
2625 struct dhcp_state *state = D_STATE(ifp); 2649 struct dhcp_state *state = D_STATE(ifp);
2626#ifdef ARP 2650#ifdef ARP
2627 struct ipv4_addr *ia; 2651 struct ipv4_addr *ia;
2628#endif 2652#endif
2629 2653
2630 if (state == NULL || state->state == DHS_NONE) 2654 if (state == NULL || state->state == DHS_NONE)
2631 return; 2655 return;
2632 ifo = ifp->options; 2656 ifo = ifp->options;
2633 state->state = DHS_REBOOT; 2657 state->state = DHS_REBOOT;
2634 state->interval = 0; 2658 state->interval = 0;
2635 2659
2636 if (ifo->options & DHCPCD_LINK && !if_is_link_up(ifp)) { 2660 if (ifo->options & DHCPCD_LINK && !if_is_link_up(ifp)) {
2637 loginfox("%s: waiting for carrier", ifp->name); 2661 loginfox("%s: waiting for carrier", ifp->name);
2638 return; 2662 return;
2639 } 2663 }
2640 if (ifo->options & DHCPCD_STATIC) { 2664 if (ifo->options & DHCPCD_STATIC) {
2641 dhcp_static(ifp); 2665 dhcp_static(ifp);
2642 return; 2666 return;
2643 } 2667 }
2644 if (ifo->options & DHCPCD_INFORM) { 2668 if (ifo->options & DHCPCD_INFORM) {
2645 loginfox("%s: informing address of %s", 2669 loginfox("%s: informing address of %s",
2646 ifp->name, inet_ntoa(state->lease.addr)); 2670 ifp->name, inet_ntoa(state->lease.addr));
2647 dhcp_inform(ifp); 2671 dhcp_inform(ifp);
2648 return; 2672 return;
2649 } 2673 }
2650 if (ifo->reboot == 0 || state->offer == NULL) { 2674 if (ifo->reboot == 0 || state->offer == NULL) {
2651 dhcp_discover(ifp); 2675 dhcp_discover(ifp);
2652 return; 2676 return;
2653 } 2677 }
2654 if (!IS_DHCP(state->offer)) 2678 if (!IS_DHCP(state->offer))
2655 return; 2679 return;
2656 2680
2657 loginfox("%s: rebinding lease of %s", 2681 loginfox("%s: rebinding lease of %s",
2658 ifp->name, inet_ntoa(state->lease.addr)); 2682 ifp->name, inet_ntoa(state->lease.addr));
2659 2683
2660#ifdef ARP 2684#ifdef ARP
2661#ifndef KERNEL_RFC5227 2685#ifndef KERNEL_RFC5227
2662 /* Create the DHCP ARP state so we can defend it. */ 2686 /* Create the DHCP ARP state so we can defend it. */
2663 (void)dhcp_arp_new(ifp, &state->lease.addr); 2687 (void)dhcp_arp_new(ifp, &state->lease.addr);
2664#endif 2688#endif
2665 2689
2666 /* If the address exists on the interface and no other interface 2690 /* If the address exists on the interface and no other interface
2667 * is currently using it then announce it to ensure this 2691 * is currently using it then announce it to ensure this
2668 * interface gets the reply. */ 2692 * interface gets the reply. */
2669 ia = ipv4_iffindaddr(ifp, &state->lease.addr, NULL); 2693 ia = ipv4_iffindaddr(ifp, &state->lease.addr, NULL);
2670 if (ia != NULL && 2694 if (ia != NULL &&
2671 !(ifp->ctx->options & DHCPCD_TEST) && 2695 !(ifp->ctx->options & DHCPCD_TEST) &&
2672#ifdef IN_IFF_NOTUSEABLE 2696#ifdef IN_IFF_NOTUSEABLE
2673 !(ia->addr_flags & IN_IFF_NOTUSEABLE) && 2697 !(ia->addr_flags & IN_IFF_NOTUSEABLE) &&
2674#endif 2698#endif
2675 dhcp_activeaddr(ifp, &state->lease.addr) == 0) 2699 dhcp_activeaddr(ifp, &state->lease.addr) == 0)
2676 arp_ifannounceaddr(ifp, &state->lease.addr); 2700 arp_ifannounceaddr(ifp, &state->lease.addr);
2677#endif 2701#endif
2678 2702
2679 dhcp_new_xid(ifp); 2703 dhcp_new_xid(ifp);
2680 state->lease.server.s_addr = INADDR_ANY; 2704 state->lease.server.s_addr = INADDR_ANY;
2681 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); 2705 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
2682 2706
2683#ifdef IPV4LL 2707#ifdef IPV4LL
2684 /* Need to add this before dhcp_expire and friends. */ 2708 /* Need to add this before dhcp_expire and friends. */
2685 if (!ifo->fallback && ifo->options & DHCPCD_IPV4LL) 2709 if (!ifo->fallback && ifo->options & DHCPCD_IPV4LL)
2686 eloop_timeout_add_sec(ifp->ctx->eloop, 2710 eloop_timeout_add_sec(ifp->ctx->eloop,
2687 ifo->reboot, ipv4ll_start, ifp); 2711 ifo->reboot, ipv4ll_start, ifp);
2688#endif 2712#endif
2689 2713
2690 if (ifo->options & DHCPCD_LASTLEASE && state->lease.frominfo) 2714 if (ifo->options & DHCPCD_LASTLEASE && state->lease.frominfo)
2691 eloop_timeout_add_sec(ifp->ctx->eloop, 2715 eloop_timeout_add_sec(ifp->ctx->eloop,
2692 ifo->reboot, dhcp_lastlease, ifp); 2716 ifo->reboot, dhcp_lastlease, ifp);
2693 else if (!(ifo->options & DHCPCD_INFORM)) 2717 else if (!(ifo->options & DHCPCD_INFORM))
2694 eloop_timeout_add_sec(ifp->ctx->eloop, 2718 eloop_timeout_add_sec(ifp->ctx->eloop,
2695 ifo->reboot, dhcp_expire, ifp); 2719 ifo->reboot, dhcp_expire, ifp);
2696 2720
2697 /* Don't bother ARP checking as the server could NAK us first. 2721 /* Don't bother ARP checking as the server could NAK us first.
2698 * Don't call dhcp_request as that would change the state */ 2722 * Don't call dhcp_request as that would change the state */
2699 send_request(ifp); 2723 send_request(ifp);
2700} 2724}
2701 2725
2702void 2726void
2703dhcp_drop(struct interface *ifp, const char *reason) 2727dhcp_drop(struct interface *ifp, const char *reason)
2704{ 2728{
2705 struct dhcp_state *state; 2729 struct dhcp_state *state;
2706#ifdef RELEASE_SLOW 2730#ifdef RELEASE_SLOW
2707 struct timespec ts; 2731 struct timespec ts;
2708#endif 2732#endif
2709 2733
2710 state = D_STATE(ifp); 2734 state = D_STATE(ifp);
2711 /* dhcp_start may just have been called and we don't yet have a state 2735 /* dhcp_start may just have been called and we don't yet have a state
2712 * but we do have a timeout, so punt it. */ 2736 * but we do have a timeout, so punt it. */
2713 if (state == NULL || state->state == DHS_NONE) { 2737 if (state == NULL || state->state == DHS_NONE) {
2714 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); 2738 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
2715 return; 2739 return;
2716 } 2740 }
2717 2741
2718#ifdef ARP 2742#ifdef ARP
2719 if (state->addr != NULL) 2743 if (state->addr != NULL)
2720 arp_freeaddr(ifp, &state->addr->addr); 2744 arp_freeaddr(ifp, &state->addr->addr);
2721#endif 2745#endif
2722#ifdef ARPING 2746#ifdef ARPING
2723 state->arping_index = -1; 2747 state->arping_index = -1;
2724#endif 2748#endif
2725 2749
2726 if (ifp->options->options & DHCPCD_RELEASE && 2750 if (ifp->options->options & DHCPCD_RELEASE &&
2727 !(ifp->options->options & DHCPCD_INFORM)) 2751 !(ifp->options->options & DHCPCD_INFORM))
2728 { 2752 {
2729 /* Failure to send the release may cause this function to 2753 /* Failure to send the release may cause this function to
2730 * re-enter so guard by setting the state. */ 2754 * re-enter so guard by setting the state. */
2731 if (state->state == DHS_RELEASE) 2755 if (state->state == DHS_RELEASE)
2732 return; 2756 return;
2733 state->state = DHS_RELEASE; 2757 state->state = DHS_RELEASE;
2734 2758
2735 dhcp_unlink(ifp->ctx, state->leasefile); 2759 dhcp_unlink(ifp->ctx, state->leasefile);
2736 if (if_is_link_up(ifp) && 2760 if (if_is_link_up(ifp) &&
2737 state->new != NULL && 2761 state->new != NULL &&
2738 state->lease.server.s_addr != INADDR_ANY) 2762 state->lease.server.s_addr != INADDR_ANY)
2739 { 2763 {
2740 loginfox("%s: releasing lease of %s", 2764 loginfox("%s: releasing lease of %s",
2741 ifp->name, inet_ntoa(state->lease.addr)); 2765 ifp->name, inet_ntoa(state->lease.addr));
2742 dhcp_new_xid(ifp); 2766 dhcp_new_xid(ifp);
2743 send_message(ifp, DHCP_RELEASE, NULL); 2767 send_message(ifp, DHCP_RELEASE, NULL);
2744#ifdef RELEASE_SLOW 2768#ifdef RELEASE_SLOW
2745 /* Give the packet a chance to go */ 2769 /* Give the packet a chance to go */
2746 ts.tv_sec = RELEASE_DELAY_S; 2770 ts.tv_sec = RELEASE_DELAY_S;
2747 ts.tv_nsec = RELEASE_DELAY_NS; 2771 ts.tv_nsec = RELEASE_DELAY_NS;
2748 nanosleep(&ts, NULL); 2772 nanosleep(&ts, NULL);
2749#endif 2773#endif
2750 } 2774 }
2751 } 2775 }
2752#ifdef AUTH 2776#ifdef AUTH
2753 else if (state->auth.reconf != NULL) { 2777 else if (state->auth.reconf != NULL) {
2754 /* 2778 /*
2755 * Drop the lease as the token may only be present 2779 * Drop the lease as the token may only be present
2756 * in the initial reply message and not subsequent 2780 * in the initial reply message and not subsequent
2757 * renewals. 2781 * renewals.
2758 * If dhcpcd is restarted, the token is lost. 2782 * If dhcpcd is restarted, the token is lost.
2759 * XXX persist this in another file? 2783 * XXX persist this in another file?
2760 */ 2784 */
2761 dhcp_unlink(ifp->ctx, state->leasefile); 2785 dhcp_unlink(ifp->ctx, state->leasefile);
2762 } 2786 }
2763#endif 2787#endif
2764 2788
2765 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); 2789 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
2766#ifdef AUTH 2790#ifdef AUTH
2767 dhcp_auth_reset(&state->auth); 2791 dhcp_auth_reset(&state->auth);
2768#endif 2792#endif
2769 2793
2770 /* Close DHCP ports so a changed interface family is picked 2794 /* Close DHCP ports so a changed interface family is picked
2771 * up by a new BPF state. */ 2795 * up by a new BPF state. */
2772 dhcp_close(ifp); 2796 dhcp_close(ifp);
2773 2797
2774 state->state = DHS_NONE; 2798 state->state = DHS_NONE;
2775 free(state->offer); 2799 free(state->offer);
2776 state->offer = NULL; 2800 state->offer = NULL;
2777 state->offer_len = 0; 2801 state->offer_len = 0;
2778 free(state->old); 2802 free(state->old);
2779 state->old = state->new; 2803 state->old = state->new;
2780 state->old_len = state->new_len; 2804 state->old_len = state->new_len;
2781 state->new = NULL; 2805 state->new = NULL;
2782 state->new_len = 0; 2806 state->new_len = 0;
2783 state->reason = reason; 2807 state->reason = reason;
2784 ipv4_applyaddr(ifp); 2808 ipv4_applyaddr(ifp);
2785 free(state->old); 2809 free(state->old);
2786 state->old = NULL; 2810 state->old = NULL;
2787 state->old_len = 0; 2811 state->old_len = 0;
2788 state->lease.addr.s_addr = 0; 2812 state->lease.addr.s_addr = 0;
2789 ifp->options->options &= ~(DHCPCD_CSR_WARNED | 2813 ifp->options->options &= ~(DHCPCD_CSR_WARNED |
2790 DHCPCD_ROUTER_HOST_ROUTE_WARNED); 2814 DHCPCD_ROUTER_HOST_ROUTE_WARNED);
2791} 2815}
2792 2816
2793static int 2817static int
2794blacklisted_ip(const struct if_options *ifo, in_addr_t addr) 2818blacklisted_ip(const struct if_options *ifo, in_addr_t addr)
2795{ 2819{
2796 size_t i; 2820 size_t i;
2797 2821
2798 for (i = 0; i < ifo->blacklist_len; i += 2) 2822 for (i = 0; i < ifo->blacklist_len; i += 2)
2799 if (ifo->blacklist[i] == (addr & ifo->blacklist[i + 1])) 2823 if (ifo->blacklist[i] == (addr & ifo->blacklist[i + 1]))
2800 return 1; 2824 return 1;
2801 return 0; 2825 return 0;
2802} 2826}
2803 2827
2804#define WHTLST_NONE 0 2828#define WHTLST_NONE 0
2805#define WHTLST_MATCH 1 2829#define WHTLST_MATCH 1
2806#define WHTLST_NOMATCH 2 2830#define WHTLST_NOMATCH 2
2807static unsigned int 2831static unsigned int
2808whitelisted_ip(const struct if_options *ifo, in_addr_t addr) 2832whitelisted_ip(const struct if_options *ifo, in_addr_t addr)
2809{ 2833{
2810 size_t i; 2834 size_t i;
2811 2835
2812 if (ifo->whitelist_len == 0) 2836 if (ifo->whitelist_len == 0)
2813 return WHTLST_NONE; 2837 return WHTLST_NONE;
2814 for (i = 0; i < ifo->whitelist_len; i += 2) 2838 for (i = 0; i < ifo->whitelist_len; i += 2)
2815 if (ifo->whitelist[i] == (addr & ifo->whitelist[i + 1])) 2839 if (ifo->whitelist[i] == (addr & ifo->whitelist[i + 1]))
2816 return WHTLST_MATCH; 2840 return WHTLST_MATCH;
2817 return WHTLST_NOMATCH; 2841 return WHTLST_NOMATCH;
2818} 2842}
2819 2843
2820static void 2844static void
2821log_dhcp(int loglevel, const char *msg, 2845log_dhcp(int loglevel, const char *msg,
2822 const struct interface *ifp, const struct bootp *bootp, size_t bootp_len, 2846 const struct interface *ifp, const struct bootp *bootp, size_t bootp_len,
2823 const struct in_addr *from, int ad) 2847 const struct in_addr *from, int ad)
2824{ 2848{
2825 const char *tfrom; 2849 const char *tfrom;
2826 char *a, sname[sizeof(bootp->sname) * 4]; 2850 char *a, sname[sizeof(bootp->sname) * 4];
2827 struct in_addr addr; 2851 struct in_addr addr;
2828 int r; 2852 int r;
2829 uint8_t overl; 2853 uint8_t overl;
2830 2854
2831 if (strcmp(msg, "NAK:") == 0) { 2855 if (strcmp(msg, "NAK:") == 0) {
2832 a = get_option_string(ifp->ctx, bootp, bootp_len, DHO_MESSAGE); 2856 a = get_option_string(ifp->ctx, bootp, bootp_len, DHO_MESSAGE);
2833 if (a) { 2857 if (a) {
2834 char *tmp; 2858 char *tmp;
2835 size_t al, tmpl; 2859 size_t al, tmpl;
2836 2860
2837 al = strlen(a); 2861 al = strlen(a);
2838 tmpl = (al * 4) + 1; 2862 tmpl = (al * 4) + 1;
2839 tmp = malloc(tmpl); 2863 tmp = malloc(tmpl);
2840 if (tmp == NULL) { 2864 if (tmp == NULL) {
2841 logerr(__func__); 2865 logerr(__func__);
2842 free(a); 2866 free(a);
2843 return; 2867 return;
2844 } 2868 }
2845 print_string(tmp, tmpl, OT_STRING, (uint8_t *)a, al); 2869 print_string(tmp, tmpl, OT_STRING, (uint8_t *)a, al);
2846 free(a); 2870 free(a);
2847 a = tmp; 2871 a = tmp;
2848 } 2872 }
2849 } else if (ad && bootp->yiaddr != 0) { 2873 } else if (ad && bootp->yiaddr != 0) {
2850 addr.s_addr = bootp->yiaddr; 2874 addr.s_addr = bootp->yiaddr;
2851 a = strdup(inet_ntoa(addr)); 2875 a = strdup(inet_ntoa(addr));
2852 if (a == NULL) { 2876 if (a == NULL) {
2853 logerr(__func__); 2877 logerr(__func__);
2854 return; 2878 return;
2855 } 2879 }
2856 } else 2880 } else
2857 a = NULL; 2881 a = NULL;
2858 2882
2859 tfrom = "from"; 2883 tfrom = "from";
2860 r = get_option_addr(ifp->ctx, &addr, bootp, bootp_len, DHO_SERVERID); 2884 r = get_option_addr(ifp->ctx, &addr, bootp, bootp_len, DHO_SERVERID);
2861 if (get_option_uint8(ifp->ctx, &overl, bootp, bootp_len, 2885 if (get_option_uint8(ifp->ctx, &overl, bootp, bootp_len,
2862 DHO_OPTSOVERLOADED) == -1) 2886 DHO_OPTSOVERLOADED) == -1)
2863 overl = 0; 2887 overl = 0;
2864 if (bootp->sname[0] && r == 0 && !(overl & 2)) { 2888 if (bootp->sname[0] && r == 0 && !(overl & 2)) {
2865 print_string(sname, sizeof(sname), OT_STRING | OT_DOMAIN, 2889 print_string(sname, sizeof(sname), OT_STRING | OT_DOMAIN,
2866 bootp->sname, sizeof(bootp->sname)); 2890 bootp->sname, sizeof(bootp->sname));
2867 if (a == NULL) 2891 if (a == NULL)
2868 logmessage(loglevel, "%s: %s %s %s %s", 2892 logmessage(loglevel, "%s: %s %s %s %s",
2869 ifp->name, msg, tfrom, inet_ntoa(addr), sname); 2893 ifp->name, msg, tfrom, inet_ntoa(addr), sname);
2870 else 2894 else
2871 logmessage(loglevel, "%s: %s %s %s %s %s", 2895 logmessage(loglevel, "%s: %s %s %s %s %s",
2872 ifp->name, msg, a, tfrom, inet_ntoa(addr), sname); 2896 ifp->name, msg, a, tfrom, inet_ntoa(addr), sname);
2873 } else { 2897 } else {
2874 if (r != 0) { 2898 if (r != 0) {
2875 tfrom = "via"; 2899 tfrom = "via";
2876 addr = *from; 2900 addr = *from;
2877 } 2901 }
2878 if (a == NULL) 2902 if (a == NULL)
2879 logmessage(loglevel, "%s: %s %s %s", 2903 logmessage(loglevel, "%s: %s %s %s",
2880 ifp->name, msg, tfrom, inet_ntoa(addr)); 2904 ifp->name, msg, tfrom, inet_ntoa(addr));
2881 else 2905 else
2882 logmessage(loglevel, "%s: %s %s %s %s", 2906 logmessage(loglevel, "%s: %s %s %s %s",
2883 ifp->name, msg, a, tfrom, inet_ntoa(addr)); 2907 ifp->name, msg, a, tfrom, inet_ntoa(addr));
2884 } 2908 }
2885 free(a); 2909 free(a);
2886} 2910}
2887 2911
2888/* If we're sharing the same IP address with another interface on the 2912/* If we're sharing the same IP address with another interface on the
2889 * same network, we may receive the DHCP reply on the wrong interface. 2913 * same network, we may receive the DHCP reply on the wrong interface.
2890 * Try and re-direct it here. */ 2914 * Try and re-direct it here. */
2891static void 2915static void
2892dhcp_redirect_dhcp(struct interface *ifp, struct bootp *bootp, size_t bootp_len, 2916dhcp_redirect_dhcp(struct interface *ifp, struct bootp *bootp, size_t bootp_len,
2893 const struct in_addr *from) 2917 const struct in_addr *from)
2894{ 2918{
2895 struct interface *ifn; 2919 struct interface *ifn;
2896 const struct dhcp_state *state; 2920 const struct dhcp_state *state;
2897 uint32_t xid; 2921 uint32_t xid;
2898 2922
2899 xid = ntohl(bootp->xid); 2923 xid = ntohl(bootp->xid);
2900 TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) { 2924 TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) {
2901 if (ifn == ifp) 2925 if (ifn == ifp)
2902 continue; 2926 continue;
2903 state = D_CSTATE(ifn); 2927 state = D_CSTATE(ifn);
2904 if (state == NULL || state->state == DHS_NONE) 2928 if (state == NULL || state->state == DHS_NONE)
2905 continue; 2929 continue;
2906 if (state->xid != xid) 2930 if (state->xid != xid)
2907 continue; 2931 continue;
2908 if (ifn->hwlen <= sizeof(bootp->chaddr) && 2932 if (ifn->hwlen <= sizeof(bootp->chaddr) &&
2909 memcmp(bootp->chaddr, ifn->hwaddr, ifn->hwlen)) 2933 memcmp(bootp->chaddr, ifn->hwaddr, ifn->hwlen))
2910 continue; 2934 continue;
2911 logdebugx("%s: redirecting DHCP message to %s", 2935 logdebugx("%s: redirecting DHCP message to %s",
2912 ifp->name, ifn->name); 2936 ifp->name, ifn->name);
2913 dhcp_handledhcp(ifn, bootp, bootp_len, from); 2937 dhcp_handledhcp(ifn, bootp, bootp_len, from);
2914 } 2938 }
2915} 2939}
2916 2940
2917static void 2941static void
2918dhcp_handledhcp(struct interface *ifp, struct bootp *bootp, size_t bootp_len, 2942dhcp_handledhcp(struct interface *ifp, struct bootp *bootp, size_t bootp_len,
2919 const struct in_addr *from) 2943 const struct in_addr *from)
2920{ 2944{
2921 struct dhcp_state *state = D_STATE(ifp); 2945 struct dhcp_state *state = D_STATE(ifp);
2922 struct if_options *ifo = ifp->options; 2946 struct if_options *ifo = ifp->options;
2923 struct dhcp_lease *lease = &state->lease; 2947 struct dhcp_lease *lease = &state->lease;
2924 uint8_t type, tmp; 2948 uint8_t type, tmp;
2925 struct in_addr addr; 2949 struct in_addr addr;
2926 unsigned int i; 2950 unsigned int i;
2927 char *msg; 2951 char *msg;
2928 bool bootp_copied; 2952 bool bootp_copied;
 2953 uint32_t v6only_time = 0;
 2954 bool use_v6only = false;
2929#ifdef AUTH 2955#ifdef AUTH
2930 const uint8_t *auth; 2956 const uint8_t *auth;
2931 size_t auth_len; 2957 size_t auth_len;
2932#endif 2958#endif
2933#ifdef IN_IFF_DUPLICATED 2959#ifdef IN_IFF_DUPLICATED
2934 struct ipv4_addr *ia; 2960 struct ipv4_addr *ia;
2935#endif 2961#endif
2936 2962
2937#define LOGDHCP0(l, m) \ 2963#define LOGDHCP0(l, m) \
2938 log_dhcp((l), (m), ifp, bootp, bootp_len, from, 0) 2964 log_dhcp((l), (m), ifp, bootp, bootp_len, from, 0)
2939#define LOGDHCP(l, m) \ 2965#define LOGDHCP(l, m) \
2940 log_dhcp((l), (m), ifp, bootp, bootp_len, from, 1) 2966 log_dhcp((l), (m), ifp, bootp, bootp_len, from, 1)
2941 2967
2942#define IS_STATE_ACTIVE(s) ((s)-state != DHS_NONE && \ 2968#define IS_STATE_ACTIVE(s) ((s)-state != DHS_NONE && \
2943 (s)->state != DHS_INIT && (s)->state != DHS_BOUND) 2969 (s)->state != DHS_INIT && (s)->state != DHS_BOUND)
2944 2970
2945 if (bootp->op != BOOTREPLY) { 2971 if (bootp->op != BOOTREPLY) {
2946 if (IS_STATE_ACTIVE(state)) 2972 if (IS_STATE_ACTIVE(state))
2947 logdebugx("%s: op (%d) is not BOOTREPLY", 2973 logdebugx("%s: op (%d) is not BOOTREPLY",
2948 ifp->name, bootp->op); 2974 ifp->name, bootp->op);
2949 return; 2975 return;
2950 } 2976 }
2951 2977
2952 if (state->xid != ntohl(bootp->xid)) { 2978 if (state->xid != ntohl(bootp->xid)) {
2953 if (IS_STATE_ACTIVE(state)) 2979 if (IS_STATE_ACTIVE(state))
2954 logdebugx("%s: wrong xid 0x%x (expecting 0x%x) from %s", 2980 logdebugx("%s: wrong xid 0x%x (expecting 0x%x) from %s",
2955 ifp->name, ntohl(bootp->xid), state->xid, 2981 ifp->name, ntohl(bootp->xid), state->xid,
2956 inet_ntoa(*from)); 2982 inet_ntoa(*from));
2957 dhcp_redirect_dhcp(ifp, bootp, bootp_len, from); 2983 dhcp_redirect_dhcp(ifp, bootp, bootp_len, from);
2958 return; 2984 return;
2959 } 2985 }
2960 2986
2961 if (ifp->hwlen <= sizeof(bootp->chaddr) && 2987 if (ifp->hwlen <= sizeof(bootp->chaddr) &&
2962 memcmp(bootp->chaddr, ifp->hwaddr, ifp->hwlen)) 2988 memcmp(bootp->chaddr, ifp->hwaddr, ifp->hwlen))
2963 { 2989 {
2964 if (IS_STATE_ACTIVE(state)) { 2990 if (IS_STATE_ACTIVE(state)) {
2965 char buf[sizeof(bootp->chaddr) * 3]; 2991 char buf[sizeof(bootp->chaddr) * 3];
2966 2992
2967 logdebugx("%s: xid 0x%x is for hwaddr %s", 2993 logdebugx("%s: xid 0x%x is for hwaddr %s",
2968 ifp->name, ntohl(bootp->xid), 2994 ifp->name, ntohl(bootp->xid),
2969 hwaddr_ntoa(bootp->chaddr, sizeof(bootp->chaddr), 2995 hwaddr_ntoa(bootp->chaddr, sizeof(bootp->chaddr),
2970 buf, sizeof(buf))); 2996 buf, sizeof(buf)));
2971 } 2997 }
2972 dhcp_redirect_dhcp(ifp, bootp, bootp_len, from); 2998 dhcp_redirect_dhcp(ifp, bootp, bootp_len, from);
2973 return; 2999 return;
2974 } 3000 }
2975 3001
2976 if (!ifp->active) 3002 if (!ifp->active)
2977 return; 3003 return;
2978 3004
2979 i = whitelisted_ip(ifp->options, from->s_addr); 3005 i = whitelisted_ip(ifp->options, from->s_addr);
2980 switch (i) { 3006 switch (i) {
2981 case WHTLST_NOMATCH: 3007 case WHTLST_NOMATCH:
2982 logwarnx("%s: non whitelisted DHCP packet from %s", 3008 logwarnx("%s: non whitelisted DHCP packet from %s",
2983 ifp->name, inet_ntoa(*from)); 3009 ifp->name, inet_ntoa(*from));
2984 return; 3010 return;
2985 case WHTLST_MATCH: 3011 case WHTLST_MATCH:
2986 break; 3012 break;
2987 case WHTLST_NONE: 3013 case WHTLST_NONE:
2988 if (blacklisted_ip(ifp->options, from->s_addr) == 1) { 3014 if (blacklisted_ip(ifp->options, from->s_addr) == 1) {
2989 logwarnx("%s: blacklisted DHCP packet from %s", 3015 logwarnx("%s: blacklisted DHCP packet from %s",
2990 ifp->name, inet_ntoa(*from)); 3016 ifp->name, inet_ntoa(*from));
2991 return; 3017 return;
2992 } 3018 }
2993 } 3019 }
2994 3020
2995 /* We may have found a BOOTP server */ 3021 /* We may have found a BOOTP server */
2996 if (get_option_uint8(ifp->ctx, &type, 3022 if (get_option_uint8(ifp->ctx, &type,
2997 bootp, bootp_len, DHO_MESSAGETYPE) == -1) 3023 bootp, bootp_len, DHO_MESSAGETYPE) == -1)
2998 type = 0; 3024 type = 0;
2999 else if (ifo->options & DHCPCD_BOOTP) { 3025 else if (ifo->options & DHCPCD_BOOTP) {
3000 logdebugx("%s: ignoring DHCP reply (expecting BOOTP)", 3026 logdebugx("%s: ignoring DHCP reply (expecting BOOTP)",
3001 ifp->name); 3027 ifp->name);
3002 return; 3028 return;
3003 } 3029 }
3004 3030
3005#ifdef AUTH 3031#ifdef AUTH
3006 /* Authenticate the message */ 3032 /* Authenticate the message */
3007 auth = get_option(ifp->ctx, bootp, bootp_len, 3033 auth = get_option(ifp->ctx, bootp, bootp_len,
3008 DHO_AUTHENTICATION, &auth_len); 3034 DHO_AUTHENTICATION, &auth_len);
3009 if (auth) { 3035 if (auth) {
3010 if (dhcp_auth_validate(&state->auth, &ifo->auth, 3036 if (dhcp_auth_validate(&state->auth, &ifo->auth,
3011 (uint8_t *)bootp, bootp_len, 4, type, 3037 (uint8_t *)bootp, bootp_len, 4, type,
3012 auth, auth_len) == NULL) 3038 auth, auth_len) == NULL)
3013 { 3039 {
3014 LOGDHCP0(LOG_ERR, "authentication failed"); 3040 LOGDHCP0(LOG_ERR, "authentication failed");
3015 return; 3041 return;
3016 } 3042 }
3017 if (state->auth.token) 3043 if (state->auth.token)
3018 logdebugx("%s: validated using 0x%08" PRIu32, 3044 logdebugx("%s: validated using 0x%08" PRIu32,
3019 ifp->name, state->auth.token->secretid); 3045 ifp->name, state->auth.token->secretid);
3020 else 3046 else
3021 loginfox("%s: accepted reconfigure key", ifp->name); 3047 loginfox("%s: accepted reconfigure key", ifp->name);
3022 } else if (ifo->auth.options & DHCPCD_AUTH_SEND) { 3048 } else if (ifo->auth.options & DHCPCD_AUTH_SEND) {
3023 if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) { 3049 if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) {
3024 LOGDHCP0(LOG_ERR, "no authentication"); 3050 LOGDHCP0(LOG_ERR, "no authentication");
3025 return; 3051 return;
3026 } 3052 }
3027 LOGDHCP0(LOG_WARNING, "no authentication"); 3053 LOGDHCP0(LOG_WARNING, "no authentication");
3028 } 3054 }
3029#endif 3055#endif
3030 3056
3031 /* RFC 3203 */ 3057 /* RFC 3203 */
3032 if (type == DHCP_FORCERENEW) { 3058 if (type == DHCP_FORCERENEW) {
3033 if (from->s_addr == INADDR_ANY || 3059 if (from->s_addr == INADDR_ANY ||
3034 from->s_addr == INADDR_BROADCAST) 3060 from->s_addr == INADDR_BROADCAST)
3035 { 3061 {
3036 LOGDHCP(LOG_ERR, "discarding Force Renew"); 3062 LOGDHCP(LOG_ERR, "discarding Force Renew");
3037 return; 3063 return;
3038 } 3064 }
3039#ifdef AUTH 3065#ifdef AUTH
3040 if (auth == NULL) { 3066 if (auth == NULL) {
3041 LOGDHCP(LOG_ERR, "unauthenticated Force Renew"); 3067 LOGDHCP(LOG_ERR, "unauthenticated Force Renew");
3042 if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) 3068 if (ifo->auth.options & DHCPCD_AUTH_REQUIRE)
3043 return; 3069 return;
3044 } 3070 }
3045 if (state->state != DHS_BOUND && state->state != DHS_INFORM) { 3071 if (state->state != DHS_BOUND && state->state != DHS_INFORM) {
3046 LOGDHCP(LOG_DEBUG, "not bound, ignoring Force Renew"); 3072 LOGDHCP(LOG_DEBUG, "not bound, ignoring Force Renew");
3047 return; 3073 return;
3048 } 3074 }
3049 LOGDHCP(LOG_INFO, "Force Renew from"); 3075 LOGDHCP(LOG_INFO, "Force Renew from");
3050 /* The rebind and expire timings are still the same, we just 3076 /* The rebind and expire timings are still the same, we just
3051 * enter the renew state early */ 3077 * enter the renew state early */
3052 if (state->state == DHS_BOUND) 3078 if (state->state == DHS_BOUND)
3053 dhcp_renew(ifp); 3079 dhcp_renew(ifp);
3054 else { 3080 else {
3055 eloop_timeout_delete(ifp->ctx->eloop, 3081 eloop_timeout_delete(ifp->ctx->eloop,
3056 send_inform, ifp); 3082 send_inform, ifp);
3057 dhcp_inform(ifp); 3083 dhcp_inform(ifp);
3058 } 3084 }
3059#else 3085#else
3060 LOGDHCP(LOG_ERR, "unauthenticated Force Renew"); 3086 LOGDHCP(LOG_ERR, "unauthenticated Force Renew");
3061#endif 3087#endif
3062 return; 3088 return;
3063 } 3089 }
3064 3090
3065 if (state->state == DHS_BOUND) { 3091 if (state->state == DHS_BOUND) {
3066 LOGDHCP(LOG_DEBUG, "bound, ignoring"); 3092 LOGDHCP(LOG_DEBUG, "bound, ignoring");
3067 return; 3093 return;
3068 } 3094 }
3069 3095
3070 if (state->state == DHS_PROBE) { 3096 if (state->state == DHS_PROBE) {
3071 /* Ignore any DHCP messages whilst probing a lease to bind. */ 3097 /* Ignore any DHCP messages whilst probing a lease to bind. */
3072 LOGDHCP(LOG_DEBUG, "probing, ignoring"); 3098 LOGDHCP(LOG_DEBUG, "probing, ignoring");
3073 return; 3099 return;
3074 } 3100 }
3075 3101
3076 /* reset the message counter */ 3102 /* reset the message counter */
3077 state->interval = 0; 3103 state->interval = 0;
3078 3104
3079 /* Ensure that no reject options are present */ 3105 /* Ensure that no reject options are present */
3080 for (i = 1; i < 255; i++) { 3106 for (i = 1; i < 255; i++) {
3081 if (has_option_mask(ifo->rejectmask, i) && 3107 if (has_option_mask(ifo->rejectmask, i) &&
3082 get_option_uint8(ifp->ctx, &tmp, 3108 get_option_uint8(ifp->ctx, &tmp,
3083 bootp, bootp_len, (uint8_t)i) == 0) 3109 bootp, bootp_len, (uint8_t)i) == 0)
3084 { 3110 {
3085 LOGDHCP(LOG_WARNING, "reject DHCP"); 3111 LOGDHCP(LOG_WARNING, "reject DHCP");
3086 return; 3112 return;
3087 } 3113 }
3088 } 3114 }
3089 3115
3090 if (type == DHCP_NAK) { 3116 if (type == DHCP_NAK) {
3091 /* For NAK, only check if we require the ServerID */ 3117 /* For NAK, only check if we require the ServerID */
3092 if (has_option_mask(ifo->requiremask, DHO_SERVERID) && 3118 if (has_option_mask(ifo->requiremask, DHO_SERVERID) &&
3093 get_option_addr(ifp->ctx, &addr, 3119 get_option_addr(ifp->ctx, &addr,
3094 bootp, bootp_len, DHO_SERVERID) == -1) 3120 bootp, bootp_len, DHO_SERVERID) == -1)
3095 { 3121 {
3096 LOGDHCP(LOG_WARNING, "reject NAK"); 3122 LOGDHCP(LOG_WARNING, "reject NAK");
3097 return; 3123 return;
3098 } 3124 }
3099 3125
3100 /* We should restart on a NAK */ 3126 /* We should restart on a NAK */
3101 LOGDHCP(LOG_WARNING, "NAK:"); 3127 LOGDHCP(LOG_WARNING, "NAK:");
3102 if ((msg = get_option_string(ifp->ctx, 3128 if ((msg = get_option_string(ifp->ctx,
3103 bootp, bootp_len, DHO_MESSAGE))) 3129 bootp, bootp_len, DHO_MESSAGE)))
3104 { 3130 {
3105 logwarnx("%s: message: %s", ifp->name, msg); 3131 logwarnx("%s: message: %s", ifp->name, msg);
3106 free(msg); 3132 free(msg);
3107 } 3133 }
3108 if (state->state == DHS_INFORM) /* INFORM should not be NAKed */ 3134 if (state->state == DHS_INFORM) /* INFORM should not be NAKed */
3109 return; 3135 return;
3110 if (!(ifp->ctx->options & DHCPCD_TEST)) { 3136 if (!(ifp->ctx->options & DHCPCD_TEST)) {
3111 dhcp_drop(ifp, "NAK"); 3137 dhcp_drop(ifp, "NAK");
3112 dhcp_unlink(ifp->ctx, state->leasefile); 3138 dhcp_unlink(ifp->ctx, state->leasefile);
3113 } 3139 }
3114 3140
3115 /* If we constantly get NAKS then we should slowly back off */ 3141 /* If we constantly get NAKS then we should slowly back off */
3116 eloop_timeout_add_sec(ifp->ctx->eloop, 3142 eloop_timeout_add_sec(ifp->ctx->eloop,
3117 state->nakoff, dhcp_discover, ifp); 3143 state->nakoff, dhcp_discover, ifp);
3118 if (state->nakoff == 0) 3144 if (state->nakoff == 0)
3119 state->nakoff = 1; 3145 state->nakoff = 1;
3120 else { 3146 else {
3121 state->nakoff *= 2; 3147 state->nakoff *= 2;
3122 if (state->nakoff > NAKOFF_MAX) 3148 if (state->nakoff > NAKOFF_MAX)
3123 state->nakoff = NAKOFF_MAX; 3149 state->nakoff = NAKOFF_MAX;
3124 } 3150 }
3125 return; 3151 return;
3126 } 3152 }
3127 3153
3128 /* Ensure that all required options are present */ 3154 /* Ensure that all required options are present */
3129 for (i = 1; i < 255; i++) { 3155 for (i = 1; i < 255; i++) {
3130 if (has_option_mask(ifo->requiremask, i) && 3156 if (has_option_mask(ifo->requiremask, i) &&
3131 get_option_uint8(ifp->ctx, &tmp, 3157 get_option_uint8(ifp->ctx, &tmp,
3132 bootp, bootp_len, (uint8_t)i) != 0) 3158 bootp, bootp_len, (uint8_t)i) != 0)
3133 { 3159 {
3134 /* If we are BOOTP, then ignore the need for serverid. 3160 /* If we are BOOTP, then ignore the need for serverid.
3135 * To ignore BOOTP, require dhcp_message_type. 3161 * To ignore BOOTP, require dhcp_message_type.
3136 * However, nothing really stops BOOTP from providing 3162 * However, nothing really stops BOOTP from providing
3137 * DHCP style options as well so the above isn't 3163 * DHCP style options as well so the above isn't
3138 * always true. */ 3164 * always true. */
3139 if (type == 0 && i == DHO_SERVERID) 3165 if (type == 0 && i == DHO_SERVERID)
3140 continue; 3166 continue;
3141 LOGDHCP(LOG_WARNING, "reject DHCP"); 3167 LOGDHCP(LOG_WARNING, "reject DHCP");
3142 return; 3168 return;
3143 } 3169 }
3144 } 3170 }
3145 3171
 3172 if (has_option_mask(ifo->requestmask, DHO_IPV6_PREFERRED_ONLY)) {
 3173 if (get_option_uint32(ifp->ctx, &v6only_time, bootp, bootp_len,
 3174 DHO_IPV6_PREFERRED_ONLY) == 0 &&
 3175 (state->state == DHS_DISCOVER || state->state == DHS_REBOOT))
 3176 {
 3177 char v6msg[128];
 3178
 3179 use_v6only = true;
 3180 if (v6only_time < MIN_V6ONLY_WAIT)
 3181 v6only_time = MIN_V6ONLY_WAIT;
 3182 snprintf(v6msg, sizeof(v6msg),
 3183 "IPv6-Only Preferred received (%u seconds)",
 3184 v6only_time);
 3185 LOGDHCP(LOG_INFO, v6msg);
 3186 }
 3187 }
 3188
3146 /* DHCP Auto-Configure, RFC 2563 */ 3189 /* DHCP Auto-Configure, RFC 2563 */
3147 if (type == DHCP_OFFER && bootp->yiaddr == 0) { 3190 if (type == DHCP_OFFER && bootp->yiaddr == 0) {
3148 LOGDHCP(LOG_WARNING, "no address given"); 3191 LOGDHCP(LOG_WARNING, "no address given");
3149 if ((msg = get_option_string(ifp->ctx, 3192 if ((msg = get_option_string(ifp->ctx,
3150 bootp, bootp_len, DHO_MESSAGE))) 3193 bootp, bootp_len, DHO_MESSAGE)))
3151 { 3194 {
3152 logwarnx("%s: message: %s", ifp->name, msg); 3195 logwarnx("%s: message: %s", ifp->name, msg);
3153 free(msg); 3196 free(msg);
3154 } 3197 }
3155#ifdef IPV4LL 3198#ifdef IPV4LL
3156 if (state->state == DHS_DISCOVER && 3199 if (state->state == DHS_DISCOVER &&
3157 get_option_uint8(ifp->ctx, &tmp, bootp, bootp_len, 3200 get_option_uint8(ifp->ctx, &tmp, bootp, bootp_len,
3158 DHO_AUTOCONFIGURE) == 0) 3201 DHO_AUTOCONFIGURE) == 0)
3159 { 3202 {
3160 switch (tmp) { 3203 switch (tmp) {
3161 case 0: 3204 case 0:
3162 LOGDHCP(LOG_WARNING, "IPv4LL disabled from"); 3205 LOGDHCP(LOG_WARNING, "IPv4LL disabled from");
3163 ipv4ll_drop(ifp); 3206 ipv4ll_drop(ifp);
3164#ifdef ARP 3207#ifdef ARP
3165 arp_drop(ifp); 3208 arp_drop(ifp);
3166#endif 3209#endif
3167 break; 3210 break;
3168 case 1: 3211 case 1:
3169 LOGDHCP(LOG_WARNING, "IPv4LL enabled from"); 3212 LOGDHCP(LOG_WARNING, "IPv4LL enabled from");
3170 ipv4ll_start(ifp); 3213 ipv4ll_start(ifp);
3171 break; 3214 break;
3172 default: 3215 default:
3173 logerrx("%s: unknown auto configuration " 3216 logerrx("%s: unknown auto configuration "
3174 "option %d", 3217 "option %d",
3175 ifp->name, tmp); 3218 ifp->name, tmp);
3176 break; 3219 break;
3177 } 3220 }
3178 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); 3221 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
3179 eloop_timeout_add_sec(ifp->ctx->eloop, 3222 eloop_timeout_add_sec(ifp->ctx->eloop,
3180 DHCP_MAX, dhcp_discover, ifp); 3223 use_v6only ? v6only_time : DHCP_MAX,
 3224 dhcp_discover, ifp);
3181 } 3225 }
3182#endif 3226#endif
3183 return; 3227 return;
3184 } 3228 }
3185 3229
 3230 if (use_v6only) {
 3231 dhcp_drop(ifp, "EXPIRE");
 3232 dhcp_unlink(ifp->ctx, state->leasefile);
 3233 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
 3234 eloop_timeout_add_sec(ifp->ctx->eloop, v6only_time,
 3235 dhcp_discover, ifp);
 3236 return;
 3237 }
 3238
3186 /* Ensure that the address offered is valid */ 3239 /* Ensure that the address offered is valid */
3187 if ((type == 0 || type == DHCP_OFFER || type == DHCP_ACK) && 3240 if ((type == 0 || type == DHCP_OFFER || type == DHCP_ACK) &&
3188 (bootp->ciaddr == INADDR_ANY || bootp->ciaddr == INADDR_BROADCAST) 3241 (bootp->ciaddr == INADDR_ANY || bootp->ciaddr == INADDR_BROADCAST)
3189 && 3242 &&
3190 (bootp->yiaddr == INADDR_ANY || bootp->yiaddr == INADDR_BROADCAST)) 3243 (bootp->yiaddr == INADDR_ANY || bootp->yiaddr == INADDR_BROADCAST))
3191 { 3244 {
3192 LOGDHCP(LOG_WARNING, "reject invalid address"); 3245 LOGDHCP(LOG_WARNING, "reject invalid address");
3193 return; 3246 return;
3194 } 3247 }
3195 3248
3196#ifdef IN_IFF_DUPLICATED 3249#ifdef IN_IFF_DUPLICATED
3197 ia = ipv4_iffindaddr(ifp, &lease->addr, NULL); 3250 ia = ipv4_iffindaddr(ifp, &lease->addr, NULL);
3198 if (ia && ia->addr_flags & IN_IFF_DUPLICATED) { 3251 if (ia && ia->addr_flags & IN_IFF_DUPLICATED) {
3199 LOGDHCP(LOG_WARNING, "declined duplicate address"); 3252 LOGDHCP(LOG_WARNING, "declined duplicate address");
3200 if (type) 3253 if (type)
3201 dhcp_decline(ifp); 3254 dhcp_decline(ifp);
3202 ipv4_deladdr(ia, 0); 3255 ipv4_deladdr(ia, 0);
3203 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); 3256 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
3204 eloop_timeout_add_sec(ifp->ctx->eloop, 3257 eloop_timeout_add_sec(ifp->ctx->eloop,
3205 DHCP_RAND_MAX, dhcp_discover, ifp); 3258 DHCP_RAND_MAX, dhcp_discover, ifp);
3206 return; 3259 return;
3207 } 3260 }
3208#endif 3261#endif
3209 3262
3210 bootp_copied = false; 3263 bootp_copied = false;
3211 if ((type == 0 || type == DHCP_OFFER) && state->state == DHS_DISCOVER) { 3264 if ((type == 0 || type == DHCP_OFFER) && state->state == DHS_DISCOVER) {
3212 lease->frominfo = 0; 3265 lease->frominfo = 0;
3213 lease->addr.s_addr = bootp->yiaddr; 3266 lease->addr.s_addr = bootp->yiaddr;
3214 memcpy(&lease->cookie, bootp->vend, sizeof(lease->cookie)); 3267 memcpy(&lease->cookie, bootp->vend, sizeof(lease->cookie));
3215 if (type == 0 || 3268 if (type == 0 ||
3216 get_option_addr(ifp->ctx, 3269 get_option_addr(ifp->ctx,
3217 &lease->server, bootp, bootp_len, DHO_SERVERID) != 0) 3270 &lease->server, bootp, bootp_len, DHO_SERVERID) != 0)
3218 lease->server.s_addr = INADDR_ANY; 3271 lease->server.s_addr = INADDR_ANY;
3219 3272
3220 /* Test for rapid commit in the OFFER */ 3273 /* Test for rapid commit in the OFFER */
3221 if (!(ifp->ctx->options & DHCPCD_TEST) && 3274 if (!(ifp->ctx->options & DHCPCD_TEST) &&
3222 has_option_mask(ifo->requestmask, DHO_RAPIDCOMMIT) && 3275 has_option_mask(ifo->requestmask, DHO_RAPIDCOMMIT) &&
3223 get_option(ifp->ctx, bootp, bootp_len, 3276 get_option(ifp->ctx, bootp, bootp_len,
3224 DHO_RAPIDCOMMIT, NULL)) 3277 DHO_RAPIDCOMMIT, NULL))
3225 { 3278 {
3226 state->state = DHS_REQUEST; 3279 state->state = DHS_REQUEST;
3227 goto rapidcommit; 3280 goto rapidcommit;
3228 } 3281 }
3229 3282
3230 LOGDHCP(LOG_INFO, "offered"); 3283 LOGDHCP(LOG_INFO, "offered");
3231 if (state->offer_len < bootp_len) { 3284 if (state->offer_len < bootp_len) {
3232 free(state->offer); 3285 free(state->offer);
3233 if ((state->offer = malloc(bootp_len)) == NULL) { 3286 if ((state->offer = malloc(bootp_len)) == NULL) {
3234 logerr(__func__); 3287 logerr(__func__);
3235 state->offer_len = 0; 3288 state->offer_len = 0;
3236 return; 3289 return;
3237 } 3290 }
3238 } 3291 }
3239 state->offer_len = bootp_len; 3292 state->offer_len = bootp_len;
3240 memcpy(state->offer, bootp, bootp_len); 3293 memcpy(state->offer, bootp, bootp_len);
3241 bootp_copied = true; 3294 bootp_copied = true;
3242 if (ifp->ctx->options & DHCPCD_TEST) { 3295 if (ifp->ctx->options & DHCPCD_TEST) {
3243 free(state->old); 3296 free(state->old);
3244 state->old = state->new; 3297 state->old = state->new;
3245 state->old_len = state->new_len; 3298 state->old_len = state->new_len;
3246 state->new = state->offer; 3299 state->new = state->offer;
3247 state->new_len = state->offer_len; 3300 state->new_len = state->offer_len;
3248 state->offer = NULL; 3301 state->offer = NULL;
3249 state->offer_len = 0; 3302 state->offer_len = 0;
3250 state->reason = "TEST"; 3303 state->reason = "TEST";
3251 script_runreason(ifp, state->reason); 3304 script_runreason(ifp, state->reason);
3252 eloop_exit(ifp->ctx->eloop, EXIT_SUCCESS); 3305 eloop_exit(ifp->ctx->eloop, EXIT_SUCCESS);
3253 state->bpf->bpf_flags |= BPF_EOF; 3306 state->bpf->bpf_flags |= BPF_EOF;
3254 return; 3307 return;
3255 } 3308 }
3256 eloop_timeout_delete(ifp->ctx->eloop, send_discover, ifp); 3309 eloop_timeout_delete(ifp->ctx->eloop, send_discover, ifp);
3257 /* We don't request BOOTP addresses */ 3310 /* We don't request BOOTP addresses */
3258 if (type) { 3311 if (type) {
3259 /* We used to ARP check here, but that seems to be in 3312 /* We used to ARP check here, but that seems to be in
3260 * violation of RFC2131 where it only describes 3313 * violation of RFC2131 where it only describes
3261 * DECLINE after REQUEST. 3314 * DECLINE after REQUEST.
3262 * It also seems that some MS DHCP servers actually 3315 * It also seems that some MS DHCP servers actually
3263 * ignore DECLINE if no REQUEST, ie we decline a 3316 * ignore DECLINE if no REQUEST, ie we decline a
3264 * DISCOVER. */ 3317 * DISCOVER. */
3265 dhcp_request(ifp); 3318 dhcp_request(ifp);
3266 return; 3319 return;
3267 } 3320 }
3268 } 3321 }
3269 3322
3270 if (type) { 3323 if (type) {
3271 if (type == DHCP_OFFER) { 3324 if (type == DHCP_OFFER) {
3272 LOGDHCP(LOG_WARNING, "ignoring offer of"); 3325 LOGDHCP(LOG_WARNING, "ignoring offer of");
3273 return; 3326 return;
3274 } 3327 }
3275 3328
3276 /* We should only be dealing with acks */ 3329 /* We should only be dealing with acks */
3277 if (type != DHCP_ACK) { 3330 if (type != DHCP_ACK) {
3278 LOGDHCP(LOG_ERR, "not ACK or OFFER"); 3331 LOGDHCP(LOG_ERR, "not ACK or OFFER");
3279 return; 3332 return;
3280 } 3333 }
3281 3334
3282 if (state->state == DHS_DISCOVER) { 3335 if (state->state == DHS_DISCOVER) {
3283 /* We only allow ACK of rapid commit DISCOVER. */ 3336 /* We only allow ACK of rapid commit DISCOVER. */
3284 if (has_option_mask(ifo->requestmask, 3337 if (has_option_mask(ifo->requestmask,
3285 DHO_RAPIDCOMMIT) && 3338 DHO_RAPIDCOMMIT) &&
3286 get_option(ifp->ctx, bootp, bootp_len, 3339 get_option(ifp->ctx, bootp, bootp_len,
3287 DHO_RAPIDCOMMIT, NULL)) 3340 DHO_RAPIDCOMMIT, NULL))
3288 state->state = DHS_REQUEST; 3341 state->state = DHS_REQUEST;
3289 else { 3342 else {
3290 LOGDHCP(LOG_DEBUG, "ignoring ack of"); 3343 LOGDHCP(LOG_DEBUG, "ignoring ack of");
3291 return; 3344 return;
3292 } 3345 }
3293 } 3346 }
3294 3347
3295rapidcommit: 3348rapidcommit:
3296 if (!(ifo->options & DHCPCD_INFORM)) 3349 if (!(ifo->options & DHCPCD_INFORM))
3297 LOGDHCP(LOG_DEBUG, "acknowledged"); 3350 LOGDHCP(LOG_DEBUG, "acknowledged");
3298 else 3351 else
3299 ifo->options &= ~DHCPCD_STATIC; 3352 ifo->options &= ~DHCPCD_STATIC;
3300 } 3353 }
3301 3354
3302 /* No NAK, so reset the backoff 3355 /* No NAK, so reset the backoff
3303 * We don't reset on an OFFER message because the server could 3356 * We don't reset on an OFFER message because the server could
3304 * potentially NAK the REQUEST. */ 3357 * potentially NAK the REQUEST. */
3305 state->nakoff = 0; 3358 state->nakoff = 0;
3306 3359
3307 /* BOOTP could have already assigned this above. */ 3360 /* BOOTP could have already assigned this above. */
3308 if (!bootp_copied) { 3361 if (!bootp_copied) {
3309 if (state->offer_len < bootp_len) { 3362 if (state->offer_len < bootp_len) {
3310 free(state->offer); 3363 free(state->offer);
3311 if ((state->offer = malloc(bootp_len)) == NULL) { 3364 if ((state->offer = malloc(bootp_len)) == NULL) {
3312 logerr(__func__); 3365 logerr(__func__);
3313 state->offer_len = 0; 3366 state->offer_len = 0;
3314 return; 3367 return;
3315 } 3368 }
3316 } 3369 }
3317 state->offer_len = bootp_len; 3370 state->offer_len = bootp_len;
3318 memcpy(state->offer, bootp, bootp_len); 3371 memcpy(state->offer, bootp, bootp_len);
3319 } 3372 }
3320 3373
3321 lease->frominfo = 0; 3374 lease->frominfo = 0;
3322 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); 3375 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
3323 3376
3324#if defined(ARP) || defined(KERNEL_RFC5227) 3377#if defined(ARP) || defined(KERNEL_RFC5227)
3325 dhcp_arp_bind(ifp); 3378 dhcp_arp_bind(ifp);
3326#else 3379#else
3327 dhcp_bind(ifp); 3380 dhcp_bind(ifp);
3328#endif 3381#endif
3329} 3382}
3330 3383
3331static void * 3384static void *
3332get_udp_data(void *packet, size_t *len) 3385get_udp_data(void *packet, size_t *len)
3333{ 3386{
3334 const struct ip *ip = packet; 3387 const struct ip *ip = packet;
3335 size_t ip_hl = (size_t)ip->ip_hl * 4; 3388 size_t ip_hl = (size_t)ip->ip_hl * 4;
3336 char *p = packet; 3389 char *p = packet;
3337 3390
3338 p += ip_hl + sizeof(struct udphdr); 3391 p += ip_hl + sizeof(struct udphdr);
3339 *len = (size_t)ntohs(ip->ip_len) - sizeof(struct udphdr) - ip_hl; 3392 *len = (size_t)ntohs(ip->ip_len) - sizeof(struct udphdr) - ip_hl;
3340 return p; 3393 return p;
3341} 3394}
3342 3395
3343static bool 3396static bool
3344is_packet_udp_bootp(void *packet, size_t plen) 3397is_packet_udp_bootp(void *packet, size_t plen)
3345{ 3398{
3346 struct ip *ip = packet; 3399 struct ip *ip = packet;
3347 size_t ip_hlen; 3400 size_t ip_hlen;
3348 struct udphdr udp; 3401 struct udphdr udp;
3349 3402
3350 if (plen < sizeof(*ip)) 3403 if (plen < sizeof(*ip))
3351 return false; 3404 return false;
3352 3405
3353 if (ip->ip_v != IPVERSION || ip->ip_p != IPPROTO_UDP) 3406 if (ip->ip_v != IPVERSION || ip->ip_p != IPPROTO_UDP)
3354 return false; 3407 return false;
3355 3408
3356 /* Sanity. */ 3409 /* Sanity. */
3357 if (ntohs(ip->ip_len) > plen) 3410 if (ntohs(ip->ip_len) > plen)
3358 return false; 3411 return false;
3359 3412
3360 ip_hlen = (size_t)ip->ip_hl * 4; 3413 ip_hlen = (size_t)ip->ip_hl * 4;
3361 if (ip_hlen < sizeof(*ip)) 3414 if (ip_hlen < sizeof(*ip))
3362 return false; 3415 return false;
3363 3416
3364 /* Check we have a UDP header and BOOTP. */ 3417 /* Check we have a UDP header and BOOTP. */
3365 if (ip_hlen + sizeof(udp) + offsetof(struct bootp, vend) > plen) 3418 if (ip_hlen + sizeof(udp) + offsetof(struct bootp, vend) > plen)
3366 return false; 3419 return false;
3367 3420
3368 /* Sanity. */ 3421 /* Sanity. */
3369 memcpy(&udp, (char *)ip + ip_hlen, sizeof(udp)); 3422 memcpy(&udp, (char *)ip + ip_hlen, sizeof(udp));
3370 if (ntohs(udp.uh_ulen) < sizeof(udp)) 3423 if (ntohs(udp.uh_ulen) < sizeof(udp))
3371 return false; 3424 return false;
3372 if (ip_hlen + ntohs(udp.uh_ulen) > plen) 3425 if (ip_hlen + ntohs(udp.uh_ulen) > plen)
3373 return false; 3426 return false;
3374 3427
3375 /* Check it's to and from the right ports. */ 3428 /* Check it's to and from the right ports. */
3376 if (udp.uh_dport != htons(BOOTPC) || udp.uh_sport != htons(BOOTPS)) 3429 if (udp.uh_dport != htons(BOOTPC) || udp.uh_sport != htons(BOOTPS))
3377 return false; 3430 return false;
3378 3431
3379 return true; 3432 return true;
3380} 3433}
3381 3434
3382/* Lengths have already been checked. */ 3435/* Lengths have already been checked. */
3383static bool 3436static bool
3384checksums_valid(void *packet, 3437checksums_valid(void *packet,
3385 struct in_addr *from, unsigned int flags) 3438 struct in_addr *from, unsigned int flags)
3386{ 3439{
3387 struct ip *ip = packet; 3440 struct ip *ip = packet;
3388 union pip { 3441 union pip {
3389 struct ip ip; 3442 struct ip ip;
3390 uint16_t w[sizeof(struct ip) / 2]; 3443 uint16_t w[sizeof(struct ip) / 2];
3391 } pip = { 3444 } pip = {
3392 .ip = { 3445 .ip = {
3393 .ip_p = IPPROTO_UDP, 3446 .ip_p = IPPROTO_UDP,
3394 .ip_src = ip->ip_src, 3447 .ip_src = ip->ip_src,
3395 .ip_dst = ip->ip_dst, 3448 .ip_dst = ip->ip_dst,
3396 } 3449 }
3397 }; 3450 };
3398 size_t ip_hlen; 3451 size_t ip_hlen;
3399 struct udphdr udp; 3452 struct udphdr udp;
3400 char *udpp, *uh_sump; 3453 char *udpp, *uh_sump;
3401 uint32_t csum; 3454 uint32_t csum;
3402 3455
3403 if (from != NULL) 3456 if (from != NULL)
3404 from->s_addr = ip->ip_src.s_addr; 3457 from->s_addr = ip->ip_src.s_addr;
3405 3458
3406 ip_hlen = (size_t)ip->ip_hl * 4; 3459 ip_hlen = (size_t)ip->ip_hl * 4;
3407 if (in_cksum(ip, ip_hlen, NULL) != 0) 3460 if (in_cksum(ip, ip_hlen, NULL) != 0)
3408 return false; 3461 return false;
3409 3462
3410 if (flags & BPF_PARTIALCSUM) 3463 if (flags & BPF_PARTIALCSUM)
3411 return true; 3464 return true;
3412 3465
3413 udpp = (char *)ip + ip_hlen; 3466 udpp = (char *)ip + ip_hlen;
3414 memcpy(&udp, udpp, sizeof(udp)); 3467 memcpy(&udp, udpp, sizeof(udp));
3415 if (udp.uh_sum == 0) 3468 if (udp.uh_sum == 0)
3416 return true; 3469 return true;
3417 3470
3418 /* UDP checksum is based on a pseudo IP header alongside 3471 /* UDP checksum is based on a pseudo IP header alongside
3419 * the UDP header and payload. */ 3472 * the UDP header and payload. */
3420 pip.ip.ip_len = udp.uh_ulen; 3473 pip.ip.ip_len = udp.uh_ulen;
3421 csum = 0; 3474 csum = 0;
3422 3475
3423 /* Need to zero the UDP sum in the packet for the checksum to work. */ 3476 /* Need to zero the UDP sum in the packet for the checksum to work. */
3424 uh_sump = udpp + offsetof(struct udphdr, uh_sum); 3477 uh_sump = udpp + offsetof(struct udphdr, uh_sum);
3425 memset(uh_sump, 0, sizeof(udp.uh_sum)); 3478 memset(uh_sump, 0, sizeof(udp.uh_sum));
3426 3479
3427 /* Checksum pseudo header and then UDP + payload. */ 3480 /* Checksum pseudo header and then UDP + payload. */
3428 in_cksum(pip.w, sizeof(pip.w), &csum); 3481 in_cksum(pip.w, sizeof(pip.w), &csum);
3429 csum = in_cksum(udpp, ntohs(udp.uh_ulen), &csum); 3482 csum = in_cksum(udpp, ntohs(udp.uh_ulen), &csum);
3430 3483
3431#if 0 /* Not needed, just here for completeness. */ 3484#if 0 /* Not needed, just here for completeness. */
3432 /* Put the checksum back. */ 3485 /* Put the checksum back. */
3433 memcpy(uh_sump, &udp.uh_sum, sizeof(udp.uh_sum)); 3486 memcpy(uh_sump, &udp.uh_sum, sizeof(udp.uh_sum));
3434#endif 3487#endif
3435 3488
3436 return csum == udp.uh_sum; 3489 return csum == udp.uh_sum;
3437} 3490}
3438 3491
3439static void 3492static void
3440dhcp_handlebootp(struct interface *ifp, struct bootp *bootp, size_t len, 3493dhcp_handlebootp(struct interface *ifp, struct bootp *bootp, size_t len,
3441 struct in_addr *from) 3494 struct in_addr *from)
3442{ 3495{
3443 size_t v; 3496 size_t v;
3444 3497
3445 if (len < offsetof(struct bootp, vend)) { 3498 if (len < offsetof(struct bootp, vend)) {
3446 logerrx("%s: truncated packet (%zu) from %s", 3499 logerrx("%s: truncated packet (%zu) from %s",
3447 ifp->name, len, inet_ntoa(*from)); 3500 ifp->name, len, inet_ntoa(*from));
3448 return; 3501 return;
3449 } 3502 }
3450 3503
3451 /* Unlikely, but appeases sanitizers. */ 3504 /* Unlikely, but appeases sanitizers. */
3452 if (len > FRAMELEN_MAX) { 3505 if (len > FRAMELEN_MAX) {
3453 logerrx("%s: packet exceeded frame length (%zu) from %s", 3506 logerrx("%s: packet exceeded frame length (%zu) from %s",
3454 ifp->name, len, inet_ntoa(*from)); 3507 ifp->name, len, inet_ntoa(*from));
3455 return; 3508 return;
3456 } 3509 }
3457 3510
3458 /* To make our IS_DHCP macro easy, ensure the vendor 3511 /* To make our IS_DHCP macro easy, ensure the vendor
3459 * area has at least 4 octets. */ 3512 * area has at least 4 octets. */
3460 v = len - offsetof(struct bootp, vend); 3513 v = len - offsetof(struct bootp, vend);
3461 while (v < 4) { 3514 while (v < 4) {
3462 bootp->vend[v++] = '\0'; 3515 bootp->vend[v++] = '\0';
3463 len++; 3516 len++;
3464 } 3517 }
3465 3518
3466 dhcp_handledhcp(ifp, bootp, len, from); 3519 dhcp_handledhcp(ifp, bootp, len, from);
3467} 3520}
3468 3521
3469void 3522void
3470dhcp_packet(struct interface *ifp, uint8_t *data, size_t len, 3523dhcp_packet(struct interface *ifp, uint8_t *data, size_t len,
3471 unsigned int bpf_flags) 3524 unsigned int bpf_flags)
3472{ 3525{
3473 struct bootp *bootp; 3526 struct bootp *bootp;
3474 struct in_addr from; 3527 struct in_addr from;
3475 size_t udp_len; 3528 size_t udp_len;
3476 size_t fl = bpf_frame_header_len(ifp); 3529 size_t fl = bpf_frame_header_len(ifp);
3477#ifdef PRIVSEP 3530#ifdef PRIVSEP
3478 const struct dhcp_state *state = D_CSTATE(ifp); 3531 const struct dhcp_state *state = D_CSTATE(ifp);
3479 3532
3480 /* It's possible that an interface departs and arrives in short 3533 /* It's possible that an interface departs and arrives in short
3481 * order to receive a BPF frame out of order. 3534 * order to receive a BPF frame out of order.
3482 * There is a similar check in ARP, but much lower down the stack. 3535 * There is a similar check in ARP, but much lower down the stack.
3483 * It's not needed for other inet protocols because we send the 3536 * It's not needed for other inet protocols because we send the
3484 * message as a whole and select the interface off that and then 3537 * message as a whole and select the interface off that and then
3485 * check state. BPF on the other hand is very interface 3538 * check state. BPF on the other hand is very interface
3486 * specific and we do need this check. */ 3539 * specific and we do need this check. */
3487 if (state == NULL) 3540 if (state == NULL)
3488 return; 3541 return;
3489 3542
3490 /* Ignore double reads */ 3543 /* Ignore double reads */
3491 if (IN_PRIVSEP(ifp->ctx)) { 3544 if (IN_PRIVSEP(ifp->ctx)) {
3492 switch (state->state) { 3545 switch (state->state) {
3493 case DHS_BOUND: /* FALLTHROUGH */ 3546 case DHS_BOUND: /* FALLTHROUGH */
3494 case DHS_RENEW: 3547 case DHS_RENEW:
3495 return; 3548 return;
3496 default: 3549 default:
3497 break; 3550 break;
3498 } 3551 }
3499 } 3552 }
3500#endif 3553#endif
3501 3554
3502 /* Trim frame header */ 3555 /* Trim frame header */
3503 if (fl != 0) { 3556 if (fl != 0) {
3504 if (len < fl) { 3557 if (len < fl) {
3505 logerrx("%s: %s: short frame header %zu", 3558 logerrx("%s: %s: short frame header %zu",
3506 __func__, ifp->name, len); 3559 __func__, ifp->name, len);
3507 return; 3560 return;
3508 } 3561 }
3509 len -= fl; 3562 len -= fl;
3510 /* Move the data to avoid alignment errors. */ 3563 /* Move the data to avoid alignment errors. */
3511 memmove(data, data + fl, len); 3564 memmove(data, data + fl, len);
3512 } 3565 }
3513 3566
3514 /* Validate filter. */ 3567 /* Validate filter. */
3515 if (!is_packet_udp_bootp(data, len)) { 3568 if (!is_packet_udp_bootp(data, len)) {
3516#ifdef BPF_DEBUG 3569#ifdef BPF_DEBUG
3517 logerrx("%s: DHCP BPF validation failure", ifp->name); 3570 logerrx("%s: DHCP BPF validation failure", ifp->name);
3518#endif 3571#endif
3519 return; 3572 return;
3520 } 3573 }
3521 3574
3522 if (!checksums_valid(data, &from, bpf_flags)) { 3575 if (!checksums_valid(data, &from, bpf_flags)) {
3523 logerrx("%s: checksum failure from %s", 3576 logerrx("%s: checksum failure from %s",
3524 ifp->name, inet_ntoa(from)); 3577 ifp->name, inet_ntoa(from));
3525 return; 3578 return;
3526 } 3579 }
3527 3580
3528 /* 3581 /*
3529 * DHCP has a variable option area rather than a fixed vendor area. 3582 * DHCP has a variable option area rather than a fixed vendor area.
3530 * Because DHCP uses the BOOTP protocol it should still send BOOTP 3583 * Because DHCP uses the BOOTP protocol it should still send BOOTP
3531 * sized packets to be RFC compliant. 3584 * sized packets to be RFC compliant.
3532 * However some servers send a truncated vendor area. 3585 * However some servers send a truncated vendor area.
3533 * dhcpcd can work fine without the vendor area being sent. 3586 * dhcpcd can work fine without the vendor area being sent.
3534 */ 3587 */
3535 bootp = get_udp_data(data, &udp_len); 3588 bootp = get_udp_data(data, &udp_len);
3536 dhcp_handlebootp(ifp, bootp, udp_len, &from); 3589 dhcp_handlebootp(ifp, bootp, udp_len, &from);
3537} 3590}
3538 3591
3539static void 3592static void
3540dhcp_readbpf(void *arg) 3593dhcp_readbpf(void *arg)
3541{ 3594{
3542 struct interface *ifp = arg; 3595 struct interface *ifp = arg;
3543 uint8_t buf[FRAMELEN_MAX]; 3596 uint8_t buf[FRAMELEN_MAX];
3544 ssize_t bytes; 3597 ssize_t bytes;
3545 struct dhcp_state *state = D_STATE(ifp); 3598 struct dhcp_state *state = D_STATE(ifp);
3546 struct bpf *bpf = state->bpf; 3599 struct bpf *bpf = state->bpf;
3547 3600
3548 bpf->bpf_flags &= ~BPF_EOF; 3601 bpf->bpf_flags &= ~BPF_EOF;
3549 while (!(bpf->bpf_flags & BPF_EOF)) { 3602 while (!(bpf->bpf_flags & BPF_EOF)) {
3550 bytes = bpf_read(bpf, buf, sizeof(buf)); 3603 bytes = bpf_read(bpf, buf, sizeof(buf));
3551 if (bytes == -1) { 3604 if (bytes == -1) {
3552 if (state->state != DHS_NONE) { 3605 if (state->state != DHS_NONE) {
3553 logerr("%s: %s", __func__, ifp->name); 3606 logerr("%s: %s", __func__, ifp->name);
3554 dhcp_close(ifp); 3607 dhcp_close(ifp);
3555 } 3608 }
3556 break; 3609 break;
3557 } 3610 }
3558 dhcp_packet(ifp, buf, (size_t)bytes, bpf->bpf_flags); 3611 dhcp_packet(ifp, buf, (size_t)bytes, bpf->bpf_flags);
3559 /* Check we still have a state after processing. */ 3612 /* Check we still have a state after processing. */
3560 if ((state = D_STATE(ifp)) == NULL) 3613 if ((state = D_STATE(ifp)) == NULL)
3561 break; 3614 break;
3562 if ((bpf = state->bpf) == NULL) 3615 if ((bpf = state->bpf) == NULL)
3563 break; 3616 break;
3564 } 3617 }
3565} 3618}
3566 3619
3567void 3620void
3568dhcp_recvmsg(struct dhcpcd_ctx *ctx, struct msghdr *msg) 3621dhcp_recvmsg(struct dhcpcd_ctx *ctx, struct msghdr *msg)
3569{ 3622{
3570 struct sockaddr_in *from = (struct sockaddr_in *)msg->msg_name; 3623 struct sockaddr_in *from = (struct sockaddr_in *)msg->msg_name;
3571 struct iovec *iov = &msg->msg_iov[0]; 3624 struct iovec *iov = &msg->msg_iov[0];
3572 struct interface *ifp; 3625 struct interface *ifp;
3573 const struct dhcp_state *state; 3626 const struct dhcp_state *state;
3574 3627
3575 ifp = if_findifpfromcmsg(ctx, msg, NULL); 3628 ifp = if_findifpfromcmsg(ctx, msg, NULL);
3576 if (ifp == NULL) { 3629 if (ifp == NULL) {
3577 logerr(__func__); 3630 logerr(__func__);
3578 return; 3631 return;
3579 } 3632 }
3580 state = D_CSTATE(ifp); 3633 state = D_CSTATE(ifp);
3581 if (state == NULL) { 3634 if (state == NULL) {
3582 /* Try re-directing it to another interface. */ 3635 /* Try re-directing it to another interface. */
3583 dhcp_redirect_dhcp(ifp, (struct bootp *)iov->iov_base, 3636 dhcp_redirect_dhcp(ifp, (struct bootp *)iov->iov_base,
3584 iov->iov_len, &from->sin_addr); 3637 iov->iov_len, &from->sin_addr);
3585 return; 3638 return;
3586 } 3639 }
3587 3640
3588 if (state->bpf != NULL) { 3641 if (state->bpf != NULL) {
3589 /* Avoid a duplicate read if BPF is open for the interface. */ 3642 /* Avoid a duplicate read if BPF is open for the interface. */
3590 return; 3643 return;
3591 } 3644 }
3592#ifdef PRIVSEP 3645#ifdef PRIVSEP
3593 if (IN_PRIVSEP(ctx)) { 3646 if (IN_PRIVSEP(ctx)) {
3594 switch (state->state) { 3647 switch (state->state) {
3595 case DHS_BOUND: /* FALLTHROUGH */ 3648 case DHS_BOUND: /* FALLTHROUGH */
3596 case DHS_RENEW: 3649 case DHS_RENEW:
3597 break; 3650 break;
3598 default: 3651 default:
3599 /* Any other state we ignore it or will receive 3652 /* Any other state we ignore it or will receive
3600 * via BPF. */ 3653 * via BPF. */
3601 return; 3654 return;
3602 } 3655 }
3603 } 3656 }
3604#endif 3657#endif
3605 3658
3606 dhcp_handlebootp(ifp, iov->iov_base, iov->iov_len, 3659 dhcp_handlebootp(ifp, iov->iov_base, iov->iov_len,
3607 &from->sin_addr); 3660 &from->sin_addr);
3608} 3661}
3609 3662
3610static void 3663static void
3611dhcp_readudp(struct dhcpcd_ctx *ctx, struct interface *ifp) 3664dhcp_readudp(struct dhcpcd_ctx *ctx, struct interface *ifp)
3612{ 3665{
3613 const struct dhcp_state *state; 3666 const struct dhcp_state *state;
3614 struct sockaddr_in from; 3667 struct sockaddr_in from;
3615 union { 3668 union {
3616 struct bootp bootp; 3669 struct bootp bootp;
3617 uint8_t buf[10 * 1024]; /* Maximum MTU */ 3670 uint8_t buf[10 * 1024]; /* Maximum MTU */
3618 } iovbuf; 3671 } iovbuf;
3619 struct iovec iov = { 3672 struct iovec iov = {
3620 .iov_base = iovbuf.buf, 3673 .iov_base = iovbuf.buf,
3621 .iov_len = sizeof(iovbuf.buf), 3674 .iov_len = sizeof(iovbuf.buf),
3622 }; 3675 };
3623 union { 3676 union {
3624 struct cmsghdr hdr; 3677 struct cmsghdr hdr;
3625#ifdef IP_RECVIF 3678#ifdef IP_RECVIF
3626 uint8_t buf[CMSG_SPACE(sizeof(struct sockaddr_dl))]; 3679 uint8_t buf[CMSG_SPACE(sizeof(struct sockaddr_dl))];
3627#else 3680#else
3628 uint8_t buf[CMSG_SPACE(sizeof(struct in_pktinfo))]; 3681 uint8_t buf[CMSG_SPACE(sizeof(struct in_pktinfo))];
3629#endif 3682#endif
3630 } cmsgbuf = { .buf = { 0 } }; 3683 } cmsgbuf = { .buf = { 0 } };
3631 struct msghdr msg = { 3684 struct msghdr msg = {
3632 .msg_name = &from, .msg_namelen = sizeof(from), 3685 .msg_name = &from, .msg_namelen = sizeof(from),
3633 .msg_iov = &iov, .msg_iovlen = 1, 3686 .msg_iov = &iov, .msg_iovlen = 1,
3634 .msg_control = cmsgbuf.buf, .msg_controllen = sizeof(cmsgbuf.buf), 3687 .msg_control = cmsgbuf.buf, .msg_controllen = sizeof(cmsgbuf.buf),
3635 }; 3688 };
3636 int s; 3689 int s;
3637 ssize_t bytes; 3690 ssize_t bytes;
3638 3691
3639 if (ifp != NULL) { 3692 if (ifp != NULL) {
3640 state = D_CSTATE(ifp); 3693 state = D_CSTATE(ifp);
3641 s = state->udp_rfd; 3694 s = state->udp_rfd;
3642 } else 3695 } else
3643 s = ctx->udp_rfd; 3696 s = ctx->udp_rfd;
3644 3697
3645 bytes = recvmsg(s, &msg, 0); 3698 bytes = recvmsg(s, &msg, 0);
3646 if (bytes == -1) { 3699 if (bytes == -1) {
3647 logerr(__func__); 3700 logerr(__func__);
3648 return; 3701 return;
3649 } 3702 }
3650 3703
3651 iov.iov_len = (size_t)bytes; 3704 iov.iov_len = (size_t)bytes;
3652 dhcp_recvmsg(ctx, &msg); 3705 dhcp_recvmsg(ctx, &msg);
3653} 3706}
3654 3707
3655static void 3708static void
3656dhcp_handleudp(void *arg) 3709dhcp_handleudp(void *arg)
3657{ 3710{
3658 struct dhcpcd_ctx *ctx = arg; 3711 struct dhcpcd_ctx *ctx = arg;
3659 3712
3660 dhcp_readudp(ctx, NULL); 3713 dhcp_readudp(ctx, NULL);
3661} 3714}
3662 3715
3663static void 3716static void
3664dhcp_handleifudp(void *arg) 3717dhcp_handleifudp(void *arg)
3665{ 3718{
3666 struct interface *ifp = arg; 3719 struct interface *ifp = arg;
3667 3720
3668 dhcp_readudp(ifp->ctx, ifp); 3721 dhcp_readudp(ifp->ctx, ifp);
3669} 3722}
3670 3723
3671static int 3724static int
3672dhcp_openbpf(struct interface *ifp) 3725dhcp_openbpf(struct interface *ifp)
3673{ 3726{
3674 struct dhcp_state *state; 3727 struct dhcp_state *state;
3675 3728
3676 state = D_STATE(ifp); 3729 state = D_STATE(ifp);
3677 3730
3678#ifdef PRIVSEP 3731#ifdef PRIVSEP
3679 if (IN_PRIVSEP_SE(ifp->ctx)) { 3732 if (IN_PRIVSEP_SE(ifp->ctx)) {
3680 if (ps_bpf_openbootp(ifp) == -1) { 3733 if (ps_bpf_openbootp(ifp) == -1) {
3681 logerr(__func__); 3734 logerr(__func__);
3682 return -1; 3735 return -1;
3683 } 3736 }
3684 return 0; 3737 return 0;
3685 } 3738 }
3686#endif 3739#endif
3687 3740
3688 if (state->bpf != NULL) 3741 if (state->bpf != NULL)
3689 return 0; 3742 return 0;
3690 3743
3691 state->bpf = bpf_open(ifp, bpf_bootp, NULL); 3744 state->bpf = bpf_open(ifp, bpf_bootp, NULL);
3692 if (state->bpf == NULL) { 3745 if (state->bpf == NULL) {
3693 if (errno == ENOENT) { 3746 if (errno == ENOENT) {
3694 logerrx("%s not found", bpf_name); 3747 logerrx("%s not found", bpf_name);
3695 /* May as well disable IPv4 entirely at 3748 /* May as well disable IPv4 entirely at
3696 * this point as we really need it. */ 3749 * this point as we really need it. */
3697 ifp->options->options &= ~DHCPCD_IPV4; 3750 ifp->options->options &= ~DHCPCD_IPV4;
3698 } else 3751 } else
3699 logerr("%s: %s", __func__, ifp->name); 3752 logerr("%s: %s", __func__, ifp->name);
3700 return -1; 3753 return -1;
3701 } 3754 }
3702 3755
3703 eloop_event_add(ifp->ctx->eloop, 3756 eloop_event_add(ifp->ctx->eloop,
3704 state->bpf->bpf_fd, dhcp_readbpf, ifp); 3757 state->bpf->bpf_fd, dhcp_readbpf, ifp);
3705 return 0; 3758 return 0;
3706} 3759}
3707 3760
3708void 3761void
3709dhcp_free(struct interface *ifp) 3762dhcp_free(struct interface *ifp)
3710{ 3763{
3711 struct dhcp_state *state = D_STATE(ifp); 3764 struct dhcp_state *state = D_STATE(ifp);
3712 struct dhcpcd_ctx *ctx; 3765 struct dhcpcd_ctx *ctx;
3713 3766
3714 dhcp_close(ifp); 3767 dhcp_close(ifp);
3715#ifdef ARP 3768#ifdef ARP
3716 arp_drop(ifp); 3769 arp_drop(ifp);
3717#endif 3770#endif
3718 if (state) { 3771 if (state) {
3719 state->state = DHS_NONE; 3772 state->state = DHS_NONE;
3720 free(state->old); 3773 free(state->old);
3721 free(state->new); 3774 free(state->new);
3722 free(state->offer); 3775 free(state->offer);
3723 free(state->clientid); 3776 free(state->clientid);
3724 free(state); 3777 free(state);
3725 } 3778 }
3726 3779
3727 ctx = ifp->ctx; 3780 ctx = ifp->ctx;
3728 /* If we don't have any more DHCP enabled interfaces, 3781 /* If we don't have any more DHCP enabled interfaces,
3729 * close the global socket and release resources */ 3782 * close the global socket and release resources */
3730 if (ctx->ifaces) { 3783 if (ctx->ifaces) {
3731 TAILQ_FOREACH(ifp, ctx->ifaces, next) { 3784 TAILQ_FOREACH(ifp, ctx->ifaces, next) {
3732 state = D_STATE(ifp); 3785 state = D_STATE(ifp);
3733 if (state != NULL && state->state != DHS_NONE) 3786 if (state != NULL && state->state != DHS_NONE)
3734 break; 3787 break;
3735 } 3788 }
3736 } 3789 }
3737 if (ifp == NULL) { 3790 if (ifp == NULL) {
3738 if (ctx->udp_rfd != -1) { 3791 if (ctx->udp_rfd != -1) {
3739 eloop_event_delete(ctx->eloop, ctx->udp_rfd); 3792 eloop_event_delete(ctx->eloop, ctx->udp_rfd);
3740 close(ctx->udp_rfd); 3793 close(ctx->udp_rfd);
3741 ctx->udp_rfd = -1; 3794 ctx->udp_rfd = -1;
3742 } 3795 }
3743 if (ctx->udp_wfd != -1) { 3796 if (ctx->udp_wfd != -1) {
3744 close(ctx->udp_wfd); 3797 close(ctx->udp_wfd);
3745 ctx->udp_wfd = -1; 3798 ctx->udp_wfd = -1;
3746 } 3799 }
3747 3800
3748 free(ctx->opt_buffer); 3801 free(ctx->opt_buffer);
3749 ctx->opt_buffer = NULL; 3802 ctx->opt_buffer = NULL;
3750 } 3803 }
3751} 3804}
3752 3805
3753static int 3806static int
3754dhcp_initstate(struct interface *ifp) 3807dhcp_initstate(struct interface *ifp)
3755{ 3808{
3756 struct dhcp_state *state; 3809 struct dhcp_state *state;
3757 3810
3758 state = D_STATE(ifp); 3811 state = D_STATE(ifp);
3759 if (state != NULL) 3812 if (state != NULL)
3760 return 0; 3813 return 0;
3761 3814
3762 ifp->if_data[IF_DATA_DHCP] = calloc(1, sizeof(*state)); 3815 ifp->if_data[IF_DATA_DHCP] = calloc(1, sizeof(*state));
3763 state = D_STATE(ifp); 3816 state = D_STATE(ifp);
3764 if (state == NULL) 3817 if (state == NULL)
3765 return -1; 3818 return -1;
3766 3819
3767 state->state = DHS_NONE; 3820 state->state = DHS_NONE;
3768 /* 0 is a valid fd, so init to -1 */ 3821 /* 0 is a valid fd, so init to -1 */
3769 state->udp_rfd = -1; 3822 state->udp_rfd = -1;
3770#ifdef ARPING 3823#ifdef ARPING
3771 state->arping_index = -1; 3824 state->arping_index = -1;
3772#endif 3825#endif
3773 return 1; 3826 return 1;
3774} 3827}
3775 3828
3776static int 3829static int
3777dhcp_init(struct interface *ifp) 3830dhcp_init(struct interface *ifp)
3778{ 3831{
3779 struct dhcp_state *state; 3832 struct dhcp_state *state;
3780 struct if_options *ifo; 3833 struct if_options *ifo;
3781 uint8_t len; 3834 uint8_t len;
3782 char buf[(sizeof(ifo->clientid) - 1) * 3]; 3835 char buf[(sizeof(ifo->clientid) - 1) * 3];
3783 3836
3784 if (dhcp_initstate(ifp) == -1) 3837 if (dhcp_initstate(ifp) == -1)
3785 return -1; 3838 return -1;
3786 3839
3787 state = D_STATE(ifp); 3840 state = D_STATE(ifp);
3788 state->state = DHS_INIT; 3841 state->state = DHS_INIT;
3789 state->reason = "PREINIT"; 3842 state->reason = "PREINIT";
3790 state->nakoff = 0; 3843 state->nakoff = 0;
3791 dhcp_set_leasefile(state->leasefile, sizeof(state->leasefile), 3844 dhcp_set_leasefile(state->leasefile, sizeof(state->leasefile),
3792 AF_INET, ifp); 3845 AF_INET, ifp);
3793 3846
3794 ifo = ifp->options; 3847 ifo = ifp->options;
3795 /* We need to drop the leasefile so that dhcp_start 3848 /* We need to drop the leasefile so that dhcp_start
3796 * doesn't load it. */ 3849 * doesn't load it. */
3797 if (ifo->options & DHCPCD_REQUEST) 3850 if (ifo->options & DHCPCD_REQUEST)
3798 dhcp_unlink(ifp->ctx, state->leasefile); 3851 dhcp_unlink(ifp->ctx, state->leasefile);
3799 3852
3800 free(state->clientid); 3853 free(state->clientid);
3801 state->clientid = NULL; 3854 state->clientid = NULL;
3802 3855
3803 if (ifo->options & DHCPCD_ANONYMOUS) { 3856 if (ifo->options & DHCPCD_ANONYMOUS) {
3804 uint8_t duid[DUID_LEN]; 3857 uint8_t duid[DUID_LEN];
3805 uint8_t duid_len; 3858 uint8_t duid_len;
3806 3859
3807 duid_len = (uint8_t)duid_make(duid, ifp, DUID_LL); 3860 duid_len = (uint8_t)duid_make(duid, ifp, DUID_LL);
3808 if (duid_len != 0) { 3861 if (duid_len != 0) {
3809 state->clientid = malloc((size_t)duid_len + 6); 3862 state->clientid = malloc((size_t)duid_len + 6);
3810 if (state->clientid == NULL) 3863 if (state->clientid == NULL)
3811 goto eexit; 3864 goto eexit;
3812 state->clientid[0] =(uint8_t)(duid_len + 5); 3865 state->clientid[0] =(uint8_t)(duid_len + 5);
3813 state->clientid[1] = 255; /* RFC 4361 */ 3866 state->clientid[1] = 255; /* RFC 4361 */
3814 memcpy(state->clientid + 2, ifo->iaid, 4); 3867 memcpy(state->clientid + 2, ifo->iaid, 4);
3815 memset(state->clientid + 2, 0, 4); /* IAID */ 3868 memset(state->clientid + 2, 0, 4); /* IAID */
3816 memcpy(state->clientid + 6, duid, duid_len); 3869 memcpy(state->clientid + 6, duid, duid_len);
3817 } 3870 }
3818 } else if (*ifo->clientid) { 3871 } else if (*ifo->clientid) {
3819 state->clientid = malloc((size_t)(ifo->clientid[0] + 1)); 3872 state->clientid = malloc((size_t)(ifo->clientid[0] + 1));
3820 if (state->clientid == NULL) 3873 if (state->clientid == NULL)
3821 goto eexit; 3874 goto eexit;
3822 memcpy(state->clientid, ifo->clientid, 3875 memcpy(state->clientid, ifo->clientid,
3823 (size_t)(ifo->clientid[0]) + 1); 3876 (size_t)(ifo->clientid[0]) + 1);
3824 } else if (ifo->options & DHCPCD_CLIENTID) { 3877 } else if (ifo->options & DHCPCD_CLIENTID) {
3825 if (ifo->options & DHCPCD_DUID) { 3878 if (ifo->options & DHCPCD_DUID) {
3826 state->clientid = malloc(ifp->ctx->duid_len + 6); 3879 state->clientid = malloc(ifp->ctx->duid_len + 6);
3827 if (state->clientid == NULL) 3880 if (state->clientid == NULL)
3828 goto eexit; 3881 goto eexit;
3829 state->clientid[0] =(uint8_t)(ifp->ctx->duid_len + 5); 3882 state->clientid[0] =(uint8_t)(ifp->ctx->duid_len + 5);
3830 state->clientid[1] = 255; /* RFC 4361 */ 3883 state->clientid[1] = 255; /* RFC 4361 */
3831 memcpy(state->clientid + 2, ifo->iaid, 4); 3884 memcpy(state->clientid + 2, ifo->iaid, 4);
3832 memcpy(state->clientid + 6, ifp->ctx->duid, 3885 memcpy(state->clientid + 6, ifp->ctx->duid,
3833 ifp->ctx->duid_len); 3886 ifp->ctx->duid_len);
3834 } else { 3887 } else {
3835 len = (uint8_t)(ifp->hwlen + 1); 3888 len = (uint8_t)(ifp->hwlen + 1);
3836 state->clientid = malloc((size_t)len + 1); 3889 state->clientid = malloc((size_t)len + 1);
3837 if (state->clientid == NULL) 3890 if (state->clientid == NULL)
3838 goto eexit; 3891 goto eexit;
3839 state->clientid[0] = len; 3892 state->clientid[0] = len;
3840 state->clientid[1] = (uint8_t)ifp->hwtype; 3893 state->clientid[1] = (uint8_t)ifp->hwtype;
3841 memcpy(state->clientid + 2, ifp->hwaddr, 3894 memcpy(state->clientid + 2, ifp->hwaddr,
3842 ifp->hwlen); 3895 ifp->hwlen);
3843 } 3896 }
3844 } 3897 }
3845 3898
3846 if (ifo->options & DHCPCD_DUID) 3899 if (ifo->options & DHCPCD_DUID)
3847 /* Don't bother logging as DUID and IAID are reported 3900 /* Don't bother logging as DUID and IAID are reported
3848 * at device start. */ 3901 * at device start. */
3849 return 0; 3902 return 0;
3850 3903
3851 if (ifo->options & DHCPCD_CLIENTID && state->clientid != NULL) 3904 if (ifo->options & DHCPCD_CLIENTID && state->clientid != NULL)
3852 logdebugx("%s: using ClientID %s", ifp->name, 3905 logdebugx("%s: using ClientID %s", ifp->name,
3853 hwaddr_ntoa(state->clientid + 1, state->clientid[0], 3906 hwaddr_ntoa(state->clientid + 1, state->clientid[0],
3854 buf, sizeof(buf))); 3907 buf, sizeof(buf)));
3855 else if (ifp->hwlen) 3908 else if (ifp->hwlen)
3856 logdebugx("%s: using hwaddr %s", ifp->name, 3909 logdebugx("%s: using hwaddr %s", ifp->name,
3857 hwaddr_ntoa(ifp->hwaddr, ifp->hwlen, buf, sizeof(buf))); 3910 hwaddr_ntoa(ifp->hwaddr, ifp->hwlen, buf, sizeof(buf)));
3858 return 0; 3911 return 0;
3859 3912
3860eexit: 3913eexit:
3861 logerr(__func__); 3914 logerr(__func__);
3862 return -1; 3915 return -1;
3863} 3916}
3864 3917
3865static void 3918static void
3866dhcp_start1(void *arg) 3919dhcp_start1(void *arg)
3867{ 3920{
3868 struct interface *ifp = arg; 3921 struct interface *ifp = arg;
3869 struct dhcpcd_ctx *ctx = ifp->ctx; 3922 struct dhcpcd_ctx *ctx = ifp->ctx;
3870 struct if_options *ifo = ifp->options; 3923 struct if_options *ifo = ifp->options;
3871 struct dhcp_state *state; 3924 struct dhcp_state *state;
3872 uint32_t l; 3925 uint32_t l;
3873 int nolease; 3926 int nolease;
3874 3927
3875 if (!(ifo->options & DHCPCD_IPV4)) 3928 if (!(ifo->options & DHCPCD_IPV4))
3876 return; 3929 return;
3877 3930
3878 /* Listen on *.*.*.*:bootpc so that the kernel never sends an 3931 /* Listen on *.*.*.*:bootpc so that the kernel never sends an
3879 * ICMP port unreachable message back to the DHCP server. 3932 * ICMP port unreachable message back to the DHCP server.
3880 * Only do this in master mode so we don't swallow messages 3933 * Only do this in master mode so we don't swallow messages
3881 * for dhcpcd running on another interface. */ 3934 * for dhcpcd running on another interface. */
3882 if ((ctx->options & (DHCPCD_MASTER|DHCPCD_PRIVSEP)) == DHCPCD_MASTER 3935 if ((ctx->options & (DHCPCD_MASTER|DHCPCD_PRIVSEP)) == DHCPCD_MASTER
3883 && ctx->udp_rfd == -1) 3936 && ctx->udp_rfd == -1)
3884 { 3937 {
3885 ctx->udp_rfd = dhcp_openudp(NULL); 3938 ctx->udp_rfd = dhcp_openudp(NULL);
3886 if (ctx->udp_rfd == -1) { 3939 if (ctx->udp_rfd == -1) {
3887 logerr(__func__); 3940 logerr(__func__);
3888 return; 3941 return;
3889 } 3942 }
3890 eloop_event_add(ctx->eloop, ctx->udp_rfd, dhcp_handleudp, ctx); 3943 eloop_event_add(ctx->eloop, ctx->udp_rfd, dhcp_handleudp, ctx);
3891 } 3944 }
3892 if (!IN_PRIVSEP(ctx) && ctx->udp_wfd == -1) { 3945 if (!IN_PRIVSEP(ctx) && ctx->udp_wfd == -1) {
3893 ctx->udp_wfd = xsocket(PF_INET, SOCK_RAW|SOCK_CXNB,IPPROTO_UDP); 3946 ctx->udp_wfd = xsocket(PF_INET, SOCK_RAW|SOCK_CXNB,IPPROTO_UDP);
3894 if (ctx->udp_wfd == -1) { 3947 if (ctx->udp_wfd == -1) {
3895 logerr(__func__); 3948 logerr(__func__);
3896 return; 3949 return;
3897 } 3950 }
3898 } 3951 }
3899 3952
3900 if (dhcp_init(ifp) == -1) { 3953 if (dhcp_init(ifp) == -1) {
3901 logerr("%s: dhcp_init", ifp->name); 3954 logerr("%s: dhcp_init", ifp->name);
3902 return; 3955 return;
3903 } 3956 }
3904 3957
3905 state = D_STATE(ifp); 3958 state = D_STATE(ifp);
3906 clock_gettime(CLOCK_MONOTONIC, &state->started); 3959 clock_gettime(CLOCK_MONOTONIC, &state->started);
3907 state->interval = 0; 3960 state->interval = 0;
3908 free(state->offer); 3961 free(state->offer);
3909 state->offer = NULL; 3962 state->offer = NULL;
3910 state->offer_len = 0; 3963 state->offer_len = 0;
3911 3964
3912#ifdef ARPING 3965#ifdef ARPING
3913 if (ifo->arping_len && state->arping_index < ifo->arping_len) { 3966 if (ifo->arping_len && state->arping_index < ifo->arping_len) {
3914 dhcp_arping(ifp); 3967 dhcp_arping(ifp);
3915 return; 3968 return;
3916 } 3969 }
3917#endif 3970#endif
3918 3971
3919 if (ifo->options & DHCPCD_STATIC) { 3972 if (ifo->options & DHCPCD_STATIC) {
3920 dhcp_static(ifp); 3973 dhcp_static(ifp);
3921 return; 3974 return;
3922 } 3975 }
3923 3976
3924 if (ifo->options & DHCPCD_INFORM) { 3977 if (ifo->options & DHCPCD_INFORM) {
3925 dhcp_inform(ifp); 3978 dhcp_inform(ifp);
3926 return; 3979 return;
3927 } 3980 }
3928 3981
3929 /* We don't want to read the old lease if we NAK an old test */ 3982 /* We don't want to read the old lease if we NAK an old test */
3930 nolease = state->offer && ifp->ctx->options & DHCPCD_TEST; 3983 nolease = state->offer && ifp->ctx->options & DHCPCD_TEST;
3931 if (!nolease && ifo->options & DHCPCD_DHCP) { 3984 if (!nolease && ifo->options & DHCPCD_DHCP) {
3932 state->offer_len = read_lease(ifp, &state->offer); 3985 state->offer_len = read_lease(ifp, &state->offer);
3933 /* Check the saved lease matches the type we want */ 3986 /* Check the saved lease matches the type we want */
3934 if (state->offer) { 3987 if (state->offer) {
3935#ifdef IN_IFF_DUPLICATED 3988#ifdef IN_IFF_DUPLICATED
3936 struct in_addr addr; 3989 struct in_addr addr;
3937 struct ipv4_addr *ia; 3990 struct ipv4_addr *ia;
3938 3991
3939 addr.s_addr = state->offer->yiaddr; 3992 addr.s_addr = state->offer->yiaddr;
3940 ia = ipv4_iffindaddr(ifp, &addr, NULL); 3993 ia = ipv4_iffindaddr(ifp, &addr, NULL);
3941#endif 3994#endif
3942 3995
3943 if ((!IS_DHCP(state->offer) && 3996 if ((!IS_DHCP(state->offer) &&
3944 !(ifo->options & DHCPCD_BOOTP)) || 3997 !(ifo->options & DHCPCD_BOOTP)) ||
3945#ifdef IN_IFF_DUPLICATED 3998#ifdef IN_IFF_DUPLICATED
3946 (ia && ia->addr_flags & IN_IFF_DUPLICATED) || 3999 (ia && ia->addr_flags & IN_IFF_DUPLICATED) ||
3947#endif 4000#endif
3948 (IS_DHCP(state->offer) && 4001 (IS_DHCP(state->offer) &&
3949 ifo->options & DHCPCD_BOOTP)) 4002 ifo->options & DHCPCD_BOOTP))
3950 { 4003 {
3951 free(state->offer); 4004 free(state->offer);
3952 state->offer = NULL; 4005 state->offer = NULL;
3953 state->offer_len = 0; 4006 state->offer_len = 0;
3954 } 4007 }
3955 } 4008 }
3956 } 4009 }
3957 if (state->offer) { 4010 if (state->offer) {
3958 struct ipv4_addr *ia; 4011 struct ipv4_addr *ia;
3959 time_t mtime; 4012 time_t mtime;
3960 4013
3961 get_lease(ifp, &state->lease, state->offer, state->offer_len); 4014 get_lease(ifp, &state->lease, state->offer, state->offer_len);
3962 state->lease.frominfo = 1; 4015 state->lease.frominfo = 1;
3963 if (state->new == NULL && 4016 if (state->new == NULL &&
3964 (ia = ipv4_iffindaddr(ifp, 4017 (ia = ipv4_iffindaddr(ifp,
3965 &state->lease.addr, &state->lease.mask)) != NULL) 4018 &state->lease.addr, &state->lease.mask)) != NULL)
3966 { 4019 {
3967 /* We still have the IP address from the last lease. 4020 /* We still have the IP address from the last lease.
3968 * Fake add the address and routes from it so the lease 4021 * Fake add the address and routes from it so the lease
3969 * can be cleaned up. */ 4022 * can be cleaned up. */
3970 state->new = malloc(state->offer_len); 4023 state->new = malloc(state->offer_len);
3971 if (state->new) { 4024 if (state->new) {
3972 memcpy(state->new, 4025 memcpy(state->new,
3973 state->offer, state->offer_len); 4026 state->offer, state->offer_len);
3974 state->new_len = state->offer_len; 4027 state->new_len = state->offer_len;
3975 state->addr = ia; 4028 state->addr = ia;
3976 state->added |= STATE_ADDED | STATE_FAKE; 4029 state->added |= STATE_ADDED | STATE_FAKE;
3977 rt_build(ifp->ctx, AF_INET); 4030 rt_build(ifp->ctx, AF_INET);
3978 } else 4031 } else
3979 logerr(__func__); 4032 logerr(__func__);
3980 } 4033 }
3981 if (!IS_DHCP(state->offer)) { 4034 if (!IS_DHCP(state->offer)) {
3982 free(state->offer); 4035 free(state->offer);
3983 state->offer = NULL; 4036 state->offer = NULL;
3984 state->offer_len = 0; 4037 state->offer_len = 0;
3985 } else if (!(ifo->options & DHCPCD_LASTLEASE_EXTEND) && 4038 } else if (!(ifo->options & DHCPCD_LASTLEASE_EXTEND) &&
3986 state->lease.leasetime != DHCP_INFINITE_LIFETIME && 4039 state->lease.leasetime != DHCP_INFINITE_LIFETIME &&
3987 dhcp_filemtime(ifp->ctx, state->leasefile, &mtime) == 0) 4040 dhcp_filemtime(ifp->ctx, state->leasefile, &mtime) == 0)
3988 { 4041 {
3989 time_t now; 4042 time_t now;
3990 4043
3991 /* Offset lease times and check expiry */ 4044 /* Offset lease times and check expiry */
3992 now = time(NULL); 4045 now = time(NULL);
3993 if (now == -1 || 4046 if (now == -1 ||
3994 (time_t)state->lease.leasetime < now - mtime) 4047 (time_t)state->lease.leasetime < now - mtime)
3995 { 4048 {
3996 logdebugx("%s: discarding expired lease", 4049 logdebugx("%s: discarding expired lease",
3997 ifp->name); 4050 ifp->name);
3998 free(state->offer); 4051 free(state->offer);
3999 state->offer = NULL; 4052 state->offer = NULL;
4000 state->offer_len = 0; 4053 state->offer_len = 0;
4001 state->lease.addr.s_addr = 0; 4054 state->lease.addr.s_addr = 0;
4002 /* Technically we should discard the lease 4055 /* Technically we should discard the lease
4003 * as it's expired, just as DHCPv6 addresses 4056 * as it's expired, just as DHCPv6 addresses
4004 * would be by the kernel. 4057 * would be by the kernel.
4005 * However, this may violate POLA so 4058 * However, this may violate POLA so
4006 * we currently leave it be. 4059 * we currently leave it be.
4007 * If we get a totally different lease from 4060 * If we get a totally different lease from
4008 * the DHCP server we'll drop it anyway, as 4061 * the DHCP server we'll drop it anyway, as
4009 * we will on any other event which would 4062 * we will on any other event which would
4010 * trigger a lease drop. 4063 * trigger a lease drop.
4011 * This should only happen if dhcpcd stops 4064 * This should only happen if dhcpcd stops
4012 * running and the lease expires before 4065 * running and the lease expires before
4013 * dhcpcd starts again. */ 4066 * dhcpcd starts again. */
4014#if 0 4067#if 0
4015 if (state->new) 4068 if (state->new)
4016 dhcp_drop(ifp, "EXPIRE"); 4069 dhcp_drop(ifp, "EXPIRE");
4017#endif 4070#endif
4018 } else { 4071 } else {
4019 l = (uint32_t)(now - mtime); 4072 l = (uint32_t)(now - mtime);
4020 state->lease.leasetime -= l; 4073 state->lease.leasetime -= l;
4021 state->lease.renewaltime -= l; 4074 state->lease.renewaltime -= l;
4022 state->lease.rebindtime -= l; 4075 state->lease.rebindtime -= l;
4023 } 4076 }
4024 } 4077 }
4025 } 4078 }
4026 4079
4027#ifdef IPV4LL 4080#ifdef IPV4LL
4028 if (!(ifo->options & DHCPCD_DHCP)) { 4081 if (!(ifo->options & DHCPCD_DHCP)) {
4029 if (ifo->options & DHCPCD_IPV4LL) 4082 if (ifo->options & DHCPCD_IPV4LL)
4030 ipv4ll_start(ifp); 4083 ipv4ll_start(ifp);
4031 return; 4084 return;
4032 } 4085 }
4033#endif 4086#endif
4034 4087
4035 if (state->offer == NULL || 4088 if (state->offer == NULL ||
4036 !IS_DHCP(state->offer) || 4089 !IS_DHCP(state->offer) ||
4037 ifo->options & DHCPCD_ANONYMOUS) 4090 ifo->options & DHCPCD_ANONYMOUS)
4038 dhcp_discover(ifp); 4091 dhcp_discover(ifp);
4039 else 4092 else
4040 dhcp_reboot(ifp); 4093 dhcp_reboot(ifp);
4041} 4094}
4042 4095
4043void 4096void
4044dhcp_start(struct interface *ifp) 4097dhcp_start(struct interface *ifp)
4045{ 4098{
4046 unsigned int delay; 4099 unsigned int delay;
4047#ifdef ARPING 4100#ifdef ARPING
4048 const struct dhcp_state *state; 4101 const struct dhcp_state *state;
4049#endif 4102#endif
4050 4103
4051 if (!(ifp->options->options & DHCPCD_IPV4)) 4104 if (!(ifp->options->options & DHCPCD_IPV4))
4052 return; 4105 return;
4053 4106
4054 /* If we haven't been given a netmask for our requested address, 4107 /* If we haven't been given a netmask for our requested address,
4055 * set it now. */ 4108 * set it now. */
4056 if (ifp->options->req_addr.s_addr != INADDR_ANY && 4109 if (ifp->options->req_addr.s_addr != INADDR_ANY &&
4057 ifp->options->req_mask.s_addr == INADDR_ANY) 4110 ifp->options->req_mask.s_addr == INADDR_ANY)
4058 ifp->options->req_mask.s_addr = 4111 ifp->options->req_mask.s_addr =
4059 ipv4_getnetmask(ifp->options->req_addr.s_addr); 4112 ipv4_getnetmask(ifp->options->req_addr.s_addr);
4060 4113
4061 /* If we haven't specified a ClientID and our hardware address 4114 /* If we haven't specified a ClientID and our hardware address
4062 * length is greater than BOOTP CHADDR then we enforce a ClientID 4115 * length is greater than BOOTP CHADDR then we enforce a ClientID
4063 * of the hardware address type and the hardware address. 4116 * of the hardware address type and the hardware address.
4064 * If there is no hardware address and no ClientID set, 4117 * If there is no hardware address and no ClientID set,
4065 * force a DUID based ClientID. */ 4118 * force a DUID based ClientID. */
4066 if (ifp->hwlen > 16) 4119 if (ifp->hwlen > 16)
4067 ifp->options->options |= DHCPCD_CLIENTID; 4120 ifp->options->options |= DHCPCD_CLIENTID;
4068 else if (ifp->hwlen == 0 && !(ifp->options->options & DHCPCD_CLIENTID)) 4121 else if (ifp->hwlen == 0 && !(ifp->options->options & DHCPCD_CLIENTID))
4069 ifp->options->options |= DHCPCD_CLIENTID | DHCPCD_DUID; 4122 ifp->options->options |= DHCPCD_CLIENTID | DHCPCD_DUID;
4070 4123
4071 /* Firewire and InfiniBand interfaces require ClientID and 4124 /* Firewire and InfiniBand interfaces require ClientID and
4072 * the broadcast option being set. */ 4125 * the broadcast option being set. */
4073 switch (ifp->hwtype) { 4126 switch (ifp->hwtype) {
4074 case ARPHRD_IEEE1394: /* FALLTHROUGH */ 4127 case ARPHRD_IEEE1394: /* FALLTHROUGH */
4075 case ARPHRD_INFINIBAND: 4128 case ARPHRD_INFINIBAND:
4076 ifp->options->options |= DHCPCD_CLIENTID | DHCPCD_BROADCAST; 4129 ifp->options->options |= DHCPCD_CLIENTID | DHCPCD_BROADCAST;
4077 break; 4130 break;
4078 } 4131 }
4079 4132
4080 /* If we violate RFC2131 section 3.7 then require ARP 4133 /* If we violate RFC2131 section 3.7 then require ARP
4081 * to detect if any other client wants our address. */ 4134 * to detect if any other client wants our address. */
4082 if (ifp->options->options & DHCPCD_LASTLEASE_EXTEND) 4135 if (ifp->options->options & DHCPCD_LASTLEASE_EXTEND)
4083 ifp->options->options |= DHCPCD_ARP; 4136 ifp->options->options |= DHCPCD_ARP;
4084 4137
4085 /* No point in delaying a static configuration */ 4138 /* No point in delaying a static configuration */
4086 if (ifp->options->options & DHCPCD_STATIC || 4139 if (ifp->options->options & DHCPCD_STATIC ||
4087 !(ifp->options->options & DHCPCD_INITIAL_DELAY)) 4140 !(ifp->options->options & DHCPCD_INITIAL_DELAY))
4088 { 4141 {
4089 dhcp_start1(ifp); 4142 dhcp_start1(ifp);
4090 return; 4143 return;
4091 } 4144 }
4092 4145
4093#ifdef ARPING 4146#ifdef ARPING
4094 /* If we have arpinged then we have already delayed. */ 4147 /* If we have arpinged then we have already delayed. */
4095 state = D_CSTATE(ifp); 4148 state = D_CSTATE(ifp);
4096 if (state != NULL && state->arping_index != -1) { 4149 if (state != NULL && state->arping_index != -1) {
4097 dhcp_start1(ifp); 4150 dhcp_start1(ifp);
4098 return; 4151 return;
4099 } 4152 }
4100#endif 4153#endif
4101 delay = MSEC_PER_SEC + 4154 delay = MSEC_PER_SEC +
4102 (arc4random_uniform(MSEC_PER_SEC * 2) - MSEC_PER_SEC); 4155 (arc4random_uniform(MSEC_PER_SEC * 2) - MSEC_PER_SEC);
4103 logdebugx("%s: delaying IPv4 for %0.1f seconds", 4156 logdebugx("%s: delaying IPv4 for %0.1f seconds",
4104 ifp->name, (float)delay / MSEC_PER_SEC); 4157 ifp->name, (float)delay / MSEC_PER_SEC);
4105 4158
4106 eloop_timeout_add_msec(ifp->ctx->eloop, delay, dhcp_start1, ifp); 4159 eloop_timeout_add_msec(ifp->ctx->eloop, delay, dhcp_start1, ifp);
4107} 4160}
4108 4161
4109void 4162void
4110dhcp_abort(struct interface *ifp) 4163dhcp_abort(struct interface *ifp)
4111{ 4164{
4112 struct dhcp_state *state; 4165 struct dhcp_state *state;
4113 4166
4114 state = D_STATE(ifp); 4167 state = D_STATE(ifp);
4115#ifdef ARPING 4168#ifdef ARPING
4116 if (state != NULL) 4169 if (state != NULL)
4117 state->arping_index = -1; 4170 state->arping_index = -1;
4118#endif 4171#endif
4119 4172
4120 eloop_timeout_delete(ifp->ctx->eloop, dhcp_start1, ifp); 4173 eloop_timeout_delete(ifp->ctx->eloop, dhcp_start1, ifp);
4121 4174
4122 if (state != NULL && state->added) { 4175 if (state != NULL && state->added) {
4123 rt_build(ifp->ctx, AF_INET); 4176 rt_build(ifp->ctx, AF_INET);
4124#ifdef ARP 4177#ifdef ARP
4125 if (ifp->options->options & DHCPCD_ARP) 4178 if (ifp->options->options & DHCPCD_ARP)
4126 arp_announceaddr(ifp->ctx, &state->addr->addr); 4179 arp_announceaddr(ifp->ctx, &state->addr->addr);
4127#endif 4180#endif
4128 } 4181 }
4129} 4182}
4130 4183
4131struct ipv4_addr * 4184struct ipv4_addr *
4132dhcp_handleifa(int cmd, struct ipv4_addr *ia, pid_t pid) 4185dhcp_handleifa(int cmd, struct ipv4_addr *ia, pid_t pid)
4133{ 4186{
4134 struct interface *ifp; 4187 struct interface *ifp;
4135 struct dhcp_state *state; 4188 struct dhcp_state *state;
4136 struct if_options *ifo; 4189 struct if_options *ifo;
4137 uint8_t i; 4190 uint8_t i;
4138 4191
4139 ifp = ia->iface; 4192 ifp = ia->iface;
4140 state = D_STATE(ifp); 4193 state = D_STATE(ifp);
4141 if (state == NULL || state->state == DHS_NONE) 4194 if (state == NULL || state->state == DHS_NONE)
4142 return ia; 4195 return ia;
4143 4196
4144 if (cmd == RTM_DELADDR) { 4197 if (cmd == RTM_DELADDR) {
4145 if (state->addr == ia) { 4198 if (state->addr == ia) {
4146 loginfox("%s: pid %d deleted IP address %s", 4199 loginfox("%s: pid %d deleted IP address %s",
4147 ifp->name, pid, ia->saddr); 4200 ifp->name, pid, ia->saddr);
4148 dhcp_close(ifp); 4201 dhcp_close(ifp);
4149 state->addr = NULL; 4202 state->addr = NULL;
4150 /* Don't clear the added state as we need 4203 /* Don't clear the added state as we need
4151 * to drop the lease. */ 4204 * to drop the lease. */
4152 dhcp_drop(ifp, "EXPIRE"); 4205 dhcp_drop(ifp, "EXPIRE");
4153 dhcp_start1(ifp); 4206 dhcp_start1(ifp);
4154 return ia; 4207 return ia;
4155 } 4208 }
4156 } 4209 }
4157 4210
4158 if (cmd != RTM_NEWADDR) 4211 if (cmd != RTM_NEWADDR)
4159 return ia; 4212 return ia;
4160 4213
4161#ifdef IN_IFF_NOTUSEABLE 4214#ifdef IN_IFF_NOTUSEABLE
4162 if (!(ia->addr_flags & IN_IFF_NOTUSEABLE)) 4215 if (!(ia->addr_flags & IN_IFF_NOTUSEABLE))
4163 dhcp_finish_dad(ifp, &ia->addr); 4216 dhcp_finish_dad(ifp, &ia->addr);
4164 else if (ia->addr_flags & IN_IFF_DUPLICATED) 4217 else if (ia->addr_flags & IN_IFF_DUPLICATED)
4165 return dhcp_addr_duplicated(ifp, &ia->addr) ? NULL : ia; 4218 return dhcp_addr_duplicated(ifp, &ia->addr) ? NULL : ia;
4166#endif 4219#endif
4167 4220
4168 ifo = ifp->options; 4221 ifo = ifp->options;
4169 if (ifo->options & DHCPCD_INFORM) { 4222 if (ifo->options & DHCPCD_INFORM) {
4170 if (state->state != DHS_INFORM) 4223 if (state->state != DHS_INFORM)
4171 dhcp_inform(ifp); 4224 dhcp_inform(ifp);
4172 return ia; 4225 return ia;
4173 } 4226 }
4174 4227
4175 if (!(ifo->options & DHCPCD_STATIC)) 4228 if (!(ifo->options & DHCPCD_STATIC))
4176 return ia; 4229 return ia;
4177 if (ifo->req_addr.s_addr != INADDR_ANY) 4230 if (ifo->req_addr.s_addr != INADDR_ANY)
4178 return ia; 4231 return ia;
4179 4232
4180 free(state->old); 4233 free(state->old);
4181 state->old = state->new; 4234 state->old = state->new;
4182 state->new_len = dhcp_message_new(&state->new, &ia->addr, &ia->mask); 4235 state->new_len = dhcp_message_new(&state->new, &ia->addr, &ia->mask);
4183 if (state->new == NULL) 4236 if (state->new == NULL)
4184 return ia; 4237 return ia;

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

--- src/external/bsd/dhcpcd/dist/src/Attic/dhcpcd.8.in 2020/09/06 14:55:34 1.8
+++ src/external/bsd/dhcpcd/dist/src/Attic/dhcpcd.8.in 2020/11/01 14:24:01 1.9
@@ -1,858 +1,850 @@ @@ -1,858 +1,850 @@
1.\" SPDX-License-Identifier: BSD-2-Clause 1.\" SPDX-License-Identifier: BSD-2-Clause
2.\" 2.\"
3.\" Copyright (c) 2006-2020 Roy Marples 3.\" Copyright (c) 2006-2020 Roy Marples
4.\" All rights reserved 4.\" All rights reserved
5.\" 5.\"
6.\" Redistribution and use in source and binary forms, with or without 6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions 7.\" modification, are permitted provided that the following conditions
8.\" are met: 8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright 9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer. 10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
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 September 2, 2020 27.Dd October 30, 2020
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
41.Op Fl h , Fl Fl hostname Ar hostname 41.Op Fl h , Fl Fl hostname Ar hostname
42.Op Fl I , Fl Fl clientid Ar clientid 42.Op Fl I , Fl Fl clientid Ar clientid
43.Op Fl i , Fl Fl vendorclassid Ar vendorclassid 43.Op Fl i , Fl Fl vendorclassid Ar vendorclassid
44.Op Fl j , Fl Fl logfile Ar logfile 44.Op Fl j , Fl Fl logfile Ar logfile
45.Op Fl l , Fl Fl leasetime Ar seconds 45.Op Fl l , Fl Fl leasetime Ar seconds
46.Op Fl m , Fl Fl metric Ar metric 46.Op Fl m , Fl Fl metric Ar metric
47.Op Fl O , Fl Fl nooption Ar option 47.Op Fl O , Fl Fl nooption Ar option
48.Op Fl o , Fl Fl option Ar option 48.Op Fl o , Fl Fl option Ar option
49.Op Fl Q , Fl Fl require Ar option 49.Op Fl Q , Fl Fl require Ar option
50.Op Fl r , Fl Fl request Ar address 50.Op Fl r , Fl Fl request Ar address
51.Op Fl S , Fl Fl static Ar value 51.Op Fl S , Fl Fl static Ar value
52.Op Fl s , Fl Fl inform Ar address Ns Op Ar /cidr Ns Op Ar /broadcast_address 52.Op Fl s , Fl Fl inform Ar address Ns Op Ar /cidr Ns Op Ar /broadcast_address
53.Op Fl Fl inform6 53.Op Fl Fl inform6
54.Op Fl t , Fl Fl timeout Ar seconds 54.Op Fl t , Fl Fl timeout Ar seconds
55.Op Fl u , Fl Fl userclass Ar class 55.Op Fl u , Fl Fl userclass Ar class
56.Op Fl v , Fl Fl vendor Ar code , Ar value 56.Op Fl v , Fl Fl vendor Ar code , Ar value
57.Op Fl W , Fl Fl whitelist Ar address Ns Op Ar /cidr 57.Op Fl W , Fl Fl whitelist Ar address Ns Op Ar /cidr
58.Op Fl w 58.Op Fl w
59.Op Fl Fl waitip Ns = Ns Op 4 | 6 59.Op Fl Fl waitip Ns = Ns Op 4 | 6
60.Op Fl y , Fl Fl reboot Ar seconds 60.Op Fl y , Fl Fl reboot Ar seconds
61.Op Fl X , Fl Fl blacklist Ar address Ns Op Ar /cidr 61.Op Fl X , Fl Fl blacklist Ar address Ns Op Ar /cidr
62.Op Fl Z , Fl Fl denyinterfaces Ar pattern 62.Op Fl Z , Fl Fl denyinterfaces Ar pattern
63.Op Fl z , Fl Fl allowinterfaces Ar pattern 63.Op Fl z , Fl Fl allowinterfaces Ar pattern
64.Op Fl Fl inactive 64.Op Fl Fl inactive
65.Op interface 65.Op interface
66.Op ... 66.Op ...
67.Nm 67.Nm
68.Fl n , Fl Fl rebind 68.Fl n , Fl Fl rebind
69.Op interface 69.Op interface
70.Nm 70.Nm
71.Fl k , Fl Fl release 71.Fl k , Fl Fl release
72.Op interface 72.Op interface
73.Nm 73.Nm
74.Fl U , Fl Fl dumplease 74.Fl U , Fl Fl dumplease
75.Op Ar interface 75.Op Ar interface
76.Nm 76.Nm
77.Fl Fl version 77.Fl Fl version
78.Nm 78.Nm
79.Fl x , Fl Fl exit 79.Fl x , Fl Fl exit
80.Op interface 80.Op interface
81.Sh DESCRIPTION 81.Sh DESCRIPTION
82.Nm 82.Nm
83is an implementation of the DHCP client specified in 83is an implementation of the DHCP client specified in
84.Li RFC 2131 . 84.Li RFC 2131 .
85.Nm 85.Nm
86gets the host information 86gets the host information
87.Po 87.Po
88IP address, routes, etc 88IP address, routes, etc
89.Pc 89.Pc
90from a DHCP server and configures the network 90from a DHCP server and configures the network
91.Ar interface 91.Ar interface
92of the 92of the
93machine on which it is running. 93machine on which it is running.
94.Nm 94.Nm
95then runs the configuration script which writes DNS information to 95then runs the configuration script which writes DNS information to
96.Xr resolvconf 8 , 96.Xr resolvconf 8 ,
97if available, otherwise directly to 97if available, otherwise directly to
98.Pa /etc/resolv.conf . 98.Pa /etc/resolv.conf .
99If the hostname is currently blank, (null) or localhost, or 99If the hostname is currently blank, (null) or localhost, or
100.Va force_hostname 100.Va force_hostname
101is YES or TRUE or 1 then 101is YES or TRUE or 1 then
102.Nm 102.Nm
103sets the hostname to the one supplied by the DHCP server. 103sets the hostname to the one supplied by the DHCP server.
104.Nm 104.Nm
105then daemonises and waits for the lease renewal time to lapse. 105then daemonises and waits for the lease renewal time to lapse.
106It will then attempt to renew its lease and reconfigure if the new lease 106It will then attempt to renew its lease and reconfigure if the new lease
107changes when the lease begins to expire or the DHCP server sends a message 107changes when the lease begins to expire or the DHCP server sends a message
108to renew early. 108to renew early.
109.Pp 109.Pp
110If any interface reports a working carrier then 110If any interface reports a working carrier then
111.Nm 111.Nm
112will try to obtain a lease before forking to the background, 112will try to obtain a lease before forking to the background,
113otherwise it will fork right away. 113otherwise it will fork right away.
114This behaviour can be modified with the 114This behaviour can be modified with the
115.Fl b , Fl Fl background 115.Fl b , Fl Fl background
116and 116and
117.Fl w , Fl Fl waitip 117.Fl w , Fl Fl waitip
118options. 118options.
119.Pp 119.Pp
120.Nm 120.Nm
121is also an implementation of the BOOTP client specified in 121is also an implementation of the BOOTP client specified in
122.Li RFC 951 . 122.Li RFC 951 .
123.Pp 123.Pp
124.Nm 124.Nm
125is also an implementation of the IPv6 Router Solicitor as specified in 125is also an implementation of the IPv6 Router Solicitor as specified in
126.Li RFC 4861 126.Li RFC 4861
127and 127and
128.Li RFC 6106 . 128.Li RFC 6106 .
129.Pp 129.Pp
130.Nm 130.Nm
131is also an implementation of the IPv6 Privacy Extensions to AutoConf as 131is also an implementation of the IPv6 Privacy Extensions to AutoConf as
132specified in 132specified in
133.Li RFC 4941 . 133.Li RFC 4941 .
134This feature needs to be enabled in the kernel and 134This feature needs to be enabled in the kernel and
135.Nm 135.Nm
136will start using it. 136will start using it.
137.Pp 137.Pp
138.Nm 138.Nm
139is also an implementation of the DHCPv6 client as specified in 139is also an implementation of the DHCPv6 client as specified in
140.Li RFC 3315 . 140.Li RFC 3315 .
141By default, 141By default,
142.Nm 142.Nm
143only starts DHCPv6 when instructed to do so by an IPV6 Router Advertisement. 143only starts DHCPv6 when instructed to do so by an IPV6 Router Advertisement.
144If no Identity Association is configured, 144If no Identity Association is configured,
145then a Non-temporary Address is requested. 145then a Non-temporary Address is requested.
146.Ss Local Link configuration 146.Ss Local Link configuration
147If 147If
148.Nm 148.Nm
149failed to obtain a lease, it probes for a valid IPv4LL address 149failed to obtain a lease, it probes for a valid IPv4LL address
150.Po 150.Po
151aka ZeroConf, aka APIPA 151aka ZeroConf, aka APIPA
152.Pc . 152.Pc .
153Once obtained it restarts the process of looking for a DHCP server to get a 153Once obtained it restarts the process of looking for a DHCP server to get a
154proper address. 154proper address.
155.Pp 155.Pp
156When using IPv4LL, 156When using IPv4LL,
157.Nm 157.Nm
158nearly always succeeds and returns an exit code of 0. 158nearly always succeeds and returns an exit code of 0.
159In the rare case it fails, it normally means that there is a reverse ARP proxy 159In the rare case it fails, it normally means that there is a reverse ARP proxy
160installed which always defeats IPv4LL probing. 160installed which always defeats IPv4LL probing.
161To disable this behaviour, you can use the 161To disable this behaviour, you can use the
162.Fl L , Fl Fl noipv4ll 162.Fl L , Fl Fl noipv4ll
163option. 163option.
164.Ss Multiple interfaces 164.Ss Multiple interfaces
165If a list of interfaces are given on the command line, then 165If a list of interfaces are given on the command line, then
166.Nm 166.Nm
167only works with those interfaces, otherwise 167only works with those interfaces, otherwise
168.Nm 168.Nm
169discovers available Ethernet interfaces that can be configured. 169discovers available Ethernet interfaces that can be configured.
170When 170When
171.Nm 171.Nm
172not limited to one interface on the command line, 172not limited to one interface on the command line,
173it is running in Master mode. 173it is running in Master mode.
174The 174The
175.Nm dhcpcd-ui 175.Nm dhcpcd-ui
176project expects dhcpcd to be running this way. 176project expects dhcpcd to be running this way.
177.Pp 177.Pp
178If a single interface is given then 178If a single interface is given then
179.Nm 179.Nm
180only works for that interface and runs as a separate instance to other 180only works for that interface and runs as a separate instance to other
181.Nm 181.Nm
182processes. 182processes.
183.Fl w , Fl Fl waitip 183.Fl w , Fl Fl waitip
184option is enabled in this instance to maintain compatibility with older 184option is enabled in this instance to maintain compatibility with older
185versions. 185versions.
186Using a single interface also affects the 186Using a single interface also affects the
187.Fl k , 187.Fl k ,
188.Fl N , 188.Fl N ,
189.Fl n 189.Fl n
190and 190and
191.Fl x 191.Fl x
192options, where the same interface will need to be specified, as a lack of an 192options, where the same interface will need to be specified, as a lack of an
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 206.Pp
207Non-ethernet interfaces and some virtual ethernet interfaces 207Non-ethernet interfaces and some virtual ethernet interfaces
208such as TAP and bridge are ignored by default, 208such as TAP and bridge are ignored by default,
209as is the FireWire interface. 209as is the FireWire interface.
210To work with these devices they either need to be specified on the command line, 210To work with these devices they either need to be specified on the command line,
211be listed in 211be listed in
212.Fl Fl allowinterfaces 212.Fl Fl allowinterfaces
213or have an interface directive in 213or have an interface directive in
214.Pa @SYSCONFDIR@/dhcpcd.conf . 214.Pa @SYSCONFDIR@/dhcpcd.conf .
215.Ss Hooking into events 215.Ss Hooking into events
216.Nm 216.Nm
217runs 217runs
218.Pa @SCRIPT@ , 218.Pa @SCRIPT@ ,
219or the script specified by the 219or the script specified by the
220.Fl c , Fl Fl script 220.Fl c , Fl Fl script
221option. 221option.
222This script runs each script found in 222This script runs each script found in
223.Pa @HOOKDIR@ 223.Pa @HOOKDIR@
224in a lexical order. 224in a lexical order.
225The default installation supplies the scripts 225The default installation supplies the scripts
226.Pa 01-test , 226.Pa 01-test ,
227.Pa 02-dump , 227.Pa 02-dump ,
228.Pa 20-resolv.conf 228.Pa 20-resolv.conf
229and 229and
230.Pa 30-hostname . 230.Pa 30-hostname .
231You can disable each script by using the 231You can disable each script by using the
232.Fl C , Fl Fl nohook 232.Fl C , Fl Fl nohook
233option. 233option.
234See 234See
235.Xr dhcpcd-run-hooks 8 235.Xr dhcpcd-run-hooks 8
236for details on how these scripts work. 236for details on how these scripts work.
237.Nm 237.Nm
238currently ignores the exit code of the script. 238currently ignores the exit code of the script.
239.Pp 239.Pp
240More scripts are supplied in 240More scripts are supplied in
241.Pa @DATADIR@/dhcpcd/hooks 241.Pa @DATADIR@/dhcpcd/hooks
242and need to be copied to 242and need to be copied to
243.Pa @HOOKDIR@ 243.Pa @HOOKDIR@
244if you intend to use them. 244if you intend to use them.
245For example, you could install 245For example, you could install
246.Pa 29-lookup-hostname 246.Pa 29-lookup-hostname
247so that 247so that
248.Nm 248.Nm
249can lookup the hostname of the IP address in DNS if no hostname 249can lookup the hostname of the IP address in DNS if no hostname
250is given by the lease and one is not already set. 250is given by the lease and one is not already set.
251.Ss Fine tuning 251.Ss Fine tuning
252You can fine-tune the behaviour of 252You can fine-tune the behaviour of
253.Nm 253.Nm
254with the following options: 254with the following options:
255.Bl -tag -width indent 255.Bl -tag -width indent
256.It Fl b , Fl Fl background 256.It Fl b , Fl Fl background
257Background immediately. 257Background immediately.
258This is useful for startup scripts which don't disable link messages for 258This is useful for startup scripts which don't disable link messages for
259carrier status. 259carrier status.
260.It Fl c , Fl Fl script Ar script 260.It Fl c , Fl Fl script Ar script
261Use this 261Use this
262.Ar script 262.Ar script
263instead of the default 263instead of the default
264.Pa @SCRIPT@ . 264.Pa @SCRIPT@ .
265.It Fl D , Fl Fl duid 265.It Fl D , Fl Fl duid
266Use a DHCP Unique Identifier. 266Use a DHCP Unique Identifier.
267If a system UUID is available, that will be used to create a DUID-UUID, 267If a system UUID is available, that will be used to create a DUID-UUID,
268otheriwse if persistent storage is available then a DUID-LLT 268otheriwse if persistent storage is available then a DUID-LLT
269(link local address + time) is generated, 269(link local address + time) is generated,
270otherwise DUID-LL is generated (link local address). 270otherwise DUID-LL is generated (link local address).
271This, plus the IAID will be used as the 271This, plus the IAID will be used as the
272.Fl I , Fl Fl clientid . 272.Fl I , Fl Fl clientid .
273The DUID generated will be held in 273The DUID generated will be held in
274.Pa @DBDIR@/duid 274.Pa @DBDIR@/duid
275and should not be copied to other hosts. 275and should not be copied to other hosts.
276This file also takes precedence over the above rules. 276This file also takes precedence over the above rules.
277.It Fl d , Fl Fl debug 277.It Fl d , Fl Fl debug
278Echo debug messages to the stderr and syslog. 278Echo debug messages to the stderr and syslog.
279.It Fl E , Fl Fl lastlease 279.It Fl E , Fl Fl lastlease
280If 280If
281.Nm 281.Nm
282cannot obtain a lease, then try to use the last lease acquired for the 282cannot obtain a lease, then try to use the last lease acquired for the
283interface. 283interface.
284.It Fl Fl lastleaseextend 284.It Fl Fl lastleaseextend
285Same as the above, but the lease will be retained even if it expires. 285Same as the above, but the lease will be retained even if it expires.
286.Nm 286.Nm
287will give it up if any other host tries to claim it for their own via ARP. 287will give it up if any other host tries to claim it for their own via ARP.
288This violates RFC 2131, section 3.7, which states the lease should be 288This violates RFC 2131, section 3.7, which states the lease should be
289dropped once it has expired. 289dropped once it has expired.
290.It Fl e , Fl Fl env Ar value 290.It Fl e , Fl Fl env Ar value
291Push 291Push
292.Ar value 292.Ar value
293to the environment for use in 293to the environment for use in
294.Xr dhcpcd-run-hooks 8 . 294.Xr dhcpcd-run-hooks 8 .
295For example, you can force the hostname hook to always set the hostname with 295For example, you can force the hostname hook to always set the hostname with
296.Fl e 296.Fl e
297.Va force_hostname=YES . 297.Va force_hostname=YES .
298.It Fl g , Fl Fl reconfigure 298.It Fl g , Fl Fl reconfigure
299.Nm 299.Nm
300will re-apply IP address, routing and run 300will re-apply IP address, routing and run
301.Xr dhcpcd-run-hooks 8 301.Xr dhcpcd-run-hooks 8
302for each interface. 302for each interface.
303This is useful so that a 3rd party such as PPP or VPN can change the routing 303This is useful so that a 3rd party such as PPP or VPN can change the routing
304table and / or DNS, etc and then instruct 304table and / or DNS, etc and then instruct
305.Nm 305.Nm
306to put things back afterwards. 306to put things back afterwards.
307.Nm 307.Nm
308does not read a new configuration when this happens - you should rebind if you 308does not read a new configuration when this happens - you should rebind if you
309need that functionality. 309need that functionality.
310.It Fl F , Fl Fl fqdn Ar fqdn 310.It Fl F , Fl Fl fqdn Ar fqdn
311Requests that the DHCP server updates DNS using FQDN instead of just a 311Requests that the DHCP server updates DNS using FQDN instead of just a
312hostname. 312hostname.
313Valid values for 313Valid values for
314.Ar fqdn 314.Ar fqdn
315are disable, none, ptr and both. 315are disable, none, ptr and both.
316.Nm 316.Nm
317itself never does any DNS updates. 317itself never does any DNS updates.
318.Nm 318.Nm
319encodes the FQDN hostname as specified in 319encodes the FQDN hostname as specified in
320.Li RFC 1035 . 320.Li RFC 1035 .
321.It Fl f , Fl Fl config Ar file 321.It Fl f , Fl Fl config Ar file
322Specify a config to load instead of 322Specify a config to load instead of
323.Pa @SYSCONFDIR@/dhcpcd.conf . 323.Pa @SYSCONFDIR@/dhcpcd.conf .
324.Nm 324.Nm
325always processes the config file before any command line options. 325always processes the config file before any command line options.
326.It Fl h , Fl Fl hostname Ar hostname 326.It Fl h , Fl Fl hostname Ar hostname
327Sends 327Sends
328.Ar hostname 328.Ar hostname
329to the DHCP server so it can be registered in DNS. 329to the DHCP server so it can be registered in DNS.
330If 330If
331.Ar hostname 331.Ar hostname
332is an empty string then the current system hostname is sent. 332is an empty string then the current system hostname is sent.
333If 333If
334.Ar hostname 334.Ar hostname
335is a FQDN (i.e., contains a .) then it will be encoded as such. 335is a FQDN (i.e., contains a .) then it will be encoded as such.
336.It Fl I , Fl Fl clientid Ar clientid 336.It Fl I , Fl Fl clientid Ar clientid
337Send the 337Send the
338.Ar clientid . 338.Ar clientid .
339If the string is of the format 01:02:03 then it is encoded as hex. 339If the string is of the format 01:02:03 then it is encoded as hex.
340For interfaces whose hardware address is longer than 8 bytes, or if the 340For interfaces whose hardware address is longer than 8 bytes, or if the
341.Ar clientid 341.Ar clientid
342is an empty string then 342is an empty string then
343.Nm 343.Nm
344sends a default 344sends a default
345.Ar clientid 345.Ar clientid
346of the hardware family and the hardware address. 346of the hardware family and the hardware address.
347.It Fl i , Fl Fl vendorclassid Ar vendorclassid 347.It Fl i , Fl Fl vendorclassid Ar vendorclassid
348Override the DHCPv4 348Override the DHCPv4
349.Ar vendorclassid 349.Ar vendorclassid
350field sent. 350field sent.
351The default is 351The default is
352dhcpcd-<version>:<os>:<machine>:<platform>. 352dhcpcd-<version>:<os>:<machine>:<platform>.
353For example 353For example
354.D1 dhcpcd-5.5.6:NetBSD-6.99.5:i386:i386 354.D1 dhcpcd-5.5.6:NetBSD-6.99.5:i386:i386
355If not set then none is sent. 355If not set then none is sent.
356Some badly configured DHCP servers reject unknown vendorclassids. 356Some badly configured DHCP servers reject unknown vendorclassids.
357To work around it, try and impersonate Windows by using the MSFT vendorclassid. 357To work around it, try and impersonate Windows by using the MSFT vendorclassid.
358.It Fl j , Fl Fl logfile Ar logfile 358.It Fl j , Fl Fl logfile Ar logfile
359Writes to the specified 359Writes to the specified
360.Ar logfile . 360.Ar logfile .
361.Nm 361.Nm
362still writes to 362still writes to
363.Xr syslog 3 . 363.Xr syslog 3 .
364The 364The
365.Ar logfile 365.Ar logfile
366is reopened when 366is reopened when
367.Nm 367.Nm
368receives the 368receives the
369.Dv SIGUSR2 369.Dv SIGUSR2
370signal. 370signal.
371.It Fl k , Fl Fl release Op Ar interface 371.It Fl k , Fl Fl release Op Ar interface
372This causes an existing 372This causes an existing
373.Nm 373.Nm
374process running on the 374process running on the
375.Ar interface 375.Ar interface
376to release its lease and de-configure the 376to release its lease and de-configure the
377.Ar interface 377.Ar interface
378regardless of the 378regardless of the
379.Fl p , Fl Fl persistent 379.Fl p , Fl Fl persistent
380option. 380option.
381If no 381If no
382.Ar interface 382.Ar interface
383is specified then this applies to all interfaces in Master mode. 383is specified then this applies to all interfaces in Master mode.
384If no interfaces are left running, 384If no interfaces are left running,
385.Nm 385.Nm
386will exit. 386will exit.
387.It Fl l , Fl Fl leasetime Ar seconds 387.It Fl l , Fl Fl leasetime Ar seconds
388Request a lease time of 388Request a lease time of
389.Ar seconds . 389.Ar seconds .
390.Ar -1 390.Ar -1
391represents an infinite lease time. 391represents an infinite lease time.
392By default 392By default
393.Nm 393.Nm
394does not request any lease time and leaves it in the hands of the 394does not request any lease time and leaves it in the hands of the
395DHCP server. 395DHCP server.
396.It Fl M , Fl Fl master 396.It Fl M , Fl Fl master
397Start 397Start
398.Nm 398.Nm
399in Master mode even if only one interface specified on the command line. 399in Master mode even if only one interface specified on the command line.
400See the Multiple Interfaces section above. 400See the Multiple Interfaces section above.
401.It Fl m , Fl Fl metric Ar metric 401.It Fl m , Fl Fl metric Ar metric
402Metrics are used to prefer an interface over another one, lowest wins. 402Metrics are used to prefer an interface over another one, lowest wins.
403.Nm 403.Nm
404will supply a default metic of 200 + 404will supply a default metic of 200 +
405.Xr if_nametoindex 3 . 405.Xr if_nametoindex 3 .
406An extra 100 will be added for wireless interfaces. 406An extra 100 will be added for wireless interfaces.
407.It Fl n , Fl Fl rebind Op Ar interface 407.It Fl n , Fl Fl rebind Op Ar interface
408Notifies 408Notifies
409.Nm 409.Nm
410to reload its configuration and rebind the specified 410to reload its configuration and rebind the specified
411.Ar interface . 411.Ar interface .
412If no 412If no
413.Ar interface 413.Ar interface
414is specified then this applies to all interfaces in Master mode. 414is specified then this applies to all interfaces in Master mode.
415If 415If
416.Nm 416.Nm
417is not running, then it starts up as normal. 417is not running, then it starts up as normal.
418.It Fl N , Fl Fl renew Op Ar interface 418.It Fl N , Fl Fl renew Op Ar interface
419Notifies 419Notifies
420.Nm 420.Nm
421to renew existing addresses on the specified 421to renew existing addresses on the specified
422.Ar interface . 422.Ar interface .
423If no 423If no
424.Ar interface 424.Ar interface
425is specified then this applies to all interfaces in Master mode. 425is specified then this applies to all interfaces in Master mode.
426If 426If
427.Nm 427.Nm
428is not running, then it starts up as normal. 428is not running, then it starts up as normal.
429Unlike the 429Unlike the
430.Fl n , Fl Fl rebind 430.Fl n , Fl Fl rebind
431option above, the configuration for 431option above, the configuration for
432.Nm 432.Nm
433is not reloaded. 433is not reloaded.
434.It Fl o , Fl Fl option Ar option 434.It Fl o , Fl Fl option Ar option
435Request the DHCP 435Request the DHCP
436.Ar option 436.Ar option
437variable for use in 437variable for use in
438.Pa @SCRIPT@ . 438.Pa @SCRIPT@ .
439.It Fl p , Fl Fl persistent 439.It Fl p , Fl Fl persistent
440.Nm 440.Nm
441normally de-configures the 441normally de-configures the
442.Ar interface 442.Ar interface
443and configuration when it exits. 443and configuration when it exits.
444Sometimes, this isn't desirable if, for example, you have root mounted over 444Sometimes, this isn't desirable if, for example, you have root mounted over
445NFS or SSH clients connect to this host and they need to be notified of 445NFS or SSH clients connect to this host and they need to be notified of
446the host shutting down. 446the host shutting down.
447You can use this option to stop this from happening. 447You can use this option to stop this from happening.
448.It Fl r , Fl Fl request Ar address 448.It Fl r , Fl Fl request Ar address
449Request the 449Request the
450.Ar address 450.Ar address
451in the DHCP DISCOVER message. 451in the DHCP DISCOVER message.
452There is no guarantee this is the address the DHCP server will actually give. 452There is no guarantee this is the address the DHCP server will actually give.
453If no 453If no
454.Ar address 454.Ar address
455is given then the first address currently assigned to the 455is given then the first address currently assigned to the
456.Ar interface 456.Ar interface
457is used. 457is used.
458.It Fl s , Fl Fl inform Ar address Ns Op Ar /cidr Ns Op Ar /broadcast_address 458.It Fl s , Fl Fl inform Ar address Ns Op Ar /cidr Ns Op Ar /broadcast_address
459Behaves like 459Behaves like
460.Fl r , Fl Fl request 460.Fl r , Fl Fl request
461as above, but sends a DHCP INFORM instead of DISCOVER/REQUEST. 461as above, but sends a DHCP INFORM instead of DISCOVER/REQUEST.
462This does not get a lease as such, just notifies the DHCP server of the 462This does not get a lease as such, just notifies the DHCP server of the
463.Ar address 463.Ar address
464in use. 464in use.
465You should also include the optional 465You should also include the optional
466.Ar cidr 466.Ar cidr
467network number in case the address is not already configured on the interface. 467network number in case the address is not already configured on the interface.
468.Nm 468.Nm
469remains running and pretends it has an infinite lease. 469remains running and pretends it has an infinite lease.
470.Nm 470.Nm
471will not de-configure the interface when it exits. 471will not de-configure the interface when it exits.
472If 472If
473.Nm 473.Nm
474fails to contact a DHCP server then it returns a failure instead of falling 474fails to contact a DHCP server then it returns a failure instead of falling
475back on IPv4LL. 475back on IPv4LL.
476.It Fl Fl inform6 476.It Fl Fl inform6
477Performs a DHCPv6 Information Request. 477Performs a DHCPv6 Information Request.
478No address is requested or specified, but all other DHCPv6 options are allowed. 478No address is requested or specified, but all other DHCPv6 options are allowed.
479This is normally performed automatically when the IPv6 Router Advertises 479This is normally performed automatically when the IPv6 Router Advertises
480that the client should perform this operation. 480that the client should perform this operation.
481This option is only needed when 481This option is only needed when
482.Nm 482.Nm
483is not processing IPv6RA messages and the need for DHCPv6 Information Request 483is not processing IPv6RA messages and the need for DHCPv6 Information Request
484exists. 484exists.
485.It Fl S , Fl Fl static Ar value 485.It Fl S , Fl Fl static Ar value
486Configures a static DHCP 486Configures a static DHCP
487.Ar value . 487.Ar value .
488If you set 488If you set
489.Ic ip_address 489.Ic ip_address
490then 490then
491.Nm 491.Nm
492will not attempt to obtain a lease and just use the value for the address with 492will not attempt to obtain a lease and just use the value for the address with
493an infinite lease time. 493an infinite lease time.
494.Pp 494.Pp
495Here is an example which configures a static address, routes and DNS. 495Here is an example which configures a static address, routes and DNS.
496.D1 dhcpcd -S ip_address=192.168.0.10/24 \e 496.D1 dhcpcd -S ip_address=192.168.0.10/24 \e
497.D1 -S routers=192.168.0.1 \e 497.D1 -S routers=192.168.0.1 \e
498.D1 -S domain_name_servers=192.168.0.1 \e 498.D1 -S domain_name_servers=192.168.0.1 \e
499.D1 eth0 499.D1 eth0
500.Pp 500.Pp
501You cannot presently set static DHCPv6 values. 501You cannot presently set static DHCPv6 values.
502Use the 502Use the
503.Fl e , Fl Fl env 503.Fl e , Fl Fl env
504option instead. 504option instead.
505.It Fl t , Fl Fl timeout Ar seconds 505.It Fl t , Fl Fl timeout Ar seconds
506Timeout after 506Timeout after
507.Ar seconds , 507.Ar seconds ,
508instead of the default 30. 508instead of the default 30.
509A setting of 0 509A setting of 0
510.Ar seconds 510.Ar seconds
511causes 511causes
512.Nm 512.Nm
513to wait forever to get a lease. 513to wait forever to get a lease.
514If 514If
515.Nm 515.Nm
516is working on a single interface then 516is working on a single interface then
517.Nm 517.Nm
518will exit when a timeout occurs, otherwise 518will exit when a timeout occurs, otherwise
519.Nm 519.Nm
520will fork into the background. 520will fork into the background.
521.It Fl u , Fl Fl userclass Ar class 521.It Fl u , Fl Fl userclass Ar class
522Tags the DHCPv4 message with the userclass 522Tags the DHCPv4 message with the userclass
523.Ar class . 523.Ar class .
524DHCP servers use this to give members of the class DHCP options other than the 524DHCP servers use this to give members of the class DHCP options other than the
525default, without having to know things like hardware address or hostname. 525default, without having to know things like hardware address or hostname.
526.It Fl v , Fl Fl vendor Ar code , Ns Ar value 526.It Fl v , Fl Fl vendor Ar code , Ns Ar value
527Add an encapsulated vendor option. 527Add an encapsulated vendor option.
528.Ar code 528.Ar code
529should be between 1 and 254 inclusive. 529should be between 1 and 254 inclusive.
530To add a raw vendor string, omit 530To add a raw vendor string, omit
531.Ar code 531.Ar code
532but keep the comma. 532but keep the comma.
533Examples. 533Examples.
534.Pp 534.Pp
535Set the vendor option 01 with an IP address. 535Set the vendor option 01 with an IP address.
536.D1 dhcpcd \-v 01,192.168.0.2 eth0 536.D1 dhcpcd \-v 01,192.168.0.2 eth0
537Set the vendor option 02 with a hex code. 537Set the vendor option 02 with a hex code.
538.D1 dhcpcd \-v 02,01:02:03:04:05 eth0 538.D1 dhcpcd \-v 02,01:02:03:04:05 eth0
539Set the vendor option 03 with an IP address as a string. 539Set the vendor option 03 with an IP address as a string.
540.D1 dhcpcd \-v 03,\e"192.168.0.2\e" eth0 540.D1 dhcpcd \-v 03,\e"192.168.0.2\e" eth0
541Set un-encapsulated vendor option to hello world. 541Set un-encapsulated vendor option to hello world.
542.D1 dhcpcd \-v ,"hello world" eth0 542.D1 dhcpcd \-v ,"hello world" eth0
543.It Fl Fl version 543.It Fl Fl version
544Display both program version and copyright information. 544Display both program version and copyright information.
545.Nm 545.Nm
546then exits before doing any configuration. 546then exits before doing any configuration.
547.It Fl w 547.It Fl w
548Wait for an address to be assigned before forking to the background. 548Wait for an address to be assigned before forking to the background.
549Does not take an argument, unlike the below option. 549Does not take an argument, unlike the below option.
550.It Fl Fl waitip Ns = Ns Op 4 | 6 550.It Fl Fl waitip Ns = Ns Op 4 | 6
551Wait for an address to be assigned before forking to the background. 551Wait for an address to be assigned before forking to the background.
5524 means wait for an IPv4 address to be assigned. 5524 means wait for an IPv4 address to be assigned.
5536 means wait for an IPv6 address to be assigned. 5536 means wait for an IPv6 address to be assigned.
554If no argument is given, 554If no argument is given,
555.Nm 555.Nm
556will wait for any address protocol to be assigned. 556will wait for any address protocol to be assigned.
557It is possible to wait for more than one address protocol and 557It is possible to wait for more than one address protocol and
558.Nm 558.Nm
559will only fork to the background when all waiting conditions are satisfied. 559will only fork to the background when all waiting conditions are satisfied.
560.It Fl x , Fl Fl exit Op Ar interface 560.It Fl x , Fl Fl exit Op Ar interface
561This will signal an existing 561This will signal an existing
562.Nm 562.Nm
563process running on the 563process running on the
564.Ar interface 564.Ar interface
565to exit. 565to exit.
566If no 566If no
567.Ar interface 567.Ar interface
568is specified, then the above is applied to all interfaces in Master mode. 568is specified, then the above is applied to all interfaces in Master mode.
569See the 569See the
570.Fl p , Fl Fl persistent 570.Fl p , Fl Fl persistent
571option to control configuration persistence on exit, 571option to control configuration persistence on exit,
572which is enabled by default in 572which is enabled by default in
573.Xr dhcpcd.conf 5 . 573.Xr dhcpcd.conf 5 .
574.Nm 574.Nm
575then waits until this process has exited. 575then waits until this process has exited.
576.It Fl y , Fl Fl reboot Ar seconds 576.It Fl y , Fl Fl reboot Ar seconds
577Allow 577Allow
578.Ar reboot 578.Ar reboot
579seconds before moving to the discover phase if we have an old lease to use. 579seconds before moving to the discover phase if we have an old lease to use.
580Allow 580Allow
581.Ar reboot 581.Ar reboot
582seconds before starting fallback states from the discover phase. 582seconds before starting fallback states from the discover phase.
583IPv4LL is started when the first 583IPv4LL is started when the first
584.Ar reboot 584.Ar reboot
585timeout is reached. 585timeout is reached.
586The default is 5 seconds. 586The default is 5 seconds.
587A setting of 0 seconds causes 587A setting of 0 seconds causes
588.Nm 588.Nm
589to skip the reboot phase and go straight into discover. 589to skip the reboot phase and go straight into discover.
590This has no effect on DHCPv6 other than skipping the reboot phase. 590This has no effect on DHCPv6 other than skipping the reboot phase.
591.El 591.El
592.Ss Restricting behaviour 592.Ss Restricting behaviour
593.Nm 593.Nm
594will try to do as much as it can by default. 594will try to do as much as it can by default.
595However, there are sometimes situations where you don't want the things to be 595However, there are sometimes situations where you don't want the things to be
596configured exactly how the DHCP server wants. 596configured exactly how the DHCP server wants.
597Here are some options that deal with turning these bits off. 597Here are some options that deal with turning these bits off.
598.Pp 598.Pp
599Note that when 599Note that when
600.Nm 600.Nm
601is restricted to a single interface then the interface also needs to be 601is restricted to a single interface then the interface also needs to be
602specified when asking 602specified when asking
603.Nm 603.Nm
604to exit using the commandline. 604to exit using the commandline.
605If the protocol is restricted as well then the protocol needs to be included 605If the protocol is restricted as well then the protocol needs to be included
606with the exit instruction. 606with the exit instruction.
607.Bl -tag -width indent 607.Bl -tag -width indent
608.It Fl 1 , Fl Fl oneshot 608.It Fl 1 , Fl Fl oneshot
609Exit after configuring an interface. 609Exit after configuring an interface.
610Use the 610Use the
611.Fl w , Fl Fl waitip 611.Fl w , Fl Fl waitip
612option to specify which protocol(s) to configure before exiting. 612option to specify which protocol(s) to configure before exiting.
613.It Fl 4 , Fl Fl ipv4only 613.It Fl 4 , Fl Fl ipv4only
614Configure IPv4 only. 614Configure IPv4 only.
615.It Fl 6 , Fl Fl ipv6only 615.It Fl 6 , Fl Fl ipv6only
616Configure IPv6 only. 616Configure IPv6 only.
617.It Fl A , Fl Fl noarp 617.It Fl A , Fl Fl noarp
618Don't request or claim the address by ARP. 618Don't request or claim the address by ARP.
619This also disables IPv4LL. 619This also disables IPv4LL.
620.It Fl B , Fl Fl nobackground 620.It Fl B , Fl Fl nobackground
621Don't run in the background when we acquire a lease. 621Don't run in the background when we acquire a lease.
622This is mainly useful for running under the control of another process, such 622This is mainly useful for running under the control of another process, such
623as a debugger or a network manager. 623as a debugger or a network manager.
624.It Fl C , Fl Fl nohook Ar script 624.It Fl C , Fl Fl nohook Ar script
625Don't run this hook script. 625Don't run this hook script.
626Matches full name, or prefixed with 2 numbers optionally ending with 626Matches full name, or prefixed with 2 numbers optionally ending with
627.Pa .sh . 627.Pa .sh .
628.Pp 628.Pp
629So to stop 629So to stop
630.Nm 630.Nm
631from touching your DNS settings you would do:- 631from touching your DNS settings you would do:-
632.D1 dhcpcd -C resolv.conf eth0 632.D1 dhcpcd -C resolv.conf eth0
633.It Fl G , Fl Fl nogateway 633.It Fl G , Fl Fl nogateway
634Don't set any default routes. 634Don't set any default routes.
635.It Fl H , Fl Fl xidhwaddr 635.It Fl H , Fl Fl xidhwaddr
636Use the last four bytes of the hardware address as the DHCP xid instead 636Use the last four bytes of the hardware address as the DHCP xid instead
637of a randomly generated number. 637of a randomly generated number.
638.It Fl J , Fl Fl broadcast 638.It Fl J , Fl Fl broadcast
639Instructs the DHCP server to broadcast replies back to the client. 639Instructs the DHCP server to broadcast replies back to the client.
640Normally this is only set for non-Ethernet interfaces, 640Normally this is only set for non-Ethernet interfaces,
641such as FireWire and InfiniBand. 641such as FireWire and InfiniBand.
642In most instances, 642In most instances,
643.Nm 643.Nm
644will set this automatically. 644will set this automatically.
645.It Fl K , Fl Fl nolink 645.It Fl K , Fl Fl nolink
646Don't receive link messages for carrier status. 646Don't receive link messages for carrier status.
647You should only have to use this with buggy device drivers or running 647You should only have to use this with buggy device drivers or running
648.Nm 648.Nm
649through a network manager. 649through a network manager.
650.It Fl L , Fl Fl noipv4ll 650.It Fl L , Fl Fl noipv4ll
651Don't use IPv4LL (aka APIPA, aka Bonjour, aka ZeroConf). 651Don't use IPv4LL (aka APIPA, aka Bonjour, aka ZeroConf).
652.It Fl O , Fl Fl nooption Ar option 652.It Fl O , Fl Fl nooption Ar option
653Removes the 653Removes the
654.Ar option 654.Ar option
655from the DHCP message before processing. 655from the DHCP message before processing.
656.It Fl P , Fl Fl printpidfile 656.It Fl P , Fl Fl printpidfile
657Print the 657Print the
658.Pa pidfile 658.Pa pidfile
659.Nm 659.Nm
660will use based on commmand-line arguments to stdout. 660will use based on commmand-line arguments to stdout.
661.It Fl Q , Fl Fl require Ar option 661.It Fl Q , Fl Fl require Ar option
662Requires the 662Requires the
663.Ar option 663.Ar option
664to be present in all DHCP messages, otherwise the message is ignored. 664to be present in all DHCP messages, otherwise the message is ignored.
665To enforce that 665To enforce that
666.Nm 666.Nm
667only responds to DHCP servers and not BOOTP servers, you can 667only responds to DHCP servers and not BOOTP servers, you can
668.Fl Q 668.Fl Q
669.Ar dhcp_message_type . 669.Ar dhcp_message_type .
670.It Fl q , Fl Fl quiet 670.It Fl q , Fl Fl quiet
671Quiet 671Quiet
672.Nm 672.Nm
673on the command line, only warnings and errors will be displayed. 673on the command line, only warnings and errors will be displayed.
674If this option is used another time then all console output is disabled. 674If this option is used another time then all console output is disabled.
675These messages are still logged via 675These messages are still logged via
676.Xr syslog 3 . 676.Xr syslog 3 .
677.It Fl T , Fl Fl test 677.It Fl T , Fl Fl test
678On receipt of DHCP messages just call 678On receipt of DHCP messages just call
679.Pa @SCRIPT@ 679.Pa @SCRIPT@
680with the reason of TEST which echos the DHCP variables found in the message 680with the reason of TEST which echos the DHCP variables found in the message
681to the console. 681to the console.
682The interface configuration isn't touched and neither are any configuration 682The interface configuration isn't touched and neither are any configuration
683files. 683files.
684The 684The
685.Ar rapid_commit 685.Ar rapid_commit
686option is not sent in TEST mode so that the server does not lease an address. 686option is not sent in TEST mode so that the server does not lease an address.
687To test INFORM the interface needs to be configured with the desired address 687To test INFORM the interface needs to be configured with the desired address
688before starting 688before starting
689.Nm . 689.Nm .
690.It Fl U , Fl Fl dumplease Op Ar interface 690.It Fl U , Fl Fl dumplease Op Ar interface
691Dumps the current lease for the 691Dumps the current lease for the
692.Ar interface 692.Ar interface
693to stdout. 693to stdout.
694If no 694If no
695.Ar interface 695.Ar interface
696is given then all interfaces are dumped. 696is given then all interfaces are dumped.
697Use the 697Use the
698.Fl 4 698.Fl 4
699or 699or
700.Fl 6 700.Fl 6
701flags to specify an address family. 701flags to specify an address family.
702If a lease is piped in via standard input then that is dumped. 702If a lease is piped in via standard input then that is dumped.
703In this case, specifying an address family is mandatory. 703In this case, specifying an address family is mandatory.
704.It Fl V , Fl Fl variables 704.It Fl V , Fl Fl variables
705Display a list of option codes, the associated variable and encoding for use in 705Display a list of option codes, the associated variable and encoding for use in
706.Xr dhcpcd-run-hooks 8 . 706.Xr dhcpcd-run-hooks 8 .
707Variables are prefixed with new_ and old_ unless the option number is -. 707Variables are prefixed with new_ and old_ unless the option number is -.
708Variables without an option are part of the DHCP message and cannot be 708Variables without an option are part of the DHCP message and cannot be
709directly requested. 709directly requested.
710.It Fl W , Fl Fl whitelist Ar address Ns Op /cidr 710.It Fl W , Fl Fl whitelist Ar address Ns Op /cidr
711Only accept packets from 711Only accept packets from
712.Ar address Ns Op /cidr . 712.Ar address Ns Op /cidr .
713.Fl X , Fl Fl blacklist 713.Fl X , Fl Fl blacklist
714is ignored if 714is ignored if
715.Fl W , Fl Fl whitelist 715.Fl W , Fl Fl whitelist
716is set. 716is set.
717.It Fl X , Fl Fl blacklist Ar address Ns Op Ar /cidr 717.It Fl X , Fl Fl blacklist Ar address Ns Op Ar /cidr
718Ignore all packets from 718Ignore all packets from
719.Ar address Ns Op Ar /cidr . 719.Ar address Ns Op Ar /cidr .
720.It Fl Z , Fl Fl denyinterfaces Ar pattern 720.It Fl Z , Fl Fl denyinterfaces Ar pattern
721When discovering interfaces, the interface name must not match 721When discovering interfaces, the interface name must not match
722.Ar pattern 722.Ar pattern
723which is a space or comma separated list of patterns passed to 723which is a space or comma separated list of patterns passed to
724.Xr fnmatch 3 . 724.Xr fnmatch 3 .
725.It Fl z , Fl Fl allowinterfaces Ar pattern 725.It Fl z , Fl Fl allowinterfaces Ar pattern
726When discovering interfaces, the interface name must match 726When discovering interfaces, the interface name must match
727.Ar pattern 727.Ar pattern
728which is a space or comma separated list of patterns passed to 728which is a space or comma separated list of patterns passed to
729.Xr fnmatch 3 . 729.Xr fnmatch 3 .
730If the same interface is matched in 730If the same interface is matched in
731.Fl Z , Fl Fl denyinterfaces 731.Fl Z , Fl Fl denyinterfaces
732then it is still denied. 732then it is still denied.
733.It Fl Fl inactive 733.It Fl Fl inactive
734Don't start any interfaces other than those specified on the command line. 734Don't start any interfaces other than those specified on the command line.
735This allows 735This allows
736.Nm 736.Nm
737to be started in Master mode and then wait for subsequent 737to be started in Master mode and then wait for subsequent
738.Nm 738.Nm
739commands to start each interface as required. 739commands to start each interface as required.
740.It Fl Fl nodev 740.It Fl Fl nodev
741Don't load any 741Don't load any
742.Pa /dev 742.Pa /dev
743management modules. 743management modules.
744.El 744.El
745.Sh 3RDPARTY LINK MANAGEMENT 745.Sh 3RDPARTY LINK MANAGEMENT
746Some interfaces require configuration by 3rd parties, such as PPP or VPN. 746Some interfaces require configuration by 3rd parties, such as PPP or VPN.
747When an interface configuration in 747When an interface configuration in
748.Nm 748.Nm
749is marked as STATIC or INFORM without an address then 749is marked as STATIC or INFORM without an address then
750.Nm 750.Nm
751will monitor the interface until an address is added or removed from it and 751will monitor the interface until an address is added or removed from it and
752act accordingly. 752act accordingly.
753For point to point interfaces (like PPP), a default route to its 753For point to point interfaces (like PPP), a default route to its
754destination is automatically added to the configuration. 754destination is automatically added to the configuration.
755If the point to point interface is configured for INFORM, then 755If the point to point interface is configured for INFORM, then
756.Nm 756.Nm
757unicasts INFORM to the destination, otherwise it defaults to STATIC. 757unicasts INFORM to the destination, otherwise it defaults to STATIC.
758.Sh NOTES 758.Sh NOTES
759.Nm 759.Nm
760requires a Berkley Packet Filter, or BPF device on BSD based systems and a 760requires a Berkley Packet Filter, or BPF device on BSD based systems and a
761Linux Socket Filter, or LPF device on Linux based systems for all IPv4 761Linux Socket Filter, or LPF device on Linux based systems for all IPv4
762configuration. 762configuration.
763.Pp 763.Pp
764If restricting 764If restricting
765.Nm 765.Nm
766to a single interface and optionally address family via the command-line 766to a single interface and optionally address family via the command-line
767then all further calls to 767then all further calls to
768.Nm 768.Nm
769to rebind, reconfigure or exit need to include the same restrictive flags 769to rebind, reconfigure or exit need to include the same restrictive flags
770so that 770so that
771.Nm 771.Nm
772knows which process to signal. 772knows which process to signal.
773.Pp 773.Pp
774Some DHCP servers implement ClientID filtering. 774Some DHCP servers implement ClientID filtering.
775If 775If
776.Nm 776.Nm
777is replacing an in-use DHCP client then you might need to adjust the clientid 777is replacing an in-use DHCP client then you might need to adjust the clientid
778option 778option
779.Nm 779.Nm
780sends to match. 780sends to match.
781If using a DUID in place of the ClientID, edit 781If using a DUID in place of the ClientID, edit
782.Pa @DBDIR@/duid 782.Pa @DBDIR@/duid
783accordingly. 783accordingly.
784.Sh FILES 784.Sh FILES
785.Bl -ohang 785.Bl -ohang
786.It Pa @SYSCONFDIR@/dhcpcd.conf 786.It Pa @SYSCONFDIR@/dhcpcd.conf
787Configuration file for dhcpcd. 787Configuration file for dhcpcd.
788If you always use the same options, put them here. 788If you always use the same options, put them here.
789.It Pa @SCRIPT@ 789.It Pa @SCRIPT@
790Bourne shell script that is run to configure or de-configure an interface. 790Bourne shell script that is run to configure or de-configure an interface.
791.It Pa @LIBDIR@/dhcpcd/dev 791.It Pa @LIBDIR@/dhcpcd/dev
792Linux 792Linux
793.Pa /dev 793.Pa /dev
794management modules. 794management modules.
795.It Pa @HOOKDIR@ 795.It Pa @HOOKDIR@
796A directory containing bourne shell scripts that are run by the above script. 796A directory containing bourne shell scripts that are run by the above script.
797Each script can be disabled by using the 797Each script can be disabled by using the
798.Fl C , Fl Fl nohook 798.Fl C , Fl Fl nohook
799option described above. 799option described above.
800.It Pa @DBDIR@/duid 800.It Pa @DBDIR@/duid
801Text file that holds the DUID used to identify the host. 801Text file that holds the DUID used to identify the host.
802.It Pa @DBDIR@/secret 802.It Pa @DBDIR@/secret
803Text file that holds a secret key known only to the host. 803Text file that holds a secret key known only to the host.
804.It Pa @DBDIR@/ Ns Ar interface Ns Ar -ssid Ns .lease 804.It Pa @DBDIR@/ Ns Ar interface Ns Ar -ssid Ns .lease
805The actual DHCP message sent by the server. 805The actual DHCP message sent by the server.
806We use this when reading the last 806We use this when reading the last
807lease and use the file's mtime as when it was issued. 807lease and use the file's mtime as when it was issued.
808.It Pa @DBDIR@/ Ns Ar interface Ns Ar -ssid Ns .lease6 808.It Pa @DBDIR@/ Ns Ar interface Ns Ar -ssid Ns .lease6
809The actual DHCPv6 message sent by the server. 809The actual DHCPv6 message sent by the server.
810We use this when reading the last 810We use this when reading the last
811lease and use the file's mtime as when it was issued. 811lease and use the file's mtime as when it was issued.
812.It Pa @DBDIR@/rdm_monotonic 812.It Pa @DBDIR@/rdm_monotonic
813Stores the monotonic counter used in the 813Stores the monotonic counter used in the
814.Ar replay 814.Ar replay
815field in Authentication Options. 815field in Authentication Options.
816.It Pa @RUNDIR@/pid 816.It Pa @RUNDIR@/pid
817Stores the PID of 817Stores the PID of
818.Nm 818.Nm
819running on all interfaces. 819running on all interfaces.
820.It Pa @RUNDIR@/ Ns Ar interface Ns .pid 820.It Pa @RUNDIR@/ Ns Ar interface Ns .pid
821Stores the PID of 821Stores the PID of
822.Nm 822.Nm
823running on the 823running on the
824.Ar interface . 824.Ar interface .
825.It Pa @RUNDIR@/sock 825.It Pa @RUNDIR@/sock
826Control socket to the master daemon. 826Control socket to the master daemon.
827.It Pa @RUNDIR@/unpriv.sock 827.It Pa @RUNDIR@/unpriv.sock
828Unprivileged socket to the master daemon, only allows state retrieval. 828Unprivileged socket to the master daemon, only allows state retrieval.
829.It Pa @RUNDIR@/ Ns Ar interface Ns .sock 829.It Pa @RUNDIR@/ Ns Ar interface Ns .sock
830Control socket to per interface daemon. 830Control socket to per interface daemon.
831.El 831.El
832.Sh SEE ALSO 832.Sh SEE ALSO
833.Xr fnmatch 3 , 833.Xr fnmatch 3 ,
834.Xr if_nametoindex 3 , 834.Xr if_nametoindex 3 ,
835.Xr dhcpcd.conf 5 , 835.Xr dhcpcd.conf 5 ,
836.Xr resolv.conf 5 , 836.Xr resolv.conf 5 ,
837.Xr dhcpcd-run-hooks 8 , 837.Xr dhcpcd-run-hooks 8 ,
838.Xr resolvconf 8 838.Xr resolvconf 8
839.Sh STANDARDS 839.Sh STANDARDS
840RFC\ 951, RFC\ 1534, RFC\ 2104, RFC\ 2131, RFC\ 2132, RFC\ 2563, RFC\ 2855, 840RFC\ 951, RFC\ 1534, RFC\ 2104, RFC\ 2131, RFC\ 2132, RFC\ 2563, RFC\ 2855,
841RFC\ 3004, RFC\ 3118, RFC\ 3203, RFC\ 3315, RFC\ 3361, RFC\ 3633, RFC\ 3396, 841RFC\ 3004, RFC\ 3118, RFC\ 3203, RFC\ 3315, RFC\ 3361, RFC\ 3633, RFC\ 3396,
842RFC\ 3397, RFC\ 3442, RFC\ 3495, RFC\ 3925, RFC\ 3927, RFC\ 4039, RFC\ 4075, 842RFC\ 3397, RFC\ 3442, RFC\ 3495, RFC\ 3925, RFC\ 3927, RFC\ 4039, RFC\ 4075,
843RFC\ 4242, RFC\ 4361, RFC\ 4390, RFC\ 4702, RFC\ 4074, RFC\ 4861, RFC\ 4833, 843RFC\ 4242, RFC\ 4361, RFC\ 4390, RFC\ 4702, RFC\ 4074, RFC\ 4861, RFC\ 4833,
844RFC\ 4941, RFC\ 5227, RFC\ 5942, RFC\ 5969, RFC\ 6106, RFC\ 6334, RFC\ 6355, 844RFC\ 4941, RFC\ 5227, RFC\ 5942, RFC\ 5969, RFC\ 6106, RFC\ 6334, RFC\ 6355,
845RFC\ 6603, RFC\ 6704, RFC\ 7217, RFC\ 7550, RFC\ 7844. 845RFC\ 6603, RFC\ 6704, RFC\ 7217, RFC\ 7550, RFC\ 7844.
846.Sh AUTHORS 846.Sh AUTHORS
847.An Roy Marples Aq Mt roy@marples.name 847.An Roy Marples Aq Mt roy@marples.name
848.Sh BUGS 848.Sh BUGS
849If 
850.Nm 
851is running in a 
852.Xr chroot 2 
853then re-opening the 
854.Fl Fl logfile 
855from SIGUSR2 may not work. 
856.Pp 
857Please report them to 849Please report them to
858.Lk http://roy.marples.name/projects/dhcpcd 850.Lk http://roy.marples.name/projects/dhcpcd

cvs diff -r1.44 -r1.45 src/external/bsd/dhcpcd/dist/src/dhcpcd.c (switch to unified diff)

--- src/external/bsd/dhcpcd/dist/src/dhcpcd.c 2020/10/12 14:09:03 1.44
+++ src/external/bsd/dhcpcd/dist/src/dhcpcd.c 2020/11/01 14:24:01 1.45
@@ -426,2163 +426,2169 @@ stop_interface(struct interface *ifp, co @@ -426,2163 +426,2169 @@ stop_interface(struct interface *ifp, co
426 /* De-activate the interface */ 426 /* De-activate the interface */
427 ifp->active = IF_INACTIVE; 427 ifp->active = IF_INACTIVE;
428 ifp->options->options &= ~DHCPCD_STOPPING; 428 ifp->options->options &= ~DHCPCD_STOPPING;
429 429
430 if (!(ctx->options & (DHCPCD_MASTER | DHCPCD_TEST))) 430 if (!(ctx->options & (DHCPCD_MASTER | DHCPCD_TEST)))
431 eloop_exit(ctx->eloop, EXIT_FAILURE); 431 eloop_exit(ctx->eloop, EXIT_FAILURE);
432} 432}
433 433
434static void 434static void
435configure_interface1(struct interface *ifp) 435configure_interface1(struct interface *ifp)
436{ 436{
437 struct if_options *ifo = ifp->options; 437 struct if_options *ifo = ifp->options;
438 438
439 /* Do any platform specific configuration */ 439 /* Do any platform specific configuration */
440 if_conf(ifp); 440 if_conf(ifp);
441 441
442 /* If we want to release a lease, we can't really persist the 442 /* If we want to release a lease, we can't really persist the
443 * address either. */ 443 * address either. */
444 if (ifo->options & DHCPCD_RELEASE) 444 if (ifo->options & DHCPCD_RELEASE)
445 ifo->options &= ~DHCPCD_PERSISTENT; 445 ifo->options &= ~DHCPCD_PERSISTENT;
446 446
447 if (ifp->flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) { 447 if (ifp->flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) {
448 ifo->options &= ~DHCPCD_ARP; 448 ifo->options &= ~DHCPCD_ARP;
449 if (!(ifp->flags & IFF_MULTICAST)) 449 if (!(ifp->flags & IFF_MULTICAST))
450 ifo->options &= ~DHCPCD_IPV6RS; 450 ifo->options &= ~DHCPCD_IPV6RS;
451 if (!(ifo->options & (DHCPCD_INFORM | DHCPCD_WANTDHCP))) 451 if (!(ifo->options & (DHCPCD_INFORM | DHCPCD_WANTDHCP)))
452 ifo->options |= DHCPCD_STATIC; 452 ifo->options |= DHCPCD_STATIC;
453 } 453 }
454 454
455 if (ifo->metric != -1) 455 if (ifo->metric != -1)
456 ifp->metric = (unsigned int)ifo->metric; 456 ifp->metric = (unsigned int)ifo->metric;
457 457
458#ifdef INET6 458#ifdef INET6
459 /* We want to setup INET6 on the interface as soon as possible. */ 459 /* We want to setup INET6 on the interface as soon as possible. */
460 if (ifp->active == IF_ACTIVE_USER && 460 if (ifp->active == IF_ACTIVE_USER &&
461 ifo->options & DHCPCD_IPV6 && 461 ifo->options & DHCPCD_IPV6 &&
462 !(ifp->ctx->options & (DHCPCD_DUMPLEASE | DHCPCD_TEST))) 462 !(ifp->ctx->options & (DHCPCD_DUMPLEASE | DHCPCD_TEST)))
463 { 463 {
464 /* If not doing any DHCP, disable the RDNSS requirement. */ 464 /* If not doing any DHCP, disable the RDNSS requirement. */
465 if (!(ifo->options & (DHCPCD_DHCP | DHCPCD_DHCP6))) 465 if (!(ifo->options & (DHCPCD_DHCP | DHCPCD_DHCP6)))
466 ifo->options &= ~DHCPCD_IPV6RA_REQRDNSS; 466 ifo->options &= ~DHCPCD_IPV6RA_REQRDNSS;
467 if_setup_inet6(ifp); 467 if_setup_inet6(ifp);
468 } 468 }
469#endif 469#endif
470 470
471 if (!(ifo->options & DHCPCD_IAID)) { 471 if (!(ifo->options & DHCPCD_IAID)) {
472 /* 472 /*
473 * An IAID is for identifying a unqiue interface within 473 * An IAID is for identifying a unqiue interface within
474 * the client. It is 4 bytes long. Working out a default 474 * the client. It is 4 bytes long. Working out a default
475 * value is problematic. 475 * value is problematic.
476 * 476 *
477 * Interface name and number are not stable 477 * Interface name and number are not stable
478 * between different OS's. Some OS's also cannot make 478 * between different OS's. Some OS's also cannot make
479 * up their mind what the interface should be called 479 * up their mind what the interface should be called
480 * (yes, udev, I'm looking at you). 480 * (yes, udev, I'm looking at you).
481 * Also, the name could be longer than 4 bytes. 481 * Also, the name could be longer than 4 bytes.
482 * Also, with pluggable interfaces the name and index 482 * Also, with pluggable interfaces the name and index
483 * could easily get swapped per actual interface. 483 * could easily get swapped per actual interface.
484 * 484 *
485 * The MAC address is 6 bytes long, the final 3 485 * The MAC address is 6 bytes long, the final 3
486 * being unique to the manufacturer and the initial 3 486 * being unique to the manufacturer and the initial 3
487 * being unique to the organisation which makes it. 487 * being unique to the organisation which makes it.
488 * We could use the last 4 bytes of the MAC address 488 * We could use the last 4 bytes of the MAC address
489 * as the IAID as it's the most stable part given the 489 * as the IAID as it's the most stable part given the
490 * above, but equally it's not guaranteed to be 490 * above, but equally it's not guaranteed to be
491 * unique. 491 * unique.
492 * 492 *
493 * Given the above, and our need to reliably work 493 * Given the above, and our need to reliably work
494 * between reboots without persitent storage, 494 * between reboots without persitent storage,
495 * generating the IAID from the MAC address is the only 495 * generating the IAID from the MAC address is the only
496 * logical default. 496 * logical default.
497 * Saying that, if a VLANID has been specified then we 497 * Saying that, if a VLANID has been specified then we
498 * can use that. It's possible that different interfaces 498 * can use that. It's possible that different interfaces
499 * can have the same VLANID, but this is no worse than 499 * can have the same VLANID, but this is no worse than
500 * generating the IAID from the duplicate MAC address. 500 * generating the IAID from the duplicate MAC address.
501 * 501 *
502 * dhclient uses the last 4 bytes of the MAC address. 502 * dhclient uses the last 4 bytes of the MAC address.
503 * dibbler uses an increamenting counter. 503 * dibbler uses an increamenting counter.
504 * wide-dhcpv6 uses 0 or a configured value. 504 * wide-dhcpv6 uses 0 or a configured value.
505 * odhcp6c uses 1. 505 * odhcp6c uses 1.
506 * Windows 7 uses the first 3 bytes of the MAC address 506 * Windows 7 uses the first 3 bytes of the MAC address
507 * and an unknown byte. 507 * and an unknown byte.
508 * dhcpcd-6.1.0 and earlier used the interface name, 508 * dhcpcd-6.1.0 and earlier used the interface name,
509 * falling back to interface index if name > 4. 509 * falling back to interface index if name > 4.
510 */ 510 */
511 if (ifp->vlanid != 0) { 511 if (ifp->vlanid != 0) {
512 uint32_t vlanid; 512 uint32_t vlanid;
513 513
514 /* Maximal VLANID is 4095, so prefix with 0xff 514 /* Maximal VLANID is 4095, so prefix with 0xff
515 * so we don't conflict with an interface index. */ 515 * so we don't conflict with an interface index. */
516 vlanid = htonl(ifp->vlanid | 0xff000000); 516 vlanid = htonl(ifp->vlanid | 0xff000000);
517 memcpy(ifo->iaid, &vlanid, sizeof(vlanid)); 517 memcpy(ifo->iaid, &vlanid, sizeof(vlanid));
518 } else if (ifo->options & DHCPCD_ANONYMOUS) 518 } else if (ifo->options & DHCPCD_ANONYMOUS)
519 memset(ifo->iaid, 0, sizeof(ifo->iaid)); 519 memset(ifo->iaid, 0, sizeof(ifo->iaid));
520 else if (ifp->hwlen >= sizeof(ifo->iaid)) { 520 else if (ifp->hwlen >= sizeof(ifo->iaid)) {
521 memcpy(ifo->iaid, 521 memcpy(ifo->iaid,
522 ifp->hwaddr + ifp->hwlen - sizeof(ifo->iaid), 522 ifp->hwaddr + ifp->hwlen - sizeof(ifo->iaid),
523 sizeof(ifo->iaid)); 523 sizeof(ifo->iaid));
524 } else { 524 } else {
525 uint32_t len; 525 uint32_t len;
526 526
527 len = (uint32_t)strlen(ifp->name); 527 len = (uint32_t)strlen(ifp->name);
528 if (len <= sizeof(ifo->iaid)) { 528 if (len <= sizeof(ifo->iaid)) {
529 memcpy(ifo->iaid, ifp->name, len); 529 memcpy(ifo->iaid, ifp->name, len);
530 if (len < sizeof(ifo->iaid)) 530 if (len < sizeof(ifo->iaid))
531 memset(ifo->iaid + len, 0, 531 memset(ifo->iaid + len, 0,
532 sizeof(ifo->iaid) - len); 532 sizeof(ifo->iaid) - len);
533 } else { 533 } else {
534 /* IAID is the same size as a uint32_t */ 534 /* IAID is the same size as a uint32_t */
535 len = htonl(ifp->index); 535 len = htonl(ifp->index);
536 memcpy(ifo->iaid, &len, sizeof(ifo->iaid)); 536 memcpy(ifo->iaid, &len, sizeof(ifo->iaid));
537 } 537 }
538 } 538 }
539 ifo->options |= DHCPCD_IAID; 539 ifo->options |= DHCPCD_IAID;
540 } 540 }
541 541
542#ifdef DHCP6 542#ifdef DHCP6
543 if (ifo->ia_len == 0 && ifo->options & DHCPCD_IPV6 && 543 if (ifo->ia_len == 0 && ifo->options & DHCPCD_IPV6 &&
544 ifp->name[0] != '\0') 544 ifp->name[0] != '\0')
545 { 545 {
546 ifo->ia = malloc(sizeof(*ifo->ia)); 546 ifo->ia = malloc(sizeof(*ifo->ia));
547 if (ifo->ia == NULL) 547 if (ifo->ia == NULL)
548 logerr(__func__); 548 logerr(__func__);
549 else { 549 else {
550 ifo->ia_len = 1; 550 ifo->ia_len = 1;
551 ifo->ia->ia_type = D6_OPTION_IA_NA; 551 ifo->ia->ia_type = D6_OPTION_IA_NA;
552 memcpy(ifo->ia->iaid, ifo->iaid, sizeof(ifo->iaid)); 552 memcpy(ifo->ia->iaid, ifo->iaid, sizeof(ifo->iaid));
553 memset(&ifo->ia->addr, 0, sizeof(ifo->ia->addr)); 553 memset(&ifo->ia->addr, 0, sizeof(ifo->ia->addr));
554#ifndef SMALL 554#ifndef SMALL
555 ifo->ia->sla = NULL; 555 ifo->ia->sla = NULL;
556 ifo->ia->sla_len = 0; 556 ifo->ia->sla_len = 0;
557#endif 557#endif
558 } 558 }
559 } else { 559 } else {
560 size_t i; 560 size_t i;
561 561
562 for (i = 0; i < ifo->ia_len; i++) { 562 for (i = 0; i < ifo->ia_len; i++) {
563 if (!ifo->ia[i].iaid_set) { 563 if (!ifo->ia[i].iaid_set) {
564 memcpy(&ifo->ia[i].iaid, ifo->iaid, 564 memcpy(&ifo->ia[i].iaid, ifo->iaid,
565 sizeof(ifo->ia[i].iaid)); 565 sizeof(ifo->ia[i].iaid));
566 ifo->ia[i].iaid_set = 1; 566 ifo->ia[i].iaid_set = 1;
567 } 567 }
568 } 568 }
569 } 569 }
570#endif 570#endif
571 571
572 /* If root is network mounted, we don't want to kill the connection 572 /* If root is network mounted, we don't want to kill the connection
573 * if the DHCP server goes the way of the dodo OR dhcpcd is rebooting 573 * if the DHCP server goes the way of the dodo OR dhcpcd is rebooting
574 * and the lease file has expired. */ 574 * and the lease file has expired. */
575 if (is_root_local() == 0) 575 if (is_root_local() == 0)
576 ifo->options |= DHCPCD_LASTLEASE_EXTEND; 576 ifo->options |= DHCPCD_LASTLEASE_EXTEND;
577} 577}
578 578
579int 579int
580dhcpcd_selectprofile(struct interface *ifp, const char *profile) 580dhcpcd_selectprofile(struct interface *ifp, const char *profile)
581{ 581{
582 struct if_options *ifo; 582 struct if_options *ifo;
583 char pssid[PROFILE_LEN]; 583 char pssid[PROFILE_LEN];
584 584
585 if (ifp->ssid_len) { 585 if (ifp->ssid_len) {
586 ssize_t r; 586 ssize_t r;
587 587
588 r = print_string(pssid, sizeof(pssid), OT_ESCSTRING, 588 r = print_string(pssid, sizeof(pssid), OT_ESCSTRING,
589 ifp->ssid, ifp->ssid_len); 589 ifp->ssid, ifp->ssid_len);
590 if (r == -1) { 590 if (r == -1) {
591 logerr(__func__); 591 logerr(__func__);
592 pssid[0] = '\0'; 592 pssid[0] = '\0';
593 } 593 }
594 } else 594 } else
595 pssid[0] = '\0'; 595 pssid[0] = '\0';
596 ifo = read_config(ifp->ctx, ifp->name, pssid, profile); 596 ifo = read_config(ifp->ctx, ifp->name, pssid, profile);
597 if (ifo == NULL) { 597 if (ifo == NULL) {
598 logdebugx("%s: no profile %s", ifp->name, profile); 598 logdebugx("%s: no profile %s", ifp->name, profile);
599 return -1; 599 return -1;
600 } 600 }
601 if (profile != NULL) { 601 if (profile != NULL) {
602 strlcpy(ifp->profile, profile, sizeof(ifp->profile)); 602 strlcpy(ifp->profile, profile, sizeof(ifp->profile));
603 loginfox("%s: selected profile %s", ifp->name, profile); 603 loginfox("%s: selected profile %s", ifp->name, profile);
604 } else 604 } else
605 *ifp->profile = '\0'; 605 *ifp->profile = '\0';
606 606
607 free_options(ifp->ctx, ifp->options); 607 free_options(ifp->ctx, ifp->options);
608 ifp->options = ifo; 608 ifp->options = ifo;
609 if (profile) { 609 if (profile) {
610 add_options(ifp->ctx, ifp->name, ifp->options, 610 add_options(ifp->ctx, ifp->name, ifp->options,
611 ifp->ctx->argc, ifp->ctx->argv); 611 ifp->ctx->argc, ifp->ctx->argv);
612 configure_interface1(ifp); 612 configure_interface1(ifp);
613 } 613 }
614 return 1; 614 return 1;
615} 615}
616 616
617static void 617static void
618configure_interface(struct interface *ifp, int argc, char **argv, 618configure_interface(struct interface *ifp, int argc, char **argv,
619 unsigned long long options) 619 unsigned long long options)
620{ 620{
621 time_t old; 621 time_t old;
622 622
623 old = ifp->options ? ifp->options->mtime : 0; 623 old = ifp->options ? ifp->options->mtime : 0;
624 dhcpcd_selectprofile(ifp, NULL); 624 dhcpcd_selectprofile(ifp, NULL);
625 if (ifp->options == NULL) { 625 if (ifp->options == NULL) {
626 /* dhcpcd cannot continue with this interface. */ 626 /* dhcpcd cannot continue with this interface. */
627 ifp->active = IF_INACTIVE; 627 ifp->active = IF_INACTIVE;
628 return; 628 return;
629 } 629 }
630 add_options(ifp->ctx, ifp->name, ifp->options, argc, argv); 630 add_options(ifp->ctx, ifp->name, ifp->options, argc, argv);
631 ifp->options->options |= options; 631 ifp->options->options |= options;
632 configure_interface1(ifp); 632 configure_interface1(ifp);
633 633
634 /* If the mtime has changed drop any old lease */ 634 /* If the mtime has changed drop any old lease */
635 if (old != 0 && ifp->options->mtime != old) { 635 if (old != 0 && ifp->options->mtime != old) {
636 logwarnx("%s: config file changed, expiring leases", 636 logwarnx("%s: config file changed, expiring leases",
637 ifp->name); 637 ifp->name);
638 dhcpcd_drop(ifp, 0); 638 dhcpcd_drop(ifp, 0);
639 } 639 }
640} 640}
641 641
642static void 642static void
643dhcpcd_initstate2(struct interface *ifp, unsigned long long options) 643dhcpcd_initstate2(struct interface *ifp, unsigned long long options)
644{ 644{
645 struct if_options *ifo; 645 struct if_options *ifo;
646 646
647 if (options) { 647 if (options) {
648 if ((ifo = default_config(ifp->ctx)) == NULL) { 648 if ((ifo = default_config(ifp->ctx)) == NULL) {
649 logerr(__func__); 649 logerr(__func__);
650 return; 650 return;
651 } 651 }
652 ifo->options |= options; 652 ifo->options |= options;
653 free(ifp->options); 653 free(ifp->options);
654 ifp->options = ifo; 654 ifp->options = ifo;
655 } else 655 } else
656 ifo = ifp->options; 656 ifo = ifp->options;
657 657
658#ifdef INET6 658#ifdef INET6
659 if (ifo->options & DHCPCD_IPV6 && ipv6_init(ifp->ctx) == -1) { 659 if (ifo->options & DHCPCD_IPV6 && ipv6_init(ifp->ctx) == -1) {
660 logerr(__func__); 660 logerr(__func__);
661 ifo->options &= ~DHCPCD_IPV6; 661 ifo->options &= ~DHCPCD_IPV6;
662 } 662 }
663#endif 663#endif
664} 664}
665 665
666static void 666static void
667dhcpcd_initstate1(struct interface *ifp, int argc, char **argv, 667dhcpcd_initstate1(struct interface *ifp, int argc, char **argv,
668 unsigned long long options) 668 unsigned long long options)
669{ 669{
670 670
671 configure_interface(ifp, argc, argv, options); 671 configure_interface(ifp, argc, argv, options);
672 if (ifp->active) 672 if (ifp->active)
673 dhcpcd_initstate2(ifp, 0); 673 dhcpcd_initstate2(ifp, 0);
674} 674}
675 675
676static void 676static void
677dhcpcd_initstate(struct interface *ifp, unsigned long long options) 677dhcpcd_initstate(struct interface *ifp, unsigned long long options)
678{ 678{
679 679
680 dhcpcd_initstate1(ifp, ifp->ctx->argc, ifp->ctx->argv, options); 680 dhcpcd_initstate1(ifp, ifp->ctx->argc, ifp->ctx->argv, options);
681} 681}
682 682
683static void 683static void
684dhcpcd_reportssid(struct interface *ifp) 684dhcpcd_reportssid(struct interface *ifp)
685{ 685{
686 char pssid[IF_SSIDLEN * 4]; 686 char pssid[IF_SSIDLEN * 4];
687 687
688 if (print_string(pssid, sizeof(pssid), OT_ESCSTRING, 688 if (print_string(pssid, sizeof(pssid), OT_ESCSTRING,
689 ifp->ssid, ifp->ssid_len) == -1) 689 ifp->ssid, ifp->ssid_len) == -1)
690 { 690 {
691 logerr(__func__); 691 logerr(__func__);
692 return; 692 return;
693 } 693 }
694 694
695 loginfox("%s: connected to Access Point: %s", ifp->name, pssid); 695 loginfox("%s: connected to Access Point: %s", ifp->name, pssid);
696} 696}
697 697
698void 698void
699dhcpcd_handlecarrier(struct interface *ifp, int carrier, unsigned int flags) 699dhcpcd_handlecarrier(struct interface *ifp, int carrier, unsigned int flags)
700{ 700{
701 bool was_link_up = if_is_link_up(ifp); 701 bool was_link_up = if_is_link_up(ifp);
702 702
703 ifp->carrier = carrier; 703 ifp->carrier = carrier;
704 ifp->flags = flags; 704 ifp->flags = flags;
705 705
706 if (!if_is_link_up(ifp)) { 706 if (!if_is_link_up(ifp)) {
707 if (!was_link_up || !ifp->active) 707 if (!was_link_up || !ifp->active)
708 return; 708 return;
709 loginfox("%s: carrier lost", ifp->name); 709 loginfox("%s: carrier lost", ifp->name);
710 script_runreason(ifp, "NOCARRIER"); 710 script_runreason(ifp, "NOCARRIER");
711#ifdef NOCARRIER_PRESERVE_IP 711#ifdef NOCARRIER_PRESERVE_IP
712 if (ifp->flags & IFF_UP && 712 if (ifp->flags & IFF_UP &&
713 !(ifp->options->options & DHCPCD_ANONYMOUS)) 713 !(ifp->options->options & DHCPCD_ANONYMOUS))
714 { 714 {
715#ifdef ARP 715#ifdef ARP
716 arp_drop(ifp); 716 arp_drop(ifp);
717#endif 717#endif
718#ifdef INET 718#ifdef INET
719 dhcp_abort(ifp); 719 dhcp_abort(ifp);
720#endif 720#endif
721#ifdef DHCP6 721#ifdef DHCP6
722 dhcp6_abort(ifp); 722 dhcp6_abort(ifp);
723#endif 723#endif
724 } else 724 } else
725#endif 725#endif
726 dhcpcd_drop(ifp, 0); 726 dhcpcd_drop(ifp, 0);
727 if (ifp->options->options & DHCPCD_ANONYMOUS) { 727 if (ifp->options->options & DHCPCD_ANONYMOUS) {
728 bool is_up = ifp->flags & IFF_UP; 728 bool is_up = ifp->flags & IFF_UP;
729 729
730 if (is_up) 730 if (is_up)
731 if_down(ifp); 731 if_down(ifp);
732 if (if_randomisemac(ifp) == -1 && errno != ENXIO) 732 if (if_randomisemac(ifp) == -1 && errno != ENXIO)
733 logerr(__func__); 733 logerr(__func__);
734 if (is_up) 734 if (is_up)
735 if_up(ifp); 735 if_up(ifp);
736 } 736 }
737 return; 737 return;
738 } 738 }
739 739
740 /* 740 /*
741 * At this point carrier is NOT DOWN and we have IFF_UP. 741 * At this point carrier is NOT DOWN and we have IFF_UP.
742 * We should treat LINK_UNKNOWN as up as the driver may not support 742 * We should treat LINK_UNKNOWN as up as the driver may not support
743 * link state changes. 743 * link state changes.
744 * The consideration of any other information about carrier should 744 * The consideration of any other information about carrier should
745 * be handled in the OS specific if_carrier() function. 745 * be handled in the OS specific if_carrier() function.
746 */ 746 */
747 if (was_link_up) 747 if (was_link_up)
748 return; 748 return;
749 749
750 if (ifp->active) { 750 if (ifp->active) {
751 if (carrier == LINK_UNKNOWN) 751 if (carrier == LINK_UNKNOWN)
752 loginfox("%s: carrier unknown, assuming up", ifp->name); 752 loginfox("%s: carrier unknown, assuming up", ifp->name);
753 else 753 else
754 loginfox("%s: carrier acquired", ifp->name); 754 loginfox("%s: carrier acquired", ifp->name);
755 } 755 }
756 756
757#if !defined(__linux__) && !defined(__NetBSD__) 757#if !defined(__linux__) && !defined(__NetBSD__)
758 /* BSD does not emit RTM_NEWADDR or RTM_CHGADDR when the 758 /* BSD does not emit RTM_NEWADDR or RTM_CHGADDR when the
759 * hardware address changes so we have to go 759 * hardware address changes so we have to go
760 * through the disovery process to work it out. */ 760 * through the disovery process to work it out. */
761 dhcpcd_handleinterface(ifp->ctx, 0, ifp->name); 761 dhcpcd_handleinterface(ifp->ctx, 0, ifp->name);
762#endif 762#endif
763 763
764 if (ifp->wireless) { 764 if (ifp->wireless) {
765 uint8_t ossid[IF_SSIDLEN]; 765 uint8_t ossid[IF_SSIDLEN];
766 size_t olen; 766 size_t olen;
767 767
768 olen = ifp->ssid_len; 768 olen = ifp->ssid_len;
769 memcpy(ossid, ifp->ssid, ifp->ssid_len); 769 memcpy(ossid, ifp->ssid, ifp->ssid_len);
770 if_getssid(ifp); 770 if_getssid(ifp);
771 771
772 /* If we changed SSID network, drop leases */ 772 /* If we changed SSID network, drop leases */
773 if ((ifp->ssid_len != olen || 773 if ((ifp->ssid_len != olen ||
774 memcmp(ifp->ssid, ossid, ifp->ssid_len)) && ifp->active) 774 memcmp(ifp->ssid, ossid, ifp->ssid_len)) && ifp->active)
775 { 775 {
776 dhcpcd_reportssid(ifp); 776 dhcpcd_reportssid(ifp);
777#ifdef NOCARRIER_PRESERVE_IP 777#ifdef NOCARRIER_PRESERVE_IP
778 dhcpcd_drop(ifp, 0); 778 dhcpcd_drop(ifp, 0);
779#endif 779#endif
780#ifdef IPV4LL 780#ifdef IPV4LL
781 ipv4ll_reset(ifp); 781 ipv4ll_reset(ifp);
782#endif 782#endif
783 } 783 }
784 } 784 }
785 785
786 if (!ifp->active) 786 if (!ifp->active)
787 return; 787 return;
788 788
789 dhcpcd_initstate(ifp, 0); 789 dhcpcd_initstate(ifp, 0);
790 script_runreason(ifp, "CARRIER"); 790 script_runreason(ifp, "CARRIER");
791#ifdef INET6 791#ifdef INET6
792#ifdef NOCARRIER_PRESERVE_IP 792#ifdef NOCARRIER_PRESERVE_IP
793 /* Set any IPv6 Routers we remembered to expire faster than they 793 /* Set any IPv6 Routers we remembered to expire faster than they
794 * would normally as we maybe on a new network. */ 794 * would normally as we maybe on a new network. */
795 ipv6nd_startexpire(ifp); 795 ipv6nd_startexpire(ifp);
796#endif 796#endif
797#ifdef IPV6_MANAGETEMPADDR 797#ifdef IPV6_MANAGETEMPADDR
798 /* RFC4941 Section 3.5 */ 798 /* RFC4941 Section 3.5 */
799 ipv6_regentempaddrs(ifp); 799 ipv6_regentempaddrs(ifp);
800#endif 800#endif
801#endif 801#endif
802 dhcpcd_startinterface(ifp); 802 dhcpcd_startinterface(ifp);
803} 803}
804 804
805static void 805static void
806warn_iaid_conflict(struct interface *ifp, uint16_t ia_type, uint8_t *iaid) 806warn_iaid_conflict(struct interface *ifp, uint16_t ia_type, uint8_t *iaid)
807{ 807{
808 struct interface *ifn; 808 struct interface *ifn;
809#ifdef INET6 809#ifdef INET6
810 size_t i; 810 size_t i;
811 struct if_ia *ia; 811 struct if_ia *ia;
812#endif 812#endif
813 813
814 TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) { 814 TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) {
815 if (ifn == ifp || !ifn->active) 815 if (ifn == ifp || !ifn->active)
816 continue; 816 continue;
817 if (ifn->options->options & DHCPCD_ANONYMOUS) 817 if (ifn->options->options & DHCPCD_ANONYMOUS)
818 continue; 818 continue;
819 if (ia_type == 0 && 819 if (ia_type == 0 &&
820 memcmp(ifn->options->iaid, iaid, 820 memcmp(ifn->options->iaid, iaid,
821 sizeof(ifn->options->iaid)) == 0) 821 sizeof(ifn->options->iaid)) == 0)
822 break; 822 break;
823#ifdef INET6 823#ifdef INET6
824 for (i = 0; i < ifn->options->ia_len; i++) { 824 for (i = 0; i < ifn->options->ia_len; i++) {
825 ia = &ifn->options->ia[i]; 825 ia = &ifn->options->ia[i];
826 if (ia->ia_type == ia_type && 826 if (ia->ia_type == ia_type &&
827 memcmp(ia->iaid, iaid, sizeof(ia->iaid)) == 0) 827 memcmp(ia->iaid, iaid, sizeof(ia->iaid)) == 0)
828 break; 828 break;
829 } 829 }
830#endif 830#endif
831 } 831 }
832 832
833 /* This is only a problem if the interfaces are on the same network. */ 833 /* This is only a problem if the interfaces are on the same network. */
834 if (ifn) 834 if (ifn)
835 logerrx("%s: IAID conflicts with one assigned to %s", 835 logerrx("%s: IAID conflicts with one assigned to %s",
836 ifp->name, ifn->name); 836 ifp->name, ifn->name);
837} 837}
838 838
839static void 839static void
840dhcpcd_initduid(struct dhcpcd_ctx *ctx, struct interface *ifp) 840dhcpcd_initduid(struct dhcpcd_ctx *ctx, struct interface *ifp)
841{ 841{
842 char buf[DUID_LEN * 3]; 842 char buf[DUID_LEN * 3];
843 843
844 if (ctx->duid != NULL) 844 if (ctx->duid != NULL)
845 return; 845 return;
846 846
847 duid_init(ctx, ifp); 847 duid_init(ctx, ifp);
848 if (ctx->duid == NULL) 848 if (ctx->duid == NULL)
849 return; 849 return;
850 850
851 loginfox("DUID %s", 851 loginfox("DUID %s",
852 hwaddr_ntoa(ctx->duid, ctx->duid_len, buf, sizeof(buf))); 852 hwaddr_ntoa(ctx->duid, ctx->duid_len, buf, sizeof(buf)));
853} 853}
854 854
855void 855void
856dhcpcd_startinterface(void *arg) 856dhcpcd_startinterface(void *arg)
857{ 857{
858 struct interface *ifp = arg; 858 struct interface *ifp = arg;
859 struct if_options *ifo = ifp->options; 859 struct if_options *ifo = ifp->options;
860 860
861 if (ifo->options & DHCPCD_LINK && !if_is_link_up(ifp)) { 861 if (ifo->options & DHCPCD_LINK && !if_is_link_up(ifp)) {
862 loginfox("%s: waiting for carrier", ifp->name); 862 loginfox("%s: waiting for carrier", ifp->name);
863 return; 863 return;
864 } 864 }
865 865
866 if (ifo->options & (DHCPCD_DUID | DHCPCD_IPV6) && 866 if (ifo->options & (DHCPCD_DUID | DHCPCD_IPV6) &&
867 !(ifo->options & DHCPCD_ANONYMOUS)) 867 !(ifo->options & DHCPCD_ANONYMOUS))
868 { 868 {
869 char buf[sizeof(ifo->iaid) * 3]; 869 char buf[sizeof(ifo->iaid) * 3];
870#ifdef INET6 870#ifdef INET6
871 size_t i; 871 size_t i;
872 struct if_ia *ia; 872 struct if_ia *ia;
873#endif 873#endif
874 874
875 /* Try and init DUID from the interface hardware address */ 875 /* Try and init DUID from the interface hardware address */
876 dhcpcd_initduid(ifp->ctx, ifp); 876 dhcpcd_initduid(ifp->ctx, ifp);
877 877
878 /* Report IAIDs */ 878 /* Report IAIDs */
879 loginfox("%s: IAID %s", ifp->name, 879 loginfox("%s: IAID %s", ifp->name,
880 hwaddr_ntoa(ifo->iaid, sizeof(ifo->iaid), 880 hwaddr_ntoa(ifo->iaid, sizeof(ifo->iaid),
881 buf, sizeof(buf))); 881 buf, sizeof(buf)));
882 warn_iaid_conflict(ifp, 0, ifo->iaid); 882 warn_iaid_conflict(ifp, 0, ifo->iaid);
883 883
884#ifdef INET6 884#ifdef INET6
885 for (i = 0; i < ifo->ia_len; i++) { 885 for (i = 0; i < ifo->ia_len; i++) {
886 ia = &ifo->ia[i]; 886 ia = &ifo->ia[i];
887 if (memcmp(ifo->iaid, ia->iaid, sizeof(ifo->iaid))) { 887 if (memcmp(ifo->iaid, ia->iaid, sizeof(ifo->iaid))) {
888 loginfox("%s: IA type %u IAID %s", 888 loginfox("%s: IA type %u IAID %s",
889 ifp->name, ia->ia_type, 889 ifp->name, ia->ia_type,
890 hwaddr_ntoa(ia->iaid, sizeof(ia->iaid), 890 hwaddr_ntoa(ia->iaid, sizeof(ia->iaid),
891 buf, sizeof(buf))); 891 buf, sizeof(buf)));
892 warn_iaid_conflict(ifp, ia->ia_type, ia->iaid); 892 warn_iaid_conflict(ifp, ia->ia_type, ia->iaid);
893 } 893 }
894 } 894 }
895#endif 895#endif
896 } 896 }
897 897
898#ifdef INET6 898#ifdef INET6
899 if (ifo->options & DHCPCD_IPV6 && ipv6_start(ifp) == -1) { 899 if (ifo->options & DHCPCD_IPV6 && ipv6_start(ifp) == -1) {
900 logerr("%s: ipv6_start", ifp->name); 900 logerr("%s: ipv6_start", ifp->name);
901 ifo->options &= ~DHCPCD_IPV6; 901 ifo->options &= ~DHCPCD_IPV6;
902 } 902 }
903 903
904 if (ifo->options & DHCPCD_IPV6) { 904 if (ifo->options & DHCPCD_IPV6) {
905 if (ifp->active == IF_ACTIVE_USER) { 905 if (ifp->active == IF_ACTIVE_USER) {
906 ipv6_startstatic(ifp); 906 ipv6_startstatic(ifp);
907 907
908 if (ifo->options & DHCPCD_IPV6RS) 908 if (ifo->options & DHCPCD_IPV6RS)
909 ipv6nd_startrs(ifp); 909 ipv6nd_startrs(ifp);
910 } 910 }
911 911
912#ifdef DHCP6 912#ifdef DHCP6
913 /* DHCPv6 could be turned off, but the interface 913 /* DHCPv6 could be turned off, but the interface
914 * is still delegated to. */ 914 * is still delegated to. */
915 if (ifp->active) 915 if (ifp->active)
916 dhcp6_find_delegates(ifp); 916 dhcp6_find_delegates(ifp);
917 917
918 if (ifo->options & DHCPCD_DHCP6) { 918 if (ifo->options & DHCPCD_DHCP6) {
919 if (ifp->active == IF_ACTIVE_USER) { 919 if (ifp->active == IF_ACTIVE_USER) {
920 enum DH6S d6_state; 920 enum DH6S d6_state;
921 921
922 if (ifo->options & DHCPCD_IA_FORCED) 922 if (ifo->options & DHCPCD_IA_FORCED)
923 d6_state = DH6S_INIT; 923 d6_state = DH6S_INIT;
924 else if (ifo->options & DHCPCD_INFORM6) 924 else if (ifo->options & DHCPCD_INFORM6)
925 d6_state = DH6S_INFORM; 925 d6_state = DH6S_INFORM;
926 else 926 else
927 d6_state = DH6S_CONFIRM; 927 d6_state = DH6S_CONFIRM;
928 if (dhcp6_start(ifp, d6_state) == -1) 928 if (dhcp6_start(ifp, d6_state) == -1)
929 logerr("%s: dhcp6_start", ifp->name); 929 logerr("%s: dhcp6_start", ifp->name);
930 } 930 }
931 } 931 }
932#endif 932#endif
933 } 933 }
934#endif 934#endif
935 935
936#ifdef INET 936#ifdef INET
937 if (ifo->options & DHCPCD_IPV4 && ifp->active == IF_ACTIVE_USER) { 937 if (ifo->options & DHCPCD_IPV4 && ifp->active == IF_ACTIVE_USER) {
938 /* Ensure we have an IPv4 state before starting DHCP */ 938 /* Ensure we have an IPv4 state before starting DHCP */
939 if (ipv4_getstate(ifp) != NULL) 939 if (ipv4_getstate(ifp) != NULL)
940 dhcp_start(ifp); 940 dhcp_start(ifp);
941 } 941 }
942#endif 942#endif
943} 943}
944 944
945static void 945static void
946dhcpcd_prestartinterface(void *arg) 946dhcpcd_prestartinterface(void *arg)
947{ 947{
948 struct interface *ifp = arg; 948 struct interface *ifp = arg;
949 struct dhcpcd_ctx *ctx = ifp->ctx; 949 struct dhcpcd_ctx *ctx = ifp->ctx;
950 bool anondown; 950 bool anondown;
951 951
952 if (ifp->carrier <= LINK_DOWN && 952 if (ifp->carrier <= LINK_DOWN &&
953 ifp->options->options & DHCPCD_ANONYMOUS && 953 ifp->options->options & DHCPCD_ANONYMOUS &&
954 ifp->flags & IFF_UP) 954 ifp->flags & IFF_UP)
955 { 955 {
956 if_down(ifp); 956 if_down(ifp);
957 anondown = true; 957 anondown = true;
958 } else 958 } else
959 anondown = false; 959 anondown = false;
960 960
961 if ((!(ctx->options & DHCPCD_MASTER) || 961 if ((!(ctx->options & DHCPCD_MASTER) ||
962 ifp->options->options & DHCPCD_IF_UP || anondown) && 962 ifp->options->options & DHCPCD_IF_UP || anondown) &&
963 !(ifp->flags & IFF_UP)) 963 !(ifp->flags & IFF_UP))
964 { 964 {
965 if (ifp->options->options & DHCPCD_ANONYMOUS && 965 if (ifp->options->options & DHCPCD_ANONYMOUS &&
966 if_randomisemac(ifp) == -1) 966 if_randomisemac(ifp) == -1)
967 logerr(__func__); 967 logerr(__func__);
968 if (if_up(ifp) == -1) 968 if (if_up(ifp) == -1)
969 logerr(__func__); 969 logerr(__func__);
970 } 970 }
971 971
972 dhcpcd_startinterface(ifp); 972 dhcpcd_startinterface(ifp);
973} 973}
974 974
975static void 975static void
976run_preinit(struct interface *ifp) 976run_preinit(struct interface *ifp)
977{ 977{
978 978
979 if (ifp->ctx->options & DHCPCD_TEST) 979 if (ifp->ctx->options & DHCPCD_TEST)
980 return; 980 return;
981 981
982 script_runreason(ifp, "PREINIT"); 982 script_runreason(ifp, "PREINIT");
983 if (ifp->wireless && if_is_link_up(ifp)) 983 if (ifp->wireless && if_is_link_up(ifp))
984 dhcpcd_reportssid(ifp); 984 dhcpcd_reportssid(ifp);
985 if (ifp->options->options & DHCPCD_LINK && ifp->carrier != LINK_UNKNOWN) 985 if (ifp->options->options & DHCPCD_LINK && ifp->carrier != LINK_UNKNOWN)
986 script_runreason(ifp, 986 script_runreason(ifp,
987 ifp->carrier == LINK_UP ? "CARRIER" : "NOCARRIER"); 987 ifp->carrier == LINK_UP ? "CARRIER" : "NOCARRIER");
988} 988}
989 989
990void 990void
991dhcpcd_activateinterface(struct interface *ifp, unsigned long long options) 991dhcpcd_activateinterface(struct interface *ifp, unsigned long long options)
992{ 992{
993 993
994 if (!ifp->active) { 994 if (!ifp->active) {
995 ifp->active = IF_ACTIVE; 995 ifp->active = IF_ACTIVE;
996 dhcpcd_initstate2(ifp, options); 996 dhcpcd_initstate2(ifp, options);
997 /* It's possible we might not have been able to load 997 /* It's possible we might not have been able to load
998 * a config. */ 998 * a config. */
999 if (ifp->active) { 999 if (ifp->active) {
1000 configure_interface1(ifp); 1000 configure_interface1(ifp);
1001 run_preinit(ifp); 1001 run_preinit(ifp);
1002 dhcpcd_prestartinterface(ifp); 1002 dhcpcd_prestartinterface(ifp);
1003 } 1003 }
1004 } 1004 }
1005} 1005}
1006 1006
1007int 1007int
1008dhcpcd_handleinterface(void *arg, int action, const char *ifname) 1008dhcpcd_handleinterface(void *arg, int action, const char *ifname)
1009{ 1009{
1010 struct dhcpcd_ctx *ctx = arg; 1010 struct dhcpcd_ctx *ctx = arg;
1011 struct ifaddrs *ifaddrs; 1011 struct ifaddrs *ifaddrs;
1012 struct if_head *ifs; 1012 struct if_head *ifs;
1013 struct interface *ifp, *iff; 1013 struct interface *ifp, *iff;
1014 const char * const argv[] = { ifname }; 1014 const char * const argv[] = { ifname };
1015 int e; 1015 int e;
1016 1016
1017 if (action == -1) { 1017 if (action == -1) {
1018 ifp = if_find(ctx->ifaces, ifname); 1018 ifp = if_find(ctx->ifaces, ifname);
1019 if (ifp == NULL) { 1019 if (ifp == NULL) {
1020 errno = ESRCH; 1020 errno = ESRCH;
1021 return -1; 1021 return -1;
1022 } 1022 }
1023 if (ifp->active) { 1023 if (ifp->active) {
1024 logdebugx("%s: interface departed", ifp->name); 1024 logdebugx("%s: interface departed", ifp->name);
1025 stop_interface(ifp, "DEPARTED"); 1025 stop_interface(ifp, "DEPARTED");
1026 } 1026 }
1027 TAILQ_REMOVE(ctx->ifaces, ifp, next); 1027 TAILQ_REMOVE(ctx->ifaces, ifp, next);
1028 if_free(ifp); 1028 if_free(ifp);
1029 return 0; 1029 return 0;
1030 } 1030 }
1031 1031
1032 ifs = if_discover(ctx, &ifaddrs, -1, UNCONST(argv)); 1032 ifs = if_discover(ctx, &ifaddrs, -1, UNCONST(argv));
1033 if (ifs == NULL) { 1033 if (ifs == NULL) {
1034 logerr(__func__); 1034 logerr(__func__);
1035 return -1; 1035 return -1;
1036 } 1036 }
1037 1037
1038 ifp = if_find(ifs, ifname); 1038 ifp = if_find(ifs, ifname);
1039 if (ifp == NULL) { 1039 if (ifp == NULL) {
1040 /* This can happen if an interface is quickly added 1040 /* This can happen if an interface is quickly added
1041 * and then removed. */ 1041 * and then removed. */
1042 errno = ENOENT; 1042 errno = ENOENT;
1043 e = -1; 1043 e = -1;
1044 goto out; 1044 goto out;
1045 } 1045 }
1046 e = 1; 1046 e = 1;
1047 1047
1048 /* Check if we already have the interface */ 1048 /* Check if we already have the interface */
1049 iff = if_find(ctx->ifaces, ifp->name); 1049 iff = if_find(ctx->ifaces, ifp->name);
1050 1050
1051 if (iff != NULL) { 1051 if (iff != NULL) {
1052 if (iff->active) 1052 if (iff->active)
1053 logdebugx("%s: interface updated", iff->name); 1053 logdebugx("%s: interface updated", iff->name);
1054 /* The flags and hwaddr could have changed */ 1054 /* The flags and hwaddr could have changed */
1055 iff->flags = ifp->flags; 1055 iff->flags = ifp->flags;
1056 iff->hwlen = ifp->hwlen; 1056 iff->hwlen = ifp->hwlen;
1057 if (ifp->hwlen != 0) 1057 if (ifp->hwlen != 0)
1058 memcpy(iff->hwaddr, ifp->hwaddr, iff->hwlen); 1058 memcpy(iff->hwaddr, ifp->hwaddr, iff->hwlen);
1059 } else { 1059 } else {
1060 TAILQ_REMOVE(ifs, ifp, next); 1060 TAILQ_REMOVE(ifs, ifp, next);
1061 TAILQ_INSERT_TAIL(ctx->ifaces, ifp, next); 1061 TAILQ_INSERT_TAIL(ctx->ifaces, ifp, next);
1062 if (ifp->active) { 1062 if (ifp->active) {
1063 logdebugx("%s: interface added", ifp->name); 1063 logdebugx("%s: interface added", ifp->name);
1064 dhcpcd_initstate(ifp, 0); 1064 dhcpcd_initstate(ifp, 0);
1065 run_preinit(ifp); 1065 run_preinit(ifp);
1066 } 1066 }
1067 iff = ifp; 1067 iff = ifp;
1068 } 1068 }
1069 1069
1070 if (action > 0) { 1070 if (action > 0) {
1071 if_learnaddrs(ctx, ifs, &ifaddrs); 1071 if_learnaddrs(ctx, ifs, &ifaddrs);
1072 if (iff->active) 1072 if (iff->active)
1073 dhcpcd_prestartinterface(iff); 1073 dhcpcd_prestartinterface(iff);
1074 } 1074 }
1075 1075
1076out: 1076out:
1077 /* Free our discovered list */ 1077 /* Free our discovered list */
1078 while ((ifp = TAILQ_FIRST(ifs))) { 1078 while ((ifp = TAILQ_FIRST(ifs))) {
1079 TAILQ_REMOVE(ifs, ifp, next); 1079 TAILQ_REMOVE(ifs, ifp, next);
1080 if_free(ifp); 1080 if_free(ifp);
1081 } 1081 }
1082 free(ifs); 1082 free(ifs);
1083 1083
1084 return e; 1084 return e;
1085} 1085}
1086 1086
1087static void 1087static void
1088dhcpcd_handlelink(void *arg) 1088dhcpcd_handlelink(void *arg)
1089{ 1089{
1090 struct dhcpcd_ctx *ctx = arg; 1090 struct dhcpcd_ctx *ctx = arg;
1091 1091
1092 if (if_handlelink(ctx) == -1) { 1092 if (if_handlelink(ctx) == -1) {
1093 if (errno == ENOBUFS || errno == ENOMEM) { 1093 if (errno == ENOBUFS || errno == ENOMEM) {
1094 dhcpcd_linkoverflow(ctx); 1094 dhcpcd_linkoverflow(ctx);
1095 return; 1095 return;
1096 } 1096 }
1097 if (errno != ENOTSUP) 1097 if (errno != ENOTSUP)
1098 logerr(__func__); 1098 logerr(__func__);
1099 } 1099 }
1100} 1100}
1101 1101
1102static void 1102static void
1103dhcpcd_checkcarrier(void *arg) 1103dhcpcd_checkcarrier(void *arg)
1104{ 1104{
1105 struct interface *ifp0 = arg, *ifp; 1105 struct interface *ifp0 = arg, *ifp;
1106 1106
1107 ifp = if_find(ifp0->ctx->ifaces, ifp0->name); 1107 ifp = if_find(ifp0->ctx->ifaces, ifp0->name);
1108 if (ifp == NULL || ifp->carrier == ifp0->carrier) 1108 if (ifp == NULL || ifp->carrier == ifp0->carrier)
1109 return; 1109 return;
1110 1110
1111 dhcpcd_handlecarrier(ifp, ifp0->carrier, ifp0->flags); 1111 dhcpcd_handlecarrier(ifp, ifp0->carrier, ifp0->flags);
1112 if_free(ifp0); 1112 if_free(ifp0);
1113} 1113}
1114 1114
1115#ifndef SMALL 1115#ifndef SMALL
1116static void 1116static void
1117dhcpcd_setlinkrcvbuf(struct dhcpcd_ctx *ctx) 1117dhcpcd_setlinkrcvbuf(struct dhcpcd_ctx *ctx)
1118{ 1118{
1119 socklen_t socklen; 1119 socklen_t socklen;
1120 1120
1121 if (ctx->link_rcvbuf == 0) 1121 if (ctx->link_rcvbuf == 0)
1122 return; 1122 return;
1123 1123
1124 logdebugx("setting route socket receive buffer size to %d bytes", 1124 logdebugx("setting route socket receive buffer size to %d bytes",
1125 ctx->link_rcvbuf); 1125 ctx->link_rcvbuf);
1126 1126
1127 socklen = sizeof(ctx->link_rcvbuf); 1127 socklen = sizeof(ctx->link_rcvbuf);
1128 if (setsockopt(ctx->link_fd, SOL_SOCKET, 1128 if (setsockopt(ctx->link_fd, SOL_SOCKET,
1129 SO_RCVBUF, &ctx->link_rcvbuf, socklen) == -1) 1129 SO_RCVBUF, &ctx->link_rcvbuf, socklen) == -1)
1130 logerr(__func__); 1130 logerr(__func__);
1131} 1131}
1132#endif 1132#endif
1133 1133
1134static void 1134static void
1135dhcpcd_runprestartinterface(void *arg) 1135dhcpcd_runprestartinterface(void *arg)
1136{ 1136{
1137 struct interface *ifp = arg; 1137 struct interface *ifp = arg;
1138 1138
1139 run_preinit(ifp); 1139 run_preinit(ifp);
1140 dhcpcd_prestartinterface(ifp); 1140 dhcpcd_prestartinterface(ifp);
1141} 1141}
1142 1142
1143void 1143void
1144dhcpcd_linkoverflow(struct dhcpcd_ctx *ctx) 1144dhcpcd_linkoverflow(struct dhcpcd_ctx *ctx)
1145{ 1145{
1146 socklen_t socklen; 1146 socklen_t socklen;
1147 int rcvbuflen; 1147 int rcvbuflen;
1148 char buf[2048]; 1148 char buf[2048];
1149 ssize_t rlen; 1149 ssize_t rlen;
1150 size_t rcnt; 1150 size_t rcnt;
1151 struct if_head *ifaces; 1151 struct if_head *ifaces;
1152 struct ifaddrs *ifaddrs; 1152 struct ifaddrs *ifaddrs;
1153 struct interface *ifp, *ifn, *ifp1; 1153 struct interface *ifp, *ifn, *ifp1;
1154 1154
1155 socklen = sizeof(rcvbuflen); 1155 socklen = sizeof(rcvbuflen);
1156 if (getsockopt(ctx->link_fd, SOL_SOCKET, 1156 if (getsockopt(ctx->link_fd, SOL_SOCKET,
1157 SO_RCVBUF, &rcvbuflen, &socklen) == -1) 1157 SO_RCVBUF, &rcvbuflen, &socklen) == -1)
1158 rcvbuflen = 0; 1158 rcvbuflen = 0;
1159#ifdef __linux__ 1159#ifdef __linux__
1160 else 1160 else
1161 rcvbuflen /= 2; 1161 rcvbuflen /= 2;
1162#endif 1162#endif
1163 1163
1164 logerrx("route socket overflowed (rcvbuflen %d)" 1164 logerrx("route socket overflowed (rcvbuflen %d)"
1165 " - learning interface state", rcvbuflen); 1165 " - learning interface state", rcvbuflen);
1166 1166
1167 /* Drain the socket. 1167 /* Drain the socket.
1168 * We cannot open a new one due to privsep. */ 1168 * We cannot open a new one due to privsep. */
1169 rcnt = 0; 1169 rcnt = 0;
1170 do { 1170 do {
1171 rlen = read(ctx->link_fd, buf, sizeof(buf)); 1171 rlen = read(ctx->link_fd, buf, sizeof(buf));
1172 if (++rcnt % 1000 == 0) 1172 if (++rcnt % 1000 == 0)
1173 logwarnx("drained %zu messages", rcnt); 1173 logwarnx("drained %zu messages", rcnt);
1174 } while (rlen != -1 || errno == ENOBUFS || errno == ENOMEM); 1174 } while (rlen != -1 || errno == ENOBUFS || errno == ENOMEM);
1175 if (rcnt % 1000 != 0) 1175 if (rcnt % 1000 != 0)
1176 logwarnx("drained %zu messages", rcnt); 1176 logwarnx("drained %zu messages", rcnt);
1177 1177
1178 /* Work out the current interfaces. */ 1178 /* Work out the current interfaces. */
1179 ifaces = if_discover(ctx, &ifaddrs, ctx->ifc, ctx->ifv); 1179 ifaces = if_discover(ctx, &ifaddrs, ctx->ifc, ctx->ifv);
1180 if (ifaces == NULL) { 1180 if (ifaces == NULL) {
1181 logerr(__func__); 1181 logerr(__func__);
1182 return; 1182 return;
1183 } 1183 }
1184 1184
1185 /* Punt departed interfaces */ 1185 /* Punt departed interfaces */
1186 TAILQ_FOREACH_SAFE(ifp, ctx->ifaces, next, ifn) { 1186 TAILQ_FOREACH_SAFE(ifp, ctx->ifaces, next, ifn) {
1187 if (if_find(ifaces, ifp->name) != NULL) 1187 if (if_find(ifaces, ifp->name) != NULL)
1188 continue; 1188 continue;
1189 dhcpcd_handleinterface(ctx, -1, ifp->name); 1189 dhcpcd_handleinterface(ctx, -1, ifp->name);
1190 } 1190 }
1191 1191
1192 /* Add new interfaces */ 1192 /* Add new interfaces */
1193 while ((ifp = TAILQ_FIRST(ifaces)) != NULL ) { 1193 while ((ifp = TAILQ_FIRST(ifaces)) != NULL ) {
1194 TAILQ_REMOVE(ifaces, ifp, next); 1194 TAILQ_REMOVE(ifaces, ifp, next);
1195 ifp1 = if_find(ctx->ifaces, ifp->name); 1195 ifp1 = if_find(ctx->ifaces, ifp->name);
1196 if (ifp1 != NULL) { 1196 if (ifp1 != NULL) {
1197 /* If the interface already exists, 1197 /* If the interface already exists,
1198 * check carrier state. 1198 * check carrier state.
1199 * dhcpcd_checkcarrier will free ifp. */ 1199 * dhcpcd_checkcarrier will free ifp. */
1200 eloop_timeout_add_sec(ctx->eloop, 0, 1200 eloop_timeout_add_sec(ctx->eloop, 0,
1201 dhcpcd_checkcarrier, ifp); 1201 dhcpcd_checkcarrier, ifp);
1202 continue; 1202 continue;
1203 } 1203 }
1204 TAILQ_INSERT_TAIL(ctx->ifaces, ifp, next); 1204 TAILQ_INSERT_TAIL(ctx->ifaces, ifp, next);
1205 if (ifp->active) { 1205 if (ifp->active) {
1206 dhcpcd_initstate(ifp, 0); 1206 dhcpcd_initstate(ifp, 0);
1207 eloop_timeout_add_sec(ctx->eloop, 0, 1207 eloop_timeout_add_sec(ctx->eloop, 0,
1208 dhcpcd_runprestartinterface, ifp); 1208 dhcpcd_runprestartinterface, ifp);
1209 } 1209 }
1210 } 1210 }
1211 free(ifaces); 1211 free(ifaces);
1212 1212
1213 /* Update address state. */ 1213 /* Update address state. */
1214 if_markaddrsstale(ctx->ifaces); 1214 if_markaddrsstale(ctx->ifaces);
1215 if_learnaddrs(ctx, ctx->ifaces, &ifaddrs); 1215 if_learnaddrs(ctx, ctx->ifaces, &ifaddrs);
1216 if_deletestaleaddrs(ctx->ifaces); 1216 if_deletestaleaddrs(ctx->ifaces);
1217} 1217}
1218 1218
1219void 1219void
1220dhcpcd_handlehwaddr(struct interface *ifp, 1220dhcpcd_handlehwaddr(struct interface *ifp,
1221 uint16_t hwtype, const void *hwaddr, uint8_t hwlen) 1221 uint16_t hwtype, const void *hwaddr, uint8_t hwlen)
1222{ 1222{
1223 char buf[sizeof(ifp->hwaddr) * 3]; 1223 char buf[sizeof(ifp->hwaddr) * 3];
1224 1224
1225 if (hwaddr == NULL || !if_valid_hwaddr(hwaddr, hwlen)) 1225 if (hwaddr == NULL || !if_valid_hwaddr(hwaddr, hwlen))
1226 hwlen = 0; 1226 hwlen = 0;
1227 1227
1228 if (hwlen > sizeof(ifp->hwaddr)) { 1228 if (hwlen > sizeof(ifp->hwaddr)) {
1229 errno = ENOBUFS; 1229 errno = ENOBUFS;
1230 logerr("%s: %s", __func__, ifp->name); 1230 logerr("%s: %s", __func__, ifp->name);
1231 return; 1231 return;
1232 } 1232 }
1233 1233
1234 if (ifp->hwtype != hwtype) { 1234 if (ifp->hwtype != hwtype) {
1235 loginfox("%s: hardware address type changed from %d to %d", 1235 loginfox("%s: hardware address type changed from %d to %d",
1236 ifp->name, ifp->hwtype, hwtype); 1236 ifp->name, ifp->hwtype, hwtype);
1237 ifp->hwtype = hwtype; 1237 ifp->hwtype = hwtype;
1238 } 1238 }
1239 1239
1240 if (ifp->hwlen == hwlen && 1240 if (ifp->hwlen == hwlen &&
1241 (hwlen == 0 || memcmp(ifp->hwaddr, hwaddr, hwlen) == 0)) 1241 (hwlen == 0 || memcmp(ifp->hwaddr, hwaddr, hwlen) == 0))
1242 return; 1242 return;
1243 1243
1244 loginfox("%s: new hardware address: %s", ifp->name, 1244 loginfox("%s: new hardware address: %s", ifp->name,
1245 hwaddr_ntoa(hwaddr, hwlen, buf, sizeof(buf))); 1245 hwaddr_ntoa(hwaddr, hwlen, buf, sizeof(buf)));
1246 ifp->hwlen = hwlen; 1246 ifp->hwlen = hwlen;
1247 if (hwaddr != NULL) 1247 if (hwaddr != NULL)
1248 memcpy(ifp->hwaddr, hwaddr, hwlen); 1248 memcpy(ifp->hwaddr, hwaddr, hwlen);
1249} 1249}
1250 1250
1251static void 1251static void
1252if_reboot(struct interface *ifp, int argc, char **argv) 1252if_reboot(struct interface *ifp, int argc, char **argv)
1253{ 1253{
1254#ifdef INET 1254#ifdef INET
1255 unsigned long long oldopts; 1255 unsigned long long oldopts;
1256 1256
1257 oldopts = ifp->options->options; 1257 oldopts = ifp->options->options;
1258#endif 1258#endif
1259 script_runreason(ifp, "RECONFIGURE"); 1259 script_runreason(ifp, "RECONFIGURE");
1260 dhcpcd_initstate1(ifp, argc, argv, 0); 1260 dhcpcd_initstate1(ifp, argc, argv, 0);
1261#ifdef INET 1261#ifdef INET
1262 dhcp_reboot_newopts(ifp, oldopts); 1262 dhcp_reboot_newopts(ifp, oldopts);
1263#endif 1263#endif
1264#ifdef DHCP6 1264#ifdef DHCP6
1265 dhcp6_reboot(ifp); 1265 dhcp6_reboot(ifp);
1266#endif 1266#endif
1267 dhcpcd_prestartinterface(ifp); 1267 dhcpcd_prestartinterface(ifp);
1268} 1268}
1269 1269
1270static void 1270static void
1271reload_config(struct dhcpcd_ctx *ctx) 1271reload_config(struct dhcpcd_ctx *ctx)
1272{ 1272{
1273 struct if_options *ifo; 1273 struct if_options *ifo;
1274 1274
1275 free_globals(ctx); 1275 free_globals(ctx);
1276 if ((ifo = read_config(ctx, NULL, NULL, NULL)) == NULL) 1276 if ((ifo = read_config(ctx, NULL, NULL, NULL)) == NULL)
1277 return; 1277 return;
1278 add_options(ctx, NULL, ifo, ctx->argc, ctx->argv); 1278 add_options(ctx, NULL, ifo, ctx->argc, ctx->argv);
1279 /* We need to preserve these options. */ 1279 /* We need to preserve these options. */
1280 if (ctx->options & DHCPCD_STARTED) 1280 if (ctx->options & DHCPCD_STARTED)
1281 ifo->options |= DHCPCD_STARTED; 1281 ifo->options |= DHCPCD_STARTED;
1282 if (ctx->options & DHCPCD_MASTER) 1282 if (ctx->options & DHCPCD_MASTER)
1283 ifo->options |= DHCPCD_MASTER; 1283 ifo->options |= DHCPCD_MASTER;
1284 if (ctx->options & DHCPCD_DAEMONISED) 1284 if (ctx->options & DHCPCD_DAEMONISED)
1285 ifo->options |= DHCPCD_DAEMONISED; 1285 ifo->options |= DHCPCD_DAEMONISED;
1286 if (ctx->options & DHCPCD_PRIVSEP) 1286 if (ctx->options & DHCPCD_PRIVSEP)
1287 ifo->options |= DHCPCD_PRIVSEP; 1287 ifo->options |= DHCPCD_PRIVSEP;
1288 ctx->options = ifo->options; 1288 ctx->options = ifo->options;
1289 free_options(ctx, ifo); 1289 free_options(ctx, ifo);
1290} 1290}
1291 1291
1292static void 1292static void
1293reconf_reboot(struct dhcpcd_ctx *ctx, int action, int argc, char **argv, int oi) 1293reconf_reboot(struct dhcpcd_ctx *ctx, int action, int argc, char **argv, int oi)
1294{ 1294{
1295 int i; 1295 int i;
1296 struct interface *ifp; 1296 struct interface *ifp;
1297 1297
1298 TAILQ_FOREACH(ifp, ctx->ifaces, next) { 1298 TAILQ_FOREACH(ifp, ctx->ifaces, next) {
1299 for (i = oi; i < argc; i++) { 1299 for (i = oi; i < argc; i++) {
1300 if (strcmp(ifp->name, argv[i]) == 0) 1300 if (strcmp(ifp->name, argv[i]) == 0)
1301 break; 1301 break;
1302 } 1302 }
1303 if (oi != argc && i == argc) 1303 if (oi != argc && i == argc)
1304 continue; 1304 continue;
1305 if (ifp->active == IF_ACTIVE_USER) { 1305 if (ifp->active == IF_ACTIVE_USER) {
1306 if (action) 1306 if (action)
1307 if_reboot(ifp, argc, argv); 1307 if_reboot(ifp, argc, argv);
1308#ifdef INET 1308#ifdef INET
1309 else 1309 else
1310 ipv4_applyaddr(ifp); 1310 ipv4_applyaddr(ifp);
1311#endif 1311#endif
1312 } else if (i != argc) { 1312 } else if (i != argc) {
1313 ifp->active = IF_ACTIVE_USER; 1313 ifp->active = IF_ACTIVE_USER;
1314 dhcpcd_initstate1(ifp, argc, argv, 0); 1314 dhcpcd_initstate1(ifp, argc, argv, 0);
1315 run_preinit(ifp); 1315 run_preinit(ifp);
1316 dhcpcd_prestartinterface(ifp); 1316 dhcpcd_prestartinterface(ifp);
1317 } 1317 }
1318 } 1318 }
1319} 1319}
1320 1320
1321static void 1321static void
1322stop_all_interfaces(struct dhcpcd_ctx *ctx, unsigned long long opts) 1322stop_all_interfaces(struct dhcpcd_ctx *ctx, unsigned long long opts)
1323{ 1323{
1324 struct interface *ifp; 1324 struct interface *ifp;
1325 1325
1326 ctx->options |= DHCPCD_EXITING; 1326 ctx->options |= DHCPCD_EXITING;
1327 if (ctx->ifaces == NULL) 1327 if (ctx->ifaces == NULL)
1328 return; 1328 return;
1329 1329
1330 /* Drop the last interface first */ 1330 /* Drop the last interface first */
1331 TAILQ_FOREACH_REVERSE(ifp, ctx->ifaces, if_head, next) { 1331 TAILQ_FOREACH_REVERSE(ifp, ctx->ifaces, if_head, next) {
1332 if (!ifp->active) 1332 if (!ifp->active)
1333 continue; 1333 continue;
1334 ifp->options->options |= opts; 1334 ifp->options->options |= opts;
1335 if (ifp->options->options & DHCPCD_RELEASE) 1335 if (ifp->options->options & DHCPCD_RELEASE)
1336 ifp->options->options &= ~DHCPCD_PERSISTENT; 1336 ifp->options->options &= ~DHCPCD_PERSISTENT;
1337 ifp->options->options |= DHCPCD_EXITING; 1337 ifp->options->options |= DHCPCD_EXITING;
1338 stop_interface(ifp, NULL); 1338 stop_interface(ifp, NULL);
1339 } 1339 }
1340} 1340}
1341 1341
1342static void 1342static void
1343dhcpcd_ifrenew(struct interface *ifp) 1343dhcpcd_ifrenew(struct interface *ifp)
1344{ 1344{
1345 1345
1346 if (!ifp->active) 1346 if (!ifp->active)
1347 return; 1347 return;
1348 1348
1349 if (ifp->options->options & DHCPCD_LINK && !if_is_link_up(ifp)) 1349 if (ifp->options->options & DHCPCD_LINK && !if_is_link_up(ifp))
1350 return; 1350 return;
1351 1351
1352#ifdef INET 1352#ifdef INET
1353 dhcp_renew(ifp); 1353 dhcp_renew(ifp);
1354#endif 1354#endif
1355#ifdef INET6 1355#ifdef INET6
1356#define DHCPCD_RARENEW (DHCPCD_IPV6 | DHCPCD_IPV6RS) 1356#define DHCPCD_RARENEW (DHCPCD_IPV6 | DHCPCD_IPV6RS)
1357 if ((ifp->options->options & DHCPCD_RARENEW) == DHCPCD_RARENEW) 1357 if ((ifp->options->options & DHCPCD_RARENEW) == DHCPCD_RARENEW)
1358 ipv6nd_startrs(ifp); 1358 ipv6nd_startrs(ifp);
1359#endif 1359#endif
1360#ifdef DHCP6 1360#ifdef DHCP6
1361 dhcp6_renew(ifp); 1361 dhcp6_renew(ifp);
1362#endif 1362#endif
1363} 1363}
1364 1364
1365static void 1365static void
1366dhcpcd_renew(struct dhcpcd_ctx *ctx) 1366dhcpcd_renew(struct dhcpcd_ctx *ctx)
1367{ 1367{
1368 struct interface *ifp; 1368 struct interface *ifp;
1369 1369
1370 TAILQ_FOREACH(ifp, ctx->ifaces, next) { 1370 TAILQ_FOREACH(ifp, ctx->ifaces, next) {
1371 dhcpcd_ifrenew(ifp); 1371 dhcpcd_ifrenew(ifp);
1372 } 1372 }
1373} 1373}
1374 1374
1375#ifdef USE_SIGNALS 1375#ifdef USE_SIGNALS
1376#define sigmsg "received %s, %s" 1376#define sigmsg "received %s, %s"
1377static void 1377static void
1378dhcpcd_signal_cb(int sig, void *arg) 1378dhcpcd_signal_cb(int sig, void *arg)
1379{ 1379{
1380 struct dhcpcd_ctx *ctx = arg; 1380 struct dhcpcd_ctx *ctx = arg;
1381 unsigned long long opts; 1381 unsigned long long opts;
1382 int exit_code; 1382 int exit_code;
1383 1383
1384 if (ctx->options & DHCPCD_DUMPLEASE) { 1384 if (ctx->options & DHCPCD_DUMPLEASE) {
1385 eloop_exit(ctx->eloop, EXIT_FAILURE); 1385 eloop_exit(ctx->eloop, EXIT_FAILURE);
1386 return; 1386 return;
1387 } 1387 }
1388 1388
1389 if (sig != SIGCHLD && ctx->options & DHCPCD_FORKED) { 1389 if (sig != SIGCHLD && ctx->options & DHCPCD_FORKED) {
1390 if (sig != SIGHUP && 1390 if (sig != SIGHUP &&
1391 write(ctx->fork_fd, &sig, sizeof(sig)) == -1) 1391 write(ctx->fork_fd, &sig, sizeof(sig)) == -1)
1392 logerr("%s: write", __func__); 1392 logerr("%s: write", __func__);
1393 return; 1393 return;
1394 } 1394 }
1395 1395
1396 opts = 0; 1396 opts = 0;
1397 exit_code = EXIT_FAILURE; 1397 exit_code = EXIT_FAILURE;
1398 switch (sig) { 1398 switch (sig) {
1399 case SIGINT: 1399 case SIGINT:
1400 loginfox(sigmsg, "SIGINT", "stopping"); 1400 loginfox(sigmsg, "SIGINT", "stopping");
1401 break; 1401 break;
1402 case SIGTERM: 1402 case SIGTERM:
1403 loginfox(sigmsg, "SIGTERM", "stopping"); 1403 loginfox(sigmsg, "SIGTERM", "stopping");
1404 exit_code = EXIT_SUCCESS; 1404 exit_code = EXIT_SUCCESS;
1405 break; 1405 break;
1406 case SIGALRM: 1406 case SIGALRM:
1407 loginfox(sigmsg, "SIGALRM", "releasing"); 1407 loginfox(sigmsg, "SIGALRM", "releasing");
1408 opts |= DHCPCD_RELEASE; 1408 opts |= DHCPCD_RELEASE;
1409 exit_code = EXIT_SUCCESS; 1409 exit_code = EXIT_SUCCESS;
1410 break; 1410 break;
1411 case SIGHUP: 1411 case SIGHUP:
1412 loginfox(sigmsg, "SIGHUP", "rebinding"); 1412 loginfox(sigmsg, "SIGHUP", "rebinding");
1413 reload_config(ctx); 1413 reload_config(ctx);
1414 /* Preserve any options passed on the commandline 1414 /* Preserve any options passed on the commandline
1415 * when we were started. */ 1415 * when we were started. */
1416 reconf_reboot(ctx, 1, ctx->argc, ctx->argv, 1416 reconf_reboot(ctx, 1, ctx->argc, ctx->argv,
1417 ctx->argc - ctx->ifc); 1417 ctx->argc - ctx->ifc);
1418 return; 1418 return;
1419 case SIGUSR1: 1419 case SIGUSR1:
1420 loginfox(sigmsg, "SIGUSR1", "renewing"); 1420 loginfox(sigmsg, "SIGUSR1", "renewing");
1421 dhcpcd_renew(ctx); 1421 dhcpcd_renew(ctx);
1422 return; 1422 return;
1423 case SIGUSR2: 1423 case SIGUSR2:
1424 loginfox(sigmsg, "SIGUSR2", "reopening log"); 1424 loginfox(sigmsg, "SIGUSR2", "reopening log");
1425 /* XXX This may not work that well in a chroot */ 1425#ifdef PRIVSEP
1426 logclose(); 1426 if (IN_PRIVSEP(ctx)) {
 1427 if (ps_root_logreopen(ctx) == -1)
 1428 logerr("ps_root_logreopen");
 1429 return;
 1430 }
 1431#endif
1427 if (logopen(ctx->logfile) == -1) 1432 if (logopen(ctx->logfile) == -1)
1428 logerr(__func__); 1433 logerr("logopen");
1429 return; 1434 return;
1430 case SIGCHLD: 1435 case SIGCHLD:
1431 while (waitpid(-1, NULL, WNOHANG) > 0) 1436 while (waitpid(-1, NULL, WNOHANG) > 0)
1432 ; 1437 ;
1433 return; 1438 return;
1434 default: 1439 default:
1435 logerrx("received signal %d but don't know what to do with it", 1440 logerrx("received signal %d but don't know what to do with it",
1436 sig); 1441 sig);
1437 return; 1442 return;
1438 } 1443 }
1439 1444
1440 if (!(ctx->options & DHCPCD_TEST)) 1445 if (!(ctx->options & DHCPCD_TEST))
1441 stop_all_interfaces(ctx, opts); 1446 stop_all_interfaces(ctx, opts);
1442 eloop_exit(ctx->eloop, exit_code); 1447 eloop_exit(ctx->eloop, exit_code);
1443} 1448}
1444#endif 1449#endif
1445 1450
1446int 1451int
1447dhcpcd_handleargs(struct dhcpcd_ctx *ctx, struct fd_list *fd, 1452dhcpcd_handleargs(struct dhcpcd_ctx *ctx, struct fd_list *fd,
1448 int argc, char **argv) 1453 int argc, char **argv)
1449{ 1454{
1450 struct interface *ifp; 1455 struct interface *ifp;
1451 unsigned long long opts; 1456 unsigned long long opts;
1452 int opt, oi, do_reboot, do_renew, af = AF_UNSPEC; 1457 int opt, oi, do_reboot, do_renew, af = AF_UNSPEC;
1453 size_t len, l, nifaces; 1458 size_t len, l, nifaces;
1454 char *tmp, *p; 1459 char *tmp, *p;
1455 1460
1456 /* Special commands for our control socket 1461 /* Special commands for our control socket
1457 * as the other end should be blocking until it gets the 1462 * as the other end should be blocking until it gets the
1458 * expected reply we should be safely able just to change the 1463 * expected reply we should be safely able just to change the
1459 * write callback on the fd */ 1464 * write callback on the fd */
1460 /* Make any change here in privsep-control.c as well. */ 1465 /* Make any change here in privsep-control.c as well. */
1461 if (strcmp(*argv, "--version") == 0) { 1466 if (strcmp(*argv, "--version") == 0) {
1462 return control_queue(fd, UNCONST(VERSION), 1467 return control_queue(fd, UNCONST(VERSION),
1463 strlen(VERSION) + 1); 1468 strlen(VERSION) + 1);
1464 } else if (strcmp(*argv, "--getconfigfile") == 0) { 1469 } else if (strcmp(*argv, "--getconfigfile") == 0) {
1465 return control_queue(fd, UNCONST(fd->ctx->cffile), 1470 return control_queue(fd, UNCONST(fd->ctx->cffile),
1466 strlen(fd->ctx->cffile) + 1); 1471 strlen(fd->ctx->cffile) + 1);
1467 } else if (strcmp(*argv, "--getinterfaces") == 0) { 1472 } else if (strcmp(*argv, "--getinterfaces") == 0) {
1468 optind = argc = 0; 1473 optind = argc = 0;
1469 goto dumplease; 1474 goto dumplease;
1470 } else if (strcmp(*argv, "--listen") == 0) { 1475 } else if (strcmp(*argv, "--listen") == 0) {
1471 fd->flags |= FD_LISTEN; 1476 fd->flags |= FD_LISTEN;
1472 return 0; 1477 return 0;
1473 } 1478 }
1474 1479
1475 /* Log the command */ 1480 /* Log the command */
1476 len = 1; 1481 len = 1;
1477 for (opt = 0; opt < argc; opt++) 1482 for (opt = 0; opt < argc; opt++)
1478 len += strlen(argv[opt]) + 1; 1483 len += strlen(argv[opt]) + 1;
1479 tmp = malloc(len); 1484 tmp = malloc(len);
1480 if (tmp == NULL) 1485 if (tmp == NULL)
1481 return -1; 1486 return -1;
1482 p = tmp; 1487 p = tmp;
1483 for (opt = 0; opt < argc; opt++) { 1488 for (opt = 0; opt < argc; opt++) {
1484 l = strlen(argv[opt]); 1489 l = strlen(argv[opt]);
1485 strlcpy(p, argv[opt], len); 1490 strlcpy(p, argv[opt], len);
1486 len -= l + 1; 1491 len -= l + 1;
1487 p += l; 1492 p += l;
1488 *p++ = ' '; 1493 *p++ = ' ';
1489 } 1494 }
1490 *--p = '\0'; 1495 *--p = '\0';
1491 loginfox("control command: %s", tmp); 1496 loginfox("control command: %s", tmp);
1492 free(tmp); 1497 free(tmp);
1493 1498
1494 optind = 0; 1499 optind = 0;
1495 oi = 0; 1500 oi = 0;
1496 opts = 0; 1501 opts = 0;
1497 do_reboot = do_renew = 0; 1502 do_reboot = do_renew = 0;
1498 while ((opt = getopt_long(argc, argv, IF_OPTS, cf_options, &oi)) != -1) 1503 while ((opt = getopt_long(argc, argv, IF_OPTS, cf_options, &oi)) != -1)
1499 { 1504 {
1500 switch (opt) { 1505 switch (opt) {
1501 case 'g': 1506 case 'g':
1502 /* Assumed if below not set */ 1507 /* Assumed if below not set */
1503 break; 1508 break;
1504 case 'k': 1509 case 'k':
1505 opts |= DHCPCD_RELEASE; 1510 opts |= DHCPCD_RELEASE;
1506 break; 1511 break;
1507 case 'n': 1512 case 'n':
1508 do_reboot = 1; 1513 do_reboot = 1;
1509 break; 1514 break;
1510 case 'p': 1515 case 'p':
1511 opts |= DHCPCD_PERSISTENT; 1516 opts |= DHCPCD_PERSISTENT;
1512 break; 1517 break;
1513 case 'x': 1518 case 'x':
1514 opts |= DHCPCD_EXITING; 1519 opts |= DHCPCD_EXITING;
1515 break; 1520 break;
1516 case 'N': 1521 case 'N':
1517 do_renew = 1; 1522 do_renew = 1;
1518 break; 1523 break;
1519 case 'U': 1524 case 'U':
1520 opts |= DHCPCD_DUMPLEASE; 1525 opts |= DHCPCD_DUMPLEASE;
1521 break; 1526 break;
1522 case '4': 1527 case '4':
1523 af = AF_INET; 1528 af = AF_INET;
1524 break; 1529 break;
1525 case '6': 1530 case '6':
1526 af = AF_INET6; 1531 af = AF_INET6;
1527 break; 1532 break;
1528 } 1533 }
1529 } 1534 }
1530 1535
1531 if (opts & DHCPCD_DUMPLEASE) { 1536 if (opts & DHCPCD_DUMPLEASE) {
1532 ctx->options |= DHCPCD_DUMPLEASE; 1537 ctx->options |= DHCPCD_DUMPLEASE;
1533dumplease: 1538dumplease:
1534 nifaces = 0; 1539 nifaces = 0;
1535 TAILQ_FOREACH(ifp, ctx->ifaces, next) { 1540 TAILQ_FOREACH(ifp, ctx->ifaces, next) {
1536 if (!ifp->active) 1541 if (!ifp->active)
1537 continue; 1542 continue;
1538 for (oi = optind; oi < argc; oi++) { 1543 for (oi = optind; oi < argc; oi++) {
1539 if (strcmp(ifp->name, argv[oi]) == 0) 1544 if (strcmp(ifp->name, argv[oi]) == 0)
1540 break; 1545 break;
1541 } 1546 }
1542 if (optind == argc || oi < argc) { 1547 if (optind == argc || oi < argc) {
1543 opt = send_interface(NULL, ifp, af); 1548 opt = send_interface(NULL, ifp, af);
1544 if (opt == -1) 1549 if (opt == -1)
1545 goto dumperr; 1550 goto dumperr;
1546 nifaces += (size_t)opt; 1551 nifaces += (size_t)opt;
1547 } 1552 }
1548 } 1553 }
1549 if (write(fd->fd, &nifaces, sizeof(nifaces)) != sizeof(nifaces)) 1554 if (write(fd->fd, &nifaces, sizeof(nifaces)) != sizeof(nifaces))
1550 goto dumperr; 1555 goto dumperr;
1551 TAILQ_FOREACH(ifp, ctx->ifaces, next) { 1556 TAILQ_FOREACH(ifp, ctx->ifaces, next) {
1552 if (!ifp->active) 1557 if (!ifp->active)
1553 continue; 1558 continue;
1554 for (oi = optind; oi < argc; oi++) { 1559 for (oi = optind; oi < argc; oi++) {
1555 if (strcmp(ifp->name, argv[oi]) == 0) 1560 if (strcmp(ifp->name, argv[oi]) == 0)
1556 break; 1561 break;
1557 } 1562 }
1558 if (optind == argc || oi < argc) { 1563 if (optind == argc || oi < argc) {
1559 if (send_interface(fd, ifp, af) == -1) 1564 if (send_interface(fd, ifp, af) == -1)
1560 goto dumperr; 1565 goto dumperr;
1561 } 1566 }
1562 } 1567 }
1563 ctx->options &= ~DHCPCD_DUMPLEASE; 1568 ctx->options &= ~DHCPCD_DUMPLEASE;
1564 return 0; 1569 return 0;
1565dumperr: 1570dumperr:
1566 ctx->options &= ~DHCPCD_DUMPLEASE; 1571 ctx->options &= ~DHCPCD_DUMPLEASE;
1567 return -1; 1572 return -1;
1568 } 1573 }
1569 1574
1570 /* Only privileged users can control dhcpcd via the socket. */ 1575 /* Only privileged users can control dhcpcd via the socket. */
1571 if (fd->flags & FD_UNPRIV) { 1576 if (fd->flags & FD_UNPRIV) {
1572 errno = EPERM; 1577 errno = EPERM;
1573 return -1; 1578 return -1;
1574 } 1579 }
1575 1580
1576 if (opts & (DHCPCD_EXITING | DHCPCD_RELEASE)) { 1581 if (opts & (DHCPCD_EXITING | DHCPCD_RELEASE)) {
1577 if (optind == argc) { 1582 if (optind == argc) {
1578 stop_all_interfaces(ctx, opts); 1583 stop_all_interfaces(ctx, opts);
1579 eloop_exit(ctx->eloop, EXIT_SUCCESS); 1584 eloop_exit(ctx->eloop, EXIT_SUCCESS);
1580 return 0; 1585 return 0;
1581 } 1586 }
1582 for (oi = optind; oi < argc; oi++) { 1587 for (oi = optind; oi < argc; oi++) {
1583 if ((ifp = if_find(ctx->ifaces, argv[oi])) == NULL) 1588 if ((ifp = if_find(ctx->ifaces, argv[oi])) == NULL)
1584 continue; 1589 continue;
1585 if (!ifp->active) 1590 if (!ifp->active)
1586 continue; 1591 continue;
1587 ifp->options->options |= opts; 1592 ifp->options->options |= opts;
1588 if (opts & DHCPCD_RELEASE) 1593 if (opts & DHCPCD_RELEASE)
1589 ifp->options->options &= ~DHCPCD_PERSISTENT; 1594 ifp->options->options &= ~DHCPCD_PERSISTENT;
1590 stop_interface(ifp, NULL); 1595 stop_interface(ifp, NULL);
1591 } 1596 }
1592 return 0; 1597 return 0;
1593 } 1598 }
1594 1599
1595 if (do_renew) { 1600 if (do_renew) {
1596 if (optind == argc) { 1601 if (optind == argc) {
1597 dhcpcd_renew(ctx); 1602 dhcpcd_renew(ctx);
1598 return 0; 1603 return 0;
1599 } 1604 }
1600 for (oi = optind; oi < argc; oi++) { 1605 for (oi = optind; oi < argc; oi++) {
1601 if ((ifp = if_find(ctx->ifaces, argv[oi])) == NULL) 1606 if ((ifp = if_find(ctx->ifaces, argv[oi])) == NULL)
1602 continue; 1607 continue;
1603 dhcpcd_ifrenew(ifp); 1608 dhcpcd_ifrenew(ifp);
1604 } 1609 }
1605 return 0; 1610 return 0;
1606 } 1611 }
1607 1612
1608 reload_config(ctx); 1613 reload_config(ctx);
1609 /* XXX: Respect initial commandline options? */ 1614 /* XXX: Respect initial commandline options? */
1610 reconf_reboot(ctx, do_reboot, argc, argv, optind - 1); 1615 reconf_reboot(ctx, do_reboot, argc, argv, optind - 1);
1611 return 0; 1616 return 0;
1612} 1617}
1613 1618
1614static void dhcpcd_readdump1(void *); 1619static void dhcpcd_readdump1(void *);
1615 1620
1616static void 1621static void
1617dhcpcd_readdump2(void *arg) 1622dhcpcd_readdump2(void *arg)
1618{ 1623{
1619 struct dhcpcd_ctx *ctx = arg; 1624 struct dhcpcd_ctx *ctx = arg;
1620 ssize_t len; 1625 ssize_t len;
1621 int exit_code = EXIT_FAILURE; 1626 int exit_code = EXIT_FAILURE;
1622 1627
1623 len = read(ctx->control_fd, ctx->ctl_buf + ctx->ctl_bufpos, 1628 len = read(ctx->control_fd, ctx->ctl_buf + ctx->ctl_bufpos,
1624 ctx->ctl_buflen - ctx->ctl_bufpos); 1629 ctx->ctl_buflen - ctx->ctl_bufpos);
1625 if (len == -1) { 1630 if (len == -1) {
1626 logerr(__func__); 1631 logerr(__func__);
1627 goto finished; 1632 goto finished;
1628 } else if (len == 0) 1633 } else if (len == 0)
1629 goto finished; 1634 goto finished;
1630 if ((size_t)len + ctx->ctl_bufpos != ctx->ctl_buflen) { 1635 if ((size_t)len + ctx->ctl_bufpos != ctx->ctl_buflen) {
1631 ctx->ctl_bufpos += (size_t)len; 1636 ctx->ctl_bufpos += (size_t)len;
1632 return; 1637 return;
1633 } 1638 }
1634 1639
1635 if (ctx->ctl_buf[ctx->ctl_buflen - 1] != '\0') /* unlikely */ 1640 if (ctx->ctl_buf[ctx->ctl_buflen - 1] != '\0') /* unlikely */
1636 ctx->ctl_buf[ctx->ctl_buflen - 1] = '\0'; 1641 ctx->ctl_buf[ctx->ctl_buflen - 1] = '\0';
1637 script_dump(ctx->ctl_buf, ctx->ctl_buflen); 1642 script_dump(ctx->ctl_buf, ctx->ctl_buflen);
1638 fflush(stdout); 1643 fflush(stdout);
1639 if (--ctx->ctl_extra != 0) { 1644 if (--ctx->ctl_extra != 0) {
1640 putchar('\n'); 1645 putchar('\n');
1641 eloop_event_add(ctx->eloop, ctx->control_fd, 1646 eloop_event_add(ctx->eloop, ctx->control_fd,
1642 dhcpcd_readdump1, ctx); 1647 dhcpcd_readdump1, ctx);
1643 return; 1648 return;
1644 } 1649 }
1645 exit_code = EXIT_SUCCESS; 1650 exit_code = EXIT_SUCCESS;
1646 1651
1647finished: 1652finished:
1648 shutdown(ctx->control_fd, SHUT_RDWR); 1653 shutdown(ctx->control_fd, SHUT_RDWR);
1649 eloop_exit(ctx->eloop, exit_code); 1654 eloop_exit(ctx->eloop, exit_code);
1650} 1655}
1651 1656
1652static void 1657static void
1653dhcpcd_readdump1(void *arg) 1658dhcpcd_readdump1(void *arg)
1654{ 1659{
1655 struct dhcpcd_ctx *ctx = arg; 1660 struct dhcpcd_ctx *ctx = arg;
1656 ssize_t len; 1661 ssize_t len;
1657 1662
1658 len = read(ctx->control_fd, &ctx->ctl_buflen, sizeof(ctx->ctl_buflen)); 1663 len = read(ctx->control_fd, &ctx->ctl_buflen, sizeof(ctx->ctl_buflen));
1659 if (len != sizeof(ctx->ctl_buflen)) { 1664 if (len != sizeof(ctx->ctl_buflen)) {
1660 if (len != -1) 1665 if (len != -1)
1661 errno = EINVAL; 1666 errno = EINVAL;
1662 goto err; 1667 goto err;
1663 } 1668 }
1664 if (ctx->ctl_buflen > SSIZE_MAX) { 1669 if (ctx->ctl_buflen > SSIZE_MAX) {
1665 errno = ENOBUFS; 1670 errno = ENOBUFS;
1666 goto err; 1671 goto err;
1667 } 1672 }
1668 1673
1669 free(ctx->ctl_buf); 1674 free(ctx->ctl_buf);
1670 ctx->ctl_buf = malloc(ctx->ctl_buflen); 1675 ctx->ctl_buf = malloc(ctx->ctl_buflen);
1671 if (ctx->ctl_buf == NULL) 1676 if (ctx->ctl_buf == NULL)
1672 goto err; 1677 goto err;
1673 1678
1674 ctx->ctl_bufpos = 0; 1679 ctx->ctl_bufpos = 0;
1675 eloop_event_add(ctx->eloop, ctx->control_fd, 1680 eloop_event_add(ctx->eloop, ctx->control_fd,
1676 dhcpcd_readdump2, ctx); 1681 dhcpcd_readdump2, ctx);
1677 return; 1682 return;
1678 1683
1679err: 1684err:
1680 logerr(__func__); 1685 logerr(__func__);
1681 eloop_exit(ctx->eloop, EXIT_FAILURE); 1686 eloop_exit(ctx->eloop, EXIT_FAILURE);
1682} 1687}
1683 1688
1684static void 1689static void
1685dhcpcd_readdump0(void *arg) 1690dhcpcd_readdump0(void *arg)
1686{ 1691{
1687 struct dhcpcd_ctx *ctx = arg; 1692 struct dhcpcd_ctx *ctx = arg;
1688 ssize_t len; 1693 ssize_t len;
1689 1694
1690 len = read(ctx->control_fd, &ctx->ctl_extra, sizeof(ctx->ctl_extra)); 1695 len = read(ctx->control_fd, &ctx->ctl_extra, sizeof(ctx->ctl_extra));
1691 if (len != sizeof(ctx->ctl_extra)) { 1696 if (len != sizeof(ctx->ctl_extra)) {
1692 if (len != -1) 1697 if (len != -1)
1693 errno = EINVAL; 1698 errno = EINVAL;
1694 logerr(__func__); 1699 logerr(__func__);
1695 eloop_exit(ctx->eloop, EXIT_FAILURE); 1700 eloop_exit(ctx->eloop, EXIT_FAILURE);
1696 return; 1701 return;
1697 } 1702 }
1698 1703
1699 if (ctx->ctl_extra == 0) { 1704 if (ctx->ctl_extra == 0) {
1700 eloop_exit(ctx->eloop, EXIT_SUCCESS); 1705 eloop_exit(ctx->eloop, EXIT_SUCCESS);
1701 return; 1706 return;
1702 } 1707 }
1703 1708
1704 eloop_event_add(ctx->eloop, ctx->control_fd, 1709 eloop_event_add(ctx->eloop, ctx->control_fd,
1705 dhcpcd_readdump1, ctx); 1710 dhcpcd_readdump1, ctx);
1706} 1711}
1707 1712
1708static void 1713static void
1709dhcpcd_readdumptimeout(void *arg) 1714dhcpcd_readdumptimeout(void *arg)
1710{ 1715{
1711 struct dhcpcd_ctx *ctx = arg; 1716 struct dhcpcd_ctx *ctx = arg;
1712 1717
1713 logerrx(__func__); 1718 logerrx(__func__);
1714 eloop_exit(ctx->eloop, EXIT_FAILURE); 1719 eloop_exit(ctx->eloop, EXIT_FAILURE);
1715} 1720}
1716 1721
1717static int 1722static int
1718dhcpcd_readdump(struct dhcpcd_ctx *ctx) 1723dhcpcd_readdump(struct dhcpcd_ctx *ctx)
1719{ 1724{
1720 1725
1721 ctx->options |= DHCPCD_FORKED; 1726 ctx->options |= DHCPCD_FORKED;
1722 if (eloop_timeout_add_sec(ctx->eloop, 5, 1727 if (eloop_timeout_add_sec(ctx->eloop, 5,
1723 dhcpcd_readdumptimeout, ctx) == -1) 1728 dhcpcd_readdumptimeout, ctx) == -1)
1724 return -1; 1729 return -1;
1725 return eloop_event_add(ctx->eloop, ctx->control_fd, 1730 return eloop_event_add(ctx->eloop, ctx->control_fd,
1726 dhcpcd_readdump0, ctx); 1731 dhcpcd_readdump0, ctx);
1727} 1732}
1728 1733
1729static void 1734static void
1730dhcpcd_fork_cb(void *arg) 1735dhcpcd_fork_cb(void *arg)
1731{ 1736{
1732 struct dhcpcd_ctx *ctx = arg; 1737 struct dhcpcd_ctx *ctx = arg;
1733 int exit_code; 1738 int exit_code;
1734 ssize_t len; 1739 ssize_t len;
1735 1740
1736 len = read(ctx->fork_fd, &exit_code, sizeof(exit_code)); 1741 len = read(ctx->fork_fd, &exit_code, sizeof(exit_code));
1737 if (len == -1) { 1742 if (len == -1) {
1738 logerr(__func__); 1743 logerr(__func__);
1739 exit_code = EXIT_FAILURE; 1744 exit_code = EXIT_FAILURE;
1740 } else if ((size_t)len < sizeof(exit_code)) { 1745 } else if ((size_t)len < sizeof(exit_code)) {
1741 logerrx("%s: truncated read %zd (expected %zu)", 1746 logerrx("%s: truncated read %zd (expected %zu)",
1742 __func__, len, sizeof(exit_code)); 1747 __func__, len, sizeof(exit_code));
1743 exit_code = EXIT_FAILURE; 1748 exit_code = EXIT_FAILURE;
1744 } 1749 }
1745 if (ctx->options & DHCPCD_FORKED) 1750 if (ctx->options & DHCPCD_FORKED)
1746 eloop_exit(ctx->eloop, exit_code); 1751 eloop_exit(ctx->eloop, exit_code);
1747 else 1752 else
1748 dhcpcd_signal_cb(exit_code, ctx); 1753 dhcpcd_signal_cb(exit_code, ctx);
1749} 1754}
1750 1755
1751static void 1756static void
1752dhcpcd_stderr_cb(void *arg) 1757dhcpcd_stderr_cb(void *arg)
1753{ 1758{
1754 struct dhcpcd_ctx *ctx = arg; 1759 struct dhcpcd_ctx *ctx = arg;
1755 char log[BUFSIZ]; 1760 char log[BUFSIZ];
1756 ssize_t len; 1761 ssize_t len;
1757 1762
1758 len = read(ctx->stderr_fd, log, sizeof(log)); 1763 len = read(ctx->stderr_fd, log, sizeof(log));
1759 if (len == -1) { 1764 if (len == -1) {
1760 if (errno != ECONNRESET) 1765 if (errno != ECONNRESET)
1761 logerr(__func__); 1766 logerr(__func__);
1762 return; 1767 return;
1763 } 1768 }
1764 1769
1765 log[len] = '\0'; 1770 log[len] = '\0';
1766 fprintf(stderr, "%s", log); 1771 fprintf(stderr, "%s", log);
1767} 1772}
1768 1773
1769int 1774int
1770main(int argc, char **argv, char **envp) 1775main(int argc, char **argv, char **envp)
1771{ 1776{
1772 struct dhcpcd_ctx ctx; 1777 struct dhcpcd_ctx ctx;
1773 struct ifaddrs *ifaddrs = NULL; 1778 struct ifaddrs *ifaddrs = NULL;
1774 struct if_options *ifo; 1779 struct if_options *ifo;
1775 struct interface *ifp; 1780 struct interface *ifp;
1776 sa_family_t family = AF_UNSPEC; 1781 sa_family_t family = AF_UNSPEC;
1777 int opt, oi = 0, i; 1782 int opt, oi = 0, i;
1778 unsigned int logopts, t; 1783 unsigned int logopts, t;
1779 ssize_t len; 1784 ssize_t len;
1780#if defined(USE_SIGNALS) || !defined(THERE_IS_NO_FORK) 1785#if defined(USE_SIGNALS) || !defined(THERE_IS_NO_FORK)
1781 pid_t pid; 1786 pid_t pid;
1782 int fork_fd[2], stderr_fd[2]; 1787 int fork_fd[2], stderr_fd[2];
1783#endif 1788#endif
1784#ifdef USE_SIGNALS 1789#ifdef USE_SIGNALS
1785 int sig = 0; 1790 int sig = 0;
1786 const char *siga = NULL; 1791 const char *siga = NULL;
1787 size_t si; 1792 size_t si;
1788#endif 1793#endif
1789 1794
1790#ifdef SETPROCTITLE_H 1795#ifdef SETPROCTITLE_H
1791 setproctitle_init(argc, argv, envp); 1796 setproctitle_init(argc, argv, envp);
1792#else 1797#else
1793 UNUSED(envp); 1798 UNUSED(envp);
1794#endif 1799#endif
1795 1800
1796 /* Test for --help and --version */ 1801 /* Test for --help and --version */
1797 if (argc > 1) { 1802 if (argc > 1) {
1798 if (strcmp(argv[1], "--help") == 0) { 1803 if (strcmp(argv[1], "--help") == 0) {
1799 usage(); 1804 usage();
1800 return EXIT_SUCCESS; 1805 return EXIT_SUCCESS;
1801 } else if (strcmp(argv[1], "--version") == 0) { 1806 } else if (strcmp(argv[1], "--version") == 0) {
1802 printf(""PACKAGE" "VERSION"\n%s\n", dhcpcd_copyright); 1807 printf(""PACKAGE" "VERSION"\n%s\n", dhcpcd_copyright);
1803 printf("Compiled in features:" 1808 printf("Compiled in features:"
1804#ifdef INET 1809#ifdef INET
1805 " INET" 1810 " INET"
1806#endif 1811#endif
1807#ifdef ARP 1812#ifdef ARP
1808 " ARP" 1813 " ARP"
1809#endif 1814#endif
1810#ifdef ARPING 1815#ifdef ARPING
1811 " ARPing" 1816 " ARPing"
1812#endif 1817#endif
1813#ifdef IPV4LL 1818#ifdef IPV4LL
1814 " IPv4LL" 1819 " IPv4LL"
1815#endif 1820#endif
1816#ifdef INET6 1821#ifdef INET6
1817 " INET6" 1822 " INET6"
1818#endif 1823#endif
1819#ifdef DHCP6 1824#ifdef DHCP6
1820 " DHCPv6" 1825 " DHCPv6"
1821#endif 1826#endif
1822#ifdef AUTH 1827#ifdef AUTH
1823 " AUTH" 1828 " AUTH"
1824#endif 1829#endif
1825#ifdef PRIVSEP 1830#ifdef PRIVSEP
1826 " PRIVSEP" 1831 " PRIVSEP"
1827#endif 1832#endif
1828 "\n"); 1833 "\n");
1829 return EXIT_SUCCESS; 1834 return EXIT_SUCCESS;
1830 } 1835 }
1831 } 1836 }
1832 1837
1833 memset(&ctx, 0, sizeof(ctx)); 1838 memset(&ctx, 0, sizeof(ctx));
1834 1839
1835 ifo = NULL; 1840 ifo = NULL;
1836 ctx.cffile = CONFIG; 1841 ctx.cffile = CONFIG;
1837 ctx.script = UNCONST(dhcpcd_default_script); 1842 ctx.script = UNCONST(dhcpcd_default_script);
1838 ctx.control_fd = ctx.control_unpriv_fd = ctx.link_fd = -1; 1843 ctx.control_fd = ctx.control_unpriv_fd = ctx.link_fd = -1;
1839 ctx.pf_inet_fd = -1; 1844 ctx.pf_inet_fd = -1;
1840#ifdef PF_LINK 1845#ifdef PF_LINK
1841 ctx.pf_link_fd = -1; 1846 ctx.pf_link_fd = -1;
1842#endif 1847#endif
1843 1848
1844 TAILQ_INIT(&ctx.control_fds); 1849 TAILQ_INIT(&ctx.control_fds);
1845#ifdef USE_SIGNALS 1850#ifdef USE_SIGNALS
1846 ctx.fork_fd = -1; 1851 ctx.fork_fd = -1;
1847#endif 1852#endif
1848#ifdef PLUGIN_DEV 1853#ifdef PLUGIN_DEV
1849 ctx.dev_fd = -1; 1854 ctx.dev_fd = -1;
1850#endif 1855#endif
1851#ifdef INET 1856#ifdef INET
1852 ctx.udp_rfd = -1; 1857 ctx.udp_rfd = -1;
1853 ctx.udp_wfd = -1; 1858 ctx.udp_wfd = -1;
1854#endif 1859#endif
1855#if defined(INET6) && !defined(__sun) 1860#if defined(INET6) && !defined(__sun)
1856 ctx.nd_fd = -1; 1861 ctx.nd_fd = -1;
1857#endif 1862#endif
1858#ifdef DHCP6 1863#ifdef DHCP6
1859 ctx.dhcp6_rfd = -1; 1864 ctx.dhcp6_rfd = -1;
1860 ctx.dhcp6_wfd = -1; 1865 ctx.dhcp6_wfd = -1;
1861#endif 1866#endif
1862#ifdef PRIVSEP 1867#ifdef PRIVSEP
1863 ctx.ps_root_fd = ctx.ps_data_fd = -1; 1868 ctx.ps_root_fd = ctx.ps_log_fd = ctx.ps_data_fd = -1;
1864 ctx.ps_inet_fd = ctx.ps_control_fd = -1; 1869 ctx.ps_inet_fd = ctx.ps_control_fd = -1;
1865 TAILQ_INIT(&ctx.ps_processes); 1870 TAILQ_INIT(&ctx.ps_processes);
1866#endif 1871#endif
1867 1872
1868 /* Check our streams for validity */ 1873 /* Check our streams for validity */
1869 ctx.stdin_valid = fcntl(STDIN_FILENO, F_GETFD) != -1; 1874 ctx.stdin_valid = fcntl(STDIN_FILENO, F_GETFD) != -1;
1870 ctx.stdout_valid = fcntl(STDOUT_FILENO, F_GETFD) != -1; 1875 ctx.stdout_valid = fcntl(STDOUT_FILENO, F_GETFD) != -1;
1871 ctx.stderr_valid = fcntl(STDERR_FILENO, F_GETFD) != -1; 1876 ctx.stderr_valid = fcntl(STDERR_FILENO, F_GETFD) != -1;
1872 1877
1873 logopts = LOGERR_LOG | LOGERR_LOG_DATE | LOGERR_LOG_PID; 1878 logopts = LOGERR_LOG | LOGERR_LOG_DATE | LOGERR_LOG_PID;
1874 if (ctx.stderr_valid) 1879 if (ctx.stderr_valid)
1875 logopts |= LOGERR_ERR; 1880 logopts |= LOGERR_ERR;
1876 1881
1877 i = 0; 1882 i = 0;
1878 while ((opt = getopt_long(argc, argv, 1883 while ((opt = getopt_long(argc, argv,
1879 ctx.options & DHCPCD_PRINT_PIDFILE ? NOERR_IF_OPTS : IF_OPTS, 1884 ctx.options & DHCPCD_PRINT_PIDFILE ? NOERR_IF_OPTS : IF_OPTS,
1880 cf_options, &oi)) != -1) 1885 cf_options, &oi)) != -1)
1881 { 1886 {
1882 switch (opt) { 1887 switch (opt) {
1883 case '4': 1888 case '4':
1884 family = AF_INET; 1889 family = AF_INET;
1885 break; 1890 break;
1886 case '6': 1891 case '6':
1887 family = AF_INET6; 1892 family = AF_INET6;
1888 break; 1893 break;
1889 case 'f': 1894 case 'f':
1890 ctx.cffile = optarg; 1895 ctx.cffile = optarg;
1891 break; 1896 break;
1892 case 'j': 1897 case 'j':
1893 free(ctx.logfile); 1898 free(ctx.logfile);
1894 ctx.logfile = strdup(optarg); 1899 ctx.logfile = strdup(optarg);
1895 break; 1900 break;
1896#ifdef USE_SIGNALS 1901#ifdef USE_SIGNALS
1897 case 'k': 1902 case 'k':
1898 sig = SIGALRM; 1903 sig = SIGALRM;
1899 siga = "ALRM"; 1904 siga = "ALRM";
1900 break; 1905 break;
1901 case 'n': 1906 case 'n':
1902 sig = SIGHUP; 1907 sig = SIGHUP;
1903 siga = "HUP"; 1908 siga = "HUP";
1904 break; 1909 break;
1905 case 'g': 1910 case 'g':
1906 case 'p': 1911 case 'p':
1907 /* Force going via command socket as we're 1912 /* Force going via command socket as we're
1908 * out of user definable signals. */ 1913 * out of user definable signals. */
1909 i = 4; 1914 i = 4;
1910 break; 1915 break;
1911 case 'q': 1916 case 'q':
1912 /* -qq disables console output entirely. 1917 /* -qq disables console output entirely.
1913 * This is important for systemd because it logs 1918 * This is important for systemd because it logs
1914 * both console AND syslog to the same log 1919 * both console AND syslog to the same log
1915 * resulting in untold confusion. */ 1920 * resulting in untold confusion. */
1916 if (logopts & LOGERR_QUIET) 1921 if (logopts & LOGERR_QUIET)
1917 logopts &= ~LOGERR_ERR; 1922 logopts &= ~LOGERR_ERR;
1918 else 1923 else
1919 logopts |= LOGERR_QUIET; 1924 logopts |= LOGERR_QUIET;
1920 break; 1925 break;
1921 case 'x': 1926 case 'x':
1922 sig = SIGTERM; 1927 sig = SIGTERM;
1923 siga = "TERM"; 1928 siga = "TERM";
1924 break; 1929 break;
1925 case 'N': 1930 case 'N':
1926 sig = SIGUSR1; 1931 sig = SIGUSR1;
1927 siga = "USR1"; 1932 siga = "USR1";
1928 break; 1933 break;
1929#endif 1934#endif
1930 case 'P': 1935 case 'P':
1931 ctx.options |= DHCPCD_PRINT_PIDFILE; 1936 ctx.options |= DHCPCD_PRINT_PIDFILE;
1932 logopts &= ~(LOGERR_LOG | LOGERR_ERR); 1937 logopts &= ~(LOGERR_LOG | LOGERR_ERR);
1933 break; 1938 break;
1934 case 'T': 1939 case 'T':
1935 i = 1; 1940 i = 1;
1936 logopts &= ~LOGERR_LOG; 1941 logopts &= ~LOGERR_LOG;
1937 break; 1942 break;
1938 case 'U': 1943 case 'U':
1939 i = 3; 1944 i = 3;
1940 break; 1945 break;
1941 case 'V': 1946 case 'V':
1942 i = 2; 1947 i = 2;
1943 break; 1948 break;
1944 case '?': 1949 case '?':
1945 if (ctx.options & DHCPCD_PRINT_PIDFILE) 1950 if (ctx.options & DHCPCD_PRINT_PIDFILE)
1946 continue; 1951 continue;
1947 usage(); 1952 usage();
1948 goto exit_failure; 1953 goto exit_failure;
1949 } 1954 }
1950 } 1955 }
1951 1956
1952 logsetopts(logopts); 1957 logsetopts(logopts);
1953 logopen(ctx.logfile); 1958 logopen(ctx.logfile);
1954 1959
1955 ctx.argv = argv; 1960 ctx.argv = argv;
1956 ctx.argc = argc; 1961 ctx.argc = argc;
1957 ctx.ifc = argc - optind; 1962 ctx.ifc = argc - optind;
1958 ctx.ifv = argv + optind; 1963 ctx.ifv = argv + optind;
1959 1964
1960 rt_init(&ctx); 1965 rt_init(&ctx);
1961 1966
1962 ifo = read_config(&ctx, NULL, NULL, NULL); 1967 ifo = read_config(&ctx, NULL, NULL, NULL);
1963 if (ifo == NULL) { 1968 if (ifo == NULL) {
1964 if (ctx.options & DHCPCD_PRINT_PIDFILE) 1969 if (ctx.options & DHCPCD_PRINT_PIDFILE)
1965 goto printpidfile; 1970 goto printpidfile;
1966 goto exit_failure; 1971 goto exit_failure;
1967 } 1972 }
1968 opt = add_options(&ctx, NULL, ifo, argc, argv); 1973 opt = add_options(&ctx, NULL, ifo, argc, argv);
1969 if (opt != 1) { 1974 if (opt != 1) {
1970 if (ctx.options & DHCPCD_PRINT_PIDFILE) 1975 if (ctx.options & DHCPCD_PRINT_PIDFILE)
1971 goto printpidfile; 1976 goto printpidfile;
1972 if (opt == 0) 1977 if (opt == 0)
1973 usage(); 1978 usage();
1974 goto exit_failure; 1979 goto exit_failure;
1975 } 1980 }
1976 if (i == 2) { 1981 if (i == 2) {
1977 printf("Interface options:\n"); 1982 printf("Interface options:\n");
1978 if (optind == argc - 1) { 1983 if (optind == argc - 1) {
1979 free_options(&ctx, ifo); 1984 free_options(&ctx, ifo);
1980 ifo = read_config(&ctx, argv[optind], NULL, NULL); 1985 ifo = read_config(&ctx, argv[optind], NULL, NULL);
1981 if (ifo == NULL) 1986 if (ifo == NULL)
1982 goto exit_failure; 1987 goto exit_failure;
1983 add_options(&ctx, NULL, ifo, argc, argv); 1988 add_options(&ctx, NULL, ifo, argc, argv);
1984 } 1989 }
1985 if_printoptions(); 1990 if_printoptions();
1986#ifdef INET 1991#ifdef INET
1987 if (family == 0 || family == AF_INET) { 1992 if (family == 0 || family == AF_INET) {
1988 printf("\nDHCPv4 options:\n"); 1993 printf("\nDHCPv4 options:\n");
1989 dhcp_printoptions(&ctx, 1994 dhcp_printoptions(&ctx,
1990 ifo->dhcp_override, ifo->dhcp_override_len); 1995 ifo->dhcp_override, ifo->dhcp_override_len);
1991 } 1996 }
1992#endif 1997#endif
1993#ifdef INET6 1998#ifdef INET6
1994 if (family == 0 || family == AF_INET6) { 1999 if (family == 0 || family == AF_INET6) {
1995 printf("\nND options:\n"); 2000 printf("\nND options:\n");
1996 ipv6nd_printoptions(&ctx, 2001 ipv6nd_printoptions(&ctx,
1997 ifo->nd_override, ifo->nd_override_len); 2002 ifo->nd_override, ifo->nd_override_len);
1998#ifdef DHCP6 2003#ifdef DHCP6
1999 printf("\nDHCPv6 options:\n"); 2004 printf("\nDHCPv6 options:\n");
2000 dhcp6_printoptions(&ctx, 2005 dhcp6_printoptions(&ctx,
2001 ifo->dhcp6_override, ifo->dhcp6_override_len); 2006 ifo->dhcp6_override, ifo->dhcp6_override_len);
2002#endif 2007#endif
2003 } 2008 }
2004#endif 2009#endif
2005 goto exit_success; 2010 goto exit_success;
2006 } 2011 }
2007 ctx.options |= ifo->options; 2012 ctx.options |= ifo->options;
2008 if (i == 1 || i == 3) { 2013 if (i == 1 || i == 3) {
2009 if (i == 1) 2014 if (i == 1)
2010 ctx.options |= DHCPCD_TEST; 2015 ctx.options |= DHCPCD_TEST;
2011 else 2016 else
2012 ctx.options |= DHCPCD_DUMPLEASE; 2017 ctx.options |= DHCPCD_DUMPLEASE;
2013 ctx.options |= DHCPCD_PERSISTENT; 2018 ctx.options |= DHCPCD_PERSISTENT;
2014 ctx.options &= ~DHCPCD_DAEMONISE; 2019 ctx.options &= ~DHCPCD_DAEMONISE;
2015 } 2020 }
2016 2021
2017#ifdef THERE_IS_NO_FORK 2022#ifdef THERE_IS_NO_FORK
2018 ctx.options &= ~DHCPCD_DAEMONISE; 2023 ctx.options &= ~DHCPCD_DAEMONISE;
2019#endif 2024#endif
2020 2025
2021 if (ctx.options & DHCPCD_DEBUG) 2026 if (ctx.options & DHCPCD_DEBUG)
2022 logsetopts(logopts | LOGERR_DEBUG); 2027 logsetopts(logopts | LOGERR_DEBUG);
2023 2028
2024 if (!(ctx.options & (DHCPCD_TEST | DHCPCD_DUMPLEASE))) { 2029 if (!(ctx.options & (DHCPCD_TEST | DHCPCD_DUMPLEASE))) {
2025printpidfile: 2030printpidfile:
2026 /* If we have any other args, we should run as a single dhcpcd 2031 /* If we have any other args, we should run as a single dhcpcd
2027 * instance for that interface. */ 2032 * instance for that interface. */
2028 if (optind == argc - 1 && !(ctx.options & DHCPCD_MASTER)) { 2033 if (optind == argc - 1 && !(ctx.options & DHCPCD_MASTER)) {
2029 const char *per; 2034 const char *per;
2030 const char *ifname; 2035 const char *ifname;
2031 2036
2032 ifname = *ctx.ifv; 2037 ifname = *ctx.ifv;
2033 if (ifname == NULL || strlen(ifname) > IF_NAMESIZE) { 2038 if (ifname == NULL || strlen(ifname) > IF_NAMESIZE) {
2034 errno = ifname == NULL ? EINVAL : E2BIG; 2039 errno = ifname == NULL ? EINVAL : E2BIG;
2035 logerr("%s: ", ifname); 2040 logerr("%s: ", ifname);
2036 goto exit_failure; 2041 goto exit_failure;
2037 } 2042 }
2038 /* Allow a dhcpcd interface per address family */ 2043 /* Allow a dhcpcd interface per address family */
2039 switch(family) { 2044 switch(family) {
2040 case AF_INET: 2045 case AF_INET:
2041 per = "-4"; 2046 per = "-4";
2042 break; 2047 break;
2043 case AF_INET6: 2048 case AF_INET6:
2044 per = "-6"; 2049 per = "-6";
2045 break; 2050 break;
2046 default: 2051 default:
2047 per = ""; 2052 per = "";
2048 } 2053 }
2049 snprintf(ctx.pidfile, sizeof(ctx.pidfile), 2054 snprintf(ctx.pidfile, sizeof(ctx.pidfile),
2050 PIDFILE, ifname, per, "."); 2055 PIDFILE, ifname, per, ".");
2051 } else { 2056 } else {
2052 snprintf(ctx.pidfile, sizeof(ctx.pidfile), 2057 snprintf(ctx.pidfile, sizeof(ctx.pidfile),
2053 PIDFILE, "", "", ""); 2058 PIDFILE, "", "", "");
2054 ctx.options |= DHCPCD_MASTER; 2059 ctx.options |= DHCPCD_MASTER;
2055 } 2060 }
2056 if (ctx.options & DHCPCD_PRINT_PIDFILE) { 2061 if (ctx.options & DHCPCD_PRINT_PIDFILE) {
2057 printf("%s\n", ctx.pidfile); 2062 printf("%s\n", ctx.pidfile);
2058 goto exit_success; 2063 goto exit_success;
2059 } 2064 }
2060 } 2065 }
2061 2066
2062 if (chdir("/") == -1) 2067 if (chdir("/") == -1)
2063 logerr("%s: chdir: /", __func__); 2068 logerr("%s: chdir: /", __func__);
2064 2069
2065 /* Freeing allocated addresses from dumping leases can trigger 2070 /* Freeing allocated addresses from dumping leases can trigger
2066 * eloop removals as well, so init here. */ 2071 * eloop removals as well, so init here. */
2067 if ((ctx.eloop = eloop_new()) == NULL) { 2072 if ((ctx.eloop = eloop_new()) == NULL) {
2068 logerr("%s: eloop_init", __func__); 2073 logerr("%s: eloop_init", __func__);
2069 goto exit_failure; 2074 goto exit_failure;
2070 } 2075 }
2071 2076
2072#ifdef USE_SIGNALS 2077#ifdef USE_SIGNALS
2073 for (si = 0; si < dhcpcd_signals_ignore_len; si++) 2078 for (si = 0; si < dhcpcd_signals_ignore_len; si++)
2074 signal(dhcpcd_signals_ignore[si], SIG_IGN); 2079 signal(dhcpcd_signals_ignore[si], SIG_IGN);
2075 2080
2076 /* Save signal mask, block and redirect signals to our handler */ 2081 /* Save signal mask, block and redirect signals to our handler */
2077 eloop_signal_set_cb(ctx.eloop, 2082 eloop_signal_set_cb(ctx.eloop,
2078 dhcpcd_signals, dhcpcd_signals_len, 2083 dhcpcd_signals, dhcpcd_signals_len,
2079 dhcpcd_signal_cb, &ctx); 2084 dhcpcd_signal_cb, &ctx);
2080 if (eloop_signal_mask(ctx.eloop, &ctx.sigset) == -1) { 2085 if (eloop_signal_mask(ctx.eloop, &ctx.sigset) == -1) {
2081 logerr("%s: eloop_signal_mask", __func__); 2086 logerr("%s: eloop_signal_mask", __func__);
2082 goto exit_failure; 2087 goto exit_failure;
2083 } 2088 }
2084 2089
2085 if (sig != 0) { 2090 if (sig != 0) {
2086 pid = pidfile_read(ctx.pidfile); 2091 pid = pidfile_read(ctx.pidfile);
2087 if (pid != 0 && pid != -1) 2092 if (pid != 0 && pid != -1)
2088 loginfox("sending signal %s to pid %d", siga, pid); 2093 loginfox("sending signal %s to pid %d", siga, pid);
2089 if (pid == 0 || pid == -1 || kill(pid, sig) != 0) { 2094 if (pid == 0 || pid == -1 || kill(pid, sig) != 0) {
2090 if (sig != SIGHUP && sig != SIGUSR1 && errno != EPERM) 2095 if (sig != SIGHUP && sig != SIGUSR1 && errno != EPERM)
2091 logerrx(PACKAGE" not running"); 2096 logerrx(PACKAGE" not running");
2092 if (pid != 0 && pid != -1 && errno != ESRCH) { 2097 if (pid != 0 && pid != -1 && errno != ESRCH) {
2093 logerr("kill"); 2098 logerr("kill");
2094 goto exit_failure; 2099 goto exit_failure;
2095 } 2100 }
2096 unlink(ctx.pidfile); 2101 unlink(ctx.pidfile);
2097 if (sig != SIGHUP && sig != SIGUSR1) 2102 if (sig != SIGHUP && sig != SIGUSR1)
2098 goto exit_failure; 2103 goto exit_failure;
2099 } else { 2104 } else {
2100 struct timespec ts; 2105 struct timespec ts;
2101 2106
2102 if (sig == SIGHUP || sig == SIGUSR1) 2107 if (sig == SIGHUP || sig == SIGUSR1)
2103 goto exit_success; 2108 goto exit_success;
2104 /* Spin until it exits */ 2109 /* Spin until it exits */
2105 loginfox("waiting for pid %d to exit", pid); 2110 loginfox("waiting for pid %d to exit", pid);
2106 ts.tv_sec = 0; 2111 ts.tv_sec = 0;
2107 ts.tv_nsec = 100000000; /* 10th of a second */ 2112 ts.tv_nsec = 100000000; /* 10th of a second */
2108 for(i = 0; i < 100; i++) { 2113 for(i = 0; i < 100; i++) {
2109 nanosleep(&ts, NULL); 2114 nanosleep(&ts, NULL);
2110 if (pidfile_read(ctx.pidfile) == -1) 2115 if (pidfile_read(ctx.pidfile) == -1)
2111 goto exit_success; 2116 goto exit_success;
2112 } 2117 }
2113 logerrx("pid %d failed to exit", pid); 2118 logerrx("pid %d failed to exit", pid);
2114 goto exit_failure; 2119 goto exit_failure;
2115 } 2120 }
2116 } 2121 }
2117#endif 2122#endif
2118 2123
2119#ifdef PRIVSEP 2124#ifdef PRIVSEP
2120 ps_init(&ctx); 2125 ps_init(&ctx);
2121#endif 2126#endif
2122 2127
2123#ifndef SMALL 2128#ifndef SMALL
2124 if (ctx.options & DHCPCD_DUMPLEASE && 2129 if (ctx.options & DHCPCD_DUMPLEASE &&
2125 ioctl(fileno(stdin), FIONREAD, &i, sizeof(i)) == 0 && 2130 ioctl(fileno(stdin), FIONREAD, &i, sizeof(i)) == 0 &&
2126 i > 0) 2131 i > 0)
2127 { 2132 {
2128 ctx.options |= DHCPCD_FORKED; /* pretend child process */ 2133 ctx.options |= DHCPCD_FORKED; /* pretend child process */
2129#ifdef PRIVSEP 2134#ifdef PRIVSEP
2130 if (IN_PRIVSEP(&ctx) && ps_mastersandbox(&ctx, NULL) == -1) 2135 if (IN_PRIVSEP(&ctx) && ps_mastersandbox(&ctx, NULL) == -1)
2131 goto exit_failure; 2136 goto exit_failure;
2132#endif 2137#endif
2133 ifp = calloc(1, sizeof(*ifp)); 2138 ifp = calloc(1, sizeof(*ifp));
2134 if (ifp == NULL) { 2139 if (ifp == NULL) {
2135 logerr(__func__); 2140 logerr(__func__);
2136 goto exit_failure; 2141 goto exit_failure;
2137 } 2142 }
2138 ifp->ctx = &ctx; 2143 ifp->ctx = &ctx;
2139 ifp->options = ifo; 2144 ifp->options = ifo;
2140 switch (family) { 2145 switch (family) {
2141 case AF_INET: 2146 case AF_INET:
2142#ifdef INET 2147#ifdef INET
2143 if (dhcp_dump(ifp) == -1) 2148 if (dhcp_dump(ifp) == -1)
2144 goto exit_failure; 2149 goto exit_failure;
2145 break; 2150 break;
2146#else 2151#else
2147 logerrx("No DHCP support"); 2152 logerrx("No DHCP support");
2148 goto exit_failure; 2153 goto exit_failure;
2149#endif 2154#endif
2150 case AF_INET6: 2155 case AF_INET6:
2151#ifdef DHCP6 2156#ifdef DHCP6
2152 if (dhcp6_dump(ifp) == -1) 2157 if (dhcp6_dump(ifp) == -1)
2153 goto exit_failure; 2158 goto exit_failure;
2154 break; 2159 break;
2155#else 2160#else
2156 logerrx("No DHCP6 support"); 2161 logerrx("No DHCP6 support");
2157 goto exit_failure; 2162 goto exit_failure;
2158#endif 2163#endif
2159 default: 2164 default:
2160 logerrx("Family not specified. Please use -4 or -6."); 2165 logerrx("Family not specified. Please use -4 or -6.");
2161 goto exit_failure; 2166 goto exit_failure;
2162 } 2167 }
2163 goto exit_success; 2168 goto exit_success;
2164 } 2169 }
2165#endif 2170#endif
2166 2171
2167 /* Test against siga instead of sig to avoid gcc 2172 /* Test against siga instead of sig to avoid gcc
2168 * warning about a bogus potential signed overflow. 2173 * warning about a bogus potential signed overflow.
2169 * The end result will be the same. */ 2174 * The end result will be the same. */
2170 if ((siga == NULL || i == 4 || ctx.ifc != 0) && 2175 if ((siga == NULL || i == 4 || ctx.ifc != 0) &&
2171 !(ctx.options & DHCPCD_TEST)) 2176 !(ctx.options & DHCPCD_TEST))
2172 { 2177 {
2173 ctx.options |= DHCPCD_FORKED; /* avoid socket unlink */ 2178 ctx.options |= DHCPCD_FORKED; /* avoid socket unlink */
2174 if (!(ctx.options & DHCPCD_MASTER)) 2179 if (!(ctx.options & DHCPCD_MASTER))
2175 ctx.control_fd = control_open(argv[optind], family, 2180 ctx.control_fd = control_open(argv[optind], family,
2176 ctx.options & DHCPCD_DUMPLEASE); 2181 ctx.options & DHCPCD_DUMPLEASE);
2177 if (ctx.control_fd == -1) 2182 if (ctx.control_fd == -1)
2178 ctx.control_fd = control_open(NULL, AF_UNSPEC, 2183 ctx.control_fd = control_open(NULL, AF_UNSPEC,
2179 ctx.options & DHCPCD_DUMPLEASE); 2184 ctx.options & DHCPCD_DUMPLEASE);
2180 if (ctx.control_fd != -1) { 2185 if (ctx.control_fd != -1) {
2181#ifdef PRIVSEP 2186#ifdef PRIVSEP
2182 if (IN_PRIVSEP(&ctx) && 2187 if (IN_PRIVSEP(&ctx) &&
2183 ps_mastersandbox(&ctx, NULL) == -1) 2188 ps_mastersandbox(&ctx, NULL) == -1)
2184 goto exit_failure; 2189 goto exit_failure;
2185#endif 2190#endif
2186 if (!(ctx.options & DHCPCD_DUMPLEASE)) 2191 if (!(ctx.options & DHCPCD_DUMPLEASE))
2187 loginfox("sending commands to dhcpcd process"); 2192 loginfox("sending commands to dhcpcd process");
2188 len = control_send(&ctx, argc, argv); 2193 len = control_send(&ctx, argc, argv);
2189 if (len > 0) 2194 if (len > 0)
2190 logdebugx("send OK"); 2195 logdebugx("send OK");
2191 else { 2196 else {
2192 logerr("%s: control_send", __func__); 2197 logerr("%s: control_send", __func__);
2193 goto exit_failure; 2198 goto exit_failure;
2194 } 2199 }
2195 if (ctx.options & DHCPCD_DUMPLEASE) { 2200 if (ctx.options & DHCPCD_DUMPLEASE) {
2196 if (dhcpcd_readdump(&ctx) == -1) { 2201 if (dhcpcd_readdump(&ctx) == -1) {
2197 logerr("%s: dhcpcd_readdump", __func__); 2202 logerr("%s: dhcpcd_readdump", __func__);
2198 goto exit_failure; 2203 goto exit_failure;
2199 } 2204 }
2200 goto run_loop; 2205 goto run_loop;
2201 } 2206 }
2202 goto exit_success; 2207 goto exit_success;
2203 } else { 2208 } else {
2204 if (errno != ENOENT) 2209 if (errno != ENOENT)
2205 logerr("%s: control_open", __func__); 2210 logerr("%s: control_open", __func__);
2206 if (ctx.options & DHCPCD_DUMPLEASE) { 2211 if (ctx.options & DHCPCD_DUMPLEASE) {
2207 if (errno == ENOENT) 2212 if (errno == ENOENT)
2208 logerrx("dhcpcd is not running"); 2213 logerrx("dhcpcd is not running");
2209 goto exit_failure; 2214 goto exit_failure;
2210 } 2215 }
2211 if (errno == EPERM || errno == EACCES) 2216 if (errno == EPERM || errno == EACCES)
2212 goto exit_failure; 2217 goto exit_failure;
2213 } 2218 }
2214 ctx.options &= ~DHCPCD_FORKED; 2219 ctx.options &= ~DHCPCD_FORKED;
2215 } 2220 }
2216 2221
2217 if (!(ctx.options & DHCPCD_TEST)) { 2222 if (!(ctx.options & DHCPCD_TEST)) {
2218 /* Ensure we have the needed directories */ 2223 /* Ensure we have the needed directories */
2219 if (mkdir(DBDIR, 0750) == -1 && errno != EEXIST) 2224 if (mkdir(DBDIR, 0750) == -1 && errno != EEXIST)
2220 logerr("%s: mkdir: %s", __func__, DBDIR); 2225 logerr("%s: mkdir: %s", __func__, DBDIR);
2221 if (mkdir(RUNDIR, 0755) == -1 && errno != EEXIST) 2226 if (mkdir(RUNDIR, 0755) == -1 && errno != EEXIST)
2222 logerr("%s: mkdir: %s", __func__, RUNDIR); 2227 logerr("%s: mkdir: %s", __func__, RUNDIR);
2223 if ((pid = pidfile_lock(ctx.pidfile)) != 0) { 2228 if ((pid = pidfile_lock(ctx.pidfile)) != 0) {
2224 if (pid == -1) 2229 if (pid == -1)
2225 logerr("%s: pidfile_lock: %s", 2230 logerr("%s: pidfile_lock: %s",
2226 __func__, ctx.pidfile); 2231 __func__, ctx.pidfile);
2227 else 2232 else
2228 logerrx(PACKAGE 2233 logerrx(PACKAGE
2229 " already running on pid %d (%s)", 2234 " already running on pid %d (%s)",
2230 pid, ctx.pidfile); 2235 pid, ctx.pidfile);
2231 goto exit_failure; 2236 goto exit_failure;
2232 } 2237 }
2233 } 2238 }
2234 2239
2235 loginfox(PACKAGE "-" VERSION " starting"); 2240 loginfox(PACKAGE "-" VERSION " starting");
2236 if (ctx.stdin_valid && freopen(_PATH_DEVNULL, "w", stdin) == NULL) 2241 if (ctx.stdin_valid && freopen(_PATH_DEVNULL, "w", stdin) == NULL)
2237 logwarn("freopen stdin"); 2242 logwarn("freopen stdin");
2238 2243
2239#if defined(USE_SIGNALS) && !defined(THERE_IS_NO_FORK) 2244#if defined(USE_SIGNALS) && !defined(THERE_IS_NO_FORK)
2240 if (xsocketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, fork_fd) == -1 || 2245 if (xsocketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, fork_fd) == -1 ||
2241 (ctx.stderr_valid && 2246 (ctx.stderr_valid &&
2242 xsocketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, stderr_fd) == -1)) 2247 xsocketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, stderr_fd) == -1))
2243 { 2248 {
2244 logerr("socketpair"); 2249 logerr("socketpair");
2245 goto exit_failure; 2250 goto exit_failure;
2246 } 2251 }
2247 switch (pid = fork()) { 2252 switch (pid = fork()) {
2248 case -1: 2253 case -1:
2249 logerr("fork"); 2254 logerr("fork");
2250 goto exit_failure; 2255 goto exit_failure;
2251 case 0: 2256 case 0:
2252 ctx.fork_fd = fork_fd[1]; 2257 ctx.fork_fd = fork_fd[1];
2253 close(fork_fd[0]); 2258 close(fork_fd[0]);
2254#ifdef PRIVSEP_RIGHTS 2259#ifdef PRIVSEP_RIGHTS
2255 if (ps_rights_limit_fd(ctx.fork_fd) == -1) { 2260 if (ps_rights_limit_fd(ctx.fork_fd) == -1) {
2256 logerr("ps_rights_limit_fdpair"); 2261 logerr("ps_rights_limit_fdpair");
2257 goto exit_failure; 2262 goto exit_failure;
2258 } 2263 }
2259#endif 2264#endif
2260 eloop_event_add(ctx.eloop, ctx.fork_fd, dhcpcd_fork_cb, &ctx); 2265 eloop_event_add(ctx.eloop, ctx.fork_fd, dhcpcd_fork_cb, &ctx);
2261 2266
2262 /* 2267 /*
2263 * Redirect stderr to the stderr socketpair. 2268 * Redirect stderr to the stderr socketpair.
2264 * Redirect stdout as well. 2269 * Redirect stdout as well.
2265 * dhcpcd doesn't output via stdout, but something in 2270 * dhcpcd doesn't output via stdout, but something in
2266 * a called script might. 2271 * a called script might.
2267 */ 2272 */
2268 if (ctx.stderr_valid) { 2273 if (ctx.stderr_valid) {
2269 if (dup2(stderr_fd[1], STDERR_FILENO) == -1 || 2274 if (dup2(stderr_fd[1], STDERR_FILENO) == -1 ||
2270 (ctx.stdout_valid && 2275 (ctx.stdout_valid &&
2271 dup2(stderr_fd[1], STDOUT_FILENO) == -1)) 2276 dup2(stderr_fd[1], STDOUT_FILENO) == -1))
2272 logerr("dup2"); 2277 logerr("dup2");
2273 close(stderr_fd[0]); 2278 close(stderr_fd[0]);
2274 close(stderr_fd[1]); 2279 close(stderr_fd[1]);
2275 } else if (ctx.stdout_valid) { 2280 } else if (ctx.stdout_valid) {
2276 if (freopen(_PATH_DEVNULL, "w", stdout) == NULL) 2281 if (freopen(_PATH_DEVNULL, "w", stdout) == NULL)
2277 logerr("freopen stdout"); 2282 logerr("freopen stdout");
2278 } 2283 }
2279 if (setsid() == -1) { 2284 if (setsid() == -1) {
2280 logerr("%s: setsid", __func__); 2285 logerr("%s: setsid", __func__);
2281 goto exit_failure; 2286 goto exit_failure;
2282 } 2287 }
2283 /* Ensure we can never get a controlling terminal */ 2288 /* Ensure we can never get a controlling terminal */
2284 switch (pid = fork()) { 2289 switch (pid = fork()) {
2285 case -1: 2290 case -1:
2286 logerr("fork"); 2291 logerr("fork");
2287 goto exit_failure; 2292 goto exit_failure;
2288 case 0: 2293 case 0:
2289 break; 2294 break;
2290 default: 2295 default:
2291 ctx.options |= DHCPCD_FORKED; /* A lie */ 2296 ctx.options |= DHCPCD_FORKED; /* A lie */
2292 i = EXIT_SUCCESS; 2297 i = EXIT_SUCCESS;
2293 goto exit1; 2298 goto exit1;
2294 } 2299 }
2295 break; 2300 break;
2296 default: 2301 default:
2297 setproctitle("[launcher]"); 2302 setproctitle("[launcher]");
2298 ctx.options |= DHCPCD_FORKED | DHCPCD_LAUNCHER; 2303 ctx.options |= DHCPCD_FORKED | DHCPCD_LAUNCHER;
2299 ctx.fork_fd = fork_fd[0]; 2304 ctx.fork_fd = fork_fd[0];
2300 close(fork_fd[1]); 2305 close(fork_fd[1]);
2301#ifdef PRIVSEP_RIGHTS 2306#ifdef PRIVSEP_RIGHTS
2302 if (ps_rights_limit_fd(ctx.fork_fd) == -1) { 2307 if (ps_rights_limit_fd(ctx.fork_fd) == -1) {
2303 logerr("ps_rights_limit_fd"); 2308 logerr("ps_rights_limit_fd");
2304 goto exit_failure; 2309 goto exit_failure;
2305 } 2310 }
2306#endif 2311#endif
2307 eloop_event_add(ctx.eloop, ctx.fork_fd, dhcpcd_fork_cb, &ctx); 2312 eloop_event_add(ctx.eloop, ctx.fork_fd, dhcpcd_fork_cb, &ctx);
2308 2313
2309 if (ctx.stderr_valid) { 2314 if (ctx.stderr_valid) {
2310 ctx.stderr_fd = stderr_fd[0]; 2315 ctx.stderr_fd = stderr_fd[0];
2311 close(stderr_fd[1]); 2316 close(stderr_fd[1]);
2312#ifdef PRIVSEP_RIGHTS 2317#ifdef PRIVSEP_RIGHTS
2313 if (ps_rights_limit_fd(ctx.stderr_fd) == 1) { 2318 if (ps_rights_limit_fd(ctx.stderr_fd) == 1) {
2314 logerr("ps_rights_limit_fd"); 2319 logerr("ps_rights_limit_fd");
2315 goto exit_failure; 2320 goto exit_failure;
2316 } 2321 }
2317#endif 2322#endif
2318 eloop_event_add(ctx.eloop, ctx.stderr_fd, 2323 eloop_event_add(ctx.eloop, ctx.stderr_fd,
2319 dhcpcd_stderr_cb, &ctx); 2324 dhcpcd_stderr_cb, &ctx);
2320 } 2325 }
2321#ifdef PRIVSEP 2326#ifdef PRIVSEP
2322 if (IN_PRIVSEP(&ctx) && ps_mastersandbox(&ctx, NULL) == -1) 2327 if (IN_PRIVSEP(&ctx) && ps_mastersandbox(&ctx, NULL) == -1)
2323 goto exit_failure; 2328 goto exit_failure;
2324#endif 2329#endif
2325 goto run_loop; 2330 goto run_loop;
2326 } 2331 }
2327 2332
2328 /* We have now forked, setsid, forked once more. 2333 /* We have now forked, setsid, forked once more.
2329 * From this point on, we are the controlling daemon. */ 2334 * From this point on, we are the controlling daemon. */
2330 ctx.options |= DHCPCD_STARTED; 2335 ctx.options |= DHCPCD_STARTED;
 2336 logdebugx("spawned master process on PID %d", getpid());
2331 if ((pid = pidfile_lock(ctx.pidfile)) != 0) { 2337 if ((pid = pidfile_lock(ctx.pidfile)) != 0) {
2332 logerr("%s: pidfile_lock %d", __func__, pid); 2338 logerr("%s: pidfile_lock %d", __func__, pid);
2333#ifdef PRIVSEP 2339#ifdef PRIVSEP
2334 /* privsep has not started ... */ 2340 /* privsep has not started ... */
2335 ctx.options &= ~DHCPCD_PRIVSEP; 2341 ctx.options &= ~DHCPCD_PRIVSEP;
2336#endif 2342#endif
2337 goto exit_failure; 2343 goto exit_failure;
2338 } 2344 }
2339#endif 2345#endif
2340 2346
2341 os_init(); 2347 os_init();
2342 2348
2343#if defined(BSD) && defined(INET6) 2349#if defined(BSD) && defined(INET6)
2344 /* Disable the kernel RTADV sysctl as early as possible. */ 2350 /* Disable the kernel RTADV sysctl as early as possible. */
2345 if (ctx.options & DHCPCD_IPV6 && ctx.options & DHCPCD_IPV6RS) 2351 if (ctx.options & DHCPCD_IPV6 && ctx.options & DHCPCD_IPV6RS)
2346 if_disable_rtadv(); 2352 if_disable_rtadv();
2347#endif 2353#endif
2348 2354
2349#ifdef PRIVSEP 2355#ifdef PRIVSEP
2350 if (IN_PRIVSEP(&ctx) && ps_start(&ctx) == -1) { 2356 if (IN_PRIVSEP(&ctx) && ps_start(&ctx) == -1) {
2351 logerr("ps_start"); 2357 logerr("ps_start");
2352 goto exit_failure; 2358 goto exit_failure;
2353 } 2359 }
2354 if (ctx.options & DHCPCD_FORKED) 2360 if (ctx.options & DHCPCD_FORKED)
2355 goto run_loop; 2361 goto run_loop;
2356#endif 2362#endif
2357 2363
2358 if (!(ctx.options & DHCPCD_TEST)) { 2364 if (!(ctx.options & DHCPCD_TEST)) {
2359 if (control_start(&ctx, 2365 if (control_start(&ctx,
2360 ctx.options & DHCPCD_MASTER ? 2366 ctx.options & DHCPCD_MASTER ?
2361 NULL : argv[optind], family) == -1) 2367 NULL : argv[optind], family) == -1)
2362 { 2368 {
2363 logerr("%s: control_start", __func__); 2369 logerr("%s: control_start", __func__);
2364 goto exit_failure; 2370 goto exit_failure;
2365 } 2371 }
2366 } 2372 }
2367 2373
2368#ifdef PLUGIN_DEV 2374#ifdef PLUGIN_DEV
2369 /* Start any dev listening plugin which may want to 2375 /* Start any dev listening plugin which may want to
2370 * change the interface name provided by the kernel */ 2376 * change the interface name provided by the kernel */
2371 if (!IN_PRIVSEP(&ctx) && 2377 if (!IN_PRIVSEP(&ctx) &&
2372 (ctx.options & (DHCPCD_MASTER | DHCPCD_DEV)) == 2378 (ctx.options & (DHCPCD_MASTER | DHCPCD_DEV)) ==
2373 (DHCPCD_MASTER | DHCPCD_DEV)) 2379 (DHCPCD_MASTER | DHCPCD_DEV))
2374 dev_start(&ctx, dhcpcd_handleinterface); 2380 dev_start(&ctx, dhcpcd_handleinterface);
2375#endif 2381#endif
2376 2382
2377 setproctitle("%s%s%s", 2383 setproctitle("%s%s%s",
2378 ctx.options & DHCPCD_MASTER ? "[master]" : argv[optind], 2384 ctx.options & DHCPCD_MASTER ? "[master]" : argv[optind],
2379 ctx.options & DHCPCD_IPV4 ? " [ip4]" : "", 2385 ctx.options & DHCPCD_IPV4 ? " [ip4]" : "",
2380 ctx.options & DHCPCD_IPV6 ? " [ip6]" : ""); 2386 ctx.options & DHCPCD_IPV6 ? " [ip6]" : "");
2381 2387
2382 if (if_opensockets(&ctx) == -1) { 2388 if (if_opensockets(&ctx) == -1) {
2383 logerr("%s: if_opensockets", __func__); 2389 logerr("%s: if_opensockets", __func__);
2384 goto exit_failure; 2390 goto exit_failure;
2385 } 2391 }
2386#ifndef SMALL 2392#ifndef SMALL
2387 dhcpcd_setlinkrcvbuf(&ctx); 2393 dhcpcd_setlinkrcvbuf(&ctx);
2388#endif 2394#endif
2389 2395
2390 /* Try and create DUID from the machine UUID. */ 2396 /* Try and create DUID from the machine UUID. */
2391 dhcpcd_initduid(&ctx, NULL); 2397 dhcpcd_initduid(&ctx, NULL);
2392 2398
2393 /* Cache the default vendor option. */ 2399 /* Cache the default vendor option. */
2394 if (dhcp_vendor(ctx.vendor, sizeof(ctx.vendor)) == -1) 2400 if (dhcp_vendor(ctx.vendor, sizeof(ctx.vendor)) == -1)
2395 logerr("dhcp_vendor"); 2401 logerr("dhcp_vendor");
2396 2402
2397 /* Start handling kernel messages for interfaces, addresses and 2403 /* Start handling kernel messages for interfaces, addresses and
2398 * routes. */ 2404 * routes. */
2399 eloop_event_add(ctx.eloop, ctx.link_fd, dhcpcd_handlelink, &ctx); 2405 eloop_event_add(ctx.eloop, ctx.link_fd, dhcpcd_handlelink, &ctx);
2400 2406
2401#ifdef PRIVSEP 2407#ifdef PRIVSEP
2402 if (IN_PRIVSEP(&ctx) && ps_mastersandbox(&ctx, "stdio route") == -1) 2408 if (IN_PRIVSEP(&ctx) && ps_mastersandbox(&ctx, "stdio route") == -1)
2403 goto exit_failure; 2409 goto exit_failure;
2404#endif 2410#endif
2405 2411
2406 /* When running dhcpcd against a single interface, we need to retain 2412 /* When running dhcpcd against a single interface, we need to retain
2407 * the old behaviour of waiting for an IP address */ 2413 * the old behaviour of waiting for an IP address */
2408 if (ctx.ifc == 1 && !(ctx.options & DHCPCD_BACKGROUND)) 2414 if (ctx.ifc == 1 && !(ctx.options & DHCPCD_BACKGROUND))
2409 ctx.options |= DHCPCD_WAITIP; 2415 ctx.options |= DHCPCD_WAITIP;
2410 2416
2411 ctx.ifaces = if_discover(&ctx, &ifaddrs, ctx.ifc, ctx.ifv); 2417 ctx.ifaces = if_discover(&ctx, &ifaddrs, ctx.ifc, ctx.ifv);
2412 if (ctx.ifaces == NULL) { 2418 if (ctx.ifaces == NULL) {
2413 logerr("%s: if_discover", __func__); 2419 logerr("%s: if_discover", __func__);
2414 goto exit_failure; 2420 goto exit_failure;
2415 } 2421 }
2416 for (i = 0; i < ctx.ifc; i++) { 2422 for (i = 0; i < ctx.ifc; i++) {
2417 if ((ifp = if_find(ctx.ifaces, ctx.ifv[i])) == NULL) 2423 if ((ifp = if_find(ctx.ifaces, ctx.ifv[i])) == NULL)
2418 logerrx("%s: interface not found", 2424 logerrx("%s: interface not found",
2419 ctx.ifv[i]); 2425 ctx.ifv[i]);
2420 else if (!ifp->active) 2426 else if (!ifp->active)
2421 logerrx("%s: interface has an invalid configuration", 2427 logerrx("%s: interface has an invalid configuration",
2422 ctx.ifv[i]); 2428 ctx.ifv[i]);
2423 } 2429 }
2424 TAILQ_FOREACH(ifp, ctx.ifaces, next) { 2430 TAILQ_FOREACH(ifp, ctx.ifaces, next) {
2425 if (ifp->active == IF_ACTIVE_USER) 2431 if (ifp->active == IF_ACTIVE_USER)
2426 break; 2432 break;
2427 } 2433 }
2428 if (ifp == NULL) { 2434 if (ifp == NULL) {
2429 if (ctx.ifc == 0) { 2435 if (ctx.ifc == 0) {
2430 int loglevel; 2436 int loglevel;
2431 2437
2432 loglevel = ctx.options & DHCPCD_INACTIVE ? 2438 loglevel = ctx.options & DHCPCD_INACTIVE ?
2433 LOG_DEBUG : LOG_ERR; 2439 LOG_DEBUG : LOG_ERR;
2434 logmessage(loglevel, "no valid interfaces found"); 2440 logmessage(loglevel, "no valid interfaces found");
2435 dhcpcd_daemonise(&ctx); 2441 dhcpcd_daemonise(&ctx);
2436 } else 2442 } else
2437 goto exit_failure; 2443 goto exit_failure;
2438 if (!(ctx.options & DHCPCD_LINK)) { 2444 if (!(ctx.options & DHCPCD_LINK)) {
2439 logerrx("aborting as link detection is disabled"); 2445 logerrx("aborting as link detection is disabled");
2440 goto exit_failure; 2446 goto exit_failure;
2441 } 2447 }
2442 } 2448 }
2443 2449
2444 TAILQ_FOREACH(ifp, ctx.ifaces, next) { 2450 TAILQ_FOREACH(ifp, ctx.ifaces, next) {
2445 if (ifp->active) 2451 if (ifp->active)
2446 dhcpcd_initstate1(ifp, argc, argv, 0); 2452 dhcpcd_initstate1(ifp, argc, argv, 0);
2447 } 2453 }
2448 if_learnaddrs(&ctx, ctx.ifaces, &ifaddrs); 2454 if_learnaddrs(&ctx, ctx.ifaces, &ifaddrs);
2449 2455
2450 if (ctx.options & DHCPCD_BACKGROUND) 2456 if (ctx.options & DHCPCD_BACKGROUND)
2451 dhcpcd_daemonise(&ctx); 2457 dhcpcd_daemonise(&ctx);
2452 2458
2453 opt = 0; 2459 opt = 0;
2454 TAILQ_FOREACH(ifp, ctx.ifaces, next) { 2460 TAILQ_FOREACH(ifp, ctx.ifaces, next) {
2455 if (ifp->active) { 2461 if (ifp->active) {
2456 run_preinit(ifp); 2462 run_preinit(ifp);
2457 if (if_is_link_up(ifp)) 2463 if (if_is_link_up(ifp))
2458 opt = 1; 2464 opt = 1;
2459 } 2465 }
2460 } 2466 }
2461 2467
2462 if (!(ctx.options & DHCPCD_BACKGROUND)) { 2468 if (!(ctx.options & DHCPCD_BACKGROUND)) {
2463 if (ctx.options & DHCPCD_MASTER) 2469 if (ctx.options & DHCPCD_MASTER)
2464 t = ifo->timeout; 2470 t = ifo->timeout;
2465 else { 2471 else {
2466 t = 0; 2472 t = 0;
2467 TAILQ_FOREACH(ifp, ctx.ifaces, next) { 2473 TAILQ_FOREACH(ifp, ctx.ifaces, next) {
2468 if (ifp->active) { 2474 if (ifp->active) {
2469 t = ifp->options->timeout; 2475 t = ifp->options->timeout;
2470 break; 2476 break;
2471 } 2477 }
2472 } 2478 }
2473 } 2479 }
2474 if (opt == 0 && 2480 if (opt == 0 &&
2475 ctx.options & DHCPCD_LINK && 2481 ctx.options & DHCPCD_LINK &&
2476 !(ctx.options & DHCPCD_WAITIP)) 2482 !(ctx.options & DHCPCD_WAITIP))
2477 { 2483 {
2478 int loglevel; 2484 int loglevel;
2479 2485
2480 loglevel = ctx.options & DHCPCD_INACTIVE ? 2486 loglevel = ctx.options & DHCPCD_INACTIVE ?
2481 LOG_DEBUG : LOG_WARNING; 2487 LOG_DEBUG : LOG_WARNING;
2482 logmessage(loglevel, "no interfaces have a carrier"); 2488 logmessage(loglevel, "no interfaces have a carrier");
2483 dhcpcd_daemonise(&ctx); 2489 dhcpcd_daemonise(&ctx);
2484 } else if (t > 0 && 2490 } else if (t > 0 &&
2485 /* Test mode removes the daemonise bit, so check for both */ 2491 /* Test mode removes the daemonise bit, so check for both */
2486 ctx.options & (DHCPCD_DAEMONISE | DHCPCD_TEST)) 2492 ctx.options & (DHCPCD_DAEMONISE | DHCPCD_TEST))
2487 { 2493 {
2488 eloop_timeout_add_sec(ctx.eloop, t, 2494 eloop_timeout_add_sec(ctx.eloop, t,
2489 handle_exit_timeout, &ctx); 2495 handle_exit_timeout, &ctx);
2490 } 2496 }
2491 } 2497 }
2492 free_options(&ctx, ifo); 2498 free_options(&ctx, ifo);
2493 ifo = NULL; 2499 ifo = NULL;
2494 2500
2495 TAILQ_FOREACH(ifp, ctx.ifaces, next) { 2501 TAILQ_FOREACH(ifp, ctx.ifaces, next) {
2496 if (ifp->active) 2502 if (ifp->active)
2497 eloop_timeout_add_sec(ctx.eloop, 0, 2503 eloop_timeout_add_sec(ctx.eloop, 0,
2498 dhcpcd_prestartinterface, ifp); 2504 dhcpcd_prestartinterface, ifp);
2499 } 2505 }
2500 2506
2501run_loop: 2507run_loop:
2502 i = eloop_start(ctx.eloop, &ctx.sigset); 2508 i = eloop_start(ctx.eloop, &ctx.sigset);
2503 if (i < 0) { 2509 if (i < 0) {
2504 logerr("%s: eloop_start", __func__); 2510 logerr("%s: eloop_start", __func__);
2505 goto exit_failure; 2511 goto exit_failure;
2506 } 2512 }
2507 goto exit1; 2513 goto exit1;
2508 2514
2509exit_success: 2515exit_success:
2510 i = EXIT_SUCCESS; 2516 i = EXIT_SUCCESS;
2511 goto exit1; 2517 goto exit1;
2512 2518
2513exit_failure: 2519exit_failure:
2514 i = EXIT_FAILURE; 2520 i = EXIT_FAILURE;
2515 2521
2516exit1: 2522exit1:
2517 if (control_stop(&ctx) == -1) 2523 if (control_stop(&ctx) == -1)
2518 logerr("%s: control_stop", __func__); 2524 logerr("%s: control_stop", __func__);
2519 if (ifaddrs != NULL) { 2525 if (ifaddrs != NULL) {
2520#ifdef PRIVSEP_GETIFADDRS 2526#ifdef PRIVSEP_GETIFADDRS
2521 if (IN_PRIVSEP(&ctx)) 2527 if (IN_PRIVSEP(&ctx))
2522 free(ifaddrs); 2528 free(ifaddrs);
2523 else 2529 else
2524#endif 2530#endif
2525 freeifaddrs(ifaddrs); 2531 freeifaddrs(ifaddrs);
2526 } 2532 }
2527 /* ps_stop will clear DHCPCD_PRIVSEP but we need to 2533 /* ps_stop will clear DHCPCD_PRIVSEP but we need to
2528 * remember it to avoid attemping to remove the pidfile */ 2534 * remember it to avoid attemping to remove the pidfile */
2529 oi = ctx.options & DHCPCD_PRIVSEP ? 1 : 0; 2535 oi = ctx.options & DHCPCD_PRIVSEP ? 1 : 0;
2530#ifdef PRIVSEP 2536#ifdef PRIVSEP
2531 ps_stop(&ctx); 2537 ps_stop(&ctx);
2532#endif 2538#endif
2533 /* Free memory and close fd's */ 2539 /* Free memory and close fd's */
2534 if (ctx.ifaces) { 2540 if (ctx.ifaces) {
2535 while ((ifp = TAILQ_FIRST(ctx.ifaces))) { 2541 while ((ifp = TAILQ_FIRST(ctx.ifaces))) {
2536 TAILQ_REMOVE(ctx.ifaces, ifp, next); 2542 TAILQ_REMOVE(ctx.ifaces, ifp, next);
2537 if_free(ifp); 2543 if_free(ifp);
2538 } 2544 }
2539 free(ctx.ifaces); 2545 free(ctx.ifaces);
2540 ctx.ifaces = NULL; 2546 ctx.ifaces = NULL;
2541 } 2547 }
2542 free_options(&ctx, ifo); 2548 free_options(&ctx, ifo);
2543#ifdef HAVE_OPEN_MEMSTREAM 2549#ifdef HAVE_OPEN_MEMSTREAM
2544 if (ctx.script_fp) 2550 if (ctx.script_fp)
2545 fclose(ctx.script_fp); 2551 fclose(ctx.script_fp);
2546#endif 2552#endif
2547 free(ctx.script_buf); 2553 free(ctx.script_buf);
2548 free(ctx.script_env); 2554 free(ctx.script_env);
2549 rt_dispose(&ctx); 2555 rt_dispose(&ctx);
2550 free(ctx.duid); 2556 free(ctx.duid);
2551 if (ctx.link_fd != -1) { 2557 if (ctx.link_fd != -1) {
2552 eloop_event_delete(ctx.eloop, ctx.link_fd); 2558 eloop_event_delete(ctx.eloop, ctx.link_fd);
2553 close(ctx.link_fd); 2559 close(ctx.link_fd);
2554 } 2560 }
2555 if_closesockets(&ctx); 2561 if_closesockets(&ctx);
2556 free_globals(&ctx); 2562 free_globals(&ctx);
2557#ifdef INET6 2563#ifdef INET6
2558 ipv6_ctxfree(&ctx); 2564 ipv6_ctxfree(&ctx);
2559#endif 2565#endif
2560#ifdef PLUGIN_DEV 2566#ifdef PLUGIN_DEV
2561 dev_stop(&ctx); 2567 dev_stop(&ctx);
2562#endif 2568#endif
2563#ifdef PRIVSEP 2569#ifdef PRIVSEP
2564 eloop_free(ctx.ps_eloop); 2570 eloop_free(ctx.ps_eloop);
2565#endif 2571#endif
2566 eloop_free(ctx.eloop); 2572 eloop_free(ctx.eloop);
2567 if (ctx.script != dhcpcd_default_script) 2573 if (ctx.script != dhcpcd_default_script)
2568 free(ctx.script); 2574 free(ctx.script);
2569 if (ctx.options & DHCPCD_STARTED && !(ctx.options & DHCPCD_FORKED)) 2575 if (ctx.options & DHCPCD_STARTED && !(ctx.options & DHCPCD_FORKED))
2570 loginfox(PACKAGE " exited"); 2576 loginfox(PACKAGE " exited");
2571 logclose(); 2577 logclose();
2572 free(ctx.logfile); 2578 free(ctx.logfile);
2573 free(ctx.ctl_buf); 2579 free(ctx.ctl_buf);
2574#ifdef SETPROCTITLE_H 2580#ifdef SETPROCTITLE_H
2575 setproctitle_fini(); 2581 setproctitle_fini();
2576#endif 2582#endif
2577#ifdef USE_SIGNALS 2583#ifdef USE_SIGNALS
2578 if (ctx.options & DHCPCD_STARTED) { 2584 if (ctx.options & DHCPCD_STARTED) {
2579 /* Try to detach from the launch process. */ 2585 /* Try to detach from the launch process. */
2580 if (ctx.fork_fd != -1 && 2586 if (ctx.fork_fd != -1 &&
2581 write(ctx.fork_fd, &i, sizeof(i)) == -1) 2587 write(ctx.fork_fd, &i, sizeof(i)) == -1)
2582 logerr("%s: write", __func__); 2588 logerr("%s: write", __func__);
2583 } 2589 }
2584 if (ctx.options & DHCPCD_FORKED || oi != 0) 2590 if (ctx.options & DHCPCD_FORKED || oi != 0)
2585 _exit(i); /* so atexit won't remove our pidfile */ 2591 _exit(i); /* so atexit won't remove our pidfile */
2586#endif 2592#endif
2587 return i; 2593 return i;
2588} 2594}

cvs diff -r1.10 -r1.11 src/external/bsd/dhcpcd/dist/src/logerr.c (switch to unified diff)

--- src/external/bsd/dhcpcd/dist/src/logerr.c 2020/10/12 14:09:03 1.10
+++ src/external/bsd/dhcpcd/dist/src/logerr.c 2020/11/01 14:24:01 1.11
@@ -1,416 +1,496 @@ @@ -1,416 +1,496 @@
1/* SPDX-License-Identifier: BSD-2-Clause */ 1/* SPDX-License-Identifier: BSD-2-Clause */
2/* 2/*
3 * logerr: errx with logging 3 * logerr: errx with logging
4 * Copyright (c) 2006-2020 Roy Marples <roy@marples.name> 4 * Copyright (c) 2006-2020 Roy Marples <roy@marples.name>
5 * All rights reserved 5 * All rights reserved
6 6
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/time.h> 29#include <sys/time.h>
30#include <errno.h> 30#include <errno.h>
31#include <stdbool.h> 31#include <stdbool.h>
32#include <stdarg.h> 32#include <stdarg.h>
33#include <stdio.h> 33#include <stdio.h>
34#include <stdlib.h> 34#include <stdlib.h>
35#include <string.h> 35#include <string.h>
36#include <syslog.h> 36#include <syslog.h>
37#include <time.h> 37#include <time.h>
38#include <unistd.h> 38#include <unistd.h>
39 39
40#include "logerr.h" 40#include "logerr.h"
41 41
42#ifndef LOGERR_SYSLOG_FACILITY 42#ifndef LOGERR_SYSLOG_FACILITY
43#define LOGERR_SYSLOG_FACILITY LOG_DAEMON 43#define LOGERR_SYSLOG_FACILITY LOG_DAEMON
44#endif 44#endif
45 45
46#ifdef SMALL 46#ifdef SMALL
47#undef LOGERR_TAG 47#undef LOGERR_TAG
48#endif 48#endif
49 49
 50/* syslog protocol is 1k message max, RFC 3164 section 4.1 */
 51#define LOGERR_SYSLOGBUF 1024 + sizeof(int) + sizeof(pid_t)
 52
50#define UNUSED(a) (void)(a) 53#define UNUSED(a) (void)(a)
51 54
52struct logctx { 55struct logctx {
53 char log_buf[BUFSIZ]; 56 char log_buf[BUFSIZ];
54 unsigned int log_opts; 57 unsigned int log_opts;
 58 int log_fd;
 59 pid_t log_pid;
55#ifndef SMALL 60#ifndef SMALL
56 FILE *log_file; 61 FILE *log_file;
57#ifdef LOGERR_TAG 62#ifdef LOGERR_TAG
58 const char *log_tag; 63 const char *log_tag;
59#endif 64#endif
60#endif 65#endif
61}; 66};
62 67
63static struct logctx _logctx = { 68static struct logctx _logctx = {
64 /* syslog style, but without the hostname or tag. */ 69 /* syslog style, but without the hostname or tag. */
65 .log_opts = LOGERR_LOG | LOGERR_LOG_DATE | LOGERR_LOG_PID, 70 .log_opts = LOGERR_LOG | LOGERR_LOG_DATE | LOGERR_LOG_PID,
 71 .log_fd = -1,
 72 .log_pid = 0,
66}; 73};
67 74
68#if defined(LOGERR_TAG) && defined(__linux__) 75#if defined(__linux__)
69/* Poor man's getprogname(3). */ 76/* Poor man's getprogname(3). */
70static char *_logprog; 77static char *_logprog;
71static const char * 78static const char *
72getprogname(void) 79getprogname(void)
73{ 80{
74 const char *p; 81 const char *p;
75 82
76 /* Use PATH_MAX + 1 to avoid truncation. */ 83 /* Use PATH_MAX + 1 to avoid truncation. */
77 if (_logprog == NULL) { 84 if (_logprog == NULL) {
78 /* readlink(2) does not append a NULL byte, 85 /* readlink(2) does not append a NULL byte,
79 * so zero the buffer. */ 86 * so zero the buffer. */
80 if ((_logprog = calloc(1, PATH_MAX + 1)) == NULL) 87 if ((_logprog = calloc(1, PATH_MAX + 1)) == NULL)
81 return NULL; 88 return NULL;
 89 if (readlink("/proc/self/exe", _logprog, PATH_MAX + 1) == -1) {
 90 free(_logprog);
 91 _logprog = NULL;
 92 return NULL;
 93 }
82 } 94 }
83 if (readlink("/proc/self/exe", _logprog, PATH_MAX + 1) == -1) 
84 return NULL; 
85 if (_logprog[0] == '[') 95 if (_logprog[0] == '[')
86 return NULL; 96 return NULL;
87 p = strrchr(_logprog, '/'); 97 p = strrchr(_logprog, '/');
88 if (p == NULL) 98 if (p == NULL)
89 return _logprog; 99 return _logprog;
90 return p + 1; 100 return p + 1;
91} 101}
92#endif 102#endif
93 103
94#ifndef SMALL 104#ifndef SMALL
95/* Write the time, syslog style. month day time - */ 105/* Write the time, syslog style. month day time - */
96static int 106static int
97logprintdate(FILE *stream) 107logprintdate(FILE *stream)
98{ 108{
99 struct timeval tv; 109 struct timeval tv;
100 time_t now; 110 time_t now;
101 struct tm tmnow; 111 struct tm tmnow;
102 char buf[32]; 112 char buf[32];
103 113
104 if (gettimeofday(&tv, NULL) == -1) 114 if (gettimeofday(&tv, NULL) == -1)
105 return -1; 115 return -1;
106 116
107 now = tv.tv_sec; 117 now = tv.tv_sec;
108 if (localtime_r(&now, &tmnow) == NULL) 118 if (localtime_r(&now, &tmnow) == NULL)
109 return -1; 119 return -1;
110 if (strftime(buf, sizeof(buf), "%b %d %T ", &tmnow) == 0) 120 if (strftime(buf, sizeof(buf), "%b %d %T ", &tmnow) == 0)
111 return -1; 121 return -1;
112 return fprintf(stream, "%s", buf); 122 return fprintf(stream, "%s", buf);
113} 123}
114#endif 124#endif
115 125
116__printflike(3, 0) static int 126__printflike(3, 0) static int
117vlogprintf_r(struct logctx *ctx, FILE *stream, const char *fmt, va_list args) 127vlogprintf_r(struct logctx *ctx, FILE *stream, const char *fmt, va_list args)
118{ 128{
119 int len = 0, e; 129 int len = 0, e;
120 va_list a; 130 va_list a;
121#ifndef SMALL 131#ifndef SMALL
122 bool log_pid; 132 bool log_pid;
123#ifdef LOGERR_TAG 133#ifdef LOGERR_TAG
124 bool log_tag; 134 bool log_tag;
125#endif 135#endif
126 136
127 if ((stream == stderr && ctx->log_opts & LOGERR_ERR_DATE) || 137 if ((stream == stderr && ctx->log_opts & LOGERR_ERR_DATE) ||
128 (stream != stderr && ctx->log_opts & LOGERR_LOG_DATE)) 138 (stream != stderr && ctx->log_opts & LOGERR_LOG_DATE))
129 { 139 {
130 if ((e = logprintdate(stream)) == -1) 140 if ((e = logprintdate(stream)) == -1)
131 return -1; 141 return -1;
132 len += e; 142 len += e;
133 } 143 }
134 144
135#ifdef LOGERR_TAG 145#ifdef LOGERR_TAG
136 log_tag = ((stream == stderr && ctx->log_opts & LOGERR_ERR_TAG) || 146 log_tag = ((stream == stderr && ctx->log_opts & LOGERR_ERR_TAG) ||
137 (stream != stderr && ctx->log_opts & LOGERR_LOG_TAG)); 147 (stream != stderr && ctx->log_opts & LOGERR_LOG_TAG));
138 if (log_tag) { 148 if (log_tag) {
139 if (ctx->log_tag == NULL) 149 if (ctx->log_tag == NULL)
140 ctx->log_tag = getprogname(); 150 ctx->log_tag = getprogname();
141 if ((e = fprintf(stream, "%s", ctx->log_tag)) == -1) 151 if ((e = fprintf(stream, "%s", ctx->log_tag)) == -1)
142 return -1; 152 return -1;
143 len += e; 153 len += e;
144 } 154 }
145#endif 155#endif
146 156
147 log_pid = ((stream == stderr && ctx->log_opts & LOGERR_ERR_PID) || 157 log_pid = ((stream == stderr && ctx->log_opts & LOGERR_ERR_PID) ||
148 (stream != stderr && ctx->log_opts & LOGERR_LOG_PID)); 158 (stream != stderr && ctx->log_opts & LOGERR_LOG_PID));
149 if (log_pid) { 159 if (log_pid) {
150 if ((e = fprintf(stream, "[%d]", getpid())) == -1) 160 pid_t pid;
 161
 162 if (ctx->log_pid == 0)
 163 pid = getpid();
 164 else
 165 pid = ctx->log_pid;
 166 if ((e = fprintf(stream, "[%d]", pid)) == -1)
151 return -1; 167 return -1;
152 len += e; 168 len += e;
153 } 169 }
154 170
155#ifdef LOGERR_TAG 171#ifdef LOGERR_TAG
156 if (log_tag || log_pid) 172 if (log_tag || log_pid)
157#else 173#else
158 if (log_pid) 174 if (log_pid)
159#endif 175#endif
160 { 176 {
161 if ((e = fprintf(stream, ": ")) == -1) 177 if ((e = fprintf(stream, ": ")) == -1)
162 return -1; 178 return -1;
163 len += e; 179 len += e;
164 } 180 }
165#else 181#else
166 UNUSED(ctx); 182 UNUSED(ctx);
167#endif 183#endif
168 184
169 va_copy(a, args); 185 va_copy(a, args);
170 e = vfprintf(stream, fmt, a); 186 e = vfprintf(stream, fmt, a);
171 if (fputc('\n', stream) == EOF) 187 if (fputc('\n', stream) == EOF)
172 e = -1; 188 e = -1;
173 else if (e != -1) 189 else if (e != -1)
174 e++; 190 e++;
175 va_end(a); 191 va_end(a);
176 192
177 return e == -1 ? -1 : len + e; 193 return e == -1 ? -1 : len + e;
178} 194}
179 195
180/* 196/*
181 * NetBSD's gcc has been modified to check for the non standard %m in printf 197 * NetBSD's gcc has been modified to check for the non standard %m in printf
182 * like functions and warn noisily about it that they should be marked as 198 * like functions and warn noisily about it that they should be marked as
183 * syslog like instead. 199 * syslog like instead.
184 * This is all well and good, but our logger also goes via vfprintf and 200 * This is all well and good, but our logger also goes via vfprintf and
185 * when marked as a sysloglike funcion, gcc will then warn us that the 201 * when marked as a sysloglike funcion, gcc will then warn us that the
186 * function should be printflike instead! 202 * function should be printflike instead!
187 * This creates an infinte loop of gcc warnings. 203 * This creates an infinte loop of gcc warnings.
188 * Until NetBSD solves this issue, we have to disable a gcc diagnostic 204 * Until NetBSD solves this issue, we have to disable a gcc diagnostic
189 * for our fully standards compliant code in the logger function. 205 * for our fully standards compliant code in the logger function.
190 */ 206 */
191#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5)) 207#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5))
192#pragma GCC diagnostic push 208#pragma GCC diagnostic push
193#pragma GCC diagnostic ignored "-Wmissing-format-attribute" 209#pragma GCC diagnostic ignored "-Wmissing-format-attribute"
194#endif 210#endif
195__printflike(2, 0) static int 211__printflike(2, 0) static int
196vlogmessage(int pri, const char *fmt, va_list args) 212vlogmessage(int pri, const char *fmt, va_list args)
197{ 213{
198 struct logctx *ctx = &_logctx; 214 struct logctx *ctx = &_logctx;
199 int len = 0; 215 int len = 0;
200 216
 217 if (ctx->log_fd != -1) {
 218 char buf[LOGERR_SYSLOGBUF];
 219 pid_t pid;
 220
 221 memcpy(buf, &pri, sizeof(pri));
 222 pid = getpid();
 223 memcpy(buf + sizeof(pri), &pid, sizeof(pid));
 224 len = vsnprintf(buf + sizeof(pri) + sizeof(pid),
 225 sizeof(buf) - sizeof(pri) - sizeof(pid),
 226 fmt, args);
 227 if (len != -1)
 228 len = (int)write(ctx->log_fd, buf,
 229 ((size_t)++len) + sizeof(pri) + sizeof(pid));
 230 return len;
 231 }
 232
201 if (ctx->log_opts & LOGERR_ERR && 233 if (ctx->log_opts & LOGERR_ERR &&
202 (pri <= LOG_ERR || 234 (pri <= LOG_ERR ||
203 (!(ctx->log_opts & LOGERR_QUIET) && pri <= LOG_INFO) || 235 (!(ctx->log_opts & LOGERR_QUIET) && pri <= LOG_INFO) ||
204 (ctx->log_opts & LOGERR_DEBUG && pri <= LOG_DEBUG))) 236 (ctx->log_opts & LOGERR_DEBUG && pri <= LOG_DEBUG)))
205 len = vlogprintf_r(ctx, stderr, fmt, args); 237 len = vlogprintf_r(ctx, stderr, fmt, args);
206 238
207 if (!(ctx->log_opts & LOGERR_LOG)) 
208 return len; 
209 
210#ifndef SMALL 239#ifndef SMALL
211 if (ctx->log_file != NULL && 240 if (ctx->log_file != NULL &&
212 (pri != LOG_DEBUG || (ctx->log_opts & LOGERR_DEBUG))) 241 (pri != LOG_DEBUG || (ctx->log_opts & LOGERR_DEBUG)))
213 len = vlogprintf_r(ctx, ctx->log_file, fmt, args); 242 len = vlogprintf_r(ctx, ctx->log_file, fmt, args);
214#endif 243#endif
215 244
216 vsyslog(pri, fmt, args); 245 if (ctx->log_opts & LOGERR_LOG)
 246 vsyslog(pri, fmt, args);
 247
217 return len; 248 return len;
218} 249}
219#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5)) 250#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5))
220#pragma GCC diagnostic pop 251#pragma GCC diagnostic pop
221#endif 252#endif
222 253
223__printflike(2, 3) void 254__printflike(2, 3) void
224logmessage(int pri, const char *fmt, ...) 255logmessage(int pri, const char *fmt, ...)
225{ 256{
226 va_list args; 257 va_list args;
227 258
228 va_start(args, fmt); 259 va_start(args, fmt);
229 vlogmessage(pri, fmt, args); 260 vlogmessage(pri, fmt, args);
230 va_end(args); 261 va_end(args);
231} 262}
232 263
233__printflike(2, 0) static void 264__printflike(2, 0) static void
234vlogerrmessage(int pri, const char *fmt, va_list args) 265vlogerrmessage(int pri, const char *fmt, va_list args)
235{ 266{
236 int _errno = errno; 267 int _errno = errno;
237 char buf[1024]; 268 char buf[1024];
238 269
239 vsnprintf(buf, sizeof(buf), fmt, args); 270 vsnprintf(buf, sizeof(buf), fmt, args);
240 logmessage(pri, "%s: %s", buf, strerror(_errno)); 271 logmessage(pri, "%s: %s", buf, strerror(_errno));
241 errno = _errno; 272 errno = _errno;
242} 273}
243 274
244__printflike(2, 3) void 275__printflike(2, 3) void
245logerrmessage(int pri, const char *fmt, ...) 276logerrmessage(int pri, const char *fmt, ...)
246{ 277{
247 va_list args; 278 va_list args;
248 279
249 va_start(args, fmt); 280 va_start(args, fmt);
250 vlogerrmessage(pri, fmt, args); 281 vlogerrmessage(pri, fmt, args);
251 va_end(args); 282 va_end(args);
252} 283}
253 284
254void 285void
255log_debug(const char *fmt, ...) 286log_debug(const char *fmt, ...)
256{ 287{
257 va_list args; 288 va_list args;
258 289
259 va_start(args, fmt); 290 va_start(args, fmt);
260 vlogerrmessage(LOG_DEBUG, fmt, args); 291 vlogerrmessage(LOG_DEBUG, fmt, args);
261 va_end(args); 292 va_end(args);
262} 293}
263 294
264void 295void
265log_debugx(const char *fmt, ...) 296log_debugx(const char *fmt, ...)
266{ 297{
267 va_list args; 298 va_list args;
268 299
269 va_start(args, fmt); 300 va_start(args, fmt);
270 vlogmessage(LOG_DEBUG, fmt, args); 301 vlogmessage(LOG_DEBUG, fmt, args);
271 va_end(args); 302 va_end(args);
272} 303}
273 304
274void 305void
275log_info(const char *fmt, ...) 306log_info(const char *fmt, ...)
276{ 307{
277 va_list args; 308 va_list args;
278 309
279 va_start(args, fmt); 310 va_start(args, fmt);
280 vlogerrmessage(LOG_INFO, fmt, args); 311 vlogerrmessage(LOG_INFO, fmt, args);
281 va_end(args); 312 va_end(args);
282} 313}
283 314
284void 315void
285log_infox(const char *fmt, ...) 316log_infox(const char *fmt, ...)
286{ 317{
287 va_list args; 318 va_list args;
288 319
289 va_start(args, fmt); 320 va_start(args, fmt);
290 vlogmessage(LOG_INFO, fmt, args); 321 vlogmessage(LOG_INFO, fmt, args);
291 va_end(args); 322 va_end(args);
292} 323}
293 324
294void 325void
295log_warn(const char *fmt, ...) 326log_warn(const char *fmt, ...)
296{ 327{
297 va_list args; 328 va_list args;
298 329
299 va_start(args, fmt); 330 va_start(args, fmt);
300 vlogerrmessage(LOG_WARNING, fmt, args); 331 vlogerrmessage(LOG_WARNING, fmt, args);
301 va_end(args); 332 va_end(args);
302} 333}
303 334
304void 335void
305log_warnx(const char *fmt, ...) 336log_warnx(const char *fmt, ...)
306{ 337{
307 va_list args; 338 va_list args;
308 339
309 va_start(args, fmt); 340 va_start(args, fmt);
310 vlogmessage(LOG_WARNING, fmt, args); 341 vlogmessage(LOG_WARNING, fmt, args);
311 va_end(args); 342 va_end(args);
312} 343}
313 344
314void 345void
315log_err(const char *fmt, ...) 346log_err(const char *fmt, ...)
316{ 347{
317 va_list args; 348 va_list args;
318 349
319 va_start(args, fmt); 350 va_start(args, fmt);
320 vlogerrmessage(LOG_ERR, fmt, args); 351 vlogerrmessage(LOG_ERR, fmt, args);
321 va_end(args); 352 va_end(args);
322} 353}
323 354
324void 355void
325log_errx(const char *fmt, ...) 356log_errx(const char *fmt, ...)
326{ 357{
327 va_list args; 358 va_list args;
328 359
329 va_start(args, fmt); 360 va_start(args, fmt);
330 vlogmessage(LOG_ERR, fmt, args); 361 vlogmessage(LOG_ERR, fmt, args);
331 va_end(args); 362 va_end(args);
332} 363}
333 364
 365int
 366loggetfd(void)
 367{
 368 struct logctx *ctx = &_logctx;
 369
 370 return ctx->log_fd;
 371}
 372
 373void
 374logsetfd(int fd)
 375{
 376 struct logctx *ctx = &_logctx;
 377
 378 ctx->log_fd = fd;
 379#ifndef SMALL
 380 if (fd != -1 && ctx->log_file != NULL) {
 381 fclose(ctx->log_file);
 382 ctx->log_file = NULL;
 383 }
 384#endif
 385}
 386
 387int
 388logreadfd(int fd)
 389{
 390 struct logctx *ctx = &_logctx;
 391 char buf[LOGERR_SYSLOGBUF];
 392 int len, pri;
 393
 394 len = (int)read(fd, buf, sizeof(buf));
 395 if (len == -1)
 396 return -1;
 397
 398 /* Ensure we have pri, pid and a terminator */
 399 if (len < (int)(sizeof(pri) + sizeof(pid_t) + 1) ||
 400 buf[len - 1] != '\0')
 401 {
 402 errno = EINVAL;
 403 return -1;
 404 }
 405
 406 memcpy(&pri, buf, sizeof(pri));
 407 memcpy(&ctx->log_pid, buf + sizeof(pri), sizeof(ctx->log_pid));
 408 logmessage(pri, "%s", buf + sizeof(pri) + sizeof(ctx->log_pid));
 409 ctx->log_pid = 0;
 410 return len;
 411}
 412
334unsigned int 413unsigned int
335loggetopts(void) 414loggetopts(void)
336{ 415{
337 struct logctx *ctx = &_logctx; 416 struct logctx *ctx = &_logctx;
338 417
339 return ctx->log_opts; 418 return ctx->log_opts;
340} 419}
341 420
342void 421void
343logsetopts(unsigned int opts) 422logsetopts(unsigned int opts)
344{ 423{
345 struct logctx *ctx = &_logctx; 424 struct logctx *ctx = &_logctx;
346 425
347 ctx->log_opts = opts; 426 ctx->log_opts = opts;
348 setlogmask(LOG_UPTO(opts & LOGERR_DEBUG ? LOG_DEBUG : LOG_INFO)); 427 setlogmask(LOG_UPTO(opts & LOGERR_DEBUG ? LOG_DEBUG : LOG_INFO));
349} 428}
350 429
351#ifdef LOGERR_TAG 430#ifdef LOGERR_TAG
352void 431void
353logsettag(const char *tag) 432logsettag(const char *tag)
354{ 433{
355#if !defined(SMALL) 434#if !defined(SMALL)
356 struct logctx *ctx = &_logctx; 435 struct logctx *ctx = &_logctx;
357 436
358 ctx->log_tag = tag; 437 ctx->log_tag = tag;
359#else 438#else
360 UNUSED(tag); 439 UNUSED(tag);
361#endif 440#endif
362} 441}
363#endif 442#endif
364 443
365int 444int
366logopen(const char *path) 445logopen(const char *path)
367{ 446{
368 struct logctx *ctx = &_logctx; 447 struct logctx *ctx = &_logctx;
369 int opts = 0; 448 int opts = 0;
370 449
371 /* Cache timezone */ 450 /* Cache timezone */
372 tzset(); 451 tzset();
373 452
374 (void)setvbuf(stderr, ctx->log_buf, _IOLBF, sizeof(ctx->log_buf)); 453 (void)setvbuf(stderr, ctx->log_buf, _IOLBF, sizeof(ctx->log_buf));
375 454
376 if (!(ctx->log_opts & LOGERR_LOG)) 455#ifndef SMALL
377 return 1; 456 if (ctx->log_file != NULL) {
378 457 fclose(ctx->log_file);
379#ifdef LOG_NDELAY 458 ctx->log_file = NULL;
380 opts |= LOG_NDELAY; 459 }
381#endif 460#endif
 461
382 if (ctx->log_opts & LOGERR_LOG_PID) 462 if (ctx->log_opts & LOGERR_LOG_PID)
383 opts |= LOG_PID; 463 opts |= LOG_PID;
384 openlog(NULL, opts, LOGERR_SYSLOG_FACILITY); 464 openlog(getprogname(), opts, LOGERR_SYSLOG_FACILITY);
385 if (path == NULL) 465 if (path == NULL)
386 return 1; 466 return 1;
387 467
388#ifndef SMALL 468#ifndef SMALL
389 if ((ctx->log_file = fopen(path, "ae")) == NULL) 469 if ((ctx->log_file = fopen(path, "ae")) == NULL)
390 return -1; 470 return -1;
391 setlinebuf(ctx->log_file); 471 setlinebuf(ctx->log_file);
392 return fileno(ctx->log_file); 472 return fileno(ctx->log_file);
393#else 473#else
394 errno = ENOTSUP; 474 errno = ENOTSUP;
395 return -1; 475 return -1;
396#endif 476#endif
397} 477}
398 478
399void 479void
400logclose(void) 480logclose(void)
401{ 481{
402#ifndef SMALL 482#ifndef SMALL
403 struct logctx *ctx = &_logctx; 483 struct logctx *ctx = &_logctx;
404#endif 484#endif
405 485
406 closelog(); 486 closelog();
407#ifndef SMALL 487#ifndef SMALL
408 if (ctx->log_file == NULL) 488 if (ctx->log_file == NULL)
409 return; 489 return;
410 fclose(ctx->log_file); 490 fclose(ctx->log_file);
411 ctx->log_file = NULL; 491 ctx->log_file = NULL;
412#endif 492#endif
413#if defined(LOGERR_TAG) && defined(__linux__) 493#if defined(__linux__)
414 free(_logprog); 494 free(_logprog);
415#endif 495#endif
416} 496}

cvs diff -r1.9 -r1.10 src/external/bsd/dhcpcd/dist/src/privsep.c (switch to unified diff)

--- src/external/bsd/dhcpcd/dist/src/privsep.c 2020/10/12 14:09:03 1.9
+++ src/external/bsd/dhcpcd/dist/src/privsep.c 2020/11/01 14:24:01 1.10
@@ -1,984 +1,997 @@ @@ -1,984 +1,997 @@
1/* SPDX-License-Identifier: BSD-2-Clause */ 1/* SPDX-License-Identifier: BSD-2-Clause */
2/* 2/*
3 * Privilege Separation for dhcpcd 3 * Privilege Separation for dhcpcd
4 * Copyright (c) 2006-2020 Roy Marples <roy@marples.name> 4 * Copyright (c) 2006-2020 Roy Marples <roy@marples.name>
5 * All rights reserved 5 * All rights reserved
6 6
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29/* 29/*
30 * The current design is this: 30 * The current design is this:
31 * Spawn a priv process to carry out privileged actions and 31 * Spawn a priv process to carry out privileged actions and
32 * spawning unpriv process to initate network connections such as BPF 32 * spawning unpriv process to initate network connections such as BPF
33 * or address specific listener. 33 * or address specific listener.
34 * Spawn an unpriv process to send/receive common network data. 34 * Spawn an unpriv process to send/receive common network data.
35 * Then drop all privs and start running. 35 * Then drop all privs and start running.
36 * Every process aside from the privileged actioneer is chrooted. 36 * Every process aside from the privileged actioneer is chrooted.
37 * All privsep processes ignore signals - only the master process accepts them. 37 * All privsep processes ignore signals - only the master process accepts them.
38 * 38 *
39 * dhcpcd will maintain the config file in the chroot, no need to handle 39 * dhcpcd will maintain the config file in the chroot, no need to handle
40 * this in a script or something. 40 * this in a script or something.
41 */ 41 */
42 42
43#include <sys/resource.h> 43#include <sys/resource.h>
44#include <sys/socket.h> 44#include <sys/socket.h>
45#include <sys/stat.h> 45#include <sys/stat.h>
46#include <sys/types.h> 46#include <sys/types.h>
47#include <sys/wait.h> 47#include <sys/wait.h>
48 48
49#ifdef AF_LINK 49#ifdef AF_LINK
50#include <net/if_dl.h> 50#include <net/if_dl.h>
51#endif 51#endif
52 52
53#include <assert.h> 53#include <assert.h>
54#include <errno.h> 54#include <errno.h>
55#include <fcntl.h> 55#include <fcntl.h>
56#include <grp.h> 56#include <grp.h>
57#include <paths.h> 57#include <paths.h>
58#include <pwd.h> 58#include <pwd.h>
59#include <stddef.h> /* For offsetof, struct padding debug */ 59#include <stddef.h> /* For offsetof, struct padding debug */
60#include <signal.h> 60#include <signal.h>
61#include <stdlib.h> 61#include <stdlib.h>
62#include <string.h> 62#include <string.h>
63#include <unistd.h> 63#include <unistd.h>
64 64
65#include "arp.h" 65#include "arp.h"
66#include "common.h" 66#include "common.h"
67#include "control.h" 67#include "control.h"
68#include "dev.h" 68#include "dev.h"
69#include "dhcp.h" 69#include "dhcp.h"
70#include "dhcp6.h" 70#include "dhcp6.h"
71#include "eloop.h" 71#include "eloop.h"
72#include "ipv6nd.h" 72#include "ipv6nd.h"
73#include "logerr.h" 73#include "logerr.h"
74#include "privsep.h" 74#include "privsep.h"
75 75
76#ifdef HAVE_CAPSICUM 76#ifdef HAVE_CAPSICUM
77#include <sys/capsicum.h> 77#include <sys/capsicum.h>
78#include <capsicum_helpers.h> 78#include <capsicum_helpers.h>
79#endif 79#endif
80#ifdef HAVE_UTIL_H 80#ifdef HAVE_UTIL_H
81#include <util.h> 81#include <util.h>
82#endif 82#endif
83 83
84int 84int
85ps_init(struct dhcpcd_ctx *ctx) 85ps_init(struct dhcpcd_ctx *ctx)
86{ 86{
87 struct passwd *pw; 87 struct passwd *pw;
88 struct stat st; 88 struct stat st;
89 89
90 errno = 0; 90 errno = 0;
91 if ((ctx->ps_user = pw = getpwnam(PRIVSEP_USER)) == NULL) { 91 if ((ctx->ps_user = pw = getpwnam(PRIVSEP_USER)) == NULL) {
92 ctx->options &= ~DHCPCD_PRIVSEP; 92 ctx->options &= ~DHCPCD_PRIVSEP;
93 if (errno == 0) { 93 if (errno == 0) {
94 logerrx("no such user %s", PRIVSEP_USER); 94 logerrx("no such user %s", PRIVSEP_USER);
95 /* Just incase logerrx caused an error... */ 95 /* Just incase logerrx caused an error... */
96 errno = 0; 96 errno = 0;
97 } else 97 } else
98 logerr("getpwnam"); 98 logerr("getpwnam");
99 return -1; 99 return -1;
100 } 100 }
101 101
102 if (stat(pw->pw_dir, &st) == -1 || !S_ISDIR(st.st_mode)) { 102 if (stat(pw->pw_dir, &st) == -1 || !S_ISDIR(st.st_mode)) {
103 ctx->options &= ~DHCPCD_PRIVSEP; 103 ctx->options &= ~DHCPCD_PRIVSEP;
104 logerrx("refusing chroot: %s: %s", 104 logerrx("refusing chroot: %s: %s",
105 PRIVSEP_USER, pw->pw_dir); 105 PRIVSEP_USER, pw->pw_dir);
106 errno = 0; 106 errno = 0;
107 return -1; 107 return -1;
108 } 108 }
109 109
110 ctx->options |= DHCPCD_PRIVSEP; 110 ctx->options |= DHCPCD_PRIVSEP;
111 return 0; 111 return 0;
112} 112}
113 113
114static int 114static int
115ps_dropprivs(struct dhcpcd_ctx *ctx) 115ps_dropprivs(struct dhcpcd_ctx *ctx)
116{ 116{
117 struct passwd *pw = ctx->ps_user; 117 struct passwd *pw = ctx->ps_user;
118 118
119 if (ctx->options & DHCPCD_LAUNCHER) 119 if (ctx->options & DHCPCD_LAUNCHER)
120 logdebugx("chrooting as %s to %s", pw->pw_name, pw->pw_dir); 120 logdebugx("chrooting as %s to %s", pw->pw_name, pw->pw_dir);
121 if (chroot(pw->pw_dir) == -1 && 121 if (chroot(pw->pw_dir) == -1 &&
122 (errno != EPERM || ctx->options & DHCPCD_FORKED)) 122 (errno != EPERM || ctx->options & DHCPCD_FORKED))
123 logerr("%s: chroot: %s", __func__, pw->pw_dir); 123 logerr("%s: chroot: %s", __func__, pw->pw_dir);
124 if (chdir("/") == -1) 124 if (chdir("/") == -1)
125 logerr("%s: chdir: /", __func__); 125 logerr("%s: chdir: /", __func__);
126 126
127 if ((setgroups(1, &pw->pw_gid) == -1 || 127 if ((setgroups(1, &pw->pw_gid) == -1 ||
128 setgid(pw->pw_gid) == -1 || 128 setgid(pw->pw_gid) == -1 ||
129 setuid(pw->pw_uid) == -1) && 129 setuid(pw->pw_uid) == -1) &&
130 (errno != EPERM || ctx->options & DHCPCD_FORKED)) 130 (errno != EPERM || ctx->options & DHCPCD_FORKED))
131 { 131 {
132 logerr("failed to drop privileges"); 132 logerr("failed to drop privileges");
133 return -1; 133 return -1;
134 } 134 }
135 135
136 struct rlimit rzero = { .rlim_cur = 0, .rlim_max = 0 }; 136 struct rlimit rzero = { .rlim_cur = 0, .rlim_max = 0 };
137 137
138 if (ctx->ps_control_pid != getpid()) { 138 if (ctx->ps_control_pid != getpid()) {
139 /* Prohibit new files, sockets, etc */ 139 /* Prohibit new files, sockets, etc */
140#if defined(__linux__) || defined(__sun) || defined(__OpenBSD__) 140#if defined(__linux__) || defined(__sun) || defined(__OpenBSD__)
141 /* 141 /*
142 * If poll(2) is called with nfds > RLIMIT_NOFILE 142 * If poll(2) is called with nfds > RLIMIT_NOFILE
143 * then it returns EINVAL. 143 * then it returns EINVAL.
144 * This blows. 144 * This blows.
145 * Do the best we can and limit to what we need. 145 * Do the best we can and limit to what we need.
146 * An attacker could potentially close a file and 146 * An attacker could potentially close a file and
147 * open a new one still, but that cannot be helped. 147 * open a new one still, but that cannot be helped.
148 */ 148 */
149 unsigned long maxfd; 149 unsigned long maxfd;
150 maxfd = (unsigned long)eloop_event_count(ctx->eloop); 150 maxfd = (unsigned long)eloop_event_count(ctx->eloop);
151 if (IN_PRIVSEP_SE(ctx)) 151 if (IN_PRIVSEP_SE(ctx))
152 maxfd++; /* XXX why? */ 152 maxfd++; /* XXX why? */
153 153
154 struct rlimit rmaxfd = { 154 struct rlimit rmaxfd = {
155 .rlim_cur = maxfd, 155 .rlim_cur = maxfd,
156 .rlim_max = maxfd 156 .rlim_max = maxfd
157 }; 157 };
158 if (setrlimit(RLIMIT_NOFILE, &rmaxfd) == -1) 158 if (setrlimit(RLIMIT_NOFILE, &rmaxfd) == -1)
159 logerr("setrlimit RLIMIT_NOFILE"); 159 logerr("setrlimit RLIMIT_NOFILE");
160#else 160#else
161 if (setrlimit(RLIMIT_NOFILE, &rzero) == -1) 161 if (setrlimit(RLIMIT_NOFILE, &rzero) == -1)
162 logerr("setrlimit RLIMIT_NOFILE"); 162 logerr("setrlimit RLIMIT_NOFILE");
163#endif 163#endif
164 } 164 }
165 165
166 /* Prohibit writing to files. 166 /* Prohibit writing to files.
167 * Obviously this won't work if we are using a logfile 167 * Obviously this won't work if we are using a logfile
168 * or redirecting stderr to a file. */ 168 * or redirecting stderr to a file. */
169 if (ctx->logfile == NULL && 169 if (ctx->logfile == NULL &&
170 (ctx->options & DHCPCD_STARTED || 170 (ctx->options & DHCPCD_STARTED ||
171 !ctx->stderr_valid || isatty(STDERR_FILENO) == 1)) 171 !ctx->stderr_valid || isatty(STDERR_FILENO) == 1))
172 { 172 {
173 if (setrlimit(RLIMIT_FSIZE, &rzero) == -1) 173 if (setrlimit(RLIMIT_FSIZE, &rzero) == -1)
174 logerr("setrlimit RLIMIT_FSIZE"); 174 logerr("setrlimit RLIMIT_FSIZE");
175 } 175 }
176 176
177#ifdef RLIMIT_NPROC 177#ifdef RLIMIT_NPROC
178 /* Prohibit forks */ 178 /* Prohibit forks */
179 if (setrlimit(RLIMIT_NPROC, &rzero) == -1) 179 if (setrlimit(RLIMIT_NPROC, &rzero) == -1)
180 logerr("setrlimit RLIMIT_NPROC"); 180 logerr("setrlimit RLIMIT_NPROC");
181#endif 181#endif
182 182
183 return 0; 183 return 0;
184} 184}
185 185
186static int 186static int
187ps_setbuf0(int fd, int ctl, int minlen) 187ps_setbuf0(int fd, int ctl, int minlen)
188{ 188{
189 int len; 189 int len;
190 socklen_t slen; 190 socklen_t slen;
191 191
192 slen = sizeof(len); 192 slen = sizeof(len);
193 if (getsockopt(fd, SOL_SOCKET, ctl, &len, &slen) == -1) 193 if (getsockopt(fd, SOL_SOCKET, ctl, &len, &slen) == -1)
194 return -1; 194 return -1;
195 195
196#ifdef __linux__ 196#ifdef __linux__
197 len /= 2; 197 len /= 2;
198#endif 198#endif
199 if (len >= minlen) 199 if (len >= minlen)
200 return 0; 200 return 0;
201 201
202 return setsockopt(fd, SOL_SOCKET, ctl, &minlen, sizeof(minlen)); 202 return setsockopt(fd, SOL_SOCKET, ctl, &minlen, sizeof(minlen));
203} 203}
204 204
205static int 205static int
206ps_setbuf(int fd) 206ps_setbuf(int fd)
207{ 207{
208 /* Ensure we can receive a fully sized privsep message. 208 /* Ensure we can receive a fully sized privsep message.
209 * Double the send buffer. */ 209 * Double the send buffer. */
210 int minlen = (int)sizeof(struct ps_msg); 210 int minlen = (int)sizeof(struct ps_msg);
211 211
212 if (ps_setbuf0(fd, SO_RCVBUF, minlen) == -1 || 212 if (ps_setbuf0(fd, SO_RCVBUF, minlen) == -1 ||
213 ps_setbuf0(fd, SO_SNDBUF, minlen * 2) == -1) 213 ps_setbuf0(fd, SO_SNDBUF, minlen * 2) == -1)
214 { 214 {
215 logerr(__func__); 215 logerr(__func__);
216 return -1; 216 return -1;
217 } 217 }
218 return 0; 218 return 0;
219} 219}
220 220
221int 221int
222ps_setbuf_fdpair(int fd[]) 222ps_setbuf_fdpair(int fd[])
223{ 223{
224 224
225 if (ps_setbuf(fd[0]) == -1 || ps_setbuf(fd[1]) == -1) 225 if (ps_setbuf(fd[0]) == -1 || ps_setbuf(fd[1]) == -1)
226 return -1; 226 return -1;
227 return 0; 227 return 0;
228} 228}
229 229
230#ifdef PRIVSEP_RIGHTS 230#ifdef PRIVSEP_RIGHTS
231int 231int
232ps_rights_limit_ioctl(int fd) 232ps_rights_limit_ioctl(int fd)
233{ 233{
234 cap_rights_t rights; 234 cap_rights_t rights;
235 235
236 cap_rights_init(&rights, CAP_IOCTL); 236 cap_rights_init(&rights, CAP_IOCTL);
237 if (cap_rights_limit(fd, &rights) == -1 && errno != ENOSYS) 237 if (cap_rights_limit(fd, &rights) == -1 && errno != ENOSYS)
238 return -1; 238 return -1;
239 return 0; 239 return 0;
240} 240}
241 241
242int 242int
243ps_rights_limit_fd_fctnl(int fd) 243ps_rights_limit_fd_fctnl(int fd)
244{ 244{
245 cap_rights_t rights; 245 cap_rights_t rights;
246 246
247 cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_EVENT, 247 cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_EVENT,
248 CAP_ACCEPT, CAP_FCNTL); 248 CAP_ACCEPT, CAP_FCNTL);
249 if (cap_rights_limit(fd, &rights) == -1 && errno != ENOSYS) 249 if (cap_rights_limit(fd, &rights) == -1 && errno != ENOSYS)
250 return -1; 250 return -1;
251 return 0; 251 return 0;
252} 252}
253 253
254int 254int
255ps_rights_limit_fd(int fd) 255ps_rights_limit_fd(int fd)
256{ 256{
257 cap_rights_t rights; 257 cap_rights_t rights;
258 258
259 cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_EVENT, CAP_SHUTDOWN); 259 cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_EVENT, CAP_SHUTDOWN);
260 if (cap_rights_limit(fd, &rights) == -1 && errno != ENOSYS) 260 if (cap_rights_limit(fd, &rights) == -1 && errno != ENOSYS)
261 return -1; 261 return -1;
262 return 0; 262 return 0;
263} 263}
264 264
265int 265int
266ps_rights_limit_fd_sockopt(int fd) 266ps_rights_limit_fd_sockopt(int fd)
267{ 267{
268 cap_rights_t rights; 268 cap_rights_t rights;
269 269
270 cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_EVENT, 270 cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_EVENT,
271 CAP_GETSOCKOPT, CAP_SETSOCKOPT); 271 CAP_GETSOCKOPT, CAP_SETSOCKOPT);
272 if (cap_rights_limit(fd, &rights) == -1 && errno != ENOSYS) 272 if (cap_rights_limit(fd, &rights) == -1 && errno != ENOSYS)
273 return -1; 273 return -1;
274 return 0; 274 return 0;
275} 275}
276 276
277int 277int
278ps_rights_limit_fd_rdonly(int fd) 278ps_rights_limit_fd_rdonly(int fd)
279{ 279{
280 cap_rights_t rights; 280 cap_rights_t rights;
281 281
282 cap_rights_init(&rights, CAP_READ, CAP_EVENT); 282 cap_rights_init(&rights, CAP_READ, CAP_EVENT);
283 if (cap_rights_limit(fd, &rights) == -1 && errno != ENOSYS) 283 if (cap_rights_limit(fd, &rights) == -1 && errno != ENOSYS)
284 return -1; 284 return -1;
285 return 0; 285 return 0;
286} 286}
287 287
288int 288int
289ps_rights_limit_fdpair(int fd[]) 289ps_rights_limit_fdpair(int fd[])
290{ 290{
291 291
292 if (ps_rights_limit_fd(fd[0]) == -1 || ps_rights_limit_fd(fd[1]) == -1) 292 if (ps_rights_limit_fd(fd[0]) == -1 || ps_rights_limit_fd(fd[1]) == -1)
293 return -1; 293 return -1;
294 return 0; 294 return 0;
295} 295}
296 296
297static int 297static int
298ps_rights_limit_stdio(struct dhcpcd_ctx *ctx) 298ps_rights_limit_stdio(struct dhcpcd_ctx *ctx)
299{ 299{
300 const int iebadf = CAPH_IGNORE_EBADF; 300 const int iebadf = CAPH_IGNORE_EBADF;
301 int error = 0; 301 int error = 0;
302 302
303 if (ctx->stdin_valid && 303 if (ctx->stdin_valid &&
304 caph_limit_stream(STDIN_FILENO, CAPH_READ | iebadf) == -1) 304 caph_limit_stream(STDIN_FILENO, CAPH_READ | iebadf) == -1)
305 error = -1; 305 error = -1;
306 if (ctx->stdout_valid && 306 if (ctx->stdout_valid &&
307 caph_limit_stream(STDOUT_FILENO, CAPH_WRITE | iebadf) == -1) 307 caph_limit_stream(STDOUT_FILENO, CAPH_WRITE | iebadf) == -1)
308 error = -1; 308 error = -1;
309 if (ctx->stderr_valid && 309 if (ctx->stderr_valid &&
310 caph_limit_stream(STDERR_FILENO, CAPH_WRITE | iebadf) == -1) 310 caph_limit_stream(STDERR_FILENO, CAPH_WRITE | iebadf) == -1)
311 error = -1; 311 error = -1;
312 312
313 return error; 313 return error;
314} 314}
315#endif 315#endif
316 316
317pid_t 317pid_t
318ps_dostart(struct dhcpcd_ctx *ctx, 318ps_dostart(struct dhcpcd_ctx *ctx,
319 pid_t *priv_pid, int *priv_fd, 319 pid_t *priv_pid, int *priv_fd,
320 void (*recv_msg)(void *), void (*recv_unpriv_msg), 320 void (*recv_msg)(void *), void (*recv_unpriv_msg),
321 void *recv_ctx, int (*callback)(void *), void (*signal_cb)(int, void *), 321 void *recv_ctx, int (*callback)(void *), void (*signal_cb)(int, void *),
322 unsigned int flags) 322 unsigned int flags)
323{ 323{
324 int fd[2]; 324 int fd[2];
325 pid_t pid; 325 pid_t pid;
326 326
327 if (xsocketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, fd) == -1) { 327 if (xsocketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, fd) == -1) {
328 logerr("%s: socketpair", __func__); 328 logerr("%s: socketpair", __func__);
329 return -1; 329 return -1;
330 } 330 }
331 if (ps_setbuf_fdpair(fd) == -1) { 331 if (ps_setbuf_fdpair(fd) == -1) {
332 logerr("%s: ps_setbuf_fdpair", __func__); 332 logerr("%s: ps_setbuf_fdpair", __func__);
333 return -1; 333 return -1;
334 } 334 }
335#ifdef PRIVSEP_RIGHTS 335#ifdef PRIVSEP_RIGHTS
336 if (ps_rights_limit_fdpair(fd) == -1) { 336 if (ps_rights_limit_fdpair(fd) == -1) {
337 logerr("%s: ps_rights_limit_fdpair", __func__); 337 logerr("%s: ps_rights_limit_fdpair", __func__);
338 return -1; 338 return -1;
339 } 339 }
340#endif 340#endif
341 341
342 switch (pid = fork()) { 342 switch (pid = fork()) {
343 case -1: 343 case -1:
344 logerr("fork"); 344 logerr("fork");
345 return -1; 345 return -1;
346 case 0: 346 case 0:
347 *priv_fd = fd[1]; 347 *priv_fd = fd[1];
348 close(fd[0]); 348 close(fd[0]);
349 break; 349 break;
350 default: 350 default:
351 *priv_pid = pid; 351 *priv_pid = pid;
352 *priv_fd = fd[0]; 352 *priv_fd = fd[0];
353 close(fd[1]); 353 close(fd[1]);
354 if (recv_unpriv_msg == NULL) 354 if (recv_unpriv_msg == NULL)
355 ; 355 ;
356 else if (eloop_event_add(ctx->eloop, *priv_fd, 356 else if (eloop_event_add(ctx->eloop, *priv_fd,
357 recv_unpriv_msg, recv_ctx) == -1) 357 recv_unpriv_msg, recv_ctx) == -1)
358 { 358 {
359 logerr("%s: eloop_event_add", __func__); 359 logerr("%s: eloop_event_add", __func__);
360 return -1; 360 return -1;
361 } 361 }
362 return pid; 362 return pid;
363 } 363 }
364 364
365 ctx->options |= DHCPCD_UNPRIV | DHCPCD_FORKED; 365 ctx->options |= DHCPCD_UNPRIV | DHCPCD_FORKED;
366 if (ctx->fork_fd != -1) { 366 if (ctx->fork_fd != -1) {
367 close(ctx->fork_fd); 367 close(ctx->fork_fd);
368 ctx->fork_fd = -1; 368 ctx->fork_fd = -1;
369 } 369 }
370 pidfile_clean(); 370 pidfile_clean();
371 eloop_clear(ctx->eloop); 371 eloop_clear(ctx->eloop);
372 372
373 /* We are not root */ 373 /* We are not root */
374 if (priv_fd != &ctx->ps_root_fd) { 374 if (priv_fd != &ctx->ps_root_fd) {
375 ps_freeprocesses(ctx, recv_ctx); 375 ps_freeprocesses(ctx, recv_ctx);
376 if (ctx->ps_root_fd != -1) { 376 if (ctx->ps_root_fd != -1) {
377 close(ctx->ps_root_fd); 377 close(ctx->ps_root_fd);
378 ctx->ps_root_fd = -1; 378 ctx->ps_root_fd = -1;
379 } 379 }
380 380
381#ifdef PRIVSEP_RIGHTS 381#ifdef PRIVSEP_RIGHTS
382 /* We cannot limit the root process in any way. */ 382 /* We cannot limit the root process in any way. */
383 if (ps_rights_limit_stdio(ctx) == -1) { 383 if (ps_rights_limit_stdio(ctx) == -1) {
384 logerr("ps_rights_limit_stdio"); 384 logerr("ps_rights_limit_stdio");
385 goto errexit; 385 goto errexit;
386 } 386 }
387#endif 387#endif
388 } 388 }
389 389
390 if (priv_fd != &ctx->ps_inet_fd && ctx->ps_inet_fd != -1) { 390 if (priv_fd != &ctx->ps_inet_fd && ctx->ps_inet_fd != -1) {
391 close(ctx->ps_inet_fd); 391 close(ctx->ps_inet_fd);
392 ctx->ps_inet_fd = -1; 392 ctx->ps_inet_fd = -1;
393 } 393 }
394 394
395 eloop_signal_set_cb(ctx->eloop, 395 eloop_signal_set_cb(ctx->eloop,
396 dhcpcd_signals, dhcpcd_signals_len, signal_cb, ctx); 396 dhcpcd_signals, dhcpcd_signals_len, signal_cb, ctx);
397 397
398 /* ctx->sigset aready has the initial sigmask set in main() */ 398 /* ctx->sigset aready has the initial sigmask set in main() */
399 if (eloop_signal_mask(ctx->eloop, NULL) == -1) { 399 if (eloop_signal_mask(ctx->eloop, NULL) == -1) {
400 logerr("%s: eloop_signal_mask", __func__); 400 logerr("%s: eloop_signal_mask", __func__);
401 goto errexit; 401 goto errexit;
402 } 402 }
403 403
404 if (eloop_event_add(ctx->eloop, *priv_fd, recv_msg, recv_ctx) == -1) 404 if (eloop_event_add(ctx->eloop, *priv_fd, recv_msg, recv_ctx) == -1)
405 { 405 {
406 logerr("%s: eloop_event_add", __func__); 406 logerr("%s: eloop_event_add", __func__);
407 goto errexit; 407 goto errexit;
408 } 408 }
409 409
410 if (callback(recv_ctx) == -1) 410 if (callback(recv_ctx) == -1)
411 goto errexit; 411 goto errexit;
412 412
413 if (flags & PSF_DROPPRIVS) 413 if (flags & PSF_DROPPRIVS)
414 ps_dropprivs(ctx); 414 ps_dropprivs(ctx);
415 415
416 return 0; 416 return 0;
417 417
418errexit: 418errexit:
419 /* Failure to start root or inet processes is fatal. */ 419 /* Failure to start root or inet processes is fatal. */
420 if (priv_fd == &ctx->ps_root_fd || priv_fd == &ctx->ps_inet_fd) 420 if (priv_fd == &ctx->ps_root_fd || priv_fd == &ctx->ps_inet_fd)
421 (void)ps_sendcmd(ctx, *priv_fd, PS_STOP, 0, NULL, 0); 421 (void)ps_sendcmd(ctx, *priv_fd, PS_STOP, 0, NULL, 0);
422 shutdown(*priv_fd, SHUT_RDWR); 422 shutdown(*priv_fd, SHUT_RDWR);
423 *priv_fd = -1; 423 *priv_fd = -1;
424 eloop_exit(ctx->eloop, EXIT_FAILURE); 424 eloop_exit(ctx->eloop, EXIT_FAILURE);
425 return -1; 425 return -1;
426} 426}
427 427
428int 428int
429ps_dostop(struct dhcpcd_ctx *ctx, pid_t *pid, int *fd) 429ps_dostop(struct dhcpcd_ctx *ctx, pid_t *pid, int *fd)
430{ 430{
431 int err = 0; 431 int err = 0;
432 432
433#ifdef PRIVSEP_DEBUG 433#ifdef PRIVSEP_DEBUG
434 logdebugx("%s: pid=%d fd=%d", __func__, *pid, *fd); 434 logdebugx("%s: pid=%d fd=%d", __func__, *pid, *fd);
435#endif 435#endif
436 436
437 if (*fd != -1) { 437 if (*fd != -1) {
438 eloop_event_delete(ctx->eloop, *fd); 438 eloop_event_delete(ctx->eloop, *fd);
439 if (ps_sendcmd(ctx, *fd, PS_STOP, 0, NULL, 0) == -1) { 439 if (ps_sendcmd(ctx, *fd, PS_STOP, 0, NULL, 0) == -1) {
440 logerr(__func__); 440 logerr(__func__);
441 err = -1; 441 err = -1;
442 } 442 }
443 (void)shutdown(*fd, SHUT_RDWR); 443 (void)shutdown(*fd, SHUT_RDWR);
444 close(*fd); 444 close(*fd);
445 *fd = -1; 445 *fd = -1;
446 } 446 }
447 447
448 /* Don't wait for the process as it may not respond to the shutdown 448 /* Don't wait for the process as it may not respond to the shutdown
449 * request. We'll reap the process on receipt of SIGCHLD. */ 449 * request. We'll reap the process on receipt of SIGCHLD. */
450 *pid = 0; 450 *pid = 0;
451 return err; 451 return err;
452} 452}
453 453
454int 454int
455ps_start(struct dhcpcd_ctx *ctx) 455ps_start(struct dhcpcd_ctx *ctx)
456{ 456{
457 pid_t pid; 457 pid_t pid;
458 458
459 TAILQ_INIT(&ctx->ps_processes); 459 TAILQ_INIT(&ctx->ps_processes);
460 460
461 switch (pid = ps_root_start(ctx)) { 461 switch (pid = ps_root_start(ctx)) {
462 case -1: 462 case -1:
463 logerr("ps_root_start"); 463 logerr("ps_root_start");
464 return -1; 464 return -1;
465 case 0: 465 case 0:
466 return 0; 466 return 0;
467 default: 467 default:
468 logdebugx("spawned privileged actioneer on PID %d", pid); 468 logdebugx("spawned privileged actioneer on PID %d", pid);
469 } 469 }
470 470
471 /* No point in spawning the generic network listener if we're 471 /* No point in spawning the generic network listener if we're
472 * not going to use it. */ 472 * not going to use it. */
473 if (!ps_inet_canstart(ctx)) 473 if (!ps_inet_canstart(ctx))
474 goto started_net; 474 goto started_net;
475 475
476 switch (pid = ps_inet_start(ctx)) { 476 switch (pid = ps_inet_start(ctx)) {
477 case -1: 477 case -1:
478 return -1; 478 return -1;
479 case 0: 479 case 0:
480 return 0; 480 return 0;
481 default: 481 default:
482 logdebugx("spawned network proxy on PID %d", pid); 482 logdebugx("spawned network proxy on PID %d", pid);
483 } 483 }
484 484
485started_net: 485started_net:
486 if (!(ctx->options & DHCPCD_TEST)) { 486 if (!(ctx->options & DHCPCD_TEST)) {
487 switch (pid = ps_ctl_start(ctx)) { 487 switch (pid = ps_ctl_start(ctx)) {
488 case -1: 488 case -1:
489 return -1; 489 return -1;
490 case 0: 490 case 0:
491 return 0; 491 return 0;
492 default: 492 default:
493 logdebugx("spawned controller proxy on PID %d", pid); 493 logdebugx("spawned controller proxy on PID %d", pid);
494 } 494 }
495 } 495 }
496 496
497#ifdef ARC4RANDOM_H 497#ifdef ARC4RANDOM_H
498 /* Seed the random number generator early incase it needs /dev/urandom 498 /* Seed the random number generator early incase it needs /dev/urandom
499 * which won't be available in the chroot. */ 499 * which won't be available in the chroot. */
500 arc4random(); 500 arc4random();
501#endif 501#endif
502 502
503 return 1; 503 return 1;
504} 504}
505 505
506int 506int
507ps_entersandbox(const char *_pledge, const char **sandbox) 507ps_entersandbox(const char *_pledge, const char **sandbox)
508{ 508{
509 509
510#if !defined(HAVE_PLEDGE) 510#if !defined(HAVE_PLEDGE)
511 UNUSED(_pledge); 511 UNUSED(_pledge);
512#endif 512#endif
513 513
514#if defined(HAVE_CAPSICUM) 514#if defined(HAVE_CAPSICUM)
515 if (sandbox != NULL) 515 if (sandbox != NULL)
516 *sandbox = "capsicum"; 516 *sandbox = "capsicum";
517 return cap_enter(); 517 return cap_enter();
518#elif defined(HAVE_PLEDGE) 518#elif defined(HAVE_PLEDGE)
519 if (sandbox != NULL) 519 if (sandbox != NULL)
520 *sandbox = "pledge"; 520 *sandbox = "pledge";
521 return pledge(_pledge, NULL); 521 return pledge(_pledge, NULL);
522#elif defined(HAVE_SECCOMP) 522#elif defined(HAVE_SECCOMP)
523 if (sandbox != NULL) 523 if (sandbox != NULL)
524 *sandbox = "seccomp"; 524 *sandbox = "seccomp";
525 return ps_seccomp_enter(); 525 return ps_seccomp_enter();
526#else 526#else
527 if (sandbox != NULL) 527 if (sandbox != NULL)
528 *sandbox = "posix resource limited"; 528 *sandbox = "posix resource limited";
529 return 0; 529 return 0;
530#endif 530#endif
531} 531}
532 532
533int 533int
534ps_mastersandbox(struct dhcpcd_ctx *ctx, const char *_pledge) 534ps_mastersandbox(struct dhcpcd_ctx *ctx, const char *_pledge)
535{ 535{
536 const char *sandbox = NULL; 536 const char *sandbox = NULL;
537 bool forked; 537 bool forked;
538 int dropped; 538 int dropped;
539 539
540 forked = ctx->options & DHCPCD_FORKED; 540 forked = ctx->options & DHCPCD_FORKED;
541 ctx->options &= ~DHCPCD_FORKED; 541 ctx->options &= ~DHCPCD_FORKED;
542 dropped = ps_dropprivs(ctx); 542 dropped = ps_dropprivs(ctx);
543 if (forked) 543 if (forked)
544 ctx->options |= DHCPCD_FORKED; 544 ctx->options |= DHCPCD_FORKED;
 545
 546 /*
 547 * If we don't have a root process, we cannot use syslog.
 548 * If it cannot be opened before chrooting then syslog(3) will fail.
 549 * openlog(3) does not return an error which doubly sucks.
 550 */
 551 if (ctx->ps_root_fd == -1) {
 552 unsigned int logopts = loggetopts();
 553
 554 logopts &= ~LOGERR_LOG;
 555 logsetopts(logopts);
 556 }
 557
545 if (dropped == -1) { 558 if (dropped == -1) {
546 logerr("%s: ps_dropprivs", __func__); 559 logerr("%s: ps_dropprivs", __func__);
547 return -1; 560 return -1;
548 } 561 }
549 562
550#ifdef PRIVSEP_RIGHTS 563#ifdef PRIVSEP_RIGHTS
551 if ((ctx->pf_inet_fd != -1 && 564 if ((ctx->pf_inet_fd != -1 &&
552 ps_rights_limit_ioctl(ctx->pf_inet_fd) == -1) || 565 ps_rights_limit_ioctl(ctx->pf_inet_fd) == -1) ||
553 ps_rights_limit_stdio(ctx) == -1) 566 ps_rights_limit_stdio(ctx) == -1)
554 { 567 {
555 logerr("%s: cap_rights_limit", __func__); 568 logerr("%s: cap_rights_limit", __func__);
556 return -1; 569 return -1;
557 } 570 }
558#endif 571#endif
559 572
560 if (_pledge == NULL) 573 if (_pledge == NULL)
561 _pledge = "stdio"; 574 _pledge = "stdio";
562 if (ps_entersandbox(_pledge, &sandbox) == -1) { 575 if (ps_entersandbox(_pledge, &sandbox) == -1) {
563 if (errno == ENOSYS) { 576 if (errno == ENOSYS) {
564 if (sandbox != NULL) 577 if (sandbox != NULL)
565 logwarnx("sandbox unavailable: %s", sandbox); 578 logwarnx("sandbox unavailable: %s", sandbox);
566 return 0; 579 return 0;
567 } 580 }
568 logerr("%s: %s", __func__, sandbox); 581 logerr("%s: %s", __func__, sandbox);
569 return -1; 582 return -1;
570 } else if (ctx->options & DHCPCD_LAUNCHER) 583 } else if (ctx->options & DHCPCD_LAUNCHER)
571 logdebugx("sandbox: %s", sandbox); 584 logdebugx("sandbox: %s", sandbox);
572 return 0; 585 return 0;
573} 586}
574 587
575int 588int
576ps_stop(struct dhcpcd_ctx *ctx) 589ps_stop(struct dhcpcd_ctx *ctx)
577{ 590{
578 int r, ret = 0; 591 int r, ret = 0;
579 592
580 if (!(ctx->options & DHCPCD_PRIVSEP) || 593 if (!(ctx->options & DHCPCD_PRIVSEP) ||
581 ctx->options & DHCPCD_FORKED || 594 ctx->options & DHCPCD_FORKED ||
582 ctx->eloop == NULL) 595 ctx->eloop == NULL)
583 return 0; 596 return 0;
584 597
585 r = ps_ctl_stop(ctx); 598 r = ps_ctl_stop(ctx);
586 if (r != 0) 599 if (r != 0)
587 ret = r; 600 ret = r;
588 601
589 r = ps_inet_stop(ctx); 602 r = ps_inet_stop(ctx);
590 if (r != 0) 603 if (r != 0)
591 ret = r; 604 ret = r;
592 605
593 /* We've been chrooted, so we need to tell the 606 /* We've been chrooted, so we need to tell the
594 * privileged actioneer to remove the pidfile. */ 607 * privileged actioneer to remove the pidfile. */
595 ps_root_unlink(ctx, ctx->pidfile); 608 ps_root_unlink(ctx, ctx->pidfile);
596 609
597 r = ps_root_stop(ctx); 610 r = ps_root_stop(ctx);
598 if (r != 0) 611 if (r != 0)
599 ret = r; 612 ret = r;
600 613
601 ctx->options &= ~DHCPCD_PRIVSEP; 614 ctx->options &= ~DHCPCD_PRIVSEP;
602 return ret; 615 return ret;
603} 616}
604 617
605void 618void
606ps_freeprocess(struct ps_process *psp) 619ps_freeprocess(struct ps_process *psp)
607{ 620{
608 621
609 TAILQ_REMOVE(&psp->psp_ctx->ps_processes, psp, next); 622 TAILQ_REMOVE(&psp->psp_ctx->ps_processes, psp, next);
610 if (psp->psp_fd != -1) { 623 if (psp->psp_fd != -1) {
611 eloop_event_delete(psp->psp_ctx->eloop, psp->psp_fd); 624 eloop_event_delete(psp->psp_ctx->eloop, psp->psp_fd);
612 close(psp->psp_fd); 625 close(psp->psp_fd);
613 } 626 }
614 if (psp->psp_work_fd != -1) { 627 if (psp->psp_work_fd != -1) {
615 eloop_event_delete(psp->psp_ctx->eloop, psp->psp_work_fd); 628 eloop_event_delete(psp->psp_ctx->eloop, psp->psp_work_fd);
616 close(psp->psp_work_fd); 629 close(psp->psp_work_fd);
617 } 630 }
618#ifdef INET 631#ifdef INET
619 if (psp->psp_bpf != NULL) 632 if (psp->psp_bpf != NULL)
620 bpf_close(psp->psp_bpf); 633 bpf_close(psp->psp_bpf);
621#endif 634#endif
622 free(psp); 635 free(psp);
623} 636}
624 637
625static void 638static void
626ps_free(struct dhcpcd_ctx *ctx) 639ps_free(struct dhcpcd_ctx *ctx)
627{ 640{
628 struct ps_process *psp; 641 struct ps_process *psp;
629 bool stop = ctx->ps_root_pid == getpid(); 642 bool stop = ctx->ps_root_pid == getpid();
630 643
631 while ((psp = TAILQ_FIRST(&ctx->ps_processes)) != NULL) { 644 while ((psp = TAILQ_FIRST(&ctx->ps_processes)) != NULL) {
632 if (stop) 645 if (stop)
633 ps_dostop(ctx, &psp->psp_pid, &psp->psp_fd); 646 ps_dostop(ctx, &psp->psp_pid, &psp->psp_fd);
634 ps_freeprocess(psp); 647 ps_freeprocess(psp);
635 } 648 }
636} 649}
637 650
638int 651int
639ps_unrollmsg(struct msghdr *msg, struct ps_msghdr *psm, 652ps_unrollmsg(struct msghdr *msg, struct ps_msghdr *psm,
640 const void *data, size_t len) 653 const void *data, size_t len)
641{ 654{
642 uint8_t *datap, *namep, *controlp; 655 uint8_t *datap, *namep, *controlp;
643 656
644 namep = UNCONST(data); 657 namep = UNCONST(data);
645 controlp = namep + psm->ps_namelen; 658 controlp = namep + psm->ps_namelen;
646 datap = controlp + psm->ps_controllen; 659 datap = controlp + psm->ps_controllen;
647 660
648 if (psm->ps_namelen != 0) { 661 if (psm->ps_namelen != 0) {
649 if (psm->ps_namelen > len) { 662 if (psm->ps_namelen > len) {
650 errno = EINVAL; 663 errno = EINVAL;
651 return -1; 664 return -1;
652 } 665 }
653 msg->msg_name = namep; 666 msg->msg_name = namep;
654 len -= psm->ps_namelen; 667 len -= psm->ps_namelen;
655 } else 668 } else
656 msg->msg_name = NULL; 669 msg->msg_name = NULL;
657 msg->msg_namelen = psm->ps_namelen; 670 msg->msg_namelen = psm->ps_namelen;
658 671
659 if (psm->ps_controllen != 0) { 672 if (psm->ps_controllen != 0) {
660 if (psm->ps_controllen > len) { 673 if (psm->ps_controllen > len) {
661 errno = EINVAL; 674 errno = EINVAL;
662 return -1; 675 return -1;
663 } 676 }
664 msg->msg_control = controlp; 677 msg->msg_control = controlp;
665 len -= psm->ps_controllen; 678 len -= psm->ps_controllen;
666 } else 679 } else
667 msg->msg_control = NULL; 680 msg->msg_control = NULL;
668 msg->msg_controllen = psm->ps_controllen; 681 msg->msg_controllen = psm->ps_controllen;
669 682
670 if (len != 0) { 683 if (len != 0) {
671 msg->msg_iovlen = 1; 684 msg->msg_iovlen = 1;
672 msg->msg_iov[0].iov_base = datap; 685 msg->msg_iov[0].iov_base = datap;
673 msg->msg_iov[0].iov_len = len; 686 msg->msg_iov[0].iov_len = len;
674 } else { 687 } else {
675 msg->msg_iovlen = 0; 688 msg->msg_iovlen = 0;
676 msg->msg_iov[0].iov_base = NULL; 689 msg->msg_iov[0].iov_base = NULL;
677 msg->msg_iov[0].iov_len = 0; 690 msg->msg_iov[0].iov_len = 0;
678 } 691 }
679 return 0; 692 return 0;
680} 693}
681 694
682ssize_t 695ssize_t
683ps_sendpsmmsg(struct dhcpcd_ctx *ctx, int fd, 696ps_sendpsmmsg(struct dhcpcd_ctx *ctx, int fd,
684 struct ps_msghdr *psm, const struct msghdr *msg) 697 struct ps_msghdr *psm, const struct msghdr *msg)
685{ 698{
686 struct iovec iov[] = { 699 struct iovec iov[] = {
687 { .iov_base = UNCONST(psm), .iov_len = sizeof(*psm) }, 700 { .iov_base = UNCONST(psm), .iov_len = sizeof(*psm) },
688 { .iov_base = NULL, }, /* name */ 701 { .iov_base = NULL, }, /* name */
689 { .iov_base = NULL, }, /* control */ 702 { .iov_base = NULL, }, /* control */
690 { .iov_base = NULL, }, /* payload 1 */ 703 { .iov_base = NULL, }, /* payload 1 */
691 { .iov_base = NULL, }, /* payload 2 */ 704 { .iov_base = NULL, }, /* payload 2 */
692 { .iov_base = NULL, }, /* payload 3 */ 705 { .iov_base = NULL, }, /* payload 3 */
693 }; 706 };
694 int iovlen; 707 int iovlen;
695 ssize_t len; 708 ssize_t len;
696 709
697 if (msg != NULL) { 710 if (msg != NULL) {
698 struct iovec *iovp = &iov[1]; 711 struct iovec *iovp = &iov[1];
699 int i; 712 int i;
700 713
701 psm->ps_namelen = msg->msg_namelen; 714 psm->ps_namelen = msg->msg_namelen;
702 psm->ps_controllen = (socklen_t)msg->msg_controllen; 715 psm->ps_controllen = (socklen_t)msg->msg_controllen;
703 716
704 iovp->iov_base = msg->msg_name; 717 iovp->iov_base = msg->msg_name;
705 iovp->iov_len = msg->msg_namelen; 718 iovp->iov_len = msg->msg_namelen;
706 iovp++; 719 iovp++;
707 iovp->iov_base = msg->msg_control; 720 iovp->iov_base = msg->msg_control;
708 iovp->iov_len = msg->msg_controllen; 721 iovp->iov_len = msg->msg_controllen;
709 iovlen = 3; 722 iovlen = 3;
710 723
711 for (i = 0; i < (int)msg->msg_iovlen; i++) { 724 for (i = 0; i < (int)msg->msg_iovlen; i++) {
712 if ((size_t)(iovlen + i) > __arraycount(iov)) { 725 if ((size_t)(iovlen + i) > __arraycount(iov)) {
713 errno = ENOBUFS; 726 errno = ENOBUFS;
714 return -1; 727 return -1;
715 } 728 }
716 iovp++; 729 iovp++;
717 iovp->iov_base = msg->msg_iov[i].iov_base; 730 iovp->iov_base = msg->msg_iov[i].iov_base;
718 iovp->iov_len = msg->msg_iov[i].iov_len; 731 iovp->iov_len = msg->msg_iov[i].iov_len;
719 } 732 }
720 iovlen += i; 733 iovlen += i;
721 } else 734 } else
722 iovlen = 1; 735 iovlen = 1;
723 736
724 len = writev(fd, iov, iovlen); 737 len = writev(fd, iov, iovlen);
725 if (len == -1) { 738 if (len == -1) {
726 logerr(__func__); 739 logerr(__func__);
727 if (ctx->options & DHCPCD_FORKED && 740 if (ctx->options & DHCPCD_FORKED &&
728 !(ctx->options & DHCPCD_PRIVSEPROOT)) 741 !(ctx->options & DHCPCD_PRIVSEPROOT))
729 eloop_exit(ctx->eloop, EXIT_FAILURE); 742 eloop_exit(ctx->eloop, EXIT_FAILURE);
730 } 743 }
731 return len; 744 return len;
732} 745}
733 746
734ssize_t 747ssize_t
735ps_sendpsmdata(struct dhcpcd_ctx *ctx, int fd, 748ps_sendpsmdata(struct dhcpcd_ctx *ctx, int fd,
736 struct ps_msghdr *psm, const void *data, size_t len) 749 struct ps_msghdr *psm, const void *data, size_t len)
737{ 750{
738 struct iovec iov[] = { 751 struct iovec iov[] = {
739 { .iov_base = UNCONST(data), .iov_len = len }, 752 { .iov_base = UNCONST(data), .iov_len = len },
740 }; 753 };
741 struct msghdr msg = { 754 struct msghdr msg = {
742 .msg_iov = iov, .msg_iovlen = 1, 755 .msg_iov = iov, .msg_iovlen = 1,
743 }; 756 };
744 757
745 return ps_sendpsmmsg(ctx, fd, psm, &msg); 758 return ps_sendpsmmsg(ctx, fd, psm, &msg);
746} 759}
747 760
748 761
749ssize_t 762ssize_t
750ps_sendmsg(struct dhcpcd_ctx *ctx, int fd, uint16_t cmd, unsigned long flags, 763ps_sendmsg(struct dhcpcd_ctx *ctx, int fd, uint16_t cmd, unsigned long flags,
751 const struct msghdr *msg) 764 const struct msghdr *msg)
752{ 765{
753 struct ps_msghdr psm = { 766 struct ps_msghdr psm = {
754 .ps_cmd = cmd, 767 .ps_cmd = cmd,
755 .ps_flags = flags, 768 .ps_flags = flags,
756 .ps_namelen = msg->msg_namelen, 769 .ps_namelen = msg->msg_namelen,
757 .ps_controllen = (socklen_t)msg->msg_controllen, 770 .ps_controllen = (socklen_t)msg->msg_controllen,
758 }; 771 };
759 size_t i; 772 size_t i;
760 773
761 for (i = 0; i < (size_t)msg->msg_iovlen; i++) 774 for (i = 0; i < (size_t)msg->msg_iovlen; i++)
762 psm.ps_datalen += msg->msg_iov[i].iov_len; 775 psm.ps_datalen += msg->msg_iov[i].iov_len;
763 776
764#if 0 /* For debugging structure padding. */ 777#if 0 /* For debugging structure padding. */
765 logerrx("psa.family %lu %zu", offsetof(struct ps_addr, psa_family), sizeof(psm.ps_id.psi_addr.psa_family)); 778 logerrx("psa.family %lu %zu", offsetof(struct ps_addr, psa_family), sizeof(psm.ps_id.psi_addr.psa_family));
766 logerrx("psa.pad %lu %zu", offsetof(struct ps_addr, psa_pad), sizeof(psm.ps_id.psi_addr.psa_pad)); 779 logerrx("psa.pad %lu %zu", offsetof(struct ps_addr, psa_pad), sizeof(psm.ps_id.psi_addr.psa_pad));
767 logerrx("psa.psa_u %lu %zu", offsetof(struct ps_addr, psa_u), sizeof(psm.ps_id.psi_addr.psa_u)); 780 logerrx("psa.psa_u %lu %zu", offsetof(struct ps_addr, psa_u), sizeof(psm.ps_id.psi_addr.psa_u));
768 logerrx("psa %zu", sizeof(psm.ps_id.psi_addr)); 781 logerrx("psa %zu", sizeof(psm.ps_id.psi_addr));
769 782
770 logerrx("psi.addr %lu %zu", offsetof(struct ps_id, psi_addr), sizeof(psm.ps_id.psi_addr)); 783 logerrx("psi.addr %lu %zu", offsetof(struct ps_id, psi_addr), sizeof(psm.ps_id.psi_addr));
771 logerrx("psi.index %lu %zu", offsetof(struct ps_id, psi_ifindex), sizeof(psm.ps_id.psi_ifindex)); 784 logerrx("psi.index %lu %zu", offsetof(struct ps_id, psi_ifindex), sizeof(psm.ps_id.psi_ifindex));
772 logerrx("psi.cmd %lu %zu", offsetof(struct ps_id, psi_cmd), sizeof(psm.ps_id.psi_cmd)); 785 logerrx("psi.cmd %lu %zu", offsetof(struct ps_id, psi_cmd), sizeof(psm.ps_id.psi_cmd));
773 logerrx("psi.pad %lu %zu", offsetof(struct ps_id, psi_pad), sizeof(psm.ps_id.psi_pad)); 786 logerrx("psi.pad %lu %zu", offsetof(struct ps_id, psi_pad), sizeof(psm.ps_id.psi_pad));
774 logerrx("psi %zu", sizeof(struct ps_id)); 787 logerrx("psi %zu", sizeof(struct ps_id));
775 788
776 logerrx("ps_cmd %lu", offsetof(struct ps_msghdr, ps_cmd)); 789 logerrx("ps_cmd %lu", offsetof(struct ps_msghdr, ps_cmd));
777 logerrx("ps_pad %lu %zu", offsetof(struct ps_msghdr, ps_pad), sizeof(psm.ps_pad)); 790 logerrx("ps_pad %lu %zu", offsetof(struct ps_msghdr, ps_pad), sizeof(psm.ps_pad));
778 logerrx("ps_flags %lu %zu", offsetof(struct ps_msghdr, ps_flags), sizeof(psm.ps_flags)); 791 logerrx("ps_flags %lu %zu", offsetof(struct ps_msghdr, ps_flags), sizeof(psm.ps_flags));
779 792
780 logerrx("ps_id %lu %zu", offsetof(struct ps_msghdr, ps_id), sizeof(psm.ps_id)); 793 logerrx("ps_id %lu %zu", offsetof(struct ps_msghdr, ps_id), sizeof(psm.ps_id));
781 794
782 logerrx("ps_namelen %lu %zu", offsetof(struct ps_msghdr, ps_namelen), sizeof(psm.ps_namelen)); 795 logerrx("ps_namelen %lu %zu", offsetof(struct ps_msghdr, ps_namelen), sizeof(psm.ps_namelen));
783 logerrx("ps_controllen %lu %zu", offsetof(struct ps_msghdr, ps_controllen), sizeof(psm.ps_controllen)); 796 logerrx("ps_controllen %lu %zu", offsetof(struct ps_msghdr, ps_controllen), sizeof(psm.ps_controllen));
784 logerrx("ps_pad2 %lu %zu", offsetof(struct ps_msghdr, ps_pad2), sizeof(psm.ps_pad2)); 797 logerrx("ps_pad2 %lu %zu", offsetof(struct ps_msghdr, ps_pad2), sizeof(psm.ps_pad2));
785 logerrx("ps_datalen %lu %zu", offsetof(struct ps_msghdr, ps_datalen), sizeof(psm.ps_datalen)); 798 logerrx("ps_datalen %lu %zu", offsetof(struct ps_msghdr, ps_datalen), sizeof(psm.ps_datalen));
786 logerrx("psm %zu", sizeof(psm)); 799 logerrx("psm %zu", sizeof(psm));
787#endif 800#endif
788 801
789 return ps_sendpsmmsg(ctx, fd, &psm, msg); 802 return ps_sendpsmmsg(ctx, fd, &psm, msg);
790} 803}
791 804
792ssize_t 805ssize_t
793ps_sendcmd(struct dhcpcd_ctx *ctx, int fd, uint16_t cmd, unsigned long flags, 806ps_sendcmd(struct dhcpcd_ctx *ctx, int fd, uint16_t cmd, unsigned long flags,
794 const void *data, size_t len) 807 const void *data, size_t len)
795{ 808{
796 struct ps_msghdr psm = { 809 struct ps_msghdr psm = {
797 .ps_cmd = cmd, 810 .ps_cmd = cmd,
798 .ps_flags = flags, 811 .ps_flags = flags,
799 }; 812 };
800 struct iovec iov[] = { 813 struct iovec iov[] = {
801 { .iov_base = UNCONST(data), .iov_len = len } 814 { .iov_base = UNCONST(data), .iov_len = len }
802 }; 815 };
803 struct msghdr msg = { 816 struct msghdr msg = {
804 .msg_iov = iov, .msg_iovlen = 1, 817 .msg_iov = iov, .msg_iovlen = 1,
805 }; 818 };
806 819
807 return ps_sendpsmmsg(ctx, fd, &psm, &msg); 820 return ps_sendpsmmsg(ctx, fd, &psm, &msg);
808} 821}
809 822
810static ssize_t 823static ssize_t
811ps_sendcmdmsg(int fd, uint16_t cmd, const struct msghdr *msg) 824ps_sendcmdmsg(int fd, uint16_t cmd, const struct msghdr *msg)
812{ 825{
813 struct ps_msghdr psm = { .ps_cmd = cmd }; 826 struct ps_msghdr psm = { .ps_cmd = cmd };
814 uint8_t data[PS_BUFLEN], *p = data; 827 uint8_t data[PS_BUFLEN], *p = data;
815 struct iovec iov[] = { 828 struct iovec iov[] = {
816 { .iov_base = &psm, .iov_len = sizeof(psm) }, 829 { .iov_base = &psm, .iov_len = sizeof(psm) },
817 { .iov_base = data, .iov_len = 0 }, 830 { .iov_base = data, .iov_len = 0 },
818 }; 831 };
819 size_t dl = sizeof(data); 832 size_t dl = sizeof(data);
820 833
821 if (msg->msg_namelen != 0) { 834 if (msg->msg_namelen != 0) {
822 if (msg->msg_namelen > dl) 835 if (msg->msg_namelen > dl)
823 goto nobufs; 836 goto nobufs;
824 psm.ps_namelen = msg->msg_namelen; 837 psm.ps_namelen = msg->msg_namelen;
825 memcpy(p, msg->msg_name, msg->msg_namelen); 838 memcpy(p, msg->msg_name, msg->msg_namelen);
826 p += msg->msg_namelen; 839 p += msg->msg_namelen;
827 dl -= msg->msg_namelen; 840 dl -= msg->msg_namelen;
828 } 841 }
829 842
830 if (msg->msg_controllen != 0) { 843 if (msg->msg_controllen != 0) {
831 if (msg->msg_controllen > dl) 844 if (msg->msg_controllen > dl)
832 goto nobufs; 845 goto nobufs;
833 psm.ps_controllen = (socklen_t)msg->msg_controllen; 846 psm.ps_controllen = (socklen_t)msg->msg_controllen;
834 memcpy(p, msg->msg_control, msg->msg_controllen); 847 memcpy(p, msg->msg_control, msg->msg_controllen);
835 p += msg->msg_controllen; 848 p += msg->msg_controllen;
836 dl -= msg->msg_controllen; 849 dl -= msg->msg_controllen;
837 } 850 }
838 851
839 psm.ps_datalen = msg->msg_iov[0].iov_len; 852 psm.ps_datalen = msg->msg_iov[0].iov_len;
840 if (psm.ps_datalen > dl) 853 if (psm.ps_datalen > dl)
841 goto nobufs; 854 goto nobufs;
842 855
843 iov[1].iov_len = psm.ps_namelen + psm.ps_controllen + psm.ps_datalen; 856 iov[1].iov_len = psm.ps_namelen + psm.ps_controllen + psm.ps_datalen;
844 if (psm.ps_datalen != 0) 857 if (psm.ps_datalen != 0)
845 memcpy(p, msg->msg_iov[0].iov_base, psm.ps_datalen); 858 memcpy(p, msg->msg_iov[0].iov_base, psm.ps_datalen);
846 return writev(fd, iov, __arraycount(iov)); 859 return writev(fd, iov, __arraycount(iov));
847 860
848nobufs: 861nobufs:
849 errno = ENOBUFS; 862 errno = ENOBUFS;
850 return -1; 863 return -1;
851} 864}
852 865
853ssize_t 866ssize_t
854ps_recvmsg(struct dhcpcd_ctx *ctx, int rfd, uint16_t cmd, int wfd) 867ps_recvmsg(struct dhcpcd_ctx *ctx, int rfd, uint16_t cmd, int wfd)
855{ 868{
856 struct sockaddr_storage ss = { .ss_family = AF_UNSPEC }; 869 struct sockaddr_storage ss = { .ss_family = AF_UNSPEC };
857 uint8_t controlbuf[sizeof(struct sockaddr_storage)] = { 0 }; 870 uint8_t controlbuf[sizeof(struct sockaddr_storage)] = { 0 };
858 uint8_t databuf[64 * 1024]; 871 uint8_t databuf[64 * 1024];
859 struct iovec iov[] = { 872 struct iovec iov[] = {
860 { .iov_base = databuf, .iov_len = sizeof(databuf) } 873 { .iov_base = databuf, .iov_len = sizeof(databuf) }
861 }; 874 };
862 struct msghdr msg = { 875 struct msghdr msg = {
863 .msg_name = &ss, .msg_namelen = sizeof(ss), 876 .msg_name = &ss, .msg_namelen = sizeof(ss),
864 .msg_control = controlbuf, .msg_controllen = sizeof(controlbuf), 877 .msg_control = controlbuf, .msg_controllen = sizeof(controlbuf),
865 .msg_iov = iov, .msg_iovlen = 1, 878 .msg_iov = iov, .msg_iovlen = 1,
866 }; 879 };
867 880
868 ssize_t len = recvmsg(rfd, &msg, 0); 881 ssize_t len = recvmsg(rfd, &msg, 0);
869 882
870 if (len == -1) 883 if (len == -1)
871 logerr("%s: recvmsg", __func__); 884 logerr("%s: recvmsg", __func__);
872 if (len == -1 || len == 0) { 885 if (len == -1 || len == 0) {
873 if (ctx->options & DHCPCD_FORKED && 886 if (ctx->options & DHCPCD_FORKED &&
874 !(ctx->options & DHCPCD_PRIVSEPROOT)) 887 !(ctx->options & DHCPCD_PRIVSEPROOT))
875 eloop_exit(ctx->eloop, 888 eloop_exit(ctx->eloop,
876 len == 0 ? EXIT_SUCCESS : EXIT_FAILURE); 889 len == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
877 return len; 890 return len;
878 } 891 }
879 892
880 iov[0].iov_len = (size_t)len; 893 iov[0].iov_len = (size_t)len;
881 len = ps_sendcmdmsg(wfd, cmd, &msg); 894 len = ps_sendcmdmsg(wfd, cmd, &msg);
882 if (len == -1) { 895 if (len == -1) {
883 logerr("ps_sendcmdmsg"); 896 logerr("ps_sendcmdmsg");
884 if (ctx->options & DHCPCD_FORKED && 897 if (ctx->options & DHCPCD_FORKED &&
885 !(ctx->options & DHCPCD_PRIVSEPROOT)) 898 !(ctx->options & DHCPCD_PRIVSEPROOT))
886 eloop_exit(ctx->eloop, EXIT_FAILURE); 899 eloop_exit(ctx->eloop, EXIT_FAILURE);
887 } 900 }
888 return len; 901 return len;
889} 902}
890 903
891ssize_t 904ssize_t
892ps_recvpsmsg(struct dhcpcd_ctx *ctx, int fd, 905ps_recvpsmsg(struct dhcpcd_ctx *ctx, int fd,
893 ssize_t (*callback)(void *, struct ps_msghdr *, struct msghdr *), 906 ssize_t (*callback)(void *, struct ps_msghdr *, struct msghdr *),
894 void *cbctx) 907 void *cbctx)
895{ 908{
896 struct ps_msg psm; 909 struct ps_msg psm;
897 ssize_t len; 910 ssize_t len;
898 size_t dlen; 911 size_t dlen;
899 struct iovec iov[1]; 912 struct iovec iov[1];
900 struct msghdr msg = { .msg_iov = iov, .msg_iovlen = 1 }; 913 struct msghdr msg = { .msg_iov = iov, .msg_iovlen = 1 };
901 bool stop = false; 914 bool stop = false;
902 915
903 len = read(fd, &psm, sizeof(psm)); 916 len = read(fd, &psm, sizeof(psm));
904#ifdef PRIVSEP_DEBUG 917#ifdef PRIVSEP_DEBUG
905 logdebugx("%s: %zd", __func__, len); 918 logdebugx("%s: %zd", __func__, len);
906#endif 919#endif
907 920
908 if (len == -1 || len == 0) 921 if (len == -1 || len == 0)
909 stop = true; 922 stop = true;
910 else { 923 else {
911 dlen = (size_t)len; 924 dlen = (size_t)len;
912 if (dlen < sizeof(psm.psm_hdr)) { 925 if (dlen < sizeof(psm.psm_hdr)) {
913 errno = EINVAL; 926 errno = EINVAL;
914 return -1; 927 return -1;
915 } 928 }
916 929
917 if (psm.psm_hdr.ps_cmd == PS_STOP) { 930 if (psm.psm_hdr.ps_cmd == PS_STOP) {
918 stop = true; 931 stop = true;
919 len = 0; 932 len = 0;
920 } 933 }
921 } 934 }
922 935
923 if (stop) { 936 if (stop) {
924#ifdef PRIVSEP_DEBUG 937#ifdef PRIVSEP_DEBUG
925 logdebugx("process %d stopping", getpid()); 938 logdebugx("process %d stopping", getpid());
926#endif 939#endif
927 ps_free(ctx); 940 ps_free(ctx);
928#ifdef PLUGIN_DEV 941#ifdef PLUGIN_DEV
929 dev_stop(ctx); 942 dev_stop(ctx);
930#endif 943#endif
931 eloop_exit(ctx->eloop, len != -1 ? EXIT_SUCCESS : EXIT_FAILURE); 944 eloop_exit(ctx->eloop, len != -1 ? EXIT_SUCCESS : EXIT_FAILURE);
932 return len; 945 return len;
933 } 946 }
934 dlen -= sizeof(psm.psm_hdr); 947 dlen -= sizeof(psm.psm_hdr);
935 948
936 if (ps_unrollmsg(&msg, &psm.psm_hdr, psm.psm_data, dlen) == -1) 949 if (ps_unrollmsg(&msg, &psm.psm_hdr, psm.psm_data, dlen) == -1)
937 return -1; 950 return -1;
938 951
939 if (callback == NULL) 952 if (callback == NULL)
940 return 0; 953 return 0;
941 954
942 errno = 0; 955 errno = 0;
943 return callback(cbctx, &psm.psm_hdr, &msg); 956 return callback(cbctx, &psm.psm_hdr, &msg);
944} 957}
945 958
946struct ps_process * 959struct ps_process *
947ps_findprocess(struct dhcpcd_ctx *ctx, struct ps_id *psid) 960ps_findprocess(struct dhcpcd_ctx *ctx, struct ps_id *psid)
948{ 961{
949 struct ps_process *psp; 962 struct ps_process *psp;
950 963
951 TAILQ_FOREACH(psp, &ctx->ps_processes, next) { 964 TAILQ_FOREACH(psp, &ctx->ps_processes, next) {
952 if (memcmp(&psp->psp_id, psid, sizeof(psp->psp_id)) == 0) 965 if (memcmp(&psp->psp_id, psid, sizeof(psp->psp_id)) == 0)
953 return psp; 966 return psp;
954 } 967 }
955 errno = ESRCH; 968 errno = ESRCH;
956 return NULL; 969 return NULL;
957} 970}
958 971
959struct ps_process * 972struct ps_process *
960ps_newprocess(struct dhcpcd_ctx *ctx, struct ps_id *psid) 973ps_newprocess(struct dhcpcd_ctx *ctx, struct ps_id *psid)
961{ 974{
962 struct ps_process *psp; 975 struct ps_process *psp;
963 976
964 psp = calloc(1, sizeof(*psp)); 977 psp = calloc(1, sizeof(*psp));
965 if (psp == NULL) 978 if (psp == NULL)
966 return NULL; 979 return NULL;
967 psp->psp_ctx = ctx; 980 psp->psp_ctx = ctx;
968 memcpy(&psp->psp_id, psid, sizeof(psp->psp_id)); 981 memcpy(&psp->psp_id, psid, sizeof(psp->psp_id));
969 psp->psp_work_fd = -1; 982 psp->psp_work_fd = -1;
970 TAILQ_INSERT_TAIL(&ctx->ps_processes, psp, next); 983 TAILQ_INSERT_TAIL(&ctx->ps_processes, psp, next);
971 return psp; 984 return psp;
972} 985}
973 986
974void 987void
975ps_freeprocesses(struct dhcpcd_ctx *ctx, struct ps_process *notthis) 988ps_freeprocesses(struct dhcpcd_ctx *ctx, struct ps_process *notthis)
976{ 989{
977 struct ps_process *psp, *psn; 990 struct ps_process *psp, *psn;
978 991
979 TAILQ_FOREACH_SAFE(psp, &ctx->ps_processes, next, psn) { 992 TAILQ_FOREACH_SAFE(psp, &ctx->ps_processes, next, psn) {
980 if (psp == notthis) 993 if (psp == notthis)
981 continue; 994 continue;
982 ps_freeprocess(psp); 995 ps_freeprocess(psp);
983 } 996 }
984} 997}