if_ether.c (5b628e0c26d11e34ac50d8f83971db6450c9d872) if_ether.c (54fc657d59324e260dd5cde0d6e7f60d43a41c60)
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

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

75
76#include <security/mac/mac_framework.h>
77
78#define SIN(s) ((struct sockaddr_in *)s)
79#define SDL(s) ((struct sockaddr_dl *)s)
80
81SYSCTL_DECL(_net_link_ether);
82SYSCTL_NODE(_net_link_ether, PF_INET, inet, CTLFLAG_RW, 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

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

75
76#include <security/mac/mac_framework.h>
77
78#define SIN(s) ((struct sockaddr_in *)s)
79#define SDL(s) ((struct sockaddr_dl *)s)
80
81SYSCTL_DECL(_net_link_ether);
82SYSCTL_NODE(_net_link_ether, PF_INET, inet, CTLFLAG_RW, 0, "");
83SYSCTL_NODE(_net_link_ether, PF_ARP, arp, CTLFLAG_RW, 0, "");
83
84VNET_DEFINE(int, useloopback) = 1; /* use loopback interface for
85 * local traffic */
86
87/* timer values */
88static VNET_DEFINE(int, arpt_keep) = (20*60); /* once resolved, good for 20
89 * minutes */
90static VNET_DEFINE(int, arp_maxtries) = 5;
91static VNET_DEFINE(int, arp_proxyall);
84
85VNET_DEFINE(int, useloopback) = 1; /* use loopback interface for
86 * local traffic */
87
88/* timer values */
89static VNET_DEFINE(int, arpt_keep) = (20*60); /* once resolved, good for 20
90 * minutes */
91static VNET_DEFINE(int, arp_maxtries) = 5;
92static VNET_DEFINE(int, arp_proxyall);
93static VNET_DEFINE(struct arpstat, arpstat); /* ARP statistics, see if_arp.h */
92
93#define V_arpt_keep VNET(arpt_keep)
94#define V_arp_maxtries VNET(arp_maxtries)
95#define V_arp_proxyall VNET(arp_proxyall)
94
95#define V_arpt_keep VNET(arpt_keep)
96#define V_arp_maxtries VNET(arp_maxtries)
97#define V_arp_proxyall VNET(arp_proxyall)
98#define V_arpstat VNET(arpstat)
96
97SYSCTL_VNET_INT(_net_link_ether_inet, OID_AUTO, max_age, CTLFLAG_RW,
98 &VNET_NAME(arpt_keep), 0,
99 "ARP entry lifetime in seconds");
100
101SYSCTL_VNET_INT(_net_link_ether_inet, OID_AUTO, maxtries, CTLFLAG_RW,
102 &VNET_NAME(arp_maxtries), 0,
103 "ARP resolution attempts before returning error");
104SYSCTL_VNET_INT(_net_link_ether_inet, OID_AUTO, useloopback, CTLFLAG_RW,
105 &VNET_NAME(useloopback), 0,
106 "Use the loopback interface for local traffic");
107SYSCTL_VNET_INT(_net_link_ether_inet, OID_AUTO, proxyall, CTLFLAG_RW,
108 &VNET_NAME(arp_proxyall), 0,
109 "Enable proxy ARP for all suitable requests");
99
100SYSCTL_VNET_INT(_net_link_ether_inet, OID_AUTO, max_age, CTLFLAG_RW,
101 &VNET_NAME(arpt_keep), 0,
102 "ARP entry lifetime in seconds");
103
104SYSCTL_VNET_INT(_net_link_ether_inet, OID_AUTO, maxtries, CTLFLAG_RW,
105 &VNET_NAME(arp_maxtries), 0,
106 "ARP resolution attempts before returning error");
107SYSCTL_VNET_INT(_net_link_ether_inet, OID_AUTO, useloopback, CTLFLAG_RW,
108 &VNET_NAME(useloopback), 0,
109 "Use the loopback interface for local traffic");
110SYSCTL_VNET_INT(_net_link_ether_inet, OID_AUTO, proxyall, CTLFLAG_RW,
111 &VNET_NAME(arp_proxyall), 0,
112 "Enable proxy ARP for all suitable requests");
113SYSCTL_VNET_STRUCT(_net_link_ether_arp, OID_AUTO, stats, CTLFLAG_RW,
114 &VNET_NAME(arpstat), arpstat,
115 "ARP statistics (struct arpstat, net/if_arp.h)");
110
111static void arp_init(void);
112void arprequest(struct ifnet *,
113 struct in_addr *, struct in_addr *, u_char *);
114static void arpintr(struct mbuf *);
115static void arptimer(void *);
116#ifdef INET
117static void in_arpinput(struct mbuf *);

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

158 struct ifnet *ifp;
159 struct llentry *lle = (struct llentry *)arg;
160
161 if (lle == NULL) {
162 panic("%s: NULL entry!\n", __func__);
163 return;
164 }
165 ifp = lle->lle_tbl->llt_ifp;
116
117static void arp_init(void);
118void arprequest(struct ifnet *,
119 struct in_addr *, struct in_addr *, u_char *);
120static void arpintr(struct mbuf *);
121static void arptimer(void *);
122#ifdef INET
123static void in_arpinput(struct mbuf *);

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

164 struct ifnet *ifp;
165 struct llentry *lle = (struct llentry *)arg;
166
167 if (lle == NULL) {
168 panic("%s: NULL entry!\n", __func__);
169 return;
170 }
171 ifp = lle->lle_tbl->llt_ifp;
172 CURVNET_SET(ifp->if_vnet);
166 IF_AFDATA_LOCK(ifp);
167 LLE_WLOCK(lle);
173 IF_AFDATA_LOCK(ifp);
174 LLE_WLOCK(lle);
168 if (((lle->la_flags & LLE_DELETED)
169 || (time_second >= lle->la_expire))
170 && (!callout_pending(&lle->la_timer) &&
171 callout_active(&lle->la_timer)))
175 if (((lle->la_flags & LLE_DELETED) ||
176 (time_second >= lle->la_expire)) &&
177 (!callout_pending(&lle->la_timer) &&
178 callout_active(&lle->la_timer))) {
172 (void) llentry_free(lle);
179 (void) llentry_free(lle);
173 else {
180 ARPSTAT_INC(timeouts);
181 } else {
174 /*
175 * Still valid, just drop our reference
176 */
177 LLE_FREE_LOCKED(lle);
178 }
179 IF_AFDATA_UNLOCK(ifp);
182 /*
183 * Still valid, just drop our reference
184 */
185 LLE_FREE_LOCKED(lle);
186 }
187 IF_AFDATA_UNLOCK(ifp);
188 CURVNET_RESTORE();
180}
181
182/*
183 * Broadcast an ARP request. Caller specifies:
184 * - arp header source ip address
185 * - arp header target ip address
186 * - arp header source ethernet address
187 */

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

233 ah->ar_op = htons(ARPOP_REQUEST);
234 bcopy((caddr_t)enaddr, (caddr_t)ar_sha(ah), ah->ar_hln);
235 bcopy((caddr_t)sip, (caddr_t)ar_spa(ah), ah->ar_pln);
236 bcopy((caddr_t)tip, (caddr_t)ar_tpa(ah), ah->ar_pln);
237 sa.sa_family = AF_ARP;
238 sa.sa_len = 2;
239 m->m_flags |= M_BCAST;
240 (*ifp->if_output)(ifp, m, &sa, NULL);
189}
190
191/*
192 * Broadcast an ARP request. Caller specifies:
193 * - arp header source ip address
194 * - arp header target ip address
195 * - arp header source ethernet address
196 */

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

242 ah->ar_op = htons(ARPOP_REQUEST);
243 bcopy((caddr_t)enaddr, (caddr_t)ar_sha(ah), ah->ar_hln);
244 bcopy((caddr_t)sip, (caddr_t)ar_spa(ah), ah->ar_pln);
245 bcopy((caddr_t)tip, (caddr_t)ar_tpa(ah), ah->ar_pln);
246 sa.sa_family = AF_ARP;
247 sa.sa_len = 2;
248 m->m_flags |= M_BCAST;
249 (*ifp->if_output)(ifp, m, &sa, NULL);
250 ARPSTAT_INC(txrequests);
241}
242
243/*
244 * Resolve an IP address into an ethernet address.
245 * On input:
246 * ifp is the interface we use
247 * rt0 is the route to the final destination (possibly useless)
248 * m is the mbuf. May be NULL if we don't have a packet.

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

334 goto retry;
335 }
336 /*
337 * There is an arptab entry, but no ethernet address
338 * response yet. Replace the held mbuf with this
339 * latest one.
340 */
341 if (m != NULL) {
251}
252
253/*
254 * Resolve an IP address into an ethernet address.
255 * On input:
256 * ifp is the interface we use
257 * rt0 is the route to the final destination (possibly useless)
258 * m is the mbuf. May be NULL if we don't have a packet.

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

344 goto retry;
345 }
346 /*
347 * There is an arptab entry, but no ethernet address
348 * response yet. Replace the held mbuf with this
349 * latest one.
350 */
351 if (m != NULL) {
342 if (la->la_hold != NULL)
352 if (la->la_hold != NULL) {
343 m_freem(la->la_hold);
353 m_freem(la->la_hold);
354 ARPSTAT_INC(dropped);
355 }
344 la->la_hold = m;
345 if (renew == 0 && (flags & LLE_EXCLUSIVE)) {
346 flags &= ~LLE_EXCLUSIVE;
347 LLE_DOWNGRADE(la);
348 }
349
350 }
351 /*

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

408 if ((m = m_pullup(m, arphdr_len(ar))) == NULL) {
409 log(LOG_ERR, "arp: runt packet\n");
410 m_freem(m);
411 return;
412 }
413 ar = mtod(m, struct arphdr *);
414 }
415
356 la->la_hold = m;
357 if (renew == 0 && (flags & LLE_EXCLUSIVE)) {
358 flags &= ~LLE_EXCLUSIVE;
359 LLE_DOWNGRADE(la);
360 }
361
362 }
363 /*

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

420 if ((m = m_pullup(m, arphdr_len(ar))) == NULL) {
421 log(LOG_ERR, "arp: runt packet\n");
422 m_freem(m);
423 return;
424 }
425 ar = mtod(m, struct arphdr *);
426 }
427
428 ARPSTAT_INC(received);
416 switch (ntohs(ar->ar_pro)) {
417#ifdef INET
418 case ETHERTYPE_IP:
419 in_arpinput(m);
420 return;
421#endif
422 }
423 m_freem(m);

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

488 return;
489 }
490
491 ah = mtod(m, struct arphdr *);
492 op = ntohs(ah->ar_op);
493 (void)memcpy(&isaddr, ar_spa(ah), sizeof (isaddr));
494 (void)memcpy(&itaddr, ar_tpa(ah), sizeof (itaddr));
495
429 switch (ntohs(ar->ar_pro)) {
430#ifdef INET
431 case ETHERTYPE_IP:
432 in_arpinput(m);
433 return;
434#endif
435 }
436 m_freem(m);

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

501 return;
502 }
503
504 ah = mtod(m, struct arphdr *);
505 op = ntohs(ah->ar_op);
506 (void)memcpy(&isaddr, ar_spa(ah), sizeof (isaddr));
507 (void)memcpy(&itaddr, ar_tpa(ah), sizeof (itaddr));
508
509 if (op == ARPOP_REPLY)
510 ARPSTAT_INC(rxreplies);
511
496 /*
497 * For a bridge, we want to check the address irrespective
498 * of the receive interface. (This will change slightly
499 * when we have clusters of interfaces).
500 * If the interface does not match, but the recieving interface
501 * is part of carp, we call carp_iamatch to see if this is a
502 * request for the virtual host ip.
503 * XXX: This is really ugly!

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

598 * potential misconfiguration.
599 */
600 if (!bridged && isaddr.s_addr == myaddr.s_addr && myaddr.s_addr != 0) {
601 log(LOG_ERR,
602 "arp: %*D is using my IP address %s on %s!\n",
603 ifp->if_addrlen, (u_char *)ar_sha(ah), ":",
604 inet_ntoa(isaddr), ifp->if_xname);
605 itaddr = myaddr;
512 /*
513 * For a bridge, we want to check the address irrespective
514 * of the receive interface. (This will change slightly
515 * when we have clusters of interfaces).
516 * If the interface does not match, but the recieving interface
517 * is part of carp, we call carp_iamatch to see if this is a
518 * request for the virtual host ip.
519 * XXX: This is really ugly!

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

614 * potential misconfiguration.
615 */
616 if (!bridged && isaddr.s_addr == myaddr.s_addr && myaddr.s_addr != 0) {
617 log(LOG_ERR,
618 "arp: %*D is using my IP address %s on %s!\n",
619 ifp->if_addrlen, (u_char *)ar_sha(ah), ":",
620 inet_ntoa(isaddr), ifp->if_xname);
621 itaddr = myaddr;
622 ARPSTAT_INC(dupips);
606 goto reply;
607 }
608 if (ifp->if_flags & IFF_STATICARP)
609 goto reply;
610
611 bzero(&sin, sizeof(sin));
612 sin.sin_len = sizeof(struct sockaddr_in);
613 sin.sin_family = AF_INET;

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

681 }
682 LLE_WUNLOCK(la);
683 if (hold != NULL)
684 (*ifp->if_output)(ifp, hold, &sa, NULL);
685 }
686reply:
687 if (op != ARPOP_REQUEST)
688 goto drop;
623 goto reply;
624 }
625 if (ifp->if_flags & IFF_STATICARP)
626 goto reply;
627
628 bzero(&sin, sizeof(sin));
629 sin.sin_len = sizeof(struct sockaddr_in);
630 sin.sin_family = AF_INET;

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

698 }
699 LLE_WUNLOCK(la);
700 if (hold != NULL)
701 (*ifp->if_output)(ifp, hold, &sa, NULL);
702 }
703reply:
704 if (op != ARPOP_REQUEST)
705 goto drop;
706 ARPSTAT_INC(rxrequests);
689
690 if (itaddr.s_addr == myaddr.s_addr) {
691 /* Shortcut.. the receiving interface is the target. */
692 (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
693 (void)memcpy(ar_sha(ah), enaddr, ah->ar_hln);
694 } else {
695 struct llentry *lle = NULL;
696

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

769 (void)memcpy(ar_spa(ah), &itaddr, ah->ar_pln);
770 ah->ar_op = htons(ARPOP_REPLY);
771 ah->ar_pro = htons(ETHERTYPE_IP); /* let's be sure! */
772 m->m_len = sizeof(*ah) + (2 * ah->ar_pln) + (2 * ah->ar_hln);
773 m->m_pkthdr.len = m->m_len;
774 sa.sa_family = AF_ARP;
775 sa.sa_len = 2;
776 (*ifp->if_output)(ifp, m, &sa, NULL);
707
708 if (itaddr.s_addr == myaddr.s_addr) {
709 /* Shortcut.. the receiving interface is the target. */
710 (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
711 (void)memcpy(ar_sha(ah), enaddr, ah->ar_hln);
712 } else {
713 struct llentry *lle = NULL;
714

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

787 (void)memcpy(ar_spa(ah), &itaddr, ah->ar_pln);
788 ah->ar_op = htons(ARPOP_REPLY);
789 ah->ar_pro = htons(ETHERTYPE_IP); /* let's be sure! */
790 m->m_len = sizeof(*ah) + (2 * ah->ar_pln) + (2 * ah->ar_hln);
791 m->m_pkthdr.len = m->m_len;
792 sa.sa_family = AF_ARP;
793 sa.sa_len = 2;
794 (*ifp->if_output)(ifp, m, &sa, NULL);
795 ARPSTAT_INC(txreplies);
777 return;
778
779drop:
780 m_freem(m);
781}
782#endif
783
784void

--- 41 unchanged lines hidden ---
796 return;
797
798drop:
799 m_freem(m);
800}
801#endif
802
803void

--- 41 unchanged lines hidden ---