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 --- 17 unchanged lines hidden (view full) --- 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)if_ether.c 8.1 (Berkeley) 6/10/93 |
34 * $FreeBSD: head/sys/netinet/if_ether.c 111888 2003-03-04 23:19:55Z jlemon $ |
35 */ 36 37/* 38 * Ethernet address resolution protocol. 39 * TODO: 40 * add "inuse/lock" bit (or ref. count) along with valid bit 41 */ 42 --- 56 unchanged lines hidden (view full) --- 99 struct mbuf *la_hold; /* last packet until resolved/timeout */ 100 u_short la_preempt; /* countdown for pre-expiry arps */ 101 u_short la_asked; /* #times we QUERIED following expiration */ 102#define la_timer la_rt->rt_rmx.rmx_expire /* deletion time in seconds */ 103}; 104 105static LIST_HEAD(, llinfo_arp) llinfo_arp; 106 |
107static struct ifqueue arpintrq; |
108static int arp_inuse, arp_allocated, arpinit_done; 109 110static int arp_maxtries = 5; 111static int useloopback = 1; /* use loopback interface for local traffic */ 112static int arp_proxyall = 0; 113 114SYSCTL_INT(_net_link_ether_inet, OID_AUTO, maxtries, CTLFLAG_RW, 115 &arp_maxtries, 0, ""); 116SYSCTL_INT(_net_link_ether_inet, OID_AUTO, useloopback, CTLFLAG_RW, 117 &useloopback, 0, ""); 118SYSCTL_INT(_net_link_ether_inet, OID_AUTO, proxyall, CTLFLAG_RW, 119 &arp_proxyall, 0, ""); 120 121static void arp_init(void); 122static void arp_rtrequest(int, struct rtentry *, struct rt_addrinfo *); 123static void arprequest(struct ifnet *, 124 struct in_addr *, struct in_addr *, u_char *); |
125static void arpintr(struct mbuf *); |
126static void arptfree(struct llinfo_arp *); 127static void arptimer(void *); 128static struct llinfo_arp 129 *arplookup(u_long, int, int); 130#ifdef INET 131static void in_arpinput(struct mbuf *); 132#endif 133 --- 358 unchanged lines hidden (view full) --- 492 return (0); 493} 494 495/* 496 * Common length and type checks are done here, 497 * then the protocol-specific routine is called. 498 */ 499static void |
500arpintr(struct mbuf *m) |
501{ |
502 struct arphdr *ar; |
503 504 if (!arpinit_done) { 505 arpinit_done = 1; 506 timeout(arptimer, (caddr_t)0, hz); 507 } |
508 if (m->m_len < sizeof(struct arphdr) && 509 ((m = m_pullup(m, sizeof(struct arphdr))) == NULL)) { 510 log(LOG_ERR, "arp: runt packet -- m_pullup failed\n"); 511 return; 512 } 513 ar = mtod(m, struct arphdr *); |
514 |
515 if (ntohs(ar->ar_hrd) != ARPHRD_ETHER && 516 ntohs(ar->ar_hrd) != ARPHRD_IEEE802 && 517 ntohs(ar->ar_hrd) != ARPHRD_ARCNET) { 518 log(LOG_ERR, "arp: unknown hardware address format (0x%2D)\n", 519 (unsigned char *)&ar->ar_hrd, ""); 520 m_freem(m); 521 return; 522 } |
523 |
524 if (m->m_pkthdr.len < arphdr_len(ar) && 525 (m = m_pullup(m, arphdr_len(ar))) == NULL) { 526 log(LOG_ERR, "arp: runt packet\n"); 527 m_freem(m); 528 return; 529 } |
530 |
531 switch (ntohs(ar->ar_pro)) { |
532#ifdef INET |
533 case ETHERTYPE_IP: 534 in_arpinput(m); 535 return; |
536#endif |
537 } |
538 m_freem(m); |
539} 540 541#ifdef INET 542/* 543 * ARP for Internet protocols on 10 Mb/s Ethernet. 544 * Algorithm is that given in RFC 826. 545 * In addition, a sanity check is performed on the sender 546 * protocol address, to catch impersonators. --- 395 unchanged lines hidden (view full) --- 942 943static void 944arp_init(void) 945{ 946 947 arpintrq.ifq_maxlen = 50; 948 mtx_init(&arpintrq.ifq_mtx, "arp_inq", NULL, MTX_DEF); 949 LIST_INIT(&llinfo_arp); |
950 netisr_register(NETISR_ARP, arpintr, &arpintrq); |
951} 952 953SYSINIT(arp, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY, arp_init, 0); |