Deleted Added
full compact
if_ether.c (139823) if_ether.c (142215)
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

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

22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * @(#)if_ether.c 8.1 (Berkeley) 6/10/93
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

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

22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * @(#)if_ether.c 8.1 (Berkeley) 6/10/93
30 * $FreeBSD: head/sys/netinet/if_ether.c 139823 2005-01-07 01:45:51Z imp $
30 * $FreeBSD: head/sys/netinet/if_ether.c 142215 2005-02-22 13:04:05Z glebius $
31 */
32
33/*
34 * Ethernet address resolution protocol.
35 * TODO:
36 * add "inuse/lock" bit (or ref. count) along with valid bit
37 */
38
39#include "opt_inet.h"
40#include "opt_bdg.h"
41#include "opt_mac.h"
31 */
32
33/*
34 * Ethernet address resolution protocol.
35 * TODO:
36 * add "inuse/lock" bit (or ref. count) along with valid bit
37 */
38
39#include "opt_inet.h"
40#include "opt_bdg.h"
41#include "opt_mac.h"
42#include "opt_carp.h"
42
43#include <sys/param.h>
44#include <sys/kernel.h>
45#include <sys/queue.h>
46#include <sys/sysctl.h>
47#include <sys/systm.h>
48#include <sys/mac.h>
49#include <sys/mbuf.h>

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

62
63#include <netinet/in.h>
64#include <netinet/in_var.h>
65#include <netinet/if_ether.h>
66
67#include <net/if_arc.h>
68#include <net/iso88025.h>
69
43
44#include <sys/param.h>
45#include <sys/kernel.h>
46#include <sys/queue.h>
47#include <sys/sysctl.h>
48#include <sys/systm.h>
49#include <sys/mac.h>
50#include <sys/mbuf.h>

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

63
64#include <netinet/in.h>
65#include <netinet/in_var.h>
66#include <netinet/if_ether.h>
67
68#include <net/if_arc.h>
69#include <net/iso88025.h>
70
71#ifdef DEV_CARP
72#include <netinet/ip_carp.h>
73#endif
74
70#define SIN(s) ((struct sockaddr_in *)s)
71#define SDL(s) ((struct sockaddr_dl *)s)
72
73SYSCTL_DECL(_net_link_ether);
74SYSCTL_NODE(_net_link_ether, PF_INET, inet, CTLFLAG_RW, 0, "");
75
76/* timer values */
77static int arpt_prune = (5*60*1); /* walk list every 5 minutes */

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

540 struct iso88025_sockaddr_dl_data *trld;
541 struct llinfo_arp *la = 0;
542 struct rtentry *rt;
543 struct ifaddr *ifa;
544 struct in_ifaddr *ia;
545 struct sockaddr_dl *sdl;
546 struct sockaddr sa;
547 struct in_addr isaddr, itaddr, myaddr;
75#define SIN(s) ((struct sockaddr_in *)s)
76#define SDL(s) ((struct sockaddr_dl *)s)
77
78SYSCTL_DECL(_net_link_ether);
79SYSCTL_NODE(_net_link_ether, PF_INET, inet, CTLFLAG_RW, 0, "");
80
81/* timer values */
82static int arpt_prune = (5*60*1); /* walk list every 5 minutes */

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

545 struct iso88025_sockaddr_dl_data *trld;
546 struct llinfo_arp *la = 0;
547 struct rtentry *rt;
548 struct ifaddr *ifa;
549 struct in_ifaddr *ia;
550 struct sockaddr_dl *sdl;
551 struct sockaddr sa;
552 struct in_addr isaddr, itaddr, myaddr;
553 u_int8_t *enaddr = NULL;
548 int op, rif_len;
549 int req_len;
550
551 req_len = arphdr_len2(ifp->if_addrlen, sizeof(struct in_addr));
552 if (m->m_len < req_len && (m = m_pullup(m, req_len)) == NULL) {
553 log(LOG_ERR, "in_arp: runt packet -- m_pullup failed\n");
554 return;
555 }
556
557 ah = mtod(m, struct arphdr *);
558 op = ntohs(ah->ar_op);
559 (void)memcpy(&isaddr, ar_spa(ah), sizeof (isaddr));
560 (void)memcpy(&itaddr, ar_tpa(ah), sizeof (itaddr));
561
562 /*
563 * For a bridge, we want to check the address irrespective
564 * of the receive interface. (This will change slightly
565 * when we have clusters of interfaces).
554 int op, rif_len;
555 int req_len;
556
557 req_len = arphdr_len2(ifp->if_addrlen, sizeof(struct in_addr));
558 if (m->m_len < req_len && (m = m_pullup(m, req_len)) == NULL) {
559 log(LOG_ERR, "in_arp: runt packet -- m_pullup failed\n");
560 return;
561 }
562
563 ah = mtod(m, struct arphdr *);
564 op = ntohs(ah->ar_op);
565 (void)memcpy(&isaddr, ar_spa(ah), sizeof (isaddr));
566 (void)memcpy(&itaddr, ar_tpa(ah), sizeof (itaddr));
567
568 /*
569 * For a bridge, we want to check the address irrespective
570 * of the receive interface. (This will change slightly
571 * when we have clusters of interfaces).
572 * If the interface does not match, but the recieving interface
573 * is part of carp, we call carp_iamatch to see if this is a
574 * request for the virtual host ip.
575 * XXX: This is really ugly!
566 */
567 LIST_FOREACH(ia, INADDR_HASH(itaddr.s_addr), ia_hash)
576 */
577 LIST_FOREACH(ia, INADDR_HASH(itaddr.s_addr), ia_hash)
568 if ((do_bridge || (ia->ia_ifp == ifp)) &&
569 itaddr.s_addr == ia->ia_addr.sin_addr.s_addr)
578 if ((do_bridge || (ia->ia_ifp == ifp)
579#ifdef DEV_CARP
580 || (ifp->if_carp
581 && carp_iamatch(ifp->if_carp, ia, &isaddr, &enaddr))
582#endif
583 ) && itaddr.s_addr == ia->ia_addr.sin_addr.s_addr)
570 goto match;
571 LIST_FOREACH(ia, INADDR_HASH(isaddr.s_addr), ia_hash)
572 if ((do_bridge || (ia->ia_ifp == ifp)) &&
573 isaddr.s_addr == ia->ia_addr.sin_addr.s_addr)
574 goto match;
575 /*
576 * No match, use the first inet address on the receive interface
577 * as a dummy address for the rest of the function.

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

582 goto match;
583 }
584 /*
585 * If bridging, fall back to using any inet address.
586 */
587 if (!do_bridge || (ia = TAILQ_FIRST(&in_ifaddrhead)) == NULL)
588 goto drop;
589match:
584 goto match;
585 LIST_FOREACH(ia, INADDR_HASH(isaddr.s_addr), ia_hash)
586 if ((do_bridge || (ia->ia_ifp == ifp)) &&
587 isaddr.s_addr == ia->ia_addr.sin_addr.s_addr)
588 goto match;
589 /*
590 * No match, use the first inet address on the receive interface
591 * as a dummy address for the rest of the function.

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

596 goto match;
597 }
598 /*
599 * If bridging, fall back to using any inet address.
600 */
601 if (!do_bridge || (ia = TAILQ_FIRST(&in_ifaddrhead)) == NULL)
602 goto drop;
603match:
604 if (!enaddr)
605 enaddr = (u_int8_t *)IF_LLADDR(ifp);
590 myaddr = ia->ia_addr.sin_addr;
606 myaddr = ia->ia_addr.sin_addr;
591 if (!bcmp(ar_sha(ah), IF_LLADDR(ifp), ifp->if_addrlen))
607 if (!bcmp(ar_sha(ah), enaddr, ifp->if_addrlen))
592 goto drop; /* it's from me, ignore it. */
593 if (!bcmp(ar_sha(ah), ifp->if_broadcastaddr, ifp->if_addrlen)) {
594 log(LOG_ERR,
595 "arp: link address is broadcast for IP address %s!\n",
596 inet_ntoa(isaddr));
597 goto drop;
598 }
599 /*

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

706 }
707 }
708reply:
709 if (op != ARPOP_REQUEST)
710 goto drop;
711 if (itaddr.s_addr == myaddr.s_addr) {
712 /* I am the target */
713 (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
608 goto drop; /* it's from me, ignore it. */
609 if (!bcmp(ar_sha(ah), ifp->if_broadcastaddr, ifp->if_addrlen)) {
610 log(LOG_ERR,
611 "arp: link address is broadcast for IP address %s!\n",
612 inet_ntoa(isaddr));
613 goto drop;
614 }
615 /*

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

722 }
723 }
724reply:
725 if (op != ARPOP_REQUEST)
726 goto drop;
727 if (itaddr.s_addr == myaddr.s_addr) {
728 /* I am the target */
729 (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
714 (void)memcpy(ar_sha(ah), IF_LLADDR(ifp), ah->ar_hln);
730 (void)memcpy(ar_sha(ah), enaddr, ah->ar_hln);
715 } else {
716 la = arplookup(itaddr.s_addr, 0, SIN_PROXY);
717 if (la == NULL) {
718 struct sockaddr_in sin;
719
720 if (!arp_proxyall)
721 goto drop;
722

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

733 * as this one came out of, or we'll get into a fight
734 * over who claims what Ether address.
735 */
736 if (rt->rt_ifp == ifp) {
737 rtfree(rt);
738 goto drop;
739 }
740 (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
731 } else {
732 la = arplookup(itaddr.s_addr, 0, SIN_PROXY);
733 if (la == NULL) {
734 struct sockaddr_in sin;
735
736 if (!arp_proxyall)
737 goto drop;
738

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

749 * as this one came out of, or we'll get into a fight
750 * over who claims what Ether address.
751 */
752 if (rt->rt_ifp == ifp) {
753 rtfree(rt);
754 goto drop;
755 }
756 (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
741 (void)memcpy(ar_sha(ah), IF_LLADDR(ifp), ah->ar_hln);
757 (void)memcpy(ar_sha(ah), enaddr, ah->ar_hln);
742 rtfree(rt);
743
744 /*
745 * Also check that the node which sent the ARP packet
746 * is on the the interface we expect it to be on. This
747 * avoids ARP chaos if an interface is connected to the
748 * wrong network.
749 */

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

875{
876 if (ntohl(IA_SIN(ifa)->sin_addr.s_addr) != INADDR_ANY)
877 arprequest(ifp, &IA_SIN(ifa)->sin_addr,
878 &IA_SIN(ifa)->sin_addr, IF_LLADDR(ifp));
879 ifa->ifa_rtrequest = arp_rtrequest;
880 ifa->ifa_flags |= RTF_CLONING;
881}
882
758 rtfree(rt);
759
760 /*
761 * Also check that the node which sent the ARP packet
762 * is on the the interface we expect it to be on. This
763 * avoids ARP chaos if an interface is connected to the
764 * wrong network.
765 */

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

891{
892 if (ntohl(IA_SIN(ifa)->sin_addr.s_addr) != INADDR_ANY)
893 arprequest(ifp, &IA_SIN(ifa)->sin_addr,
894 &IA_SIN(ifa)->sin_addr, IF_LLADDR(ifp));
895 ifa->ifa_rtrequest = arp_rtrequest;
896 ifa->ifa_flags |= RTF_CLONING;
897}
898
899void
900arp_ifinit2(ifp, ifa, enaddr)
901 struct ifnet *ifp;
902 struct ifaddr *ifa;
903 u_char *enaddr;
904{
905 if (ntohl(IA_SIN(ifa)->sin_addr.s_addr) != INADDR_ANY)
906 arprequest(ifp, &IA_SIN(ifa)->sin_addr,
907 &IA_SIN(ifa)->sin_addr, enaddr);
908 ifa->ifa_rtrequest = arp_rtrequest;
909 ifa->ifa_flags |= RTF_CLONING;
910}
911
883static void
884arp_init(void)
885{
886
887 arpintrq.ifq_maxlen = 50;
888 mtx_init(&arpintrq.ifq_mtx, "arp_inq", NULL, MTX_DEF);
889 LIST_INIT(&llinfo_arp);
890 callout_init(&arp_callout, CALLOUT_MPSAFE);
891 netisr_register(NETISR_ARP, arpintr, &arpintrq, NETISR_MPSAFE);
892 callout_reset(&arp_callout, hz, arptimer, NULL);
893}
894SYSINIT(arp, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY, arp_init, 0);
912static void
913arp_init(void)
914{
915
916 arpintrq.ifq_maxlen = 50;
917 mtx_init(&arpintrq.ifq_mtx, "arp_inq", NULL, MTX_DEF);
918 LIST_INIT(&llinfo_arp);
919 callout_init(&arp_callout, CALLOUT_MPSAFE);
920 netisr_register(NETISR_ARP, arpintr, &arpintrq, NETISR_MPSAFE);
921 callout_reset(&arp_callout, hz, arptimer, NULL);
922}
923SYSINIT(arp, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY, arp_init, 0);