This source file includes following definitions.
- arptimer
- arp_rtrequest
- arprequest
- arpresolve
- arpintr
- in_arpinput
- arptfree
- arplookup
- arpioctl
- arp_ifinit
- revarpinput
- in_revarpinput
- revarprequest
- revarpwhoarewe
- revarpwhoami
- db_print_sa
- db_print_ifa
- db_print_llinfo
- db_show_radix_node
- db_show_arptab
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 #ifdef INET
42 #include "carp.h"
43
44 #include "bridge.h"
45
46 #include <sys/param.h>
47 #include <sys/systm.h>
48 #include <sys/mbuf.h>
49 #include <sys/socket.h>
50 #include <sys/kernel.h>
51 #include <sys/syslog.h>
52 #include <sys/proc.h>
53
54 #include <net/if.h>
55 #include <net/if_dl.h>
56 #include <net/route.h>
57 #include <net/if_fddi.h>
58 #include <net/if_types.h>
59
60 #include <netinet/in.h>
61 #include <netinet/in_var.h>
62 #include <netinet/if_ether.h>
63 #if NCARP > 0
64 #include <netinet/ip_carp.h>
65 #endif
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
73
74
75 #define ETHERTYPE_IPTRAILERS ETHERTYPE_TRAIL
76
77
78 int arpt_prune = (5*60*1);
79 int arpt_keep = (20*60);
80 int arpt_down = 20;
81 #define rt_expire rt_rmx.rmx_expire
82
83 void arptfree(struct llinfo_arp *);
84 void arptimer(void *);
85 struct llinfo_arp *arplookup(u_int32_t, int, int);
86 void in_arpinput(struct mbuf *);
87
88 LIST_HEAD(, llinfo_arp) llinfo_arp;
89 struct ifqueue arpintrq = {0, 0, 0, 50};
90 int arp_inuse, arp_allocated, arp_intimer;
91 int arp_maxtries = 5;
92 int useloopback = 1;
93 int arpinit_done = 0;
94
95
96 struct in_addr myip, srv_ip;
97 int myip_initialized = 0;
98 int revarp_in_progress = 0;
99 struct ifnet *myip_ifp = NULL;
100
101 #ifdef DDB
102 #include <uvm/uvm_extern.h>
103
104 void db_print_sa(struct sockaddr *);
105 void db_print_ifa(struct ifaddr *);
106 void db_print_llinfo(caddr_t);
107 int db_show_radix_node(struct radix_node *, void *);
108 #endif
109
110
111
112
113
114 void
115 arptimer(arg)
116 void *arg;
117 {
118 struct timeout *to = (struct timeout *)arg;
119 int s;
120 struct llinfo_arp *la, *nla;
121
122 s = splsoftnet();
123 timeout_add(to, arpt_prune * hz);
124 for (la = LIST_FIRST(&llinfo_arp); la != LIST_END(&llinfo_arp);
125 la = nla) {
126 struct rtentry *rt = la->la_rt;
127
128 nla = LIST_NEXT(la, la_list);
129 if (rt->rt_expire && rt->rt_expire <= time_second)
130 arptfree(la);
131 }
132 splx(s);
133 }
134
135
136
137
138 void
139 arp_rtrequest(req, rt, info)
140 int req;
141 struct rtentry *rt;
142 struct rt_addrinfo *info;
143 {
144 struct sockaddr *gate = rt->rt_gateway;
145 struct llinfo_arp *la = (struct llinfo_arp *)rt->rt_llinfo;
146 static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
147 struct in_ifaddr *ia;
148 struct ifaddr *ifa;
149
150 if (!arpinit_done) {
151 static struct timeout arptimer_to;
152
153 arpinit_done = 1;
154
155
156
157
158 if (time_second == 0) {
159 time_second++;
160 }
161
162 timeout_set(&arptimer_to, arptimer, &arptimer_to);
163 timeout_add(&arptimer_to, hz);
164 }
165
166 if (rt->rt_flags & RTF_GATEWAY) {
167 if (req != RTM_ADD)
168 return;
169
170
171
172
173
174
175 switch (rt->rt_ifp->if_type) {
176 case IFT_FDDI:
177 if (rt->rt_ifp->if_mtu > FDDIIPMTU)
178 rt->rt_rmx.rmx_mtu = FDDIIPMTU;
179 break;
180 }
181
182 return;
183 }
184
185 switch (req) {
186
187 case RTM_ADD:
188
189
190
191
192
193 if ((rt->rt_flags & RTF_HOST) == 0 &&
194 SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff)
195 rt->rt_flags |= RTF_CLONING;
196 if (rt->rt_flags & RTF_CLONING) {
197
198
199
200 rt_setgate(rt, rt_key(rt),
201 (struct sockaddr *)&null_sdl, 0);
202 gate = rt->rt_gateway;
203 SDL(gate)->sdl_type = rt->rt_ifp->if_type;
204 SDL(gate)->sdl_index = rt->rt_ifp->if_index;
205
206
207
208
209
210 rt->rt_expire = time_second;
211
212
213
214 switch (rt->rt_ifp->if_type) {
215 case IFT_FDDI:
216 if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0 &&
217 (rt->rt_rmx.rmx_mtu > FDDIIPMTU ||
218 (rt->rt_rmx.rmx_mtu == 0 &&
219 rt->rt_ifp->if_mtu > FDDIIPMTU)))
220 rt->rt_rmx.rmx_mtu = FDDIIPMTU;
221 break;
222 }
223 break;
224 }
225
226 if (rt->rt_flags & RTF_ANNOUNCE)
227 arprequest(rt->rt_ifp,
228 &SIN(rt_key(rt))->sin_addr.s_addr,
229 &SIN(rt_key(rt))->sin_addr.s_addr,
230 (u_char *)LLADDR(SDL(gate)));
231
232 case RTM_RESOLVE:
233 if (gate->sa_family != AF_LINK ||
234 gate->sa_len < sizeof(null_sdl)) {
235 log(LOG_DEBUG, "arp_rtrequest: bad gateway value\n");
236 break;
237 }
238 SDL(gate)->sdl_type = rt->rt_ifp->if_type;
239 SDL(gate)->sdl_index = rt->rt_ifp->if_index;
240 if (la != 0)
241 break;
242
243
244
245
246 R_Malloc(la, struct llinfo_arp *, sizeof(*la));
247 rt->rt_llinfo = (caddr_t)la;
248 if (la == 0) {
249 log(LOG_DEBUG, "arp_rtrequest: malloc failed\n");
250 break;
251 }
252 arp_inuse++, arp_allocated++;
253 Bzero(la, sizeof(*la));
254 la->la_rt = rt;
255 rt->rt_flags |= RTF_LLINFO;
256 LIST_INSERT_HEAD(&llinfo_arp, la, la_list);
257
258 TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
259 if (ia->ia_ifp == rt->rt_ifp &&
260 SIN(rt_key(rt))->sin_addr.s_addr ==
261 (IA_SIN(ia))->sin_addr.s_addr)
262 break;
263 }
264 if (ia) {
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282 rt->rt_expire = 0;
283 Bcopy(((struct arpcom *)rt->rt_ifp)->ac_enaddr,
284 LLADDR(SDL(gate)),
285 SDL(gate)->sdl_alen = ETHER_ADDR_LEN);
286 if (useloopback)
287 rt->rt_ifp = lo0ifp;
288
289
290
291
292
293 ifa = &ia->ia_ifa;
294 if (ifa != rt->rt_ifa) {
295 IFAFREE(rt->rt_ifa);
296 ifa->ifa_refcnt++;
297 rt->rt_ifa = ifa;
298 }
299 }
300 break;
301
302 case RTM_DELETE:
303 if (la == 0)
304 break;
305 arp_inuse--;
306 LIST_REMOVE(la, la_list);
307 rt->rt_llinfo = 0;
308 rt->rt_flags &= ~RTF_LLINFO;
309 if (la->la_hold)
310 m_freem(la->la_hold);
311 Free((caddr_t)la);
312 }
313 }
314
315
316
317
318
319
320
321 void
322 arprequest(ifp, sip, tip, enaddr)
323 struct ifnet *ifp;
324 u_int32_t *sip, *tip;
325 u_int8_t *enaddr;
326 {
327 struct mbuf *m;
328 struct ether_header *eh;
329 struct ether_arp *ea;
330 struct sockaddr sa;
331
332 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
333 return;
334 m->m_len = sizeof(*ea);
335 m->m_pkthdr.len = sizeof(*ea);
336 MH_ALIGN(m, sizeof(*ea));
337 ea = mtod(m, struct ether_arp *);
338 eh = (struct ether_header *)sa.sa_data;
339 bzero((caddr_t)ea, sizeof (*ea));
340 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
341 sizeof(eh->ether_dhost));
342 eh->ether_type = htons(ETHERTYPE_ARP);
343 ea->arp_hrd = htons(ARPHRD_ETHER);
344 ea->arp_pro = htons(ETHERTYPE_IP);
345 ea->arp_hln = sizeof(ea->arp_sha);
346 ea->arp_pln = sizeof(ea->arp_spa);
347 ea->arp_op = htons(ARPOP_REQUEST);
348 bcopy((caddr_t)enaddr, (caddr_t)eh->ether_shost,
349 sizeof(eh->ether_shost));
350 bcopy((caddr_t)enaddr, (caddr_t)ea->arp_sha, sizeof(ea->arp_sha));
351 bcopy((caddr_t)sip, (caddr_t)ea->arp_spa, sizeof(ea->arp_spa));
352 bcopy((caddr_t)tip, (caddr_t)ea->arp_tpa, sizeof(ea->arp_tpa));
353 sa.sa_family = pseudo_AF_HDRCMPLT;
354 sa.sa_len = sizeof(sa);
355 (*ifp->if_output)(ifp, m, &sa, (struct rtentry *)0);
356 }
357
358
359
360
361
362
363
364
365
366
367
368 int
369 arpresolve(ac, rt, m, dst, desten)
370 struct arpcom *ac;
371 struct rtentry *rt;
372 struct mbuf *m;
373 struct sockaddr *dst;
374 u_char *desten;
375 {
376 struct llinfo_arp *la;
377 struct sockaddr_dl *sdl;
378
379 if (m->m_flags & M_BCAST) {
380 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)desten,
381 sizeof(etherbroadcastaddr));
382 return (1);
383 }
384 if (m->m_flags & M_MCAST) {
385 ETHER_MAP_IP_MULTICAST(&SIN(dst)->sin_addr, desten);
386 return (1);
387 }
388 if (rt) {
389 la = (struct llinfo_arp *)rt->rt_llinfo;
390 if (la == NULL)
391 log(LOG_DEBUG, "arpresolve: %s: route without link "
392 "local address\n", inet_ntoa(SIN(dst)->sin_addr));
393 } else {
394 if ((la = arplookup(SIN(dst)->sin_addr.s_addr, 1, 0)) != NULL)
395 rt = la->la_rt;
396 else
397 log(LOG_DEBUG,
398 "arpresolve: %s: can't allocate llinfo\n",
399 inet_ntoa(SIN(dst)->sin_addr));
400 }
401 if (la == 0 || rt == 0) {
402 m_freem(m);
403 return (0);
404 }
405 sdl = SDL(rt->rt_gateway);
406
407
408
409
410 if ((rt->rt_expire == 0 || rt->rt_expire > time_second) &&
411 sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) {
412 bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
413 return 1;
414 }
415 if (((struct ifnet *)ac)->if_flags & IFF_NOARP)
416 return 0;
417
418
419
420
421
422
423 if (la->la_hold)
424 m_freem(la->la_hold);
425 la->la_hold = m;
426
427
428
429 #ifdef DIAGNOSTIC
430 if (rt->rt_expire == 0) {
431
432 printf("arpresolve: unresolved and rt_expire == 0\n");
433
434 rt->rt_expire = time_second;
435 }
436 #endif
437 if (rt->rt_expire) {
438 rt->rt_flags &= ~RTF_REJECT;
439 if (la->la_asked == 0 || rt->rt_expire != time_second) {
440 rt->rt_expire = time_second;
441 if (la->la_asked++ < arp_maxtries)
442 arprequest(&ac->ac_if,
443 &(SIN(rt->rt_ifa->ifa_addr)->sin_addr.s_addr),
444 &(SIN(dst)->sin_addr.s_addr),
445 #if NCARP > 0
446 (rt->rt_ifp->if_type == IFT_CARP) ?
447 ((struct arpcom *) rt->rt_ifp->if_softc
448 )->ac_enaddr :
449 #endif
450 ac->ac_enaddr);
451 else {
452 rt->rt_flags |= RTF_REJECT;
453 rt->rt_expire += arpt_down;
454 la->la_asked = 0;
455 }
456 }
457 }
458 return (0);
459 }
460
461
462
463
464
465 void
466 arpintr()
467 {
468 struct mbuf *m;
469 struct arphdr *ar;
470 int s, len;
471
472 while (arpintrq.ifq_head) {
473 s = splnet();
474 IF_DEQUEUE(&arpintrq, m);
475 splx(s);
476 if (m == 0 || (m->m_flags & M_PKTHDR) == 0)
477 panic("arpintr");
478
479 len = sizeof(struct arphdr);
480 if (m->m_len < len && (m = m_pullup(m, len)) == NULL)
481 continue;
482
483 ar = mtod(m, struct arphdr *);
484 if (ntohs(ar->ar_hrd) != ARPHRD_ETHER) {
485 m_freem(m);
486 continue;
487 }
488
489 len += 2 * (ar->ar_hln + ar->ar_pln);
490 if (m->m_len < len && (m = m_pullup(m, len)) == NULL)
491 continue;
492
493 switch (ntohs(ar->ar_pro)) {
494 case ETHERTYPE_IP:
495 case ETHERTYPE_IPTRAILERS:
496 in_arpinput(m);
497 continue;
498 }
499 m_freem(m);
500 }
501 }
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517 void
518 in_arpinput(m)
519 struct mbuf *m;
520 {
521 struct ether_arp *ea;
522 struct arpcom *ac = (struct arpcom *)m->m_pkthdr.rcvif;
523 struct ether_header *eh;
524 struct llinfo_arp *la = 0;
525 struct rtentry *rt;
526 struct in_ifaddr *ia;
527 #if NBRIDGE > 0
528 struct in_ifaddr *bridge_ia = NULL;
529 #endif
530 #if NCARP > 0
531 u_int32_t count = 0, index = 0;
532 #endif
533 struct sockaddr_dl *sdl;
534 struct sockaddr sa;
535 struct in_addr isaddr, itaddr, myaddr;
536 u_int8_t *enaddr = NULL;
537 int op;
538
539 ea = mtod(m, struct ether_arp *);
540 op = ntohs(ea->arp_op);
541 if ((op != ARPOP_REQUEST) && (op != ARPOP_REPLY))
542 goto out;
543 #if notyet
544 if ((op == ARPOP_REPLY) && (m->m_flags & (M_BCAST|M_MCAST))) {
545 log(LOG_ERR,
546 "arp: received reply to broadcast or multicast address\n");
547 goto out;
548 }
549 #endif
550
551 bcopy((caddr_t)ea->arp_tpa, (caddr_t)&itaddr, sizeof(itaddr));
552 bcopy((caddr_t)ea->arp_spa, (caddr_t)&isaddr, sizeof(isaddr));
553
554 TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
555 if (itaddr.s_addr != ia->ia_addr.sin_addr.s_addr)
556 continue;
557
558 #if NCARP > 0
559 if (ia->ia_ifp->if_type == IFT_CARP &&
560 ((ia->ia_ifp->if_flags & (IFF_UP|IFF_RUNNING)) ==
561 (IFF_UP|IFF_RUNNING))) {
562 index++;
563 if (ia->ia_ifp == m->m_pkthdr.rcvif &&
564 carp_iamatch(ia, ea->arp_sha,
565 &count, index))
566 break;
567 } else
568 #endif
569 if (ia->ia_ifp == m->m_pkthdr.rcvif)
570 break;
571 #if NBRIDGE > 0
572
573
574
575
576
577
578
579 if (m->m_pkthdr.rcvif->if_bridge != NULL) {
580 if (m->m_pkthdr.rcvif->if_bridge ==
581 ia->ia_ifp->if_bridge)
582 bridge_ia = ia;
583 #if NCARP > 0
584 else if (ia->ia_ifp->if_carpdev != NULL &&
585 m->m_pkthdr.rcvif->if_bridge ==
586 ia->ia_ifp->if_carpdev->if_bridge &&
587 carp_iamatch(ia, ea->arp_sha,
588 &count, index))
589 bridge_ia = ia;
590 #endif
591 }
592 #endif
593 }
594
595 #if NBRIDGE > 0
596 if (ia == NULL && bridge_ia != NULL) {
597 ia = bridge_ia;
598 ac = (struct arpcom *)bridge_ia->ia_ifp;
599 }
600 #endif
601
602 if (ia == NULL) {
603 TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
604 if (isaddr.s_addr != ia->ia_addr.sin_addr.s_addr)
605 continue;
606 if (ia->ia_ifp == m->m_pkthdr.rcvif)
607 break;
608 }
609 }
610
611 if (ia == NULL && m->m_pkthdr.rcvif->if_type != IFT_CARP) {
612 struct ifaddr *ifa;
613
614 TAILQ_FOREACH(ifa, &m->m_pkthdr.rcvif->if_addrlist, ifa_list) {
615 if (ifa->ifa_addr->sa_family == AF_INET)
616 break;
617 }
618 if (ifa)
619 ia = (struct in_ifaddr *)ifa;
620 }
621
622 if (ia == NULL)
623 goto out;
624
625 if (!enaddr)
626 enaddr = ac->ac_enaddr;
627 myaddr = ia->ia_addr.sin_addr;
628
629 if (!bcmp((caddr_t)ea->arp_sha, enaddr, sizeof (ea->arp_sha)))
630 goto out;
631 if (ETHER_IS_MULTICAST (&ea->arp_sha[0]))
632 if (!bcmp((caddr_t)ea->arp_sha, (caddr_t)etherbroadcastaddr,
633 sizeof (ea->arp_sha))) {
634 log(LOG_ERR, "arp: ether address is broadcast for "
635 "IP address %s!\n", inet_ntoa(isaddr));
636 goto out;
637 }
638 if (myaddr.s_addr && isaddr.s_addr == myaddr.s_addr) {
639 log(LOG_ERR,
640 "duplicate IP address %s sent from ethernet address %s\n",
641 inet_ntoa(isaddr), ether_sprintf(ea->arp_sha));
642 itaddr = myaddr;
643 goto reply;
644 }
645 la = arplookup(isaddr.s_addr, itaddr.s_addr == myaddr.s_addr, 0);
646 if (la && (rt = la->la_rt) && (sdl = SDL(rt->rt_gateway))) {
647 if (sdl->sdl_alen) {
648 if (bcmp(ea->arp_sha, LLADDR(sdl), sdl->sdl_alen)) {
649 if (rt->rt_flags & RTF_PERMANENT_ARP) {
650 log(LOG_WARNING,
651 "arp: attempt to overwrite permanent "
652 "entry for %s by %s on %s\n",
653 inet_ntoa(isaddr),
654 ether_sprintf(ea->arp_sha),
655 ac->ac_if.if_xname);
656 goto out;
657 } else if (rt->rt_ifp != &ac->ac_if) {
658 log(LOG_WARNING,
659 "arp: attempt to overwrite entry for %s "
660 "on %s by %s on %s\n",
661 inet_ntoa(isaddr), rt->rt_ifp->if_xname,
662 ether_sprintf(ea->arp_sha),
663 ac->ac_if.if_xname);
664 goto out;
665 } else {
666 log(LOG_INFO,
667 "arp info overwritten for %s by %s on %s\n",
668 inet_ntoa(isaddr),
669 ether_sprintf(ea->arp_sha),
670 ac->ac_if.if_xname);
671 rt->rt_expire = 1;
672 }
673 }
674 } else if (rt->rt_ifp != &ac->ac_if && !(ac->ac_if.if_bridge &&
675 (rt->rt_ifp->if_bridge == ac->ac_if.if_bridge)) &&
676 !(rt->rt_ifp->if_type == IFT_CARP &&
677 rt->rt_ifp->if_carpdev == &ac->ac_if) &&
678 !(ac->ac_if.if_type == IFT_CARP &&
679 ac->ac_if.if_carpdev == rt->rt_ifp)) {
680 log(LOG_WARNING,
681 "arp: attempt to add entry for %s "
682 "on %s by %s on %s\n",
683 inet_ntoa(isaddr), rt->rt_ifp->if_xname,
684 ether_sprintf(ea->arp_sha),
685 ac->ac_if.if_xname);
686 goto out;
687 }
688 bcopy(ea->arp_sha, LLADDR(sdl),
689 sdl->sdl_alen = sizeof(ea->arp_sha));
690 if (rt->rt_expire)
691 rt->rt_expire = time_second + arpt_keep;
692 rt->rt_flags &= ~RTF_REJECT;
693 la->la_asked = 0;
694 if (la->la_hold) {
695 (*ac->ac_if.if_output)(&ac->ac_if, la->la_hold,
696 rt_key(rt), rt);
697 la->la_hold = 0;
698 }
699 }
700 reply:
701 if (op != ARPOP_REQUEST) {
702 out:
703 m_freem(m);
704 return;
705 }
706 if (itaddr.s_addr == myaddr.s_addr) {
707
708 bcopy(ea->arp_sha, ea->arp_tha, sizeof(ea->arp_sha));
709 bcopy(enaddr, ea->arp_sha, sizeof(ea->arp_sha));
710 } else {
711 la = arplookup(itaddr.s_addr, 0, SIN_PROXY);
712 if (la == 0)
713 goto out;
714 rt = la->la_rt;
715 if (rt->rt_ifp->if_type == IFT_CARP &&
716 m->m_pkthdr.rcvif->if_type != IFT_CARP)
717 goto out;
718 bcopy(ea->arp_sha, ea->arp_tha, sizeof(ea->arp_sha));
719 sdl = SDL(rt->rt_gateway);
720 bcopy(LLADDR(sdl), ea->arp_sha, sizeof(ea->arp_sha));
721 }
722
723 bcopy(ea->arp_spa, ea->arp_tpa, sizeof(ea->arp_spa));
724 bcopy(&itaddr, ea->arp_spa, sizeof(ea->arp_spa));
725 ea->arp_op = htons(ARPOP_REPLY);
726 ea->arp_pro = htons(ETHERTYPE_IP);
727 eh = (struct ether_header *)sa.sa_data;
728 bcopy(ea->arp_tha, eh->ether_dhost, sizeof(eh->ether_dhost));
729 #if NCARP > 0
730 if (ac->ac_if.if_type == IFT_CARP && ac->ac_if.if_flags & IFF_LINK1)
731 bcopy(((struct arpcom *)ac->ac_if.if_carpdev)->ac_enaddr,
732 eh->ether_shost, sizeof(eh->ether_shost));
733 else
734 #endif
735 bcopy(enaddr, eh->ether_shost, sizeof(eh->ether_shost));
736
737 eh->ether_type = htons(ETHERTYPE_ARP);
738 sa.sa_family = pseudo_AF_HDRCMPLT;
739 sa.sa_len = sizeof(sa);
740 (*ac->ac_if.if_output)(&ac->ac_if, m, &sa, (struct rtentry *)0);
741 return;
742 }
743
744
745
746
747 void
748 arptfree(la)
749 struct llinfo_arp *la;
750 {
751 struct rtentry *rt = la->la_rt;
752 struct sockaddr_dl *sdl;
753
754 if (rt == 0)
755 panic("arptfree");
756 if (rt->rt_refcnt > 0 && (sdl = SDL(rt->rt_gateway)) &&
757 sdl->sdl_family == AF_LINK) {
758 sdl->sdl_alen = 0;
759 la->la_asked = 0;
760 rt->rt_flags &= ~RTF_REJECT;
761 return;
762 }
763 rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0, rt_mask(rt),
764 0, (struct rtentry **)0, 0);
765 }
766
767
768
769
770 struct llinfo_arp *
771 arplookup(addr, create, proxy)
772 u_int32_t addr;
773 int create, proxy;
774 {
775 struct rtentry *rt;
776 static struct sockaddr_inarp sin;
777
778 sin.sin_len = sizeof(sin);
779 sin.sin_family = AF_INET;
780 sin.sin_addr.s_addr = addr;
781 sin.sin_other = proxy ? SIN_PROXY : 0;
782 rt = rtalloc1(sintosa(&sin), create, 0);
783 if (rt == 0)
784 return (0);
785 rt->rt_refcnt--;
786 if ((rt->rt_flags & RTF_GATEWAY) || (rt->rt_flags & RTF_LLINFO) == 0 ||
787 rt->rt_gateway->sa_family != AF_LINK) {
788 if (create) {
789 if (rt->rt_refcnt <= 0 &&
790 (rt->rt_flags & RTF_CLONED) != 0) {
791 rtrequest(RTM_DELETE,
792 (struct sockaddr *)rt_key(rt),
793 rt->rt_gateway, rt_mask(rt), rt->rt_flags,
794 0, 0);
795 }
796 }
797 return (0);
798 }
799 return ((struct llinfo_arp *)rt->rt_llinfo);
800 }
801
802 int
803 arpioctl(cmd, data)
804 u_long cmd;
805 caddr_t data;
806 {
807
808 return (EOPNOTSUPP);
809 }
810
811 void
812 arp_ifinit(ac, ifa)
813 struct arpcom *ac;
814 struct ifaddr *ifa;
815 {
816
817
818 arprequest(&ac->ac_if,
819 &(IA_SIN(ifa)->sin_addr.s_addr),
820 &(IA_SIN(ifa)->sin_addr.s_addr),
821 ac->ac_enaddr);
822 ifa->ifa_rtrequest = arp_rtrequest;
823 ifa->ifa_flags |= RTF_CLONING;
824 }
825
826
827
828
829
830
831
832 void
833 revarpinput(m)
834 struct mbuf *m;
835 {
836 struct arphdr *ar;
837
838 if (m->m_len < sizeof(struct arphdr))
839 goto out;
840 ar = mtod(m, struct arphdr *);
841 if (ntohs(ar->ar_hrd) != ARPHRD_ETHER)
842 goto out;
843 if (m->m_len < sizeof(struct arphdr) + 2 * (ar->ar_hln + ar->ar_pln))
844 goto out;
845 switch (ntohs(ar->ar_pro)) {
846
847 case ETHERTYPE_IP:
848 case ETHERTYPE_IPTRAILERS:
849 in_revarpinput(m);
850 return;
851
852 default:
853 break;
854 }
855 out:
856 m_freem(m);
857 }
858
859
860
861
862
863
864
865
866
867
868
869
870 void
871 in_revarpinput(m)
872 struct mbuf *m;
873 {
874 struct ifnet *ifp;
875 struct ether_arp *ar;
876 int op;
877
878 ar = mtod(m, struct ether_arp *);
879 op = ntohs(ar->arp_op);
880 switch (op) {
881 case ARPOP_REQUEST:
882 case ARPOP_REPLY:
883 in_arpinput(m);
884 return;
885 case ARPOP_REVREPLY:
886 break;
887 case ARPOP_REVREQUEST:
888 default:
889 goto out;
890 }
891 if (!revarp_in_progress)
892 goto out;
893 ifp = m->m_pkthdr.rcvif;
894 if (ifp != myip_ifp)
895 goto out;
896 if (myip_initialized)
897 goto wake;
898 if (bcmp(ar->arp_tha, ((struct arpcom *)ifp)->ac_enaddr,
899 sizeof(ar->arp_tha)))
900 goto out;
901 bcopy((caddr_t)ar->arp_spa, (caddr_t)&srv_ip, sizeof(srv_ip));
902 bcopy((caddr_t)ar->arp_tpa, (caddr_t)&myip, sizeof(myip));
903 myip_initialized = 1;
904 wake:
905 wakeup((caddr_t)&myip);
906
907 out:
908 m_freem(m);
909 }
910
911
912
913
914
915 void
916 revarprequest(ifp)
917 struct ifnet *ifp;
918 {
919 struct sockaddr sa;
920 struct mbuf *m;
921 struct ether_header *eh;
922 struct ether_arp *ea;
923 struct arpcom *ac = (struct arpcom *)ifp;
924
925 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
926 return;
927 m->m_len = sizeof(*ea);
928 m->m_pkthdr.len = sizeof(*ea);
929 MH_ALIGN(m, sizeof(*ea));
930 ea = mtod(m, struct ether_arp *);
931 eh = (struct ether_header *)sa.sa_data;
932 bzero((caddr_t)ea, sizeof(*ea));
933 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
934 sizeof(eh->ether_dhost));
935 eh->ether_type = htons(ETHERTYPE_REVARP);
936 ea->arp_hrd = htons(ARPHRD_ETHER);
937 ea->arp_pro = htons(ETHERTYPE_IP);
938 ea->arp_hln = sizeof(ea->arp_sha);
939 ea->arp_pln = sizeof(ea->arp_spa);
940 ea->arp_op = htons(ARPOP_REVREQUEST);
941 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost,
942 sizeof(ea->arp_tha));
943 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_sha,
944 sizeof(ea->arp_sha));
945 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_tha,
946 sizeof(ea->arp_tha));
947 sa.sa_family = pseudo_AF_HDRCMPLT;
948 sa.sa_len = sizeof(sa);
949 ifp->if_output(ifp, m, &sa, (struct rtentry *)0);
950 }
951
952
953
954
955
956
957 int
958 revarpwhoarewe(ifp, serv_in, clnt_in)
959 struct ifnet *ifp;
960 struct in_addr *serv_in;
961 struct in_addr *clnt_in;
962 {
963 int result, count = 20;
964
965 if (myip_initialized)
966 return EIO;
967
968 myip_ifp = ifp;
969 revarp_in_progress = 1;
970 while (count--) {
971 revarprequest(ifp);
972 result = tsleep((caddr_t)&myip, PSOCK, "revarp", hz/2);
973 if (result != EWOULDBLOCK)
974 break;
975 }
976 revarp_in_progress = 0;
977 if (!myip_initialized)
978 return ENETUNREACH;
979
980 bcopy((caddr_t)&srv_ip, serv_in, sizeof(*serv_in));
981 bcopy((caddr_t)&myip, clnt_in, sizeof(*clnt_in));
982 return 0;
983 }
984
985
986 int
987 revarpwhoami(in, ifp)
988 struct in_addr *in;
989 struct ifnet *ifp;
990 {
991 struct in_addr server;
992 return (revarpwhoarewe(ifp, &server, in));
993 }
994
995
996 #ifdef DDB
997
998 #include <machine/db_machdep.h>
999 #include <ddb/db_interface.h>
1000 #include <ddb/db_output.h>
1001
1002 void
1003 db_print_sa(sa)
1004 struct sockaddr *sa;
1005 {
1006 int len;
1007 u_char *p;
1008
1009 if (sa == 0) {
1010 db_printf("[NULL]");
1011 return;
1012 }
1013
1014 p = (u_char *)sa;
1015 len = sa->sa_len;
1016 db_printf("[");
1017 while (len > 0) {
1018 db_printf("%d", *p);
1019 p++;
1020 len--;
1021 if (len)
1022 db_printf(",");
1023 }
1024 db_printf("]\n");
1025 }
1026
1027 void
1028 db_print_ifa(ifa)
1029 struct ifaddr *ifa;
1030 {
1031 if (ifa == 0)
1032 return;
1033 db_printf(" ifa_addr=");
1034 db_print_sa(ifa->ifa_addr);
1035 db_printf(" ifa_dsta=");
1036 db_print_sa(ifa->ifa_dstaddr);
1037 db_printf(" ifa_mask=");
1038 db_print_sa(ifa->ifa_netmask);
1039 db_printf(" flags=0x%x, refcnt=%d, metric=%d\n",
1040 ifa->ifa_flags, ifa->ifa_refcnt, ifa->ifa_metric);
1041 }
1042
1043 void
1044 db_print_llinfo(li)
1045 caddr_t li;
1046 {
1047 struct llinfo_arp *la;
1048
1049 if (li == 0)
1050 return;
1051 la = (struct llinfo_arp *)li;
1052 db_printf(" la_rt=%p la_hold=%p, la_asked=0x%lx\n",
1053 la->la_rt, la->la_hold, la->la_asked);
1054 }
1055
1056
1057
1058
1059
1060 int
1061 db_show_radix_node(rn, w)
1062 struct radix_node *rn;
1063 void *w;
1064 {
1065 struct rtentry *rt = (struct rtentry *)rn;
1066
1067 db_printf("rtentry=%p", rt);
1068
1069 db_printf(" flags=0x%x refcnt=%d use=%ld expire=%ld\n",
1070 rt->rt_flags, rt->rt_refcnt, rt->rt_use, rt->rt_expire);
1071
1072 db_printf(" key="); db_print_sa(rt_key(rt));
1073 db_printf(" mask="); db_print_sa(rt_mask(rt));
1074 db_printf(" gw="); db_print_sa(rt->rt_gateway);
1075
1076 db_printf(" ifp=%p ", rt->rt_ifp);
1077 if (rt->rt_ifp)
1078 db_printf("(%s)", rt->rt_ifp->if_xname);
1079 else
1080 db_printf("(NULL)");
1081
1082 db_printf(" ifa=%p\n", rt->rt_ifa);
1083 db_print_ifa(rt->rt_ifa);
1084
1085 db_printf(" genmask="); db_print_sa(rt->rt_genmask);
1086
1087 db_printf(" gwroute=%p llinfo=%p\n", rt->rt_gwroute, rt->rt_llinfo);
1088 db_print_llinfo(rt->rt_llinfo);
1089 return (0);
1090 }
1091
1092
1093
1094
1095
1096 int
1097 db_show_arptab()
1098 {
1099 struct radix_node_head *rnh;
1100 rnh = rt_gettable(AF_INET, 0);
1101 db_printf("Route tree for AF_INET\n");
1102 if (rnh == NULL) {
1103 db_printf(" (not initialized)\n");
1104 return (0);
1105 }
1106 rn_walktree(rnh, db_show_radix_node, NULL);
1107 return (0);
1108 }
1109 #endif
1110 #endif