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