if_arp.c revision 1.126 1 /* $NetBSD: if_arp.c,v 1.126 2007/08/27 01:13:09 dyoung Exp $ */
2
3 /*-
4 * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Public Access Networks Corporation ("Panix"). It was developed under
9 * contract to Panix by Eric Haszlakiewicz and Thor Lancelot Simon.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 /*
41 * Copyright (c) 1982, 1986, 1988, 1993
42 * The Regents of the University of California. All rights reserved.
43 *
44 * Redistribution and use in source and binary forms, with or without
45 * modification, are permitted provided that the following conditions
46 * are met:
47 * 1. Redistributions of source code must retain the above copyright
48 * notice, this list of conditions and the following disclaimer.
49 * 2. Redistributions in binary form must reproduce the above copyright
50 * notice, this list of conditions and the following disclaimer in the
51 * documentation and/or other materials provided with the distribution.
52 * 3. Neither the name of the University nor the names of its contributors
53 * may be used to endorse or promote products derived from this software
54 * without specific prior written permission.
55 *
56 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
59 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
60 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
62 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
65 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66 * SUCH DAMAGE.
67 *
68 * @(#)if_ether.c 8.2 (Berkeley) 9/26/94
69 */
70
71 /*
72 * Ethernet address resolution protocol.
73 * TODO:
74 * add "inuse/lock" bit (or ref. count) along with valid bit
75 */
76
77 #include <sys/cdefs.h>
78 __KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.126 2007/08/27 01:13:09 dyoung Exp $");
79
80 #include "opt_ddb.h"
81 #include "opt_inet.h"
82
83 #ifdef INET
84
85 #include "bridge.h"
86
87 #include <sys/param.h>
88 #include <sys/systm.h>
89 #include <sys/callout.h>
90 #include <sys/malloc.h>
91 #include <sys/mbuf.h>
92 #include <sys/socket.h>
93 #include <sys/time.h>
94 #include <sys/timetc.h>
95 #include <sys/kernel.h>
96 #include <sys/errno.h>
97 #include <sys/ioctl.h>
98 #include <sys/syslog.h>
99 #include <sys/proc.h>
100 #include <sys/protosw.h>
101 #include <sys/domain.h>
102 #include <sys/sysctl.h>
103
104 #include <net/ethertypes.h>
105 #include <net/if.h>
106 #include <net/if_dl.h>
107 #include <net/if_token.h>
108 #include <net/if_types.h>
109 #include <net/if_ether.h>
110 #include <net/route.h>
111
112 #include <netinet/in.h>
113 #include <netinet/in_systm.h>
114 #include <netinet/in_var.h>
115 #include <netinet/ip.h>
116 #include <netinet/if_inarp.h>
117
118 #include "arc.h"
119 #if NARC > 0
120 #include <net/if_arc.h>
121 #endif
122 #include "fddi.h"
123 #if NFDDI > 0
124 #include <net/if_fddi.h>
125 #endif
126 #include "token.h"
127 #include "carp.h"
128 #if NCARP > 0
129 #include <netinet/ip_carp.h>
130 #endif
131
132 #define SIN(s) ((struct sockaddr_in *)s)
133 #define SRP(s) ((struct sockaddr_inarp *)s)
134
135 /*
136 * ARP trailer negotiation. Trailer protocol is not IP specific,
137 * but ARP request/response use IP addresses.
138 */
139 #define ETHERTYPE_IPTRAILERS ETHERTYPE_TRAIL
140
141 /* timer values */
142 int arpt_prune = (5*60*1); /* walk list every 5 minutes */
143 int arpt_keep = (20*60); /* once resolved, good for 20 more minutes */
144 int arpt_down = 20; /* once declared down, don't send for 20 secs */
145 int arpt_refresh = (5*60); /* time left before refreshing */
146 #define rt_expire rt_rmx.rmx_expire
147 #define rt_pksent rt_rmx.rmx_pksent
148
149 static struct sockaddr *arp_setgate(struct rtentry *, struct sockaddr *,
150 const struct sockaddr *);
151 static void arptfree(struct llinfo_arp *);
152 static void arptimer(void *);
153 static struct llinfo_arp *arplookup1(struct mbuf *, const struct in_addr *,
154 int, int, struct rtentry *);
155 static struct llinfo_arp *arplookup(struct mbuf *, const struct in_addr *,
156 int, int);
157 static void in_arpinput(struct mbuf *);
158
159 LIST_HEAD(, llinfo_arp) llinfo_arp;
160 struct ifqueue arpintrq = {
161 .ifq_head = NULL,
162 .ifq_tail = NULL,
163 .ifq_len = 0,
164 .ifq_maxlen = 50,
165 .ifq_drops = 0,
166 };
167 int arp_inuse, arp_allocated, arp_intimer;
168 int arp_maxtries = 5;
169 int useloopback = 1; /* use loopback interface for local traffic */
170 int arpinit_done = 0;
171
172 struct arpstat arpstat;
173 struct callout arptimer_ch;
174
175 /* Prototype for RTF_CLONING routes. */
176 static const struct sockaddr_dl null_sdl = { .sdl_len = sizeof(null_sdl),
177 .sdl_family = AF_LINK};
178
179 /* revarp state */
180 struct in_addr myip, srv_ip;
181 int myip_initialized = 0;
182 int revarp_in_progress = 0;
183 struct ifnet *myip_ifp = NULL;
184
185 #ifdef DDB
186 static void db_print_sa(const struct sockaddr *);
187 static void db_print_ifa(struct ifaddr *);
188 static void db_print_llinfo(void *);
189 static int db_show_rtentry(struct rtentry *, void *);
190 #endif
191
192 /*
193 * this should be elsewhere.
194 */
195
196 static char *
197 lla_snprintf(u_int8_t *, int);
198
199 static char *
200 lla_snprintf(u_int8_t *adrp, int len)
201 {
202 #define NUMBUFS 3
203 static char buf[NUMBUFS][16*3];
204 static int bnum = 0;
205
206 int i;
207 char *p;
208
209 p = buf[bnum];
210
211 *p++ = hexdigits[(*adrp)>>4];
212 *p++ = hexdigits[(*adrp++)&0xf];
213
214 for (i=1; i<len && i<16; i++) {
215 *p++ = ':';
216 *p++ = hexdigits[(*adrp)>>4];
217 *p++ = hexdigits[(*adrp++)&0xf];
218 }
219
220 *p = 0;
221 p = buf[bnum];
222 bnum = (bnum + 1) % NUMBUFS;
223 return p;
224 }
225
226 DOMAIN_DEFINE(arpdomain); /* forward declare and add to link set */
227
228 const struct protosw arpsw[] = {
229 { 0, &arpdomain, 0, 0,
230 0, 0, 0, 0,
231 0,
232 0, 0, 0, arp_drain,
233 }
234 };
235
236
237 struct domain arpdomain = {
238 .dom_family = PF_ARP,
239 .dom_name = "arp",
240 .dom_protosw = arpsw,
241 .dom_protoswNPROTOSW = &arpsw[sizeof(arpsw)/sizeof(arpsw[0])],
242 };
243
244 /*
245 * ARP table locking.
246 *
247 * to prevent lossage vs. the arp_drain routine (which may be called at
248 * any time, including in a device driver context), we do two things:
249 *
250 * 1) manipulation of la->la_hold is done at splnet() (for all of
251 * about two instructions).
252 *
253 * 2) manipulation of the arp table's linked list is done under the
254 * protection of the ARP_LOCK; if arp_drain() or arptimer is called
255 * while the arp table is locked, we punt and try again later.
256 */
257
258 static int arp_locked;
259 static inline int arp_lock_try(int);
260 static inline void arp_unlock(void);
261
262 static inline int
263 arp_lock_try(int recurse)
264 {
265 int s;
266
267 /*
268 * Use splvm() -- we're blocking things that would cause
269 * mbuf allocation.
270 */
271 s = splvm();
272 if (!recurse && arp_locked) {
273 splx(s);
274 return (0);
275 }
276 arp_locked++;
277 splx(s);
278 return (1);
279 }
280
281 static inline void
282 arp_unlock(void)
283 {
284 int s;
285
286 s = splvm();
287 arp_locked--;
288 splx(s);
289 }
290
291 #ifdef DIAGNOSTIC
292 #define ARP_LOCK(recurse) \
293 do { \
294 if (arp_lock_try(recurse) == 0) { \
295 printf("%s:%d: arp already locked\n", __FILE__, __LINE__); \
296 panic("arp_lock"); \
297 } \
298 } while (/*CONSTCOND*/ 0)
299 #define ARP_LOCK_CHECK() \
300 do { \
301 if (arp_locked == 0) { \
302 printf("%s:%d: arp lock not held\n", __FILE__, __LINE__); \
303 panic("arp lock check"); \
304 } \
305 } while (/*CONSTCOND*/ 0)
306 #else
307 #define ARP_LOCK(x) (void) arp_lock_try(x)
308 #define ARP_LOCK_CHECK() /* nothing */
309 #endif
310
311 #define ARP_UNLOCK() arp_unlock()
312
313 /*
314 * ARP protocol drain routine. Called when memory is in short supply.
315 * Called at splvm();
316 */
317
318 void
319 arp_drain(void)
320 {
321 struct llinfo_arp *la, *nla;
322 int count = 0;
323 struct mbuf *mold;
324
325 if (arp_lock_try(0) == 0) {
326 printf("arp_drain: locked; punting\n");
327 return;
328 }
329
330 for (la = LIST_FIRST(&llinfo_arp); la != 0; la = nla) {
331 nla = LIST_NEXT(la, la_list);
332
333 mold = la->la_hold;
334 la->la_hold = 0;
335
336 if (mold) {
337 m_freem(mold);
338 count++;
339 }
340 }
341 ARP_UNLOCK();
342 arpstat.as_dfrdropped += count;
343 }
344
345
346 /*
347 * Timeout routine. Age arp_tab entries periodically.
348 */
349 /* ARGSUSED */
350 static void
351 arptimer(void *arg)
352 {
353 int s;
354 struct llinfo_arp *la, *nla;
355
356 s = splsoftnet();
357
358 if (arp_lock_try(0) == 0) {
359 /* get it later.. */
360 splx(s);
361 return;
362 }
363
364 callout_reset(&arptimer_ch, arpt_prune * hz, arptimer, NULL);
365 for (la = LIST_FIRST(&llinfo_arp); la != 0; la = nla) {
366 struct rtentry *rt = la->la_rt;
367
368 nla = LIST_NEXT(la, la_list);
369 if (rt->rt_expire == 0)
370 continue;
371 if ((rt->rt_expire - time_second) < arpt_refresh &&
372 rt->rt_pksent > (time_second - arpt_keep)) {
373 /*
374 * If the entry has been used during since last
375 * refresh, try to renew it before deleting.
376 */
377 arprequest(rt->rt_ifp,
378 &satocsin(rt->rt_ifa->ifa_addr)->sin_addr,
379 &satocsin(rt_getkey(rt))->sin_addr,
380 LLADDR(rt->rt_ifp->if_sadl));
381 } else if (rt->rt_expire <= time_second)
382 arptfree(la); /* timer has expired; clear */
383 }
384
385 ARP_UNLOCK();
386
387 splx(s);
388 }
389
390 /*
391 * We set the gateway for RTF_CLONING routes to a "prototype"
392 * link-layer sockaddr whose interface type (if_type) and interface
393 * index (if_index) fields are prepared.
394 */
395 static struct sockaddr *
396 arp_setgate(struct rtentry *rt, struct sockaddr *gate,
397 const struct sockaddr *netmask)
398 {
399 /*
400 * XXX: If this is a manually added route to interface
401 * such as older version of routed or gated might provide,
402 * restore cloning bit.
403 */
404 if ((rt->rt_flags & RTF_HOST) == 0 && netmask != NULL &&
405 satocsin(netmask)->sin_addr.s_addr != 0xffffffff)
406 rt->rt_flags |= RTF_CLONING;
407 if (rt->rt_flags & RTF_CLONING) {
408 /*
409 * Case 1: This route should come from a route to iface.
410 */
411 rt_setgate(rt, (const struct sockaddr *)&null_sdl);
412 gate = rt->rt_gateway;
413 satosdl(gate)->sdl_type = rt->rt_ifp->if_type;
414 satosdl(gate)->sdl_index = rt->rt_ifp->if_index;
415 }
416 return gate;
417 }
418
419 /*
420 * Parallel to llc_rtrequest.
421 */
422 void
423 arp_rtrequest(int req, struct rtentry *rt, struct rt_addrinfo *info)
424 {
425 struct sockaddr *gate = rt->rt_gateway;
426 struct llinfo_arp *la = (struct llinfo_arp *)rt->rt_llinfo;
427 size_t allocsize;
428 struct mbuf *mold;
429 int s;
430 struct in_ifaddr *ia;
431 struct ifaddr *ifa;
432
433 if (!arpinit_done) {
434 arpinit_done = 1;
435 /*
436 * We generate expiration times from time_second
437 * so avoid accidentally creating permanent routes.
438 */
439 if (time_second == 0) {
440 #ifdef __HAVE_TIMECOUNTER
441 struct timespec ts;
442 ts.tv_sec = 1;
443 ts.tv_nsec = 0;
444 tc_setclock(&ts);
445 #else /* !__HAVE_TIMECOUNTER */
446 time.tv_sec++;
447 #endif /* !__HAVE_TIMECOUNTER */
448 }
449 callout_init(&arptimer_ch, 0);
450 callout_reset(&arptimer_ch, hz, arptimer, NULL);
451 }
452
453 if ((rt->rt_flags & RTF_GATEWAY) != 0) {
454 if (req != RTM_ADD)
455 return;
456
457 /*
458 * linklayers with particular link MTU limitation.
459 */
460 switch(rt->rt_ifp->if_type) {
461 #if NFDDI > 0
462 case IFT_FDDI:
463 if (rt->rt_ifp->if_mtu > FDDIIPMTU)
464 rt->rt_rmx.rmx_mtu = FDDIIPMTU;
465 break;
466 #endif
467 #if NARC > 0
468 case IFT_ARCNET:
469 {
470 int arcipifmtu;
471
472 if (rt->rt_ifp->if_flags & IFF_LINK0)
473 arcipifmtu = arc_ipmtu;
474 else
475 arcipifmtu = ARCMTU;
476 if (rt->rt_ifp->if_mtu > arcipifmtu)
477 rt->rt_rmx.rmx_mtu = arcipifmtu;
478 break;
479 }
480 #endif
481 }
482 return;
483 }
484
485 ARP_LOCK(1); /* we may already be locked here. */
486
487 switch (req) {
488
489 case RTM_SETGATE:
490 gate = arp_setgate(rt, gate, info->rti_info[RTAX_NETMASK]);
491 break;
492 case RTM_ADD:
493 gate = arp_setgate(rt, gate, info->rti_info[RTAX_NETMASK]);
494 if (rt->rt_flags & RTF_CLONING) {
495 /*
496 * Give this route an expiration time, even though
497 * it's a "permanent" route, so that routes cloned
498 * from it do not need their expiration time set.
499 */
500 rt->rt_expire = time_second;
501 /*
502 * linklayers with particular link MTU limitation.
503 */
504 switch (rt->rt_ifp->if_type) {
505 #if NFDDI > 0
506 case IFT_FDDI:
507 if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0 &&
508 (rt->rt_rmx.rmx_mtu > FDDIIPMTU ||
509 (rt->rt_rmx.rmx_mtu == 0 &&
510 rt->rt_ifp->if_mtu > FDDIIPMTU)))
511 rt->rt_rmx.rmx_mtu = FDDIIPMTU;
512 break;
513 #endif
514 #if NARC > 0
515 case IFT_ARCNET:
516 {
517 int arcipifmtu;
518 if (rt->rt_ifp->if_flags & IFF_LINK0)
519 arcipifmtu = arc_ipmtu;
520 else
521 arcipifmtu = ARCMTU;
522
523 if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0 &&
524 (rt->rt_rmx.rmx_mtu > arcipifmtu ||
525 (rt->rt_rmx.rmx_mtu == 0 &&
526 rt->rt_ifp->if_mtu > arcipifmtu)))
527 rt->rt_rmx.rmx_mtu = arcipifmtu;
528 break;
529 }
530 #endif
531 }
532 break;
533 }
534 /* Announce a new entry if requested. */
535 if (rt->rt_flags & RTF_ANNOUNCE)
536 arprequest(rt->rt_ifp,
537 &satocsin(rt_getkey(rt))->sin_addr,
538 &satocsin(rt_getkey(rt))->sin_addr,
539 CLLADDR(satocsdl(gate)));
540 /*FALLTHROUGH*/
541 case RTM_RESOLVE:
542 if (gate->sa_family != AF_LINK ||
543 gate->sa_len < sizeof(null_sdl)) {
544 log(LOG_DEBUG, "arp_rtrequest: bad gateway value\n");
545 break;
546 }
547 satosdl(gate)->sdl_type = rt->rt_ifp->if_type;
548 satosdl(gate)->sdl_index = rt->rt_ifp->if_index;
549 if (la != 0)
550 break; /* This happens on a route change */
551 /*
552 * Case 2: This route may come from cloning, or a manual route
553 * add with a LL address.
554 */
555 switch (satocsdl(gate)->sdl_type) {
556 #if NTOKEN > 0
557 case IFT_ISO88025:
558 allocsize = sizeof(*la) + sizeof(struct token_rif);
559 break;
560 #endif /* NTOKEN > 0 */
561 default:
562 allocsize = sizeof(*la);
563 }
564 R_Malloc(la, struct llinfo_arp *, allocsize);
565 rt->rt_llinfo = (void *)la;
566 if (la == 0) {
567 log(LOG_DEBUG, "arp_rtrequest: malloc failed\n");
568 break;
569 }
570 arp_inuse++, arp_allocated++;
571 Bzero(la, allocsize);
572 la->la_rt = rt;
573 rt->rt_flags |= RTF_LLINFO;
574 LIST_INSERT_HEAD(&llinfo_arp, la, la_list);
575
576 INADDR_TO_IA(satocsin(rt_getkey(rt))->sin_addr, ia);
577 while (ia && ia->ia_ifp != rt->rt_ifp)
578 NEXT_IA_WITH_SAME_ADDR(ia);
579 if (ia) {
580 /*
581 * This test used to be
582 * if (lo0ifp->if_flags & IFF_UP)
583 * It allowed local traffic to be forced through
584 * the hardware by configuring the loopback down.
585 * However, it causes problems during network
586 * configuration for boards that can't receive
587 * packets they send. It is now necessary to clear
588 * "useloopback" and remove the route to force
589 * traffic out to the hardware.
590 *
591 * In 4.4BSD, the above "if" statement checked
592 * rt->rt_ifa against rt_getkey(rt). It was changed
593 * to the current form so that we can provide a
594 * better support for multiple IPv4 addresses on a
595 * interface.
596 */
597 rt->rt_expire = 0;
598 (void)sockaddr_dl_setaddr(satosdl(gate),
599 CLLADDR(rt->rt_ifp->if_sadl),
600 rt->rt_ifp->if_addrlen);
601 if (useloopback)
602 rt->rt_ifp = lo0ifp;
603 /*
604 * make sure to set rt->rt_ifa to the interface
605 * address we are using, otherwise we will have trouble
606 * with source address selection.
607 */
608 ifa = &ia->ia_ifa;
609 if (ifa != rt->rt_ifa)
610 rt_replace_ifa(rt, ifa);
611 }
612 break;
613
614 case RTM_DELETE:
615 if (la == 0)
616 break;
617 arp_inuse--;
618 LIST_REMOVE(la, la_list);
619 rt->rt_llinfo = 0;
620 rt->rt_flags &= ~RTF_LLINFO;
621
622 s = splnet();
623 mold = la->la_hold;
624 la->la_hold = 0;
625 splx(s);
626
627 if (mold)
628 m_freem(mold);
629
630 Free((void *)la);
631 }
632 ARP_UNLOCK();
633 }
634
635 /*
636 * Broadcast an ARP request. Caller specifies:
637 * - arp header source ip address
638 * - arp header target ip address
639 * - arp header source ethernet address
640 */
641 void
642 arprequest(struct ifnet *ifp,
643 const struct in_addr *sip, const struct in_addr *tip,
644 const u_int8_t *enaddr)
645 {
646 struct mbuf *m;
647 struct arphdr *ah;
648 struct sockaddr sa;
649
650 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
651 return;
652 MCLAIM(m, &arpdomain.dom_mowner);
653 switch (ifp->if_type) {
654 case IFT_IEEE1394:
655 m->m_len = sizeof(*ah) + 2 * sizeof(struct in_addr) +
656 ifp->if_addrlen;
657 break;
658 default:
659 m->m_len = sizeof(*ah) + 2 * sizeof(struct in_addr) +
660 2 * ifp->if_addrlen;
661 break;
662 }
663 m->m_pkthdr.len = m->m_len;
664 MH_ALIGN(m, m->m_len);
665 ah = mtod(m, struct arphdr *);
666 bzero((void *)ah, m->m_len);
667 switch (ifp->if_type) {
668 case IFT_IEEE1394: /* RFC2734 */
669 /* fill it now for ar_tpa computation */
670 ah->ar_hrd = htons(ARPHRD_IEEE1394);
671 break;
672 default:
673 /* ifp->if_output will fill ar_hrd */
674 break;
675 }
676 ah->ar_pro = htons(ETHERTYPE_IP);
677 ah->ar_hln = ifp->if_addrlen; /* hardware address length */
678 ah->ar_pln = sizeof(struct in_addr); /* protocol address length */
679 ah->ar_op = htons(ARPOP_REQUEST);
680 memcpy(ar_sha(ah), enaddr, ah->ar_hln);
681 memcpy(ar_spa(ah), sip, ah->ar_pln);
682 memcpy(ar_tpa(ah), tip, ah->ar_pln);
683 sa.sa_family = AF_ARP;
684 sa.sa_len = 2;
685 m->m_flags |= M_BCAST;
686 arpstat.as_sndtotal++;
687 arpstat.as_sndrequest++;
688 (*ifp->if_output)(ifp, m, &sa, NULL);
689 }
690
691 /*
692 * Resolve an IP address into an ethernet address. If success,
693 * desten is filled in. If there is no entry in arptab,
694 * set one up and broadcast a request for the IP address.
695 * Hold onto this mbuf and resend it once the address
696 * is finally resolved. A return value of 1 indicates
697 * that desten has been filled in and the packet should be sent
698 * normally; a 0 return indicates that the packet has been
699 * taken over here, either now or for later transmission.
700 */
701 int
702 arpresolve(struct ifnet *ifp, struct rtentry *rt, struct mbuf *m,
703 const struct sockaddr *dst, u_char *desten)
704 {
705 struct llinfo_arp *la;
706 const struct sockaddr_dl *sdl;
707 struct mbuf *mold;
708 int s;
709
710 if ((la = arplookup1(m, &satocsin(dst)->sin_addr, 1, 0, rt)) != NULL)
711 rt = la->la_rt;
712
713 if (la == 0 || rt == 0) {
714 arpstat.as_allocfail++;
715 log(LOG_DEBUG,
716 "arpresolve: can't allocate llinfo on %s for %s\n",
717 ifp->if_xname, in_fmtaddr(satocsin(dst)->sin_addr));
718 m_freem(m);
719 return (0);
720 }
721 sdl = satocsdl(rt->rt_gateway);
722 /*
723 * Check the address family and length is valid, the address
724 * is resolved; otherwise, try to resolve.
725 */
726 if ((rt->rt_expire == 0 || rt->rt_expire > time_second) &&
727 sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) {
728 bcopy(CLLADDR(sdl), desten,
729 min(sdl->sdl_alen, ifp->if_addrlen));
730 rt->rt_pksent = time_second; /* Time for last pkt sent */
731 return 1;
732 }
733 /*
734 * There is an arptab entry, but no ethernet address
735 * response yet. Replace the held mbuf with this
736 * latest one.
737 */
738
739 arpstat.as_dfrtotal++;
740 s = splnet();
741 mold = la->la_hold;
742 la->la_hold = m;
743 splx(s);
744
745 if (mold) {
746 arpstat.as_dfrdropped++;
747 m_freem(mold);
748 }
749
750 /*
751 * Re-send the ARP request when appropriate.
752 */
753 #ifdef DIAGNOSTIC
754 if (rt->rt_expire == 0) {
755 /* This should never happen. (Should it? -gwr) */
756 printf("arpresolve: unresolved and rt_expire == 0\n");
757 /* Set expiration time to now (expired). */
758 rt->rt_expire = time_second;
759 }
760 #endif
761 if (rt->rt_expire) {
762 rt->rt_flags &= ~RTF_REJECT;
763 if (la->la_asked == 0 || rt->rt_expire != time_second) {
764 rt->rt_expire = time_second;
765 if (la->la_asked++ < arp_maxtries)
766 arprequest(ifp,
767 &satocsin(rt->rt_ifa->ifa_addr)->sin_addr,
768 &satocsin(dst)->sin_addr,
769 #if NCARP > 0
770 (rt->rt_ifp->if_type == IFT_CARP) ?
771 LLADDR(rt->rt_ifp->if_sadl):
772 #endif
773 LLADDR(ifp->if_sadl));
774 else {
775 rt->rt_flags |= RTF_REJECT;
776 rt->rt_expire += arpt_down;
777 la->la_asked = 0;
778 }
779 }
780 }
781 return (0);
782 }
783
784 /*
785 * Common length and type checks are done here,
786 * then the protocol-specific routine is called.
787 */
788 void
789 arpintr(void)
790 {
791 struct mbuf *m;
792 struct arphdr *ar;
793 int s;
794 int arplen;
795
796 while (arpintrq.ifq_head) {
797 s = splnet();
798 IF_DEQUEUE(&arpintrq, m);
799 splx(s);
800 if (m == 0 || (m->m_flags & M_PKTHDR) == 0)
801 panic("arpintr");
802
803 MCLAIM(m, &arpdomain.dom_mowner);
804 arpstat.as_rcvtotal++;
805
806 /*
807 * First, make sure we have at least struct arphdr.
808 */
809 if (m->m_len < sizeof(struct arphdr) ||
810 (ar = mtod(m, struct arphdr *)) == NULL)
811 goto badlen;
812
813 switch (m->m_pkthdr.rcvif->if_type) {
814 case IFT_IEEE1394:
815 arplen = sizeof(struct arphdr) +
816 ar->ar_hln + 2 * ar->ar_pln;
817 break;
818 default:
819 arplen = sizeof(struct arphdr) +
820 2 * ar->ar_hln + 2 * ar->ar_pln;
821 break;
822 }
823
824 if (/* XXX ntohs(ar->ar_hrd) == ARPHRD_ETHER && */
825 m->m_len >= arplen)
826 switch (ntohs(ar->ar_pro)) {
827 case ETHERTYPE_IP:
828 case ETHERTYPE_IPTRAILERS:
829 in_arpinput(m);
830 continue;
831 default:
832 arpstat.as_rcvbadproto++;
833 }
834 else {
835 badlen:
836 arpstat.as_rcvbadlen++;
837 }
838 m_freem(m);
839 }
840 }
841
842 /*
843 * ARP for Internet protocols on 10 Mb/s Ethernet.
844 * Algorithm is that given in RFC 826.
845 * In addition, a sanity check is performed on the sender
846 * protocol address, to catch impersonators.
847 * We no longer handle negotiations for use of trailer protocol:
848 * Formerly, ARP replied for protocol type ETHERTYPE_TRAIL sent
849 * along with IP replies if we wanted trailers sent to us,
850 * and also sent them in response to IP replies.
851 * This allowed either end to announce the desire to receive
852 * trailer packets.
853 * We no longer reply to requests for ETHERTYPE_TRAIL protocol either,
854 * but formerly didn't normally send requests.
855 */
856 static void
857 in_arpinput(struct mbuf *m)
858 {
859 struct arphdr *ah;
860 struct ifnet *ifp = m->m_pkthdr.rcvif;
861 struct llinfo_arp *la = 0;
862 struct rtentry *rt;
863 struct in_ifaddr *ia;
864 #if NBRIDGE > 0
865 struct in_ifaddr *bridge_ia = NULL;
866 #endif
867 #if NCARP > 0
868 u_int32_t count = 0, index = 0;
869 #endif
870 struct sockaddr_dl *sdl;
871 struct sockaddr sa;
872 struct in_addr isaddr, itaddr, myaddr;
873 int op;
874 struct mbuf *mold;
875 void *tha;
876 int s;
877
878 if (__predict_false(m_makewritable(&m, 0, m->m_pkthdr.len, M_DONTWAIT)))
879 goto out;
880 ah = mtod(m, struct arphdr *);
881 op = ntohs(ah->ar_op);
882
883 /*
884 * Fix up ah->ar_hrd if necessary, before using ar_tha() or
885 * ar_tpa().
886 */
887 switch (ifp->if_type) {
888 case IFT_IEEE1394:
889 if (ntohs(ah->ar_hrd) == ARPHRD_IEEE1394)
890 ;
891 else {
892 /* XXX this is to make sure we compute ar_tha right */
893 /* XXX check ar_hrd more strictly? */
894 ah->ar_hrd = htons(ARPHRD_IEEE1394);
895 }
896 break;
897 default:
898 /* XXX check ar_hrd? */
899 break;
900 }
901
902 memcpy(&isaddr, ar_spa(ah), sizeof (isaddr));
903 memcpy(&itaddr, ar_tpa(ah), sizeof (itaddr));
904
905 if (m->m_flags & (M_BCAST|M_MCAST))
906 arpstat.as_rcvmcast++;
907
908 /*
909 * If the target IP address is zero, ignore the packet.
910 * This prevents the code below from tring to answer
911 * when we are using IP address zero (booting).
912 */
913 if (in_nullhost(itaddr)) {
914 arpstat.as_rcvzerotpa++;
915 goto out;
916 }
917
918 /*
919 * If the source IP address is zero, this is most likely a
920 * confused host trying to use IP address zero. (Windoze?)
921 * XXX: Should we bother trying to reply to these?
922 */
923 if (in_nullhost(isaddr)) {
924 arpstat.as_rcvzerospa++;
925 goto out;
926 }
927
928 /*
929 * Search for a matching interface address
930 * or any address on the interface to use
931 * as a dummy address in the rest of this function
932 */
933
934 INADDR_TO_IA(itaddr, ia);
935 while (ia != NULL) {
936 #if NCARP > 0
937 if (ia->ia_ifp->if_type == IFT_CARP &&
938 ((ia->ia_ifp->if_flags & (IFF_UP|IFF_RUNNING)) ==
939 (IFF_UP|IFF_RUNNING))) {
940 index++;
941 if (ia->ia_ifp == m->m_pkthdr.rcvif &&
942 carp_iamatch(ia, ar_sha(ah),
943 &count, index)) {
944 break;
945 }
946 } else
947 #endif
948 if (ia->ia_ifp == m->m_pkthdr.rcvif)
949 break;
950 #if NBRIDGE > 0
951 /*
952 * If the interface we received the packet on
953 * is part of a bridge, check to see if we need
954 * to "bridge" the packet to ourselves at this
955 * layer. Note we still prefer a perfect match,
956 * but allow this weaker match if necessary.
957 */
958 if (m->m_pkthdr.rcvif->if_bridge != NULL &&
959 m->m_pkthdr.rcvif->if_bridge == ia->ia_ifp->if_bridge)
960 bridge_ia = ia;
961 #endif /* NBRIDGE > 0 */
962
963 NEXT_IA_WITH_SAME_ADDR(ia);
964 }
965
966 #if NBRIDGE > 0
967 if (ia == NULL && bridge_ia != NULL) {
968 ia = bridge_ia;
969 ifp = bridge_ia->ia_ifp;
970 }
971 #endif
972
973 if (ia == NULL) {
974 INADDR_TO_IA(isaddr, ia);
975 while ((ia != NULL) && ia->ia_ifp != m->m_pkthdr.rcvif)
976 NEXT_IA_WITH_SAME_ADDR(ia);
977
978 if (ia == NULL) {
979 IFP_TO_IA(ifp, ia);
980 if (ia == NULL) {
981 arpstat.as_rcvnoint++;
982 goto out;
983 }
984 }
985 }
986
987 myaddr = ia->ia_addr.sin_addr;
988
989 /* XXX checks for bridge case? */
990 if (!memcmp(ar_sha(ah), CLLADDR(ifp->if_sadl), ifp->if_addrlen)) {
991 arpstat.as_rcvlocalsha++;
992 goto out; /* it's from me, ignore it. */
993 }
994
995 /* XXX checks for bridge case? */
996 if (!memcmp(ar_sha(ah), ifp->if_broadcastaddr, ifp->if_addrlen)) {
997 arpstat.as_rcvbcastsha++;
998 log(LOG_ERR,
999 "%s: arp: link address is broadcast for IP address %s!\n",
1000 ifp->if_xname, in_fmtaddr(isaddr));
1001 goto out;
1002 }
1003
1004 if (in_hosteq(isaddr, myaddr)) {
1005 arpstat.as_rcvlocalspa++;
1006 log(LOG_ERR,
1007 "duplicate IP address %s sent from link address %s\n",
1008 in_fmtaddr(isaddr), lla_snprintf(ar_sha(ah), ah->ar_hln));
1009 itaddr = myaddr;
1010 goto reply;
1011 }
1012 la = arplookup(m, &isaddr, in_hosteq(itaddr, myaddr), 0);
1013 if (la && (rt = la->la_rt) && (sdl = satosdl(rt->rt_gateway))) {
1014 if (sdl->sdl_alen &&
1015 memcmp(ar_sha(ah), CLLADDR(sdl), sdl->sdl_alen)) {
1016 if (rt->rt_flags & RTF_STATIC) {
1017 arpstat.as_rcvoverperm++;
1018 log(LOG_INFO,
1019 "%s tried to overwrite permanent arp info"
1020 " for %s\n",
1021 lla_snprintf(ar_sha(ah), ah->ar_hln),
1022 in_fmtaddr(isaddr));
1023 goto out;
1024 } else if (rt->rt_ifp != ifp) {
1025 arpstat.as_rcvoverint++;
1026 log(LOG_INFO,
1027 "%s on %s tried to overwrite "
1028 "arp info for %s on %s\n",
1029 lla_snprintf(ar_sha(ah), ah->ar_hln),
1030 ifp->if_xname, in_fmtaddr(isaddr),
1031 rt->rt_ifp->if_xname);
1032 goto out;
1033 } else {
1034 arpstat.as_rcvover++;
1035 log(LOG_INFO,
1036 "arp info overwritten for %s by %s\n",
1037 in_fmtaddr(isaddr),
1038 lla_snprintf(ar_sha(ah), ah->ar_hln));
1039 }
1040 }
1041 /*
1042 * sanity check for the address length.
1043 * XXX this does not work for protocols with variable address
1044 * length. -is
1045 */
1046 if (sdl->sdl_alen &&
1047 sdl->sdl_alen != ah->ar_hln) {
1048 arpstat.as_rcvlenchg++;
1049 log(LOG_WARNING,
1050 "arp from %s: new addr len %d, was %d",
1051 in_fmtaddr(isaddr), ah->ar_hln, sdl->sdl_alen);
1052 }
1053 if (ifp->if_addrlen != ah->ar_hln) {
1054 arpstat.as_rcvbadlen++;
1055 log(LOG_WARNING,
1056 "arp from %s: addr len: new %d, i/f %d (ignored)",
1057 in_fmtaddr(isaddr), ah->ar_hln,
1058 ifp->if_addrlen);
1059 goto reply;
1060 }
1061 #if NTOKEN > 0
1062 /*
1063 * XXX uses m_data and assumes the complete answer including
1064 * XXX token-ring headers is in the same buf
1065 */
1066 if (ifp->if_type == IFT_ISO88025) {
1067 struct token_header *trh;
1068
1069 trh = (struct token_header *)M_TRHSTART(m);
1070 if (trh->token_shost[0] & TOKEN_RI_PRESENT) {
1071 struct token_rif *rif;
1072 size_t riflen;
1073
1074 rif = TOKEN_RIF(trh);
1075 riflen = (ntohs(rif->tr_rcf) &
1076 TOKEN_RCF_LEN_MASK) >> 8;
1077
1078 if (riflen > 2 &&
1079 riflen < sizeof(struct token_rif) &&
1080 (riflen & 1) == 0) {
1081 rif->tr_rcf ^= htons(TOKEN_RCF_DIRECTION);
1082 rif->tr_rcf &= htons(~TOKEN_RCF_BROADCAST_MASK);
1083 bcopy(rif, TOKEN_RIF(la), riflen);
1084 }
1085 }
1086 }
1087 #endif /* NTOKEN > 0 */
1088 (void)sockaddr_dl_setaddr(sdl, ar_sha(ah), ah->ar_hln);
1089 if (rt->rt_expire)
1090 rt->rt_expire = time_second + arpt_keep;
1091 rt->rt_flags &= ~RTF_REJECT;
1092 la->la_asked = 0;
1093
1094 s = splnet();
1095 mold = la->la_hold;
1096 la->la_hold = 0;
1097 splx(s);
1098
1099 if (mold) {
1100 arpstat.as_dfrsent++;
1101 (*ifp->if_output)(ifp, mold, rt_getkey(rt), rt);
1102 }
1103 }
1104 reply:
1105 if (op != ARPOP_REQUEST) {
1106 if (op == ARPOP_REPLY)
1107 arpstat.as_rcvreply++;
1108 out:
1109 m_freem(m);
1110 return;
1111 }
1112 arpstat.as_rcvrequest++;
1113 if (in_hosteq(itaddr, myaddr)) {
1114 /* I am the target */
1115 tha = ar_tha(ah);
1116 if (tha)
1117 memcpy(tha, ar_sha(ah), ah->ar_hln);
1118 memcpy(ar_sha(ah), CLLADDR(ifp->if_sadl), ah->ar_hln);
1119 } else {
1120 la = arplookup(m, &itaddr, 0, SIN_PROXY);
1121 if (la == 0)
1122 goto out;
1123 rt = la->la_rt;
1124 if (rt->rt_ifp->if_type == IFT_CARP &&
1125 m->m_pkthdr.rcvif->if_type != IFT_CARP)
1126 goto out;
1127 tha = ar_tha(ah);
1128 if (tha)
1129 memcpy(tha, ar_sha(ah), ah->ar_hln);
1130 sdl = satosdl(rt->rt_gateway);
1131 memcpy(ar_sha(ah), CLLADDR(sdl), ah->ar_hln);
1132 }
1133
1134 memcpy(ar_tpa(ah), ar_spa(ah), ah->ar_pln);
1135 memcpy(ar_spa(ah), &itaddr, ah->ar_pln);
1136 ah->ar_op = htons(ARPOP_REPLY);
1137 ah->ar_pro = htons(ETHERTYPE_IP); /* let's be sure! */
1138 switch (ifp->if_type) {
1139 case IFT_IEEE1394:
1140 /*
1141 * ieee1394 arp reply is broadcast
1142 */
1143 m->m_flags &= ~M_MCAST;
1144 m->m_flags |= M_BCAST;
1145 m->m_len = sizeof(*ah) + (2 * ah->ar_pln) + ah->ar_hln;
1146 break;
1147
1148 default:
1149 m->m_flags &= ~(M_BCAST|M_MCAST); /* never reply by broadcast */
1150 m->m_len = sizeof(*ah) + (2 * ah->ar_pln) + (2 * ah->ar_hln);
1151 break;
1152 }
1153 m->m_pkthdr.len = m->m_len;
1154 sa.sa_family = AF_ARP;
1155 sa.sa_len = 2;
1156 arpstat.as_sndtotal++;
1157 arpstat.as_sndreply++;
1158 (*ifp->if_output)(ifp, m, &sa, (struct rtentry *)0);
1159 return;
1160 }
1161
1162 /*
1163 * Free an arp entry.
1164 */
1165 static void arptfree(struct llinfo_arp *la)
1166 {
1167 struct rtentry *rt = la->la_rt;
1168 struct sockaddr_dl *sdl;
1169
1170 ARP_LOCK_CHECK();
1171
1172 if (rt == 0)
1173 panic("arptfree");
1174 if (rt->rt_refcnt > 0 && (sdl = satosdl(rt->rt_gateway)) &&
1175 sdl->sdl_family == AF_LINK) {
1176 sdl->sdl_alen = 0;
1177 la->la_asked = 0;
1178 rt->rt_flags &= ~RTF_REJECT;
1179 return;
1180 }
1181 rtrequest(RTM_DELETE, rt_getkey(rt), NULL, rt_mask(rt), 0, NULL);
1182 }
1183
1184 static struct llinfo_arp *
1185 arplookup(struct mbuf *m, const struct in_addr *addr, int create, int proxy)
1186 {
1187 return arplookup1(m, addr, create, proxy, NULL);
1188 }
1189
1190 /*
1191 * Lookup or enter a new address in arptab.
1192 */
1193 static struct llinfo_arp *
1194 arplookup1(struct mbuf *m, const struct in_addr *addr, int create, int proxy,
1195 struct rtentry *rt0)
1196 {
1197 struct arphdr *ah;
1198 struct ifnet *ifp = m->m_pkthdr.rcvif;
1199 struct rtentry *rt;
1200 static struct sockaddr_inarp sin;
1201 const char *why = 0;
1202
1203 ah = mtod(m, struct arphdr *);
1204 if (rt0 == NULL) {
1205 sin.sin_len = sizeof(sin);
1206 sin.sin_family = AF_INET;
1207 sin.sin_addr = *addr;
1208 sin.sin_other = proxy ? SIN_PROXY : 0;
1209 rt = rtalloc1(sintosa(&sin), create);
1210 if (rt == NULL)
1211 return (NULL);
1212 rt->rt_refcnt--;
1213 } else
1214 rt = rt0;
1215
1216 #define IS_LLINFO(__rt) \
1217 (((__rt)->rt_flags & (RTF_GATEWAY | RTF_LLINFO)) == RTF_LLINFO && \
1218 (__rt)->rt_gateway->sa_family == AF_LINK)
1219
1220
1221 if (IS_LLINFO(rt))
1222 return ((struct llinfo_arp *)rt->rt_llinfo);
1223
1224 if (create) {
1225 if (rt->rt_flags & RTF_GATEWAY)
1226 why = "host is not on local network";
1227 else if ((rt->rt_flags & RTF_LLINFO) == 0) {
1228 arpstat.as_allocfail++;
1229 why = "could not allocate llinfo";
1230 } else
1231 why = "gateway route is not ours";
1232 log(LOG_DEBUG, "arplookup: unable to enter address"
1233 " for %s@%s on %s (%s)\n",
1234 in_fmtaddr(*addr), lla_snprintf(ar_sha(ah), ah->ar_hln),
1235 (ifp) ? ifp->if_xname : 0, why);
1236 if (rt->rt_refcnt <= 0 && (rt->rt_flags & RTF_CLONED) != 0) {
1237 rtrequest(RTM_DELETE, rt_getkey(rt),
1238 rt->rt_gateway, rt_mask(rt), rt->rt_flags, 0);
1239 }
1240 }
1241 return (0);
1242 }
1243
1244 int
1245 arpioctl(u_long cmd, void *data)
1246 {
1247
1248 return (EOPNOTSUPP);
1249 }
1250
1251 void
1252 arp_ifinit(struct ifnet *ifp, struct ifaddr *ifa)
1253 {
1254 struct in_addr *ip;
1255
1256 /*
1257 * Warn the user if another station has this IP address,
1258 * but only if the interface IP address is not zero.
1259 */
1260 ip = &IA_SIN(ifa)->sin_addr;
1261 if (!in_nullhost(*ip))
1262 arprequest(ifp, ip, ip, LLADDR(ifp->if_sadl));
1263
1264 ifa->ifa_rtrequest = arp_rtrequest;
1265 ifa->ifa_flags |= RTF_CLONING;
1266 }
1267
1268 /*
1269 * Called from 10 Mb/s Ethernet interrupt handlers
1270 * when ether packet type ETHERTYPE_REVARP
1271 * is received. Common length and type checks are done here,
1272 * then the protocol-specific routine is called.
1273 */
1274 void
1275 revarpinput(struct mbuf *m)
1276 {
1277 struct arphdr *ar;
1278
1279 if (m->m_len < sizeof(struct arphdr))
1280 goto out;
1281 ar = mtod(m, struct arphdr *);
1282 #if 0 /* XXX I don't think we need this... and it will prevent other LL */
1283 if (ntohs(ar->ar_hrd) != ARPHRD_ETHER)
1284 goto out;
1285 #endif
1286 if (m->m_len < sizeof(struct arphdr) + 2 * (ar->ar_hln + ar->ar_pln))
1287 goto out;
1288 switch (ntohs(ar->ar_pro)) {
1289 case ETHERTYPE_IP:
1290 case ETHERTYPE_IPTRAILERS:
1291 in_revarpinput(m);
1292 return;
1293
1294 default:
1295 break;
1296 }
1297 out:
1298 m_freem(m);
1299 }
1300
1301 /*
1302 * RARP for Internet protocols on 10 Mb/s Ethernet.
1303 * Algorithm is that given in RFC 903.
1304 * We are only using for bootstrap purposes to get an ip address for one of
1305 * our interfaces. Thus we support no user-interface.
1306 *
1307 * Since the contents of the RARP reply are specific to the interface that
1308 * sent the request, this code must ensure that they are properly associated.
1309 *
1310 * Note: also supports ARP via RARP packets, per the RFC.
1311 */
1312 void
1313 in_revarpinput(struct mbuf *m)
1314 {
1315 struct ifnet *ifp;
1316 struct arphdr *ah;
1317 void *tha;
1318 int op;
1319
1320 ah = mtod(m, struct arphdr *);
1321 op = ntohs(ah->ar_op);
1322
1323 switch (m->m_pkthdr.rcvif->if_type) {
1324 case IFT_IEEE1394:
1325 /* ARP without target hardware address is not supported */
1326 goto out;
1327 default:
1328 break;
1329 }
1330
1331 switch (op) {
1332 case ARPOP_REQUEST:
1333 case ARPOP_REPLY: /* per RFC */
1334 in_arpinput(m);
1335 return;
1336 case ARPOP_REVREPLY:
1337 break;
1338 case ARPOP_REVREQUEST: /* handled by rarpd(8) */
1339 default:
1340 goto out;
1341 }
1342 if (!revarp_in_progress)
1343 goto out;
1344 ifp = m->m_pkthdr.rcvif;
1345 if (ifp != myip_ifp) /* !same interface */
1346 goto out;
1347 if (myip_initialized)
1348 goto wake;
1349 tha = ar_tha(ah);
1350 KASSERT(tha);
1351 if (bcmp(tha, CLLADDR(ifp->if_sadl), ifp->if_sadl->sdl_alen))
1352 goto out;
1353 memcpy(&srv_ip, ar_spa(ah), sizeof(srv_ip));
1354 memcpy(&myip, ar_tpa(ah), sizeof(myip));
1355 myip_initialized = 1;
1356 wake: /* Do wakeup every time in case it was missed. */
1357 wakeup((void *)&myip);
1358
1359 out:
1360 m_freem(m);
1361 }
1362
1363 /*
1364 * Send a RARP request for the ip address of the specified interface.
1365 * The request should be RFC 903-compliant.
1366 */
1367 void
1368 revarprequest(struct ifnet *ifp)
1369 {
1370 struct sockaddr sa;
1371 struct mbuf *m;
1372 struct arphdr *ah;
1373 void *tha;
1374
1375 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
1376 return;
1377 MCLAIM(m, &arpdomain.dom_mowner);
1378 m->m_len = sizeof(*ah) + 2*sizeof(struct in_addr) +
1379 2*ifp->if_addrlen;
1380 m->m_pkthdr.len = m->m_len;
1381 MH_ALIGN(m, m->m_len);
1382 ah = mtod(m, struct arphdr *);
1383 bzero((void *)ah, m->m_len);
1384 ah->ar_pro = htons(ETHERTYPE_IP);
1385 ah->ar_hln = ifp->if_addrlen; /* hardware address length */
1386 ah->ar_pln = sizeof(struct in_addr); /* protocol address length */
1387 ah->ar_op = htons(ARPOP_REVREQUEST);
1388
1389 memcpy(ar_sha(ah), CLLADDR(ifp->if_sadl), ah->ar_hln);
1390 tha = ar_tha(ah);
1391 KASSERT(tha);
1392 bcopy(CLLADDR(ifp->if_sadl), tha, ah->ar_hln);
1393
1394 sa.sa_family = AF_ARP;
1395 sa.sa_len = 2;
1396 m->m_flags |= M_BCAST;
1397 (*ifp->if_output)(ifp, m, &sa, (struct rtentry *)0);
1398
1399 }
1400
1401 /*
1402 * RARP for the ip address of the specified interface, but also
1403 * save the ip address of the server that sent the answer.
1404 * Timeout if no response is received.
1405 */
1406 int
1407 revarpwhoarewe(struct ifnet *ifp, struct in_addr *serv_in,
1408 struct in_addr *clnt_in)
1409 {
1410 int result, count = 20;
1411
1412 myip_initialized = 0;
1413 myip_ifp = ifp;
1414
1415 revarp_in_progress = 1;
1416 while (count--) {
1417 revarprequest(ifp);
1418 result = tsleep((void *)&myip, PSOCK, "revarp", hz/2);
1419 if (result != EWOULDBLOCK)
1420 break;
1421 }
1422 revarp_in_progress = 0;
1423
1424 if (!myip_initialized)
1425 return ENETUNREACH;
1426
1427 bcopy((void *)&srv_ip, serv_in, sizeof(*serv_in));
1428 bcopy((void *)&myip, clnt_in, sizeof(*clnt_in));
1429 return 0;
1430 }
1431
1432
1433
1435 #ifdef DDB
1436
1437 #include <machine/db_machdep.h>
1438 #include <ddb/db_interface.h>
1439 #include <ddb/db_output.h>
1440
1441 static void
1442 db_print_sa(const struct sockaddr *sa)
1443 {
1444 int len;
1445 const u_char *p;
1446
1447 if (sa == 0) {
1448 db_printf("[NULL]");
1449 return;
1450 }
1451
1452 p = (const u_char *)sa;
1453 len = sa->sa_len;
1454 db_printf("[");
1455 while (len > 0) {
1456 db_printf("%d", *p);
1457 p++; len--;
1458 if (len) db_printf(",");
1459 }
1460 db_printf("]\n");
1461 }
1462
1463 static void
1464 db_print_ifa(struct ifaddr *ifa)
1465 {
1466 if (ifa == 0)
1467 return;
1468 db_printf(" ifa_addr=");
1469 db_print_sa(ifa->ifa_addr);
1470 db_printf(" ifa_dsta=");
1471 db_print_sa(ifa->ifa_dstaddr);
1472 db_printf(" ifa_mask=");
1473 db_print_sa(ifa->ifa_netmask);
1474 db_printf(" flags=0x%x,refcnt=%d,metric=%d\n",
1475 ifa->ifa_flags,
1476 ifa->ifa_refcnt,
1477 ifa->ifa_metric);
1478 }
1479
1480 static void
1481 db_print_llinfo(void *li)
1482 {
1483 struct llinfo_arp *la;
1484
1485 if (li == 0)
1486 return;
1487 la = (struct llinfo_arp *)li;
1488 db_printf(" la_rt=%p la_hold=%p, la_asked=0x%lx\n",
1489 la->la_rt, la->la_hold, la->la_asked);
1490 }
1491
1492 /*
1493 * Function to pass to rt_walktree().
1494 * Return non-zero error to abort walk.
1495 */
1496 static int
1497 db_show_rtentry(struct rtentry *rt, void *w)
1498 {
1499 db_printf("rtentry=%p", rt);
1500
1501 db_printf(" flags=0x%x refcnt=%d use=%ld expire=%ld\n",
1502 rt->rt_flags, rt->rt_refcnt,
1503 rt->rt_use, rt->rt_expire);
1504
1505 db_printf(" key="); db_print_sa(rt_getkey(rt));
1506 db_printf(" mask="); db_print_sa(rt_mask(rt));
1507 db_printf(" gw="); db_print_sa(rt->rt_gateway);
1508
1509 db_printf(" ifp=%p ", rt->rt_ifp);
1510 if (rt->rt_ifp)
1511 db_printf("(%s)", rt->rt_ifp->if_xname);
1512 else
1513 db_printf("(NULL)");
1514
1515 db_printf(" ifa=%p\n", rt->rt_ifa);
1516 db_print_ifa(rt->rt_ifa);
1517
1518 db_printf(" gwroute=%p llinfo=%p\n",
1519 rt->rt_gwroute, rt->rt_llinfo);
1520 db_print_llinfo(rt->rt_llinfo);
1521
1522 return (0);
1523 }
1524
1525 /*
1526 * Function to print all the route trees.
1527 * Use this from ddb: "show arptab"
1528 */
1529 void
1530 db_show_arptab(db_expr_t addr, bool have_addr,
1531 db_expr_t count, const char *modif)
1532 {
1533 rt_walktree(AF_INET, db_show_rtentry, NULL);
1534 }
1535 #endif
1536
1537 SYSCTL_SETUP(sysctl_net_inet_arp_setup, "sysctl net.inet.arp subtree setup")
1538 {
1539 const struct sysctlnode *node;
1540
1541 sysctl_createv(clog, 0, NULL, NULL,
1542 CTLFLAG_PERMANENT,
1543 CTLTYPE_NODE, "net", NULL,
1544 NULL, 0, NULL, 0,
1545 CTL_NET, CTL_EOL);
1546 sysctl_createv(clog, 0, NULL, NULL,
1547 CTLFLAG_PERMANENT,
1548 CTLTYPE_NODE, "inet", NULL,
1549 NULL, 0, NULL, 0,
1550 CTL_NET, PF_INET, CTL_EOL);
1551 sysctl_createv(clog, 0, NULL, &node,
1552 CTLFLAG_PERMANENT,
1553 CTLTYPE_NODE, "arp",
1554 SYSCTL_DESCR("Address Resolution Protocol"),
1555 NULL, 0, NULL, 0,
1556 CTL_NET, PF_INET, CTL_CREATE, CTL_EOL);
1557
1558 sysctl_createv(clog, 0, NULL, NULL,
1559 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1560 CTLTYPE_INT, "prune",
1561 SYSCTL_DESCR("ARP cache pruning interval"),
1562 NULL, 0, &arpt_prune, 0,
1563 CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL);
1564
1565 sysctl_createv(clog, 0, NULL, NULL,
1566 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1567 CTLTYPE_INT, "keep",
1568 SYSCTL_DESCR("Valid ARP entry lifetime"),
1569 NULL, 0, &arpt_keep, 0,
1570 CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL);
1571
1572 sysctl_createv(clog, 0, NULL, NULL,
1573 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1574 CTLTYPE_INT, "down",
1575 SYSCTL_DESCR("Failed ARP entry lifetime"),
1576 NULL, 0, &arpt_down, 0,
1577 CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL);
1578
1579 sysctl_createv(clog, 0, NULL, NULL,
1580 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1581 CTLTYPE_INT, "refresh",
1582 SYSCTL_DESCR("ARP entry refresh interval"),
1583 NULL, 0, &arpt_refresh, 0,
1584 CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL);
1585 }
1586
1587 #endif /* INET */
1588