if_ether.c (47e8d432d5db395e2812c03093b70227e48a1c6d) if_ether.c (5d81d095984217862ae54463fa16a209cdde6998)
1/*-
2 * Copyright (c) 1982, 1986, 1988, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 491 unchanged lines hidden (view full) ---

500 * trailer packets.
501 * We no longer reply to requests for ETHERTYPE_TRAIL protocol either,
502 * but formerly didn't normally send requests.
503 */
504static int log_arp_wrong_iface = 1;
505static int log_arp_movements = 1;
506static int log_arp_permanent_modify = 1;
507static int allow_multicast = 0;
1/*-
2 * Copyright (c) 1982, 1986, 1988, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 491 unchanged lines hidden (view full) ---

500 * trailer packets.
501 * We no longer reply to requests for ETHERTYPE_TRAIL protocol either,
502 * but formerly didn't normally send requests.
503 */
504static int log_arp_wrong_iface = 1;
505static int log_arp_movements = 1;
506static int log_arp_permanent_modify = 1;
507static int allow_multicast = 0;
508static struct timeval arp_lastlog;
509static int arp_curpps;
510static int arp_maxpps = 1;
508
509SYSCTL_INT(_net_link_ether_inet, OID_AUTO, log_arp_wrong_iface, CTLFLAG_RW,
510 &log_arp_wrong_iface, 0,
511 "log arp packets arriving on the wrong interface");
512SYSCTL_INT(_net_link_ether_inet, OID_AUTO, log_arp_movements, CTLFLAG_RW,
513 &log_arp_movements, 0,
514 "log arp replies from MACs different than the one in the cache");
515SYSCTL_INT(_net_link_ether_inet, OID_AUTO, log_arp_permanent_modify, CTLFLAG_RW,
516 &log_arp_permanent_modify, 0,
517 "log arp replies from MACs different than the one in the permanent arp entry");
518SYSCTL_INT(_net_link_ether_inet, OID_AUTO, allow_multicast, CTLFLAG_RW,
519 &allow_multicast, 0, "accept multicast addresses");
511
512SYSCTL_INT(_net_link_ether_inet, OID_AUTO, log_arp_wrong_iface, CTLFLAG_RW,
513 &log_arp_wrong_iface, 0,
514 "log arp packets arriving on the wrong interface");
515SYSCTL_INT(_net_link_ether_inet, OID_AUTO, log_arp_movements, CTLFLAG_RW,
516 &log_arp_movements, 0,
517 "log arp replies from MACs different than the one in the cache");
518SYSCTL_INT(_net_link_ether_inet, OID_AUTO, log_arp_permanent_modify, CTLFLAG_RW,
519 &log_arp_permanent_modify, 0,
520 "log arp replies from MACs different than the one in the permanent arp entry");
521SYSCTL_INT(_net_link_ether_inet, OID_AUTO, allow_multicast, CTLFLAG_RW,
522 &allow_multicast, 0, "accept multicast addresses");
523SYSCTL_INT(_net_link_ether_inet, OID_AUTO, max_log_per_second,
524 CTLFLAG_RW, &arp_maxpps, 0,
525 "Maximum number of remotely triggered ARP messages that can be "
526 "logged per second");
520
527
528#define ARP_LOG(pri, ...) do { \
529 if (ppsratecheck(&arp_lastlog, &arp_curpps, arp_maxpps)) \
530 log((pri), "arp: " __VA_ARGS__); \
531} while (0)
532
521static void
522in_arpinput(struct mbuf *m)
523{
524 struct arphdr *ah;
525 struct ifnet *ifp = m->m_pkthdr.rcvif;
526 struct llentry *la = NULL;
527 struct rtentry *rt;
528 struct ifaddr *ifa;

--- 12 unchanged lines hidden (view full) ---

541
542 if (ifp->if_bridge)
543 bridged = 1;
544 if (ifp->if_type == IFT_BRIDGE)
545 is_bridge = 1;
546
547 req_len = arphdr_len2(ifp->if_addrlen, sizeof(struct in_addr));
548 if (m->m_len < req_len && (m = m_pullup(m, req_len)) == NULL) {
533static void
534in_arpinput(struct mbuf *m)
535{
536 struct arphdr *ah;
537 struct ifnet *ifp = m->m_pkthdr.rcvif;
538 struct llentry *la = NULL;
539 struct rtentry *rt;
540 struct ifaddr *ifa;

--- 12 unchanged lines hidden (view full) ---

553
554 if (ifp->if_bridge)
555 bridged = 1;
556 if (ifp->if_type == IFT_BRIDGE)
557 is_bridge = 1;
558
559 req_len = arphdr_len2(ifp->if_addrlen, sizeof(struct in_addr));
560 if (m->m_len < req_len && (m = m_pullup(m, req_len)) == NULL) {
549 log(LOG_NOTICE, "in_arp: runt packet -- m_pullup failed\n");
561 ARP_LOG(LOG_NOTICE, "runt packet -- m_pullup failed\n");
550 return;
551 }
552
553 ah = mtod(m, struct arphdr *);
554 /*
555 * ARP is only for IPv4 so we can reject packets with
556 * a protocol length not equal to an IPv4 address.
557 */
558 if (ah->ar_pln != sizeof(struct in_addr)) {
562 return;
563 }
564
565 ah = mtod(m, struct arphdr *);
566 /*
567 * ARP is only for IPv4 so we can reject packets with
568 * a protocol length not equal to an IPv4 address.
569 */
570 if (ah->ar_pln != sizeof(struct in_addr)) {
559 log(LOG_NOTICE, "in_arp: requested protocol length != %zu\n",
571 ARP_LOG(LOG_NOTICE, "requested protocol length != %zu\n",
560 sizeof(struct in_addr));
561 goto drop;
562 }
563
564 if (allow_multicast == 0 && ETHER_IS_MULTICAST(ar_sha(ah))) {
572 sizeof(struct in_addr));
573 goto drop;
574 }
575
576 if (allow_multicast == 0 && ETHER_IS_MULTICAST(ar_sha(ah))) {
565 log(LOG_NOTICE, "arp: %*D is multicast\n",
577 ARP_LOG(LOG_NOTICE, "%*D is multicast\n",
566 ifp->if_addrlen, (u_char *)ar_sha(ah), ":");
567 goto drop;
568 }
569
570 op = ntohs(ah->ar_op);
571 (void)memcpy(&isaddr, ar_spa(ah), sizeof (isaddr));
572 (void)memcpy(&itaddr, ar_tpa(ah), sizeof (itaddr));
573

--- 79 unchanged lines hidden (view full) ---

653 if (!enaddr)
654 enaddr = (u_int8_t *)IF_LLADDR(ifp);
655 carped = (ia->ia_ifa.ifa_carp != NULL);
656 myaddr = ia->ia_addr.sin_addr;
657 ifa_free(&ia->ia_ifa);
658 if (!bcmp(ar_sha(ah), enaddr, ifp->if_addrlen))
659 goto drop; /* it's from me, ignore it. */
660 if (!bcmp(ar_sha(ah), ifp->if_broadcastaddr, ifp->if_addrlen)) {
578 ifp->if_addrlen, (u_char *)ar_sha(ah), ":");
579 goto drop;
580 }
581
582 op = ntohs(ah->ar_op);
583 (void)memcpy(&isaddr, ar_spa(ah), sizeof (isaddr));
584 (void)memcpy(&itaddr, ar_tpa(ah), sizeof (itaddr));
585

--- 79 unchanged lines hidden (view full) ---

665 if (!enaddr)
666 enaddr = (u_int8_t *)IF_LLADDR(ifp);
667 carped = (ia->ia_ifa.ifa_carp != NULL);
668 myaddr = ia->ia_addr.sin_addr;
669 ifa_free(&ia->ia_ifa);
670 if (!bcmp(ar_sha(ah), enaddr, ifp->if_addrlen))
671 goto drop; /* it's from me, ignore it. */
672 if (!bcmp(ar_sha(ah), ifp->if_broadcastaddr, ifp->if_addrlen)) {
661 log(LOG_NOTICE,
662 "arp: link address is broadcast for IP address %s!\n",
663 inet_ntoa(isaddr));
673 ARP_LOG(LOG_NOTICE, "link address is broadcast for IP address "
674 "%s!\n", inet_ntoa(isaddr));
664 goto drop;
665 }
666 /*
667 * Warn if another host is using the same IP address, but only if the
668 * IP address isn't 0.0.0.0, which is used for DHCP only, in which
669 * case we suppress the warning to avoid false positive complaints of
670 * potential misconfiguration.
671 */
672 if (!bridged && !carped && isaddr.s_addr == myaddr.s_addr &&
673 myaddr.s_addr != 0) {
675 goto drop;
676 }
677 /*
678 * Warn if another host is using the same IP address, but only if the
679 * IP address isn't 0.0.0.0, which is used for DHCP only, in which
680 * case we suppress the warning to avoid false positive complaints of
681 * potential misconfiguration.
682 */
683 if (!bridged && !carped && isaddr.s_addr == myaddr.s_addr &&
684 myaddr.s_addr != 0) {
674 log(LOG_ERR, "arp: %*D is using my IP address %s on %s!\n",
685 ARP_LOG(LOG_ERR, "%*D is using my IP address %s on %s!\n",
675 ifp->if_addrlen, (u_char *)ar_sha(ah), ":",
676 inet_ntoa(isaddr), ifp->if_xname);
677 itaddr = myaddr;
678 ARPSTAT_INC(dupips);
679 goto reply;
680 }
681 if (ifp->if_flags & IFF_STATICARP)
682 goto reply;

--- 6 unchanged lines hidden (view full) ---

689 flags |= LLE_EXCLUSIVE;
690 IF_AFDATA_LOCK(ifp);
691 la = lla_lookup(LLTABLE(ifp), flags, (struct sockaddr *)&sin);
692 IF_AFDATA_UNLOCK(ifp);
693 if (la != NULL) {
694 /* the following is not an error when doing bridging */
695 if (!bridged && la->lle_tbl->llt_ifp != ifp) {
696 if (log_arp_wrong_iface)
686 ifp->if_addrlen, (u_char *)ar_sha(ah), ":",
687 inet_ntoa(isaddr), ifp->if_xname);
688 itaddr = myaddr;
689 ARPSTAT_INC(dupips);
690 goto reply;
691 }
692 if (ifp->if_flags & IFF_STATICARP)
693 goto reply;

--- 6 unchanged lines hidden (view full) ---

700 flags |= LLE_EXCLUSIVE;
701 IF_AFDATA_LOCK(ifp);
702 la = lla_lookup(LLTABLE(ifp), flags, (struct sockaddr *)&sin);
703 IF_AFDATA_UNLOCK(ifp);
704 if (la != NULL) {
705 /* the following is not an error when doing bridging */
706 if (!bridged && la->lle_tbl->llt_ifp != ifp) {
707 if (log_arp_wrong_iface)
697 log(LOG_WARNING, "arp: %s is on %s "
708 ARP_LOG(LOG_WARNING, "%s is on %s "
698 "but got reply from %*D on %s\n",
699 inet_ntoa(isaddr),
700 la->lle_tbl->llt_ifp->if_xname,
701 ifp->if_addrlen, (u_char *)ar_sha(ah), ":",
702 ifp->if_xname);
703 LLE_WUNLOCK(la);
704 goto reply;
705 }
706 if ((la->la_flags & LLE_VALID) &&
707 bcmp(ar_sha(ah), &la->ll_addr, ifp->if_addrlen)) {
708 if (la->la_flags & LLE_STATIC) {
709 LLE_WUNLOCK(la);
710 if (log_arp_permanent_modify)
709 "but got reply from %*D on %s\n",
710 inet_ntoa(isaddr),
711 la->lle_tbl->llt_ifp->if_xname,
712 ifp->if_addrlen, (u_char *)ar_sha(ah), ":",
713 ifp->if_xname);
714 LLE_WUNLOCK(la);
715 goto reply;
716 }
717 if ((la->la_flags & LLE_VALID) &&
718 bcmp(ar_sha(ah), &la->ll_addr, ifp->if_addrlen)) {
719 if (la->la_flags & LLE_STATIC) {
720 LLE_WUNLOCK(la);
721 if (log_arp_permanent_modify)
711 log(LOG_ERR,
712 "arp: %*D attempts to modify "
722 ARP_LOG(LOG_ERR,
723 "%*D attempts to modify "
713 "permanent entry for %s on %s\n",
714 ifp->if_addrlen,
715 (u_char *)ar_sha(ah), ":",
716 inet_ntoa(isaddr), ifp->if_xname);
717 goto reply;
718 }
719 if (log_arp_movements) {
724 "permanent entry for %s on %s\n",
725 ifp->if_addrlen,
726 (u_char *)ar_sha(ah), ":",
727 inet_ntoa(isaddr), ifp->if_xname);
728 goto reply;
729 }
730 if (log_arp_movements) {
720 log(LOG_INFO, "arp: %s moved from %*D "
731 ARP_LOG(LOG_INFO, "%s moved from %*D "
721 "to %*D on %s\n",
722 inet_ntoa(isaddr),
723 ifp->if_addrlen,
724 (u_char *)&la->ll_addr, ":",
725 ifp->if_addrlen, (u_char *)ar_sha(ah), ":",
726 ifp->if_xname);
727 }
728 }
729
730 if (ifp->if_addrlen != ah->ar_hln) {
731 LLE_WUNLOCK(la);
732 "to %*D on %s\n",
733 inet_ntoa(isaddr),
734 ifp->if_addrlen,
735 (u_char *)&la->ll_addr, ":",
736 ifp->if_addrlen, (u_char *)ar_sha(ah), ":",
737 ifp->if_xname);
738 }
739 }
740
741 if (ifp->if_addrlen != ah->ar_hln) {
742 LLE_WUNLOCK(la);
732 log(LOG_WARNING, "arp from %*D: addr len: new %d, "
743 ARP_LOG(LOG_WARNING, "from %*D: addr len: new %d, "
733 "i/f %d (ignored)\n", ifp->if_addrlen,
734 (u_char *) ar_sha(ah), ":", ah->ar_hln,
735 ifp->if_addrlen);
736 goto drop;
737 }
738 (void)memcpy(&la->ll_addr, ar_sha(ah), ifp->if_addrlen);
739 la->la_flags |= LLE_VALID;
740

--- 91 unchanged lines hidden (view full) ---

832 */
833 sin.sin_addr = isaddr;
834
835 /* XXX MRT use table 0 for arp checks */
836 rt = in_rtalloc1((struct sockaddr *)&sin, 0, 0UL, 0);
837 if (!rt)
838 goto drop;
839 if (rt->rt_ifp != ifp) {
744 "i/f %d (ignored)\n", ifp->if_addrlen,
745 (u_char *) ar_sha(ah), ":", ah->ar_hln,
746 ifp->if_addrlen);
747 goto drop;
748 }
749 (void)memcpy(&la->ll_addr, ar_sha(ah), ifp->if_addrlen);
750 la->la_flags |= LLE_VALID;
751

--- 91 unchanged lines hidden (view full) ---

843 */
844 sin.sin_addr = isaddr;
845
846 /* XXX MRT use table 0 for arp checks */
847 rt = in_rtalloc1((struct sockaddr *)&sin, 0, 0UL, 0);
848 if (!rt)
849 goto drop;
850 if (rt->rt_ifp != ifp) {
840 log(LOG_INFO, "arp_proxy: ignoring request"
851 ARP_LOG(LOG_INFO, "proxy: ignoring request"
841 " from %s via %s, expecting %s\n",
842 inet_ntoa(isaddr), ifp->if_xname,
843 rt->rt_ifp->if_xname);
844 RTFREE_LOCKED(rt);
845 goto drop;
846 }
847 RTFREE_LOCKED(rt);
848

--- 82 unchanged lines hidden ---
852 " from %s via %s, expecting %s\n",
853 inet_ntoa(isaddr), ifp->if_xname,
854 rt->rt_ifp->if_xname);
855 RTFREE_LOCKED(rt);
856 goto drop;
857 }
858 RTFREE_LOCKED(rt);
859

--- 82 unchanged lines hidden ---