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); |