if_arp.c revision 1.25 1 /* $NetBSD: if_arp.c,v 1.25 1995/06/04 05:06:49 mycroft Exp $ */
2
3 /*
4 * Copyright (c) 1982, 1986, 1988, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 * @(#)if_ether.c 8.1 (Berkeley) 6/10/93
36 */
37
38 /*
39 * Ethernet address resolution protocol.
40 * TODO:
41 * add "inuse/lock" bit (or ref. count) along with valid bit
42 */
43
44 #ifdef INET
45
46 #include <sys/param.h>
47 #include <sys/systm.h>
48 #include <sys/malloc.h>
49 #include <sys/mbuf.h>
50 #include <sys/socket.h>
51 #include <sys/time.h>
52 #include <sys/kernel.h>
53 #include <sys/errno.h>
54 #include <sys/ioctl.h>
55 #include <sys/syslog.h>
56
57 #include <net/if.h>
58 #include <net/if_dl.h>
59 #include <net/route.h>
60
61 #include <netinet/in.h>
62 #include <netinet/in_systm.h>
63 #include <netinet/in_var.h>
64 #include <netinet/ip.h>
65 #include <netinet/if_ether.h>
66
67 #define SIN(s) ((struct sockaddr_in *)s)
68 #define SDL(s) ((struct sockaddr_dl *)s)
69 #define SRP(s) ((struct sockaddr_inarp *)s)
70
71 /*
72 * ARP trailer negotiation. Trailer protocol is not IP specific,
73 * but ARP request/response use IP addresses.
74 */
75 #define ETHERTYPE_IPTRAILERS ETHERTYPE_TRAIL
76
77 /* timer values */
78 int arpt_prune = (5*60*1); /* walk list every 5 minutes */
79 int arpt_keep = (20*60); /* once resolved, good for 20 more minutes */
80 int arpt_down = 20; /* once declared down, don't send for 20 secs */
81 #define rt_expire rt_rmx.rmx_expire
82
83 static void arprequest
84 __P((struct arpcom *, u_int32_t *, u_int32_t *, u_int8_t *));
85 static void arptfree __P((struct llinfo_arp *));
86 static void arptimer __P((void *));
87 static struct llinfo_arp *arplookup __P((u_int32_t, int, int));
88 static void in_arpinput __P((struct mbuf *));
89
90 extern struct ifnet loif;
91 struct llinfo_arp llinfo_arp = {&llinfo_arp, &llinfo_arp};
92 struct ifqueue arpintrq = {0, 0, 0, 50};
93 int arp_inuse, arp_allocated, arp_intimer;
94 int arp_maxtries = 5;
95 int useloopback = 1; /* use loopback interface for local traffic */
96 int arpinit_done = 0;
97
98 /* revarp state */
99 static struct in_addr myip, srv_ip;
100 static int myip_initialized = 0;
101 static int revarp_in_progress = 0;
102 static struct ifnet *myip_ifp = NULL;
103
104 /*
105 * Timeout routine. Age arp_tab entries periodically.
106 */
107 /* ARGSUSED */
108 static void
109 arptimer(arg)
110 void *arg;
111 {
112 int s = splnet();
113 register struct llinfo_arp *la = llinfo_arp.la_next;
114
115 timeout(arptimer, NULL, arpt_prune * hz);
116 while (la != &llinfo_arp) {
117 register struct rtentry *rt = la->la_rt;
118
119 la = la->la_next;
120 if (rt->rt_expire && rt->rt_expire <= time.tv_sec)
121 arptfree(la->la_prev); /* timer has expired; clear */
122 }
123 splx(s);
124 }
125
126 /*
127 * Parallel to llc_rtrequest.
128 */
129 void
130 arp_rtrequest(req, rt, sa)
131 int req;
132 register struct rtentry *rt;
133 struct sockaddr *sa;
134 {
135 register struct sockaddr *gate = rt->rt_gateway;
136 register struct llinfo_arp *la = (struct llinfo_arp *)rt->rt_llinfo;
137 static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
138
139 if (!arpinit_done) {
140 arpinit_done = 1;
141 /*
142 * We generate expiration times from time.tv_sec
143 * so avoid accidently creating permanent routes.
144 */
145 if (time.tv_sec == 0) {
146 time.tv_sec++;
147 }
148 timeout(arptimer, (caddr_t)0, hz);
149 }
150 if (rt->rt_flags & RTF_GATEWAY)
151 return;
152 switch (req) {
153
154 case RTM_ADD:
155 /*
156 * XXX: If this is a manually added route to interface
157 * such as older version of routed or gated might provide,
158 * restore cloning bit.
159 */
160 if ((rt->rt_flags & RTF_HOST) == 0 &&
161 SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff)
162 rt->rt_flags |= RTF_CLONING;
163 if (rt->rt_flags & RTF_CLONING) {
164 /*
165 * Case 1: This route should come from a route to iface.
166 */
167 rt_setgate(rt, rt_key(rt),
168 (struct sockaddr *)&null_sdl);
169 gate = rt->rt_gateway;
170 SDL(gate)->sdl_type = rt->rt_ifp->if_type;
171 SDL(gate)->sdl_index = rt->rt_ifp->if_index;
172 /*
173 * Give this route an expiration time, even though
174 * it's a "permanent" route, so that routes cloned
175 * from it do not need their expiration time set.
176 */
177 rt->rt_expire = time.tv_sec;
178 break;
179 }
180 /* Announce a new entry if requested. */
181 if (rt->rt_flags & RTF_ANNOUNCE)
182 arprequest((struct arpcom *)rt->rt_ifp,
183 &SIN(rt_key(rt))->sin_addr.s_addr,
184 &SIN(rt_key(rt))->sin_addr.s_addr,
185 (u_char *)LLADDR(SDL(gate)));
186 /*FALLTHROUGH*/
187 case RTM_RESOLVE:
188 if (gate->sa_family != AF_LINK ||
189 gate->sa_len < sizeof(null_sdl)) {
190 log(LOG_DEBUG, "arp_rtrequest: bad gateway value");
191 break;
192 }
193 SDL(gate)->sdl_type = rt->rt_ifp->if_type;
194 SDL(gate)->sdl_index = rt->rt_ifp->if_index;
195 if (la != 0)
196 break; /* This happens on a route change */
197 /*
198 * Case 2: This route may come from cloning, or a manual route
199 * add with a LL address.
200 */
201 R_Malloc(la, struct llinfo_arp *, sizeof(*la));
202 rt->rt_llinfo = (caddr_t)la;
203 if (la == 0) {
204 log(LOG_DEBUG, "arp_rtrequest: malloc failed\n");
205 break;
206 }
207 arp_inuse++, arp_allocated++;
208 Bzero(la, sizeof(*la));
209 la->la_rt = rt;
210 rt->rt_flags |= RTF_LLINFO;
211 insque(la, &llinfo_arp);
212 if (SIN(rt_key(rt))->sin_addr.s_addr ==
213 (IA_SIN(rt->rt_ifa))->sin_addr.s_addr) {
214 /*
215 * This test used to be
216 * if (loif.if_flags & IFF_UP)
217 * It allowed local traffic to be forced through
218 * the hardware by configuring the loopback down.
219 * However, it causes problems during network
220 * configuration for boards that can't receive
221 * packets they send. It is now necessary to clear
222 * "useloopback" and remove the route to force
223 * traffic out to the hardware.
224 */
225 rt->rt_expire = 0;
226 Bcopy(((struct arpcom *)rt->rt_ifp)->ac_enaddr,
227 LLADDR(SDL(gate)),
228 SDL(gate)->sdl_alen = ETHER_ADDR_LEN);
229 if (useloopback)
230 rt->rt_ifp = &loif;
231 }
232 break;
233
234 case RTM_DELETE:
235 if (la == 0)
236 break;
237 arp_inuse--;
238 remque(la);
239 rt->rt_llinfo = 0;
240 rt->rt_flags &= ~RTF_LLINFO;
241 if (la->la_hold)
242 m_freem(la->la_hold);
243 Free((caddr_t)la);
244 }
245 }
246
247 /*
248 * Broadcast an ARP packet, asking who has addr on interface ac.
249 */
250 void
251 arpwhohas(ac, addr)
252 register struct arpcom *ac;
253 register struct in_addr *addr;
254 {
255 arprequest(ac, &ac->ac_ipaddr.s_addr, &addr->s_addr, ac->ac_enaddr);
256 }
257
258 /*
259 * Broadcast an ARP request. Caller specifies:
260 * - arp header source ip address
261 * - arp header target ip address
262 * - arp header source ethernet address
263 */
264 static void
265 arprequest(ac, sip, tip, enaddr)
266 register struct arpcom *ac;
267 register u_int32_t *sip, *tip;
268 register u_int8_t *enaddr;
269 {
270 register struct mbuf *m;
271 register struct ether_header *eh;
272 register struct ether_arp *ea;
273 struct sockaddr sa;
274
275 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
276 return;
277 m->m_len = sizeof(*ea);
278 m->m_pkthdr.len = sizeof(*ea);
279 MH_ALIGN(m, sizeof(*ea));
280 ea = mtod(m, struct ether_arp *);
281 eh = (struct ether_header *)sa.sa_data;
282 bzero((caddr_t)ea, sizeof (*ea));
283 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
284 sizeof(eh->ether_dhost));
285 eh->ether_type = htons(ETHERTYPE_ARP); /* if_output will not swap */
286 ea->arp_hrd = htons(ARPHRD_ETHER);
287 ea->arp_pro = htons(ETHERTYPE_IP);
288 ea->arp_hln = sizeof(ea->arp_sha); /* hardware address length */
289 ea->arp_pln = sizeof(ea->arp_spa); /* protocol address length */
290 ea->arp_op = htons(ARPOP_REQUEST);
291 bcopy((caddr_t)enaddr, (caddr_t)ea->arp_sha, sizeof(ea->arp_sha));
292 bcopy((caddr_t)sip, (caddr_t)ea->arp_spa, sizeof(ea->arp_spa));
293 bcopy((caddr_t)tip, (caddr_t)ea->arp_tpa, sizeof(ea->arp_tpa));
294 sa.sa_family = AF_UNSPEC;
295 sa.sa_len = sizeof(sa);
296 (*ac->ac_if.if_output)(&ac->ac_if, m, &sa, (struct rtentry *)0);
297 }
298
299 /*
300 * Resolve an IP address into an ethernet address. If success,
301 * desten is filled in. If there is no entry in arptab,
302 * set one up and broadcast a request for the IP address.
303 * Hold onto this mbuf and resend it once the address
304 * is finally resolved. A return value of 1 indicates
305 * that desten has been filled in and the packet should be sent
306 * normally; a 0 return indicates that the packet has been
307 * taken over here, either now or for later transmission.
308 */
309 int
310 arpresolve(ac, rt, m, dst, desten)
311 register struct arpcom *ac;
312 register struct rtentry *rt;
313 struct mbuf *m;
314 register struct sockaddr *dst;
315 register u_char *desten;
316 {
317 register struct llinfo_arp *la;
318 struct sockaddr_dl *sdl;
319
320 if (m->m_flags & M_BCAST) { /* broadcast */
321 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)desten,
322 sizeof(etherbroadcastaddr));
323 return (1);
324 }
325 if (m->m_flags & M_MCAST) { /* multicast */
326 ETHER_MAP_IP_MULTICAST(&SIN(dst)->sin_addr, desten);
327 return (1);
328 }
329 if (rt)
330 la = (struct llinfo_arp *)rt->rt_llinfo;
331 else {
332 if (la = arplookup(SIN(dst)->sin_addr.s_addr, 1, 0))
333 rt = la->la_rt;
334 }
335 if (la == 0 || rt == 0) {
336 log(LOG_DEBUG, "arpresolve: can't allocate llinfo");
337 m_freem(m);
338 return (0);
339 }
340 sdl = SDL(rt->rt_gateway);
341 /*
342 * Check the address family and length is valid, the address
343 * is resolved; otherwise, try to resolve.
344 */
345 if ((rt->rt_expire == 0 || rt->rt_expire > time.tv_sec) &&
346 sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) {
347 bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
348 return 1;
349 }
350 /*
351 * There is an arptab entry, but no ethernet address
352 * response yet. Replace the held mbuf with this
353 * latest one.
354 */
355 if (la->la_hold)
356 m_freem(la->la_hold);
357 la->la_hold = m;
358 /*
359 * Re-send the ARP request when appropriate.
360 */
361 #ifdef DIAGNOSTIC
362 if (rt->rt_expire == 0) {
363 /* This should never happen. (Should it? -gwr) */
364 printf("arpresolve: unresolved and rt_expire == 0\n");
365 /* Set expiration time to now (expired). */
366 rt->rt_expire = time.tv_sec;
367 }
368 #endif
369 if (rt->rt_expire) {
370 rt->rt_flags &= ~RTF_REJECT;
371 if (la->la_asked == 0 || rt->rt_expire != time.tv_sec) {
372 rt->rt_expire = time.tv_sec;
373 if (la->la_asked++ < arp_maxtries)
374 arpwhohas(ac, &(SIN(dst)->sin_addr));
375 else {
376 rt->rt_flags |= RTF_REJECT;
377 rt->rt_expire += arpt_down;
378 la->la_asked = 0;
379 }
380 }
381 }
382 return (0);
383 }
384
385 /*
386 * Common length and type checks are done here,
387 * then the protocol-specific routine is called.
388 */
389 void
390 arpintr()
391 {
392 register struct mbuf *m;
393 register struct arphdr *ar;
394 int s;
395
396 while (arpintrq.ifq_head) {
397 s = splimp();
398 IF_DEQUEUE(&arpintrq, m);
399 splx(s);
400 if (m == 0 || (m->m_flags & M_PKTHDR) == 0)
401 panic("arpintr");
402 if (m->m_len >= sizeof(struct arphdr) &&
403 (ar = mtod(m, struct arphdr *)) &&
404 ntohs(ar->ar_hrd) == ARPHRD_ETHER &&
405 m->m_len >=
406 sizeof(struct arphdr) + 2 * (ar->ar_hln + ar->ar_pln))
407 switch (ntohs(ar->ar_pro)) {
408
409 case ETHERTYPE_IP:
410 case ETHERTYPE_IPTRAILERS:
411 in_arpinput(m);
412 continue;
413 }
414 m_freem(m);
415 }
416 }
417
418 /*
419 * ARP for Internet protocols on 10 Mb/s Ethernet.
420 * Algorithm is that given in RFC 826.
421 * In addition, a sanity check is performed on the sender
422 * protocol address, to catch impersonators.
423 * We no longer handle negotiations for use of trailer protocol:
424 * Formerly, ARP replied for protocol type ETHERTYPE_TRAIL sent
425 * along with IP replies if we wanted trailers sent to us,
426 * and also sent them in response to IP replies.
427 * This allowed either end to announce the desire to receive
428 * trailer packets.
429 * We no longer reply to requests for ETHERTYPE_TRAIL protocol either,
430 * but formerly didn't normally send requests.
431 */
432 static void
433 in_arpinput(m)
434 struct mbuf *m;
435 {
436 register struct ether_arp *ea;
437 register struct arpcom *ac = (struct arpcom *)m->m_pkthdr.rcvif;
438 struct ether_header *eh;
439 register struct llinfo_arp *la = 0;
440 register struct rtentry *rt;
441 struct in_ifaddr *ia, *maybe_ia = 0;
442 struct sockaddr_dl *sdl;
443 struct sockaddr sa;
444 struct in_addr isaddr, itaddr, myaddr;
445 int op;
446
447 ea = mtod(m, struct ether_arp *);
448 op = ntohs(ea->arp_op);
449 bcopy((caddr_t)ea->arp_spa, (caddr_t)&isaddr, sizeof (isaddr));
450 bcopy((caddr_t)ea->arp_tpa, (caddr_t)&itaddr, sizeof (itaddr));
451 for (ia = in_ifaddr; ia; ia = ia->ia_next)
452 if (ia->ia_ifp == &ac->ac_if) {
453 maybe_ia = ia;
454 if ((itaddr.s_addr == ia->ia_addr.sin_addr.s_addr) ||
455 (isaddr.s_addr == ia->ia_addr.sin_addr.s_addr))
456 break;
457 }
458 if (maybe_ia == 0)
459 goto out;
460 myaddr = ia ? ia->ia_addr.sin_addr : maybe_ia->ia_addr.sin_addr;
461 if (!bcmp((caddr_t)ea->arp_sha, (caddr_t)ac->ac_enaddr,
462 sizeof (ea->arp_sha)))
463 goto out; /* it's from me, ignore it. */
464 if (!bcmp((caddr_t)ea->arp_sha, (caddr_t)etherbroadcastaddr,
465 sizeof (ea->arp_sha))) {
466 log(LOG_ERR,
467 "arp: ether address is broadcast for IP address %x!\n",
468 ntohl(isaddr.s_addr));
469 goto out;
470 }
471 if (isaddr.s_addr == myaddr.s_addr) {
472 log(LOG_ERR,
473 "duplicate IP address %08x sent from ethernet address %s\n",
474 ntohl(isaddr.s_addr), ether_sprintf(ea->arp_sha));
475 itaddr = myaddr;
476 goto reply;
477 }
478 la = arplookup(isaddr.s_addr, itaddr.s_addr == myaddr.s_addr, 0);
479 if (la && (rt = la->la_rt) && (sdl = SDL(rt->rt_gateway))) {
480 if (sdl->sdl_alen &&
481 bcmp((caddr_t)ea->arp_sha, LLADDR(sdl), sdl->sdl_alen))
482 log(LOG_INFO, "arp info overwritten for %08x by %s\n",
483 ntohl(isaddr.s_addr), ether_sprintf(ea->arp_sha));
484 bcopy((caddr_t)ea->arp_sha, LLADDR(sdl),
485 sdl->sdl_alen = sizeof(ea->arp_sha));
486 if (rt->rt_expire)
487 rt->rt_expire = time.tv_sec + arpt_keep;
488 rt->rt_flags &= ~RTF_REJECT;
489 la->la_asked = 0;
490 if (la->la_hold) {
491 (*ac->ac_if.if_output)(&ac->ac_if, la->la_hold,
492 rt_key(rt), rt);
493 la->la_hold = 0;
494 }
495 }
496 reply:
497 if (op != ARPOP_REQUEST) {
498 out:
499 m_freem(m);
500 return;
501 }
502 if (itaddr.s_addr == myaddr.s_addr) {
503 /* I am the target */
504 bcopy((caddr_t)ea->arp_sha, (caddr_t)ea->arp_tha,
505 sizeof(ea->arp_sha));
506 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_sha,
507 sizeof(ea->arp_sha));
508 } else {
509 la = arplookup(itaddr.s_addr, 0, SIN_PROXY);
510 if (la == 0)
511 goto out;
512 rt = la->la_rt;
513 bcopy((caddr_t)ea->arp_sha, (caddr_t)ea->arp_tha,
514 sizeof(ea->arp_sha));
515 sdl = SDL(rt->rt_gateway);
516 bcopy(LLADDR(sdl), (caddr_t)ea->arp_sha, sizeof(ea->arp_sha));
517 }
518
519 bcopy((caddr_t)ea->arp_spa, (caddr_t)ea->arp_tpa, sizeof(ea->arp_spa));
520 bcopy((caddr_t)&itaddr, (caddr_t)ea->arp_spa, sizeof(ea->arp_spa));
521 ea->arp_op = htons(ARPOP_REPLY);
522 ea->arp_pro = htons(ETHERTYPE_IP); /* let's be sure! */
523 eh = (struct ether_header *)sa.sa_data;
524 bcopy((caddr_t)ea->arp_tha, (caddr_t)eh->ether_dhost,
525 sizeof(eh->ether_dhost));
526 eh->ether_type = htons(ETHERTYPE_ARP);
527 sa.sa_family = AF_UNSPEC;
528 sa.sa_len = sizeof(sa);
529 (*ac->ac_if.if_output)(&ac->ac_if, m, &sa, (struct rtentry *)0);
530 return;
531 }
532
533 /*
534 * Free an arp entry.
535 */
536 static void
537 arptfree(la)
538 register struct llinfo_arp *la;
539 {
540 register struct rtentry *rt = la->la_rt;
541 register struct sockaddr_dl *sdl;
542
543 if (rt == 0)
544 panic("arptfree");
545 if (rt->rt_refcnt > 0 && (sdl = SDL(rt->rt_gateway)) &&
546 sdl->sdl_family == AF_LINK) {
547 sdl->sdl_alen = 0;
548 la->la_asked = 0;
549 rt->rt_flags &= ~RTF_REJECT;
550 return;
551 }
552 rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0, rt_mask(rt),
553 0, (struct rtentry **)0);
554 }
555
556 /*
557 * Lookup or enter a new address in arptab.
558 */
559 static struct llinfo_arp *
560 arplookup(addr, create, proxy)
561 u_int32_t addr;
562 int create, proxy;
563 {
564 register struct rtentry *rt;
565 static struct sockaddr_inarp sin;
566
567 sin.sin_len = sizeof(sin);
568 sin.sin_family = AF_INET;
569 sin.sin_addr.s_addr = addr;
570 sin.sin_other = proxy ? SIN_PROXY : 0;
571 rt = rtalloc1(sintosa(&sin), create);
572 if (rt == 0)
573 return (0);
574 rt->rt_refcnt--;
575 if ((rt->rt_flags & RTF_GATEWAY) || (rt->rt_flags & RTF_LLINFO) == 0 ||
576 rt->rt_gateway->sa_family != AF_LINK) {
577 if (create)
578 log(LOG_DEBUG, "arplookup: unable to enter address for %x\n", ntohl(addr));
579 return (0);
580 }
581 return ((struct llinfo_arp *)rt->rt_llinfo);
582 }
583
584 int
585 arpioctl(cmd, data)
586 u_long cmd;
587 caddr_t data;
588 {
589
590 return (EOPNOTSUPP);
591 }
592
593 void
594 arp_ifinit(ac, ifa)
595 struct arpcom *ac;
596 struct ifaddr *ifa;
597 {
598
599 ac->ac_ipaddr = IA_SIN(ifa)->sin_addr;
600 /* Warn the user if another station has this IP address. */
601 arpwhohas(ac, &ac->ac_ipaddr);
602 ifa->ifa_rtrequest = arp_rtrequest;
603 ifa->ifa_flags |= RTF_CLONING;
604 }
605
606 /*
607 * Called from 10 Mb/s Ethernet interrupt handlers
608 * when ether packet type ETHERTYPE_REVARP
609 * is received. Common length and type checks are done here,
610 * then the protocol-specific routine is called.
611 */
612 void
613 revarpinput(m)
614 struct mbuf *m;
615 {
616 struct arphdr *ar;
617 int op, s;
618
619 if (m->m_len < sizeof(struct arphdr))
620 goto out;
621 ar = mtod(m, struct arphdr *);
622 if (ntohs(ar->ar_hrd) != ARPHRD_ETHER)
623 goto out;
624 if (m->m_len < sizeof(struct arphdr) + 2 * (ar->ar_hln + ar->ar_pln))
625 goto out;
626 switch (ntohs(ar->ar_pro)) {
627
628 case ETHERTYPE_IP:
629 case ETHERTYPE_IPTRAILERS:
630 in_revarpinput(m);
631 return;
632
633 default:
634 break;
635 }
636 out:
637 m_freem(m);
638 }
639
640 /*
641 * RARP for Internet protocols on 10 Mb/s Ethernet.
642 * Algorithm is that given in RFC 903.
643 * We are only using for bootstrap purposes to get an ip address for one of
644 * our interfaces. Thus we support no user-interface.
645 *
646 * Since the contents of the RARP reply are specific to the interface that
647 * sent the request, this code must ensure that they are properly associated.
648 *
649 * Note: also supports ARP via RARP packets, per the RFC.
650 */
651 in_revarpinput(m)
652 struct mbuf *m;
653 {
654 struct ifnet *ifp;
655 struct ether_arp *ar;
656 int op, s;
657
658 ar = mtod(m, struct ether_arp *);
659 op = ntohs(ar->arp_op);
660 switch (op) {
661 case ARPOP_REQUEST:
662 case ARPOP_REPLY: /* per RFC */
663 in_arpinput(m);
664 return;
665 case ARPOP_REVREPLY:
666 break;
667 case ARPOP_REVREQUEST: /* handled by rarpd(8) */
668 default:
669 goto out;
670 }
671 if (!revarp_in_progress)
672 goto out;
673 ifp = m->m_pkthdr.rcvif;
674 if (ifp != myip_ifp) /* !same interface */
675 goto out;
676 if (myip_initialized)
677 goto wake;
678 if (bcmp(ar->arp_tha, ((struct arpcom *)ifp)->ac_enaddr,
679 sizeof(ar->arp_tha)))
680 goto out;
681 bcopy((caddr_t)ar->arp_spa, (caddr_t)&srv_ip, sizeof(srv_ip));
682 bcopy((caddr_t)ar->arp_tpa, (caddr_t)&myip, sizeof(myip));
683 myip_initialized = 1;
684 wake: /* Do wakeup every time in case it was missed. */
685 wakeup((caddr_t)&myip);
686
687 out:
688 m_freem(m);
689 }
690
691 /*
692 * Send a RARP request for the ip address of the specified interface.
693 * The request should be RFC 903-compliant.
694 */
695 void
696 revarprequest(ifp)
697 struct ifnet *ifp;
698 {
699 struct sockaddr sa;
700 struct mbuf *m;
701 struct ether_header *eh;
702 struct ether_arp *ea;
703 struct arpcom *ac = (struct arpcom *)ifp;
704
705 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
706 return;
707 m->m_len = sizeof(*ea);
708 m->m_pkthdr.len = sizeof(*ea);
709 MH_ALIGN(m, sizeof(*ea));
710 ea = mtod(m, struct ether_arp *);
711 eh = (struct ether_header *)sa.sa_data;
712 bzero((caddr_t)ea, sizeof(*ea));
713 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
714 sizeof(eh->ether_dhost));
715 eh->ether_type = htons(ETHERTYPE_REVARP);
716 ea->arp_hrd = htons(ARPHRD_ETHER);
717 ea->arp_pro = htons(ETHERTYPE_IP);
718 ea->arp_hln = sizeof(ea->arp_sha); /* hardware address length */
719 ea->arp_pln = sizeof(ea->arp_spa); /* protocol address length */
720 ea->arp_op = htons(ARPOP_REVREQUEST);
721 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_sha,
722 sizeof(ea->arp_sha));
723 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_tha,
724 sizeof(ea->arp_tha));
725 sa.sa_family = AF_UNSPEC;
726 sa.sa_len = sizeof(sa);
727 ifp->if_output(ifp, m, &sa, (struct rtentry *)0);
728 }
729
730 /*
731 * RARP for the ip address of the specified interface, but also
732 * save the ip address of the server that sent the answer.
733 * Timeout if no response is received.
734 */
735 int
736 revarpwhoarewe(ifp, serv_in, clnt_in)
737 struct ifnet *ifp;
738 struct in_addr *serv_in;
739 struct in_addr *clnt_in;
740 {
741 int result, count = 20;
742
743 if (myip_initialized)
744 return EIO;
745
746 myip_ifp = ifp;
747 revarp_in_progress = 1;
748 while (count--) {
749 revarprequest(ifp);
750 result = tsleep((caddr_t)&myip, PSOCK, "revarp", hz/2);
751 if (result != EWOULDBLOCK)
752 break;
753 }
754 revarp_in_progress = 0;
755 if (!myip_initialized)
756 return ENETUNREACH;
757
758 bcopy((caddr_t)&srv_ip, serv_in, sizeof(*serv_in));
759 bcopy((caddr_t)&myip, clnt_in, sizeof(*clnt_in));
760 return 0;
761 }
762
763 /* For compatibility: only saves interface address. */
764 int
765 revarpwhoami(in, ifp)
766 struct in_addr *in;
767 struct ifnet *ifp;
768 {
769 struct in_addr server;
770 return (revarpwhoarewe(ifp, &server, in));
771 }
772
773
775 #ifdef DDB
776 static void
777 db_print_sa(sa)
778 struct sockaddr *sa;
779 {
780 int len;
781 u_char *p;
782
783 if (sa == 0) {
784 db_printf("[NULL]");
785 return;
786 }
787
788 p = (u_char*)sa;
789 len = sa->sa_len;
790 db_printf("[");
791 while (len > 0) {
792 db_printf("%d", *p);
793 p++; len--;
794 if (len) db_printf(",");
795 }
796 db_printf("]\n");
797 }
798 static void
799 db_print_ifa(ifa)
800 struct ifaddr *ifa;
801 {
802 if (ifa == 0)
803 return;
804 db_printf(" ifa_addr=");
805 db_print_sa(ifa->ifa_addr);
806 db_printf(" ifa_dsta=");
807 db_print_sa(ifa->ifa_dstaddr);
808 db_printf(" ifa_mask=");
809 db_print_sa(ifa->ifa_netmask);
810 db_printf(" flags=0x%x,refcnt=%d,metric=%d\n",
811 ifa->ifa_flags,
812 ifa->ifa_refcnt,
813 ifa->ifa_metric);
814 }
815 static void
816 db_print_llinfo(li)
817 caddr_t li;
818 {
819 struct llinfo_arp *la;
820
821 if (li == 0)
822 return;
823 la = (struct llinfo_arp *)li;
824 db_printf(" la_rt=0x%x la_hold=0x%x, la_asked=0x%x\n",
825 la->la_rt, la->la_hold, la->la_asked);
826 }
827 /*
828 * Function to pass to rn_walktree().
829 * Return non-zero error to abort walk.
830 */
831 static int
832 db_show_radix_node(rn, w)
833 struct radix_node *rn;
834 void *w;
835 {
836 struct rtentry *rt = (struct rtentry *)rn;
837
838 db_printf("rtentry=0x%x", rt);
839
840 db_printf(" flags=0x%x refcnt=%d use=%d expire=%d\n",
841 rt->rt_flags, rt->rt_refcnt,
842 rt->rt_use, rt->rt_expire);
843
844 db_printf(" key="); db_print_sa(rt_key(rt));
845 db_printf(" mask="); db_print_sa(rt_mask(rt));
846 db_printf(" gw="); db_print_sa(rt->rt_gateway);
847
848 db_printf(" ifp=0x%lx ", rt->rt_ifp);
849 if (rt->rt_ifp)
850 db_printf("(%s%d)",
851 rt->rt_ifp->if_name,
852 rt->rt_ifp->if_unit);
853 else
854 db_printf("(NULL)");
855
856 db_printf(" ifa=0x%lx\n", rt->rt_ifa);
857 db_print_ifa(rt->rt_ifa);
858
859 db_printf(" genmask="); db_print_sa(rt->rt_genmask);
860
861 db_printf(" gwroute=0x%x llinfo=0x%x\n",
862 rt->rt_gwroute, rt->rt_llinfo);
863 db_print_llinfo(rt->rt_llinfo);
864
865 return (0);
866 }
867 /*
868 * Function to print all the route trees.
869 * Use this from ddb: "call db_show_arptab"
870 */
871 db_show_arptab()
872 {
873 struct radix_node_head *rnh;
874 rnh = rt_tables[AF_INET];
875 db_printf("Route tree for AF_INET\n");
876 if (rnh == NULL) {
877 db_printf(" (not initialized)\n");
878 return (0);
879 }
880 rn_walktree(rnh, db_show_radix_node, NULL);
881 return (0);
882 }
883 #endif
884 #endif /* INET */
885