if_arp.c revision 1.75 1 /* $NetBSD: if_arp.c,v 1.75 2001/06/11 06:19:50 tron 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. All advertising materials mentioning features or use of this software
53 * must display the following acknowledgement:
54 * This product includes software developed by the University of
55 * California, Berkeley and its contributors.
56 * 4. Neither the name of the University nor the names of its contributors
57 * may be used to endorse or promote products derived from this software
58 * without specific prior written permission.
59 *
60 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
61 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
62 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
63 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
64 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
65 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
66 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
67 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
68 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
69 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
70 * SUCH DAMAGE.
71 *
72 * @(#)if_ether.c 8.2 (Berkeley) 9/26/94
73 */
74
75 /*
76 * Ethernet address resolution protocol.
77 * TODO:
78 * add "inuse/lock" bit (or ref. count) along with valid bit
79 */
80
81 #include "opt_ddb.h"
82 #include "opt_inet.h"
83
84 #ifdef INET
85
86 #include <sys/param.h>
87 #include <sys/systm.h>
88 #include <sys/callout.h>
89 #include <sys/malloc.h>
90 #include <sys/mbuf.h>
91 #include <sys/socket.h>
92 #include <sys/time.h>
93 #include <sys/kernel.h>
94 #include <sys/errno.h>
95 #include <sys/ioctl.h>
96 #include <sys/syslog.h>
97 #include <sys/proc.h>
98 #include <sys/protosw.h>
99 #include <sys/domain.h>
100
101 #include <net/ethertypes.h>
102 #include <net/if.h>
103 #include <net/if_dl.h>
104 #include <net/if_token.h>
105 #include <net/if_types.h>
106 #include <net/route.h>
107
108
109 #include <netinet/in.h>
110 #include <netinet/in_systm.h>
111 #include <netinet/in_var.h>
112 #include <netinet/ip.h>
113 #include <netinet/if_inarp.h>
114
115 #include "loop.h"
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 #include "token.h"
126
127 #define SIN(s) ((struct sockaddr_in *)s)
128 #define SDL(s) ((struct sockaddr_dl *)s)
129 #define SRP(s) ((struct sockaddr_inarp *)s)
130
131 /*
132 * ARP trailer negotiation. Trailer protocol is not IP specific,
133 * but ARP request/response use IP addresses.
134 */
135 #define ETHERTYPE_IPTRAILERS ETHERTYPE_TRAIL
136
137 /* timer values */
138 int arpt_prune = (5*60*1); /* walk list every 5 minutes */
139 int arpt_keep = (20*60); /* once resolved, good for 20 more minutes */
140 int arpt_down = 20; /* once declared down, don't send for 20 secs */
141 #define rt_expire rt_rmx.rmx_expire
142
143 static void arprequest __P((struct ifnet *,
144 struct in_addr *, struct in_addr *, u_int8_t *));
145 static void arptfree __P((struct llinfo_arp *));
146 static void arptimer __P((void *));
147 static struct llinfo_arp *arplookup __P((struct mbuf *, struct in_addr *,
148 int, int));
149 static void in_arpinput __P((struct mbuf *));
150
151 #if NLOOP > 0
152 extern struct ifnet loif[NLOOP];
153 #endif
154 LIST_HEAD(, llinfo_arp) llinfo_arp;
155 struct ifqueue arpintrq = {0, 0, 0, 50};
156 int arp_inuse, arp_allocated, arp_intimer;
157 int arp_maxtries = 5;
158 int useloopback = 1; /* use loopback interface for local traffic */
159 int arpinit_done = 0;
160
161 struct arpstat arpstat;
162 struct callout arptimer_ch;
163
164
165 /* revarp state */
166 static struct in_addr myip, srv_ip;
167 static int myip_initialized = 0;
168 static int revarp_in_progress = 0;
169 static struct ifnet *myip_ifp = NULL;
170
171 #ifdef DDB
172 static void db_print_sa __P((struct sockaddr *));
173 static void db_print_ifa __P((struct ifaddr *));
174 static void db_print_llinfo __P((caddr_t));
175 static int db_show_radix_node __P((struct radix_node *, void *));
176 #endif
177
178 /*
179 * this should be elsewhere.
180 */
181
182 static char *
183 lla_snprintf __P((u_int8_t *, int));
184
185 static char *
186 lla_snprintf(adrp, len)
187 u_int8_t *adrp;
188 int len;
189 {
190 #define NUMBUFS 3
191 static char buf[NUMBUFS][16*3];
192 static int bnum = 0;
193 static const char hexdigits[] = {
194 '0','1','2','3','4','5','6','7',
195 '8','9','a','b','c','d','e','f'
196 };
197
198 int i;
199 char *p;
200
201 p = buf[bnum];
202
203 *p++ = hexdigits[(*adrp)>>4];
204 *p++ = hexdigits[(*adrp++)&0xf];
205
206 for (i=1; i<len && i<16; i++) {
207 *p++ = ':';
208 *p++ = hexdigits[(*adrp)>>4];
209 *p++ = hexdigits[(*adrp++)&0xf];
210 }
211
212 *p = 0;
213 p = buf[bnum];
214 bnum = (bnum + 1) % NUMBUFS;
215 return p;
216 }
217
218 struct protosw arpsw[] = {
219 { 0, 0, 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 int arp_locked;
247
248 static __inline int arp_lock_try __P((int));
249 static __inline void arp_unlock __P((void));
250
251 static __inline int
252 arp_lock_try(int recurse)
253 {
254 int s;
255
256 /*
257 * Use splvm() -- we're blocking things that would cause
258 * mbuf allocation.
259 */
260 s = splvm();
261 if (!recurse && arp_locked) {
262 splx(s);
263 return (0);
264 }
265 arp_locked++;
266 splx(s);
267 return (1);
268 }
269
270 static __inline void
271 arp_unlock()
272 {
273 int s;
274
275 s = splvm();
276 arp_locked--;
277 splx(s);
278 }
279
280 #ifdef DIAGNOSTIC
281 #define ARP_LOCK(recurse) \
282 do { \
283 if (arp_lock_try(recurse) == 0) { \
284 printf("%s:%d: arp already locked\n", __FILE__, __LINE__); \
285 panic("arp_lock"); \
286 } \
287 } while (0)
288 #define ARP_LOCK_CHECK() \
289 do { \
290 if (arp_locked == 0) { \
291 printf("%s:%d: arp lock not held\n", __FILE__, __LINE__); \
292 panic("arp lock check"); \
293 } \
294 } while (0)
295 #else
296 #define ARP_LOCK(x) (void) arp_lock_try(x)
297 #define ARP_LOCK_CHECK() /* nothing */
298 #endif
299
300 #define ARP_UNLOCK() arp_unlock()
301
302 /*
303 * ARP protocol drain routine. Called when memory is in short supply.
304 * Called at splvm();
305 */
306
307 void
308 arp_drain()
309 {
310 struct llinfo_arp *la, *nla;
311 int count = 0;
312 struct mbuf *mold;
313
314 if (arp_lock_try(0) == 0) {
315 printf("arp_drain: locked; punting\n");
316 return;
317 }
318
319 for (la = LIST_FIRST(&llinfo_arp); la != 0; la = nla) {
320 nla = LIST_NEXT(la, la_list);
321
322 mold = la->la_hold;
323 la->la_hold = 0;
324
325 if (mold) {
326 m_freem(mold);
327 count++;
328 }
329 }
330 ARP_UNLOCK();
331 arpstat.as_dfrdropped += count;
332 }
333
334
335 /*
336 * Timeout routine. Age arp_tab entries periodically.
337 */
338 /* ARGSUSED */
339 static void
340 arptimer(arg)
341 void *arg;
342 {
343 int s;
344 struct llinfo_arp *la, *nla;
345
346 s = splsoftnet();
347
348 if (arp_lock_try(0) == 0) {
349 /* get it later.. */
350 splx(s);
351 return;
352 }
353
354 callout_reset(&arptimer_ch, arpt_prune * hz, arptimer, NULL);
355 for (la = LIST_FIRST(&llinfo_arp); la != 0; la = nla) {
356 struct rtentry *rt = la->la_rt;
357
358 nla = LIST_NEXT(la, la_list);
359 if (rt->rt_expire && rt->rt_expire <= time.tv_sec)
360 arptfree(la); /* timer has expired; clear */
361 }
362
363 ARP_UNLOCK();
364
365 splx(s);
366 }
367
368 /*
369 * Parallel to llc_rtrequest.
370 */
371 void
372 arp_rtrequest(req, rt, info)
373 int req;
374 struct rtentry *rt;
375 struct rt_addrinfo *info;
376 {
377 struct sockaddr *gate = rt->rt_gateway;
378 struct llinfo_arp *la = (struct llinfo_arp *)rt->rt_llinfo;
379 static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
380 size_t allocsize;
381 struct mbuf *mold;
382 int s;
383
384 if (!arpinit_done) {
385 arpinit_done = 1;
386 /*
387 * We generate expiration times from time.tv_sec
388 * so avoid accidently creating permanent routes.
389 */
390 if (time.tv_sec == 0) {
391 time.tv_sec++;
392 }
393 callout_init(&arptimer_ch);
394 callout_reset(&arptimer_ch, hz, arptimer, NULL);
395 }
396 if (rt->rt_flags & RTF_GATEWAY)
397 return;
398
399 ARP_LOCK(1); /* we may already be locked here. */
400
401 switch (req) {
402
403 case RTM_ADD:
404 /*
405 * XXX: If this is a manually added route to interface
406 * such as older version of routed or gated might provide,
407 * restore cloning bit.
408 */
409 if ((rt->rt_flags & RTF_HOST) == 0 &&
410 SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff)
411 rt->rt_flags |= RTF_CLONING;
412 if (rt->rt_flags & RTF_CLONING) {
413 /*
414 * Case 1: This route should come from a route to iface.
415 */
416 rt_setgate(rt, rt_key(rt),
417 (struct sockaddr *)&null_sdl);
418 gate = rt->rt_gateway;
419 SDL(gate)->sdl_type = rt->rt_ifp->if_type;
420 SDL(gate)->sdl_index = rt->rt_ifp->if_index;
421 /*
422 * Give this route an expiration time, even though
423 * it's a "permanent" route, so that routes cloned
424 * from it do not need their expiration time set.
425 */
426 rt->rt_expire = time.tv_sec;
427 #if NFDDI > 0
428 if (rt->rt_ifp->if_type == IFT_FDDI
429 && (rt->rt_rmx.rmx_mtu > FDDIIPMTU
430 || (rt->rt_rmx.rmx_mtu == 0
431 && rt->rt_ifp->if_mtu > FDDIIPMTU))) {
432 rt->rt_rmx.rmx_mtu = FDDIIPMTU;
433 }
434 #endif
435 #if NARC > 0
436 if (rt->rt_ifp->if_type == IFT_ARCNET) {
437 int arcipifmtu;
438
439 if (rt->rt_ifp->if_flags & IFF_LINK0)
440 arcipifmtu = arc_ipmtu;
441 else
442 arcipifmtu = ARCMTU;
443
444 if (rt->rt_rmx.rmx_mtu > arcipifmtu ||
445 (rt->rt_rmx.rmx_mtu == 0 &&
446 rt->rt_ifp->if_mtu > arcipifmtu))
447
448 rt->rt_rmx.rmx_mtu = arcipifmtu;
449 }
450 #endif
451 break;
452 }
453 /* Announce a new entry if requested. */
454 if (rt->rt_flags & RTF_ANNOUNCE)
455 arprequest(rt->rt_ifp,
456 &SIN(rt_key(rt))->sin_addr,
457 &SIN(rt_key(rt))->sin_addr,
458 (u_char *)LLADDR(SDL(gate)));
459 /*FALLTHROUGH*/
460 case RTM_RESOLVE:
461 if (gate->sa_family != AF_LINK ||
462 gate->sa_len < sizeof(null_sdl)) {
463 log(LOG_DEBUG, "arp_rtrequest: bad gateway value\n");
464 break;
465 }
466 SDL(gate)->sdl_type = rt->rt_ifp->if_type;
467 SDL(gate)->sdl_index = rt->rt_ifp->if_index;
468 if (la != 0)
469 break; /* This happens on a route change */
470 /*
471 * Case 2: This route may come from cloning, or a manual route
472 * add with a LL address.
473 */
474 switch (SDL(gate)->sdl_type) {
475 #if NTOKEN > 0
476 case IFT_ISO88025:
477 allocsize = sizeof(*la) + sizeof(struct token_rif);
478 break;
479 #endif /* NTOKEN > 0 */
480 default:
481 allocsize = sizeof(*la);
482 }
483 R_Malloc(la, struct llinfo_arp *, allocsize);
484 rt->rt_llinfo = (caddr_t)la;
485 if (la == 0) {
486 log(LOG_DEBUG, "arp_rtrequest: malloc failed\n");
487 break;
488 }
489 arp_inuse++, arp_allocated++;
490 Bzero(la, allocsize);
491 la->la_rt = rt;
492 rt->rt_flags |= RTF_LLINFO;
493 LIST_INSERT_HEAD(&llinfo_arp, la, la_list);
494 if (in_hosteq(SIN(rt_key(rt))->sin_addr,
495 (IA_SIN(rt->rt_ifa))->sin_addr)) {
496 /*
497 * This test used to be
498 * if (loif.if_flags & IFF_UP)
499 * It allowed local traffic to be forced through
500 * the hardware by configuring the loopback down.
501 * However, it causes problems during network
502 * configuration for boards that can't receive
503 * packets they send. It is now necessary to clear
504 * "useloopback" and remove the route to force
505 * traffic out to the hardware.
506 */
507 rt->rt_expire = 0;
508 Bcopy(LLADDR(rt->rt_ifp->if_sadl),
509 LLADDR(SDL(gate)),
510 SDL(gate)->sdl_alen =
511 rt->rt_ifp->if_data.ifi_addrlen);
512 #if NLOOP > 0
513 if (useloopback)
514 rt->rt_ifp = &loif[0];
515 #endif
516 }
517 break;
518
519 case RTM_DELETE:
520 if (la == 0)
521 break;
522 arp_inuse--;
523 LIST_REMOVE(la, la_list);
524 rt->rt_llinfo = 0;
525 rt->rt_flags &= ~RTF_LLINFO;
526
527 s = splnet();
528 mold = la->la_hold;
529 la->la_hold = 0;
530 splx(s);
531
532 if (mold)
533 m_freem(mold);
534
535 Free((caddr_t)la);
536 }
537 ARP_UNLOCK();
538 }
539
540 /*
541 * Broadcast an ARP request. Caller specifies:
542 * - arp header source ip address
543 * - arp header target ip address
544 * - arp header source ethernet address
545 */
546 static void
547 arprequest(ifp, sip, tip, enaddr)
548 struct ifnet *ifp;
549 struct in_addr *sip, *tip;
550 u_int8_t *enaddr;
551 {
552 struct mbuf *m;
553 struct arphdr *ah;
554 struct sockaddr sa;
555
556 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
557 return;
558 m->m_len = sizeof(*ah) + 2*sizeof(struct in_addr) +
559 2*ifp->if_data.ifi_addrlen;
560 m->m_pkthdr.len = m->m_len;
561 MH_ALIGN(m, m->m_len);
562 ah = mtod(m, struct arphdr *);
563 bzero((caddr_t)ah, m->m_len);
564 ah->ar_pro = htons(ETHERTYPE_IP);
565 ah->ar_hln = ifp->if_data.ifi_addrlen; /* hardware address length */
566 ah->ar_pln = sizeof(struct in_addr); /* protocol address length */
567 ah->ar_op = htons(ARPOP_REQUEST);
568 bcopy((caddr_t)enaddr, (caddr_t)ar_sha(ah), ah->ar_hln);
569 bcopy((caddr_t)sip, (caddr_t)ar_spa(ah), ah->ar_pln);
570 bcopy((caddr_t)tip, (caddr_t)ar_tpa(ah), ah->ar_pln);
571 sa.sa_family = AF_ARP;
572 sa.sa_len = 2;
573 m->m_flags |= M_BCAST;
574 arpstat.as_sndtotal++;
575 arpstat.as_sndrequest++;
576 (*ifp->if_output)(ifp, m, &sa, (struct rtentry *)0);
577 }
578
579 /*
580 * Resolve an IP address into an ethernet address. If success,
581 * desten is filled in. If there is no entry in arptab,
582 * set one up and broadcast a request for the IP address.
583 * Hold onto this mbuf and resend it once the address
584 * is finally resolved. A return value of 1 indicates
585 * that desten has been filled in and the packet should be sent
586 * normally; a 0 return indicates that the packet has been
587 * taken over here, either now or for later transmission.
588 */
589 int
590 arpresolve(ifp, rt, m, dst, desten)
591 struct ifnet *ifp;
592 struct rtentry *rt;
593 struct mbuf *m;
594 struct sockaddr *dst;
595 u_char *desten;
596 {
597 struct llinfo_arp *la;
598 struct sockaddr_dl *sdl;
599 struct mbuf *mold;
600 int s;
601
602 if (rt)
603 la = (struct llinfo_arp *)rt->rt_llinfo;
604 else {
605 if ((la = arplookup(m, &SIN(dst)->sin_addr, 1, 0)) != NULL)
606 rt = la->la_rt;
607 }
608 if (la == 0 || rt == 0) {
609 arpstat.as_allocfail++;
610 log(LOG_DEBUG,
611 "arpresolve: can't allocate llinfo on %s for %s\n",
612 ifp->if_xname, in_fmtaddr(SIN(dst)->sin_addr));
613 m_freem(m);
614 return (0);
615 }
616 sdl = SDL(rt->rt_gateway);
617 /*
618 * Check the address family and length is valid, the address
619 * is resolved; otherwise, try to resolve.
620 */
621 if ((rt->rt_expire == 0 || rt->rt_expire > time.tv_sec) &&
622 sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) {
623 bcopy(LLADDR(sdl), desten,
624 min(sdl->sdl_alen, ifp->if_data.ifi_addrlen));
625 return 1;
626 }
627 /*
628 * There is an arptab entry, but no ethernet address
629 * response yet. Replace the held mbuf with this
630 * latest one.
631 */
632
633 arpstat.as_dfrtotal++;
634 s = splnet();
635 mold = la->la_hold;
636 la->la_hold = m;
637 splx(s);
638
639 if (mold) {
640 arpstat.as_dfrdropped++;
641 m_freem(mold);
642 }
643
644 /*
645 * Re-send the ARP request when appropriate.
646 */
647 #ifdef DIAGNOSTIC
648 if (rt->rt_expire == 0) {
649 /* This should never happen. (Should it? -gwr) */
650 printf("arpresolve: unresolved and rt_expire == 0\n");
651 /* Set expiration time to now (expired). */
652 rt->rt_expire = time.tv_sec;
653 }
654 #endif
655 if (rt->rt_expire) {
656 rt->rt_flags &= ~RTF_REJECT;
657 if (la->la_asked == 0 || rt->rt_expire != time.tv_sec) {
658 rt->rt_expire = time.tv_sec;
659 if (la->la_asked++ < arp_maxtries)
660 arprequest(ifp,
661 &SIN(rt->rt_ifa->ifa_addr)->sin_addr,
662 &SIN(dst)->sin_addr,
663 LLADDR(ifp->if_sadl));
664 else {
665 rt->rt_flags |= RTF_REJECT;
666 rt->rt_expire += arpt_down;
667 la->la_asked = 0;
668 }
669 }
670 }
671 return (0);
672 }
673
674 /*
675 * Common length and type checks are done here,
676 * then the protocol-specific routine is called.
677 */
678 void
679 arpintr()
680 {
681 struct mbuf *m;
682 struct arphdr *ar;
683 int s;
684
685 while (arpintrq.ifq_head) {
686 s = splnet();
687 IF_DEQUEUE(&arpintrq, m);
688 splx(s);
689 if (m == 0 || (m->m_flags & M_PKTHDR) == 0)
690 panic("arpintr");
691
692 arpstat.as_rcvtotal++;
693
694 if (m->m_len >= sizeof(struct arphdr) &&
695 (ar = mtod(m, struct arphdr *)) &&
696 /* XXX ntohs(ar->ar_hrd) == ARPHRD_ETHER && */
697 m->m_len >=
698 sizeof(struct arphdr) + 2 * (ar->ar_hln + ar->ar_pln))
699 switch (ntohs(ar->ar_pro)) {
700
701 case ETHERTYPE_IP:
702 case ETHERTYPE_IPTRAILERS:
703 in_arpinput(m);
704 continue;
705 default:
706 arpstat.as_rcvbadproto++;
707 }
708 else
709 arpstat.as_rcvbadlen++;
710 m_freem(m);
711 }
712 }
713
714 /*
715 * ARP for Internet protocols on 10 Mb/s Ethernet.
716 * Algorithm is that given in RFC 826.
717 * In addition, a sanity check is performed on the sender
718 * protocol address, to catch impersonators.
719 * We no longer handle negotiations for use of trailer protocol:
720 * Formerly, ARP replied for protocol type ETHERTYPE_TRAIL sent
721 * along with IP replies if we wanted trailers sent to us,
722 * and also sent them in response to IP replies.
723 * This allowed either end to announce the desire to receive
724 * trailer packets.
725 * We no longer reply to requests for ETHERTYPE_TRAIL protocol either,
726 * but formerly didn't normally send requests.
727 */
728 static void
729 in_arpinput(m)
730 struct mbuf *m;
731 {
732 struct arphdr *ah;
733 struct ifnet *ifp = m->m_pkthdr.rcvif;
734 struct llinfo_arp *la = 0;
735 struct rtentry *rt;
736 struct in_ifaddr *ia;
737 struct sockaddr_dl *sdl;
738 struct sockaddr sa;
739 struct in_addr isaddr, itaddr, myaddr;
740 int op;
741 struct mbuf *mold;
742 int s;
743
744 ah = mtod(m, struct arphdr *);
745 op = ntohs(ah->ar_op);
746 bcopy((caddr_t)ar_spa(ah), (caddr_t)&isaddr, sizeof (isaddr));
747 bcopy((caddr_t)ar_tpa(ah), (caddr_t)&itaddr, sizeof (itaddr));
748
749 if (m->m_flags & (M_BCAST|M_MCAST))
750 arpstat.as_rcvmcast++;
751
752 /*
753 * If the target IP address is zero, ignore the packet.
754 * This prevents the code below from tring to answer
755 * when we are using IP address zero (booting).
756 */
757 if (in_nullhost(itaddr)) {
758 arpstat.as_rcvzerotpa++;
759 goto out;
760 }
761
762 /*
763 * If the source IP address is zero, this is most likely a
764 * confused host trying to use IP address zero. (Windoze?)
765 * XXX: Should we bother trying to reply to these?
766 */
767 if (in_nullhost(isaddr)) {
768 arpstat.as_rcvzerospa++;
769 goto out;
770 }
771
772 /*
773 * Search for a matching interface address
774 * or any address on the interface to use
775 * as a dummy address in the rest of this function
776 */
777 INADDR_TO_IA(itaddr, ia);
778 while ((ia != NULL) && ia->ia_ifp != m->m_pkthdr.rcvif)
779 NEXT_IA_WITH_SAME_ADDR(ia);
780
781 if (ia == NULL) {
782 INADDR_TO_IA(isaddr, ia);
783 while ((ia != NULL) && ia->ia_ifp != m->m_pkthdr.rcvif)
784 NEXT_IA_WITH_SAME_ADDR(ia);
785
786 if (ia == NULL) {
787 IFP_TO_IA(ifp, ia);
788 if (ia == NULL) {
789 arpstat.as_rcvnoint++;
790 goto out;
791 }
792 }
793 }
794
795 myaddr = ia->ia_addr.sin_addr;
796
797 if (!bcmp((caddr_t)ar_sha(ah), LLADDR(ifp->if_sadl),
798 ifp->if_data.ifi_addrlen)) {
799 arpstat.as_rcvlocalsha++;
800 goto out; /* it's from me, ignore it. */
801 }
802
803 if (!bcmp((caddr_t)ar_sha(ah), (caddr_t)ifp->if_broadcastaddr,
804 ifp->if_data.ifi_addrlen)) {
805 arpstat.as_rcvbcastsha++;
806 log(LOG_ERR,
807 "%s: arp: link address is broadcast for IP address %s!\n",
808 ifp->if_xname, in_fmtaddr(isaddr));
809 goto out;
810 }
811
812 if (in_hosteq(isaddr, myaddr)) {
813 arpstat.as_rcvlocalspa++;
814 log(LOG_ERR,
815 "duplicate IP address %s sent from link address %s\n",
816 in_fmtaddr(isaddr), lla_snprintf(ar_sha(ah), ah->ar_hln));
817 itaddr = myaddr;
818 goto reply;
819 }
820 la = arplookup(m, &isaddr, in_hosteq(itaddr, myaddr), 0);
821 if (la && (rt = la->la_rt) && (sdl = SDL(rt->rt_gateway))) {
822 if (sdl->sdl_alen &&
823 bcmp((caddr_t)ar_sha(ah), LLADDR(sdl), sdl->sdl_alen)) {
824 if (rt->rt_flags & RTF_STATIC) {
825 arpstat.as_rcvoverperm++;
826 log(LOG_INFO,
827 "%s tried to overwrite permanent arp info"
828 " for %s\n",
829 lla_snprintf(ar_sha(ah), ah->ar_hln),
830 in_fmtaddr(isaddr));
831 goto out;
832 } else if (rt->rt_ifp != ifp) {
833 arpstat.as_rcvoverint++;
834 log(LOG_INFO,
835 "%s on %s tried to overwrite "
836 "arp info for %s on %s\n",
837 lla_snprintf(ar_sha(ah), ah->ar_hln),
838 ifp->if_xname, in_fmtaddr(isaddr),
839 rt->rt_ifp->if_xname);
840 goto out;
841 } else {
842 arpstat.as_rcvover++;
843 log(LOG_INFO,
844 "arp info overwritten for %s by %s\n",
845 in_fmtaddr(isaddr),
846 lla_snprintf(ar_sha(ah), ah->ar_hln));
847 }
848 }
849 /*
850 * sanity check for the address length.
851 * XXX this does not work for protocols with variable address
852 * length. -is
853 */
854 if (sdl->sdl_alen &&
855 sdl->sdl_alen != ah->ar_hln) {
856 arpstat.as_rcvlenchg++;
857 log(LOG_WARNING,
858 "arp from %s: new addr len %d, was %d",
859 in_fmtaddr(isaddr), ah->ar_hln, sdl->sdl_alen);
860 }
861 if (ifp->if_data.ifi_addrlen != ah->ar_hln) {
862 arpstat.as_rcvbadlen++;
863 log(LOG_WARNING,
864 "arp from %s: addr len: new %d, i/f %d (ignored)",
865 in_fmtaddr(isaddr), ah->ar_hln,
866 ifp->if_data.ifi_addrlen);
867 goto reply;
868 }
869 #if NTOKEN > 0
870 /*
871 * XXX uses m_data and assumes the complete answer including
872 * XXX token-ring headers is in the same buf
873 */
874 if (ifp->if_type == IFT_ISO88025) {
875 struct token_header *trh;
876
877 trh = (struct token_header *)M_TRHSTART(m);
878 if (trh->token_shost[0] & TOKEN_RI_PRESENT) {
879 struct token_rif *rif;
880 size_t riflen;
881
882 rif = TOKEN_RIF(trh);
883 riflen = (ntohs(rif->tr_rcf) &
884 TOKEN_RCF_LEN_MASK) >> 8;
885
886 if (riflen > 2 &&
887 riflen < sizeof(struct token_rif) &&
888 (riflen & 1) == 0) {
889 rif->tr_rcf ^= htons(TOKEN_RCF_DIRECTION);
890 rif->tr_rcf &= htons(~TOKEN_RCF_BROADCAST_MASK);
891 bcopy(rif, TOKEN_RIF(la), riflen);
892 }
893 }
894 }
895 #endif /* NTOKEN > 0 */
896 bcopy((caddr_t)ar_sha(ah), LLADDR(sdl),
897 sdl->sdl_alen = ah->ar_hln);
898 if (rt->rt_expire)
899 rt->rt_expire = time.tv_sec + arpt_keep;
900 rt->rt_flags &= ~RTF_REJECT;
901 la->la_asked = 0;
902
903 s = splnet();
904 mold = la->la_hold;
905 la->la_hold = 0;
906 splx(s);
907
908 if (mold) {
909 arpstat.as_dfrsent++;
910 (*ifp->if_output)(ifp, mold, rt_key(rt), rt);
911 }
912 }
913 reply:
914 if (op != ARPOP_REQUEST) {
915 if (op == ARPOP_REPLY)
916 arpstat.as_rcvreply++;
917 out:
918 m_freem(m);
919 return;
920 }
921 arpstat.as_rcvrequest++;
922 if (in_hosteq(itaddr, myaddr)) {
923 /* I am the target */
924 bcopy((caddr_t)ar_sha(ah), (caddr_t)ar_tha(ah), ah->ar_hln);
925 bcopy(LLADDR(ifp->if_sadl), (caddr_t)ar_sha(ah), ah->ar_hln);
926 } else {
927 la = arplookup(m, &itaddr, 0, SIN_PROXY);
928 if (la == 0)
929 goto out;
930 rt = la->la_rt;
931 bcopy((caddr_t)ar_sha(ah), (caddr_t)ar_tha(ah), ah->ar_hln);
932 sdl = SDL(rt->rt_gateway);
933 bcopy(LLADDR(sdl), (caddr_t)ar_sha(ah), ah->ar_hln);
934 }
935
936 bcopy((caddr_t)ar_spa(ah), (caddr_t)ar_tpa(ah), ah->ar_pln);
937 bcopy((caddr_t)&itaddr, (caddr_t)ar_spa(ah), ah->ar_pln);
938 ah->ar_op = htons(ARPOP_REPLY);
939 ah->ar_pro = htons(ETHERTYPE_IP); /* let's be sure! */
940 m->m_flags &= ~(M_BCAST|M_MCAST); /* never reply by broadcast */
941 m->m_len = sizeof(*ah) + (2 * ah->ar_pln) + (2 * ah->ar_hln);
942 m->m_pkthdr.len = m->m_len;
943 sa.sa_family = AF_ARP;
944 sa.sa_len = 2;
945 arpstat.as_sndtotal++;
946 arpstat.as_sndreply++;
947 (*ifp->if_output)(ifp, m, &sa, (struct rtentry *)0);
948 return;
949 }
950
951 /*
952 * Free an arp entry.
953 */
954 static void
955 arptfree(la)
956 struct llinfo_arp *la;
957 {
958 struct rtentry *rt = la->la_rt;
959 struct sockaddr_dl *sdl;
960
961 ARP_LOCK_CHECK();
962
963 if (rt == 0)
964 panic("arptfree");
965 if (rt->rt_refcnt > 0 && (sdl = SDL(rt->rt_gateway)) &&
966 sdl->sdl_family == AF_LINK) {
967 sdl->sdl_alen = 0;
968 la->la_asked = 0;
969 rt->rt_flags &= ~RTF_REJECT;
970 return;
971 }
972 rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0, rt_mask(rt),
973 0, (struct rtentry **)0);
974 }
975
976 /*
977 * Lookup or enter a new address in arptab.
978 */
979 static struct llinfo_arp *
980 arplookup(m, addr, create, proxy)
981 struct mbuf *m;
982 struct in_addr *addr;
983 int create, proxy;
984 {
985 struct arphdr *ah;
986 struct ifnet *ifp = m->m_pkthdr.rcvif;
987 struct rtentry *rt;
988 static struct sockaddr_inarp sin;
989 const char *why = 0;
990
991 ah = mtod(m, struct arphdr *);
992 sin.sin_len = sizeof(sin);
993 sin.sin_family = AF_INET;
994 sin.sin_addr = *addr;
995 sin.sin_other = proxy ? SIN_PROXY : 0;
996 rt = rtalloc1(sintosa(&sin), create);
997 if (rt == 0)
998 return (0);
999 rt->rt_refcnt--;
1000
1001 if (rt->rt_flags & RTF_GATEWAY)
1002 why = "host is not on local network";
1003 else if ((rt->rt_flags & RTF_LLINFO) == 0) {
1004 arpstat.as_allocfail++;
1005 why = "could not allocate llinfo";
1006 } else if (rt->rt_gateway->sa_family != AF_LINK)
1007 why = "gateway route is not ours";
1008 else
1009 return ((struct llinfo_arp *)rt->rt_llinfo);
1010
1011 if (create)
1012 log(LOG_DEBUG, "arplookup: unable to enter address"
1013 " for %s@%s on %s (%s)\n",
1014 in_fmtaddr(*addr), lla_snprintf(ar_sha(ah), ah->ar_hln),
1015 ifp->if_xname, why);
1016 return (0);
1017 }
1018
1019 int
1020 arpioctl(cmd, data)
1021 u_long cmd;
1022 caddr_t data;
1023 {
1024
1025 return (EOPNOTSUPP);
1026 }
1027
1028 void
1029 arp_ifinit(ifp, ifa)
1030 struct ifnet *ifp;
1031 struct ifaddr *ifa;
1032 {
1033 struct in_addr *ip;
1034
1035 /*
1036 * Warn the user if another station has this IP address,
1037 * but only if the interface IP address is not zero.
1038 */
1039 ip = &IA_SIN(ifa)->sin_addr;
1040 if (!in_nullhost(*ip))
1041 arprequest(ifp, ip, ip, LLADDR(ifp->if_sadl));
1042
1043 ifa->ifa_rtrequest = arp_rtrequest;
1044 ifa->ifa_flags |= RTF_CLONING;
1045 }
1046
1047 /*
1048 * Called from 10 Mb/s Ethernet interrupt handlers
1049 * when ether packet type ETHERTYPE_REVARP
1050 * is received. Common length and type checks are done here,
1051 * then the protocol-specific routine is called.
1052 */
1053 void
1054 revarpinput(m)
1055 struct mbuf *m;
1056 {
1057 struct arphdr *ar;
1058
1059 if (m->m_len < sizeof(struct arphdr))
1060 goto out;
1061 ar = mtod(m, struct arphdr *);
1062 #if 0 /* XXX I don't think we need this... and it will prevent other LL */
1063 if (ntohs(ar->ar_hrd) != ARPHRD_ETHER)
1064 goto out;
1065 #endif
1066 if (m->m_len < sizeof(struct arphdr) + 2 * (ar->ar_hln + ar->ar_pln))
1067 goto out;
1068 switch (ntohs(ar->ar_pro)) {
1069
1070 case ETHERTYPE_IP:
1071 case ETHERTYPE_IPTRAILERS:
1072 in_revarpinput(m);
1073 return;
1074
1075 default:
1076 break;
1077 }
1078 out:
1079 m_freem(m);
1080 }
1081
1082 /*
1083 * RARP for Internet protocols on 10 Mb/s Ethernet.
1084 * Algorithm is that given in RFC 903.
1085 * We are only using for bootstrap purposes to get an ip address for one of
1086 * our interfaces. Thus we support no user-interface.
1087 *
1088 * Since the contents of the RARP reply are specific to the interface that
1089 * sent the request, this code must ensure that they are properly associated.
1090 *
1091 * Note: also supports ARP via RARP packets, per the RFC.
1092 */
1093 void
1094 in_revarpinput(m)
1095 struct mbuf *m;
1096 {
1097 struct ifnet *ifp;
1098 struct arphdr *ah;
1099 int op;
1100
1101 ah = mtod(m, struct arphdr *);
1102 op = ntohs(ah->ar_op);
1103 switch (op) {
1104 case ARPOP_REQUEST:
1105 case ARPOP_REPLY: /* per RFC */
1106 in_arpinput(m);
1107 return;
1108 case ARPOP_REVREPLY:
1109 break;
1110 case ARPOP_REVREQUEST: /* handled by rarpd(8) */
1111 default:
1112 goto out;
1113 }
1114 if (!revarp_in_progress)
1115 goto out;
1116 ifp = m->m_pkthdr.rcvif;
1117 if (ifp != myip_ifp) /* !same interface */
1118 goto out;
1119 if (myip_initialized)
1120 goto wake;
1121 if (bcmp(ar_tha(ah), LLADDR(ifp->if_sadl), ifp->if_sadl->sdl_alen))
1122 goto out;
1123 bcopy((caddr_t)ar_spa(ah), (caddr_t)&srv_ip, sizeof(srv_ip));
1124 bcopy((caddr_t)ar_tpa(ah), (caddr_t)&myip, sizeof(myip));
1125 myip_initialized = 1;
1126 wake: /* Do wakeup every time in case it was missed. */
1127 wakeup((caddr_t)&myip);
1128
1129 out:
1130 m_freem(m);
1131 }
1132
1133 /*
1134 * Send a RARP request for the ip address of the specified interface.
1135 * The request should be RFC 903-compliant.
1136 */
1137 void
1138 revarprequest(ifp)
1139 struct ifnet *ifp;
1140 {
1141 struct sockaddr sa;
1142 struct mbuf *m;
1143 struct arphdr *ah;
1144
1145 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
1146 return;
1147 m->m_len = sizeof(*ah) + 2*sizeof(struct in_addr) +
1148 2*ifp->if_data.ifi_addrlen;
1149 m->m_pkthdr.len = m->m_len;
1150 MH_ALIGN(m, m->m_len);
1151 ah = mtod(m, struct arphdr *);
1152 bzero((caddr_t)ah, m->m_len);
1153 ah->ar_pro = htons(ETHERTYPE_IP);
1154 ah->ar_hln = ifp->if_data.ifi_addrlen; /* hardware address length */
1155 ah->ar_pln = sizeof(struct in_addr); /* protocol address length */
1156 ah->ar_op = htons(ARPOP_REVREQUEST);
1157
1158 bcopy(LLADDR(ifp->if_sadl), (caddr_t)ar_sha(ah), ah->ar_hln);
1159 bcopy(LLADDR(ifp->if_sadl), (caddr_t)ar_tha(ah), ah->ar_hln);
1160
1161 sa.sa_family = AF_ARP;
1162 sa.sa_len = 2;
1163 m->m_flags |= M_BCAST;
1164 (*ifp->if_output)(ifp, m, &sa, (struct rtentry *)0);
1165
1166 }
1167
1168 /*
1169 * RARP for the ip address of the specified interface, but also
1170 * save the ip address of the server that sent the answer.
1171 * Timeout if no response is received.
1172 */
1173 int
1174 revarpwhoarewe(ifp, serv_in, clnt_in)
1175 struct ifnet *ifp;
1176 struct in_addr *serv_in;
1177 struct in_addr *clnt_in;
1178 {
1179 int result, count = 20;
1180
1181 myip_initialized = 0;
1182 myip_ifp = ifp;
1183
1184 revarp_in_progress = 1;
1185 while (count--) {
1186 revarprequest(ifp);
1187 result = tsleep((caddr_t)&myip, PSOCK, "revarp", hz/2);
1188 if (result != EWOULDBLOCK)
1189 break;
1190 }
1191 revarp_in_progress = 0;
1192
1193 if (!myip_initialized)
1194 return ENETUNREACH;
1195
1196 bcopy((caddr_t)&srv_ip, serv_in, sizeof(*serv_in));
1197 bcopy((caddr_t)&myip, clnt_in, sizeof(*clnt_in));
1198 return 0;
1199 }
1200
1201
1202
1204 #ifdef DDB
1205
1206 #include <machine/db_machdep.h>
1207 #include <ddb/db_interface.h>
1208 #include <ddb/db_output.h>
1209 static void
1210 db_print_sa(sa)
1211 struct sockaddr *sa;
1212 {
1213 int len;
1214 u_char *p;
1215
1216 if (sa == 0) {
1217 db_printf("[NULL]");
1218 return;
1219 }
1220
1221 p = (u_char*)sa;
1222 len = sa->sa_len;
1223 db_printf("[");
1224 while (len > 0) {
1225 db_printf("%d", *p);
1226 p++; len--;
1227 if (len) db_printf(",");
1228 }
1229 db_printf("]\n");
1230 }
1231 static void
1232 db_print_ifa(ifa)
1233 struct ifaddr *ifa;
1234 {
1235 if (ifa == 0)
1236 return;
1237 db_printf(" ifa_addr=");
1238 db_print_sa(ifa->ifa_addr);
1239 db_printf(" ifa_dsta=");
1240 db_print_sa(ifa->ifa_dstaddr);
1241 db_printf(" ifa_mask=");
1242 db_print_sa(ifa->ifa_netmask);
1243 db_printf(" flags=0x%x,refcnt=%d,metric=%d\n",
1244 ifa->ifa_flags,
1245 ifa->ifa_refcnt,
1246 ifa->ifa_metric);
1247 }
1248 static void
1249 db_print_llinfo(li)
1250 caddr_t li;
1251 {
1252 struct llinfo_arp *la;
1253
1254 if (li == 0)
1255 return;
1256 la = (struct llinfo_arp *)li;
1257 db_printf(" la_rt=%p la_hold=%p, la_asked=0x%lx\n",
1258 la->la_rt, la->la_hold, la->la_asked);
1259 }
1260 /*
1261 * Function to pass to rn_walktree().
1262 * Return non-zero error to abort walk.
1263 */
1264 static int
1265 db_show_radix_node(rn, w)
1266 struct radix_node *rn;
1267 void *w;
1268 {
1269 struct rtentry *rt = (struct rtentry *)rn;
1270
1271 db_printf("rtentry=%p", rt);
1272
1273 db_printf(" flags=0x%x refcnt=%d use=%ld expire=%ld\n",
1274 rt->rt_flags, rt->rt_refcnt,
1275 rt->rt_use, rt->rt_expire);
1276
1277 db_printf(" key="); db_print_sa(rt_key(rt));
1278 db_printf(" mask="); db_print_sa(rt_mask(rt));
1279 db_printf(" gw="); db_print_sa(rt->rt_gateway);
1280
1281 db_printf(" ifp=%p ", rt->rt_ifp);
1282 if (rt->rt_ifp)
1283 db_printf("(%s)", rt->rt_ifp->if_xname);
1284 else
1285 db_printf("(NULL)");
1286
1287 db_printf(" ifa=%p\n", rt->rt_ifa);
1288 db_print_ifa(rt->rt_ifa);
1289
1290 db_printf(" genmask="); db_print_sa(rt->rt_genmask);
1291
1292 db_printf(" gwroute=%p llinfo=%p\n",
1293 rt->rt_gwroute, rt->rt_llinfo);
1294 db_print_llinfo(rt->rt_llinfo);
1295
1296 return (0);
1297 }
1298 /*
1299 * Function to print all the route trees.
1300 * Use this from ddb: "show arptab"
1301 */
1302 void
1303 db_show_arptab(addr, have_addr, count, modif)
1304 db_expr_t addr;
1305 int have_addr;
1306 db_expr_t count;
1307 char * modif;
1308 {
1309 struct radix_node_head *rnh;
1310 rnh = rt_tables[AF_INET];
1311 db_printf("Route tree for AF_INET\n");
1312 if (rnh == NULL) {
1313 db_printf(" (not initialized)\n");
1314 return;
1315 }
1316 rn_walktree(rnh, db_show_radix_node, NULL);
1317 return;
1318 }
1319 #endif
1320 #endif /* INET */
1321
1322