1 //==========================================================================
3 // sys/netinet/if_ether.c
7 //==========================================================================
8 //####BSDCOPYRIGHTBEGIN####
10 // -------------------------------------------
12 // Portions of this software may have been derived from OpenBSD or other sources,
13 // and are covered by the appropriate copyright disclaimers included herein.
15 // -------------------------------------------
17 //####BSDCOPYRIGHTEND####
18 //==========================================================================
19 //#####DESCRIPTIONBEGIN####
22 // Contributors: gthomas
28 //####DESCRIPTIONEND####
30 //==========================================================================
33 /* $OpenBSD: if_ether.c,v 1.19 1999/11/10 18:48:47 chris Exp $ */
34 /* $NetBSD: if_ether.c,v 1.31 1996/05/11 12:59:58 mycroft Exp $ */
37 * Copyright (c) 1982, 1986, 1988, 1993
38 * The Regents of the University of California. All rights reserved.
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
48 * 3. All advertising materials mentioning features or use of this software
49 * must display the following acknowledgement:
50 * This product includes software developed by the University of
51 * California, Berkeley and its contributors.
52 * 4. 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.
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
68 * @(#)if_ether.c 8.1 (Berkeley) 6/10/93
72 * Ethernet address resolution protocol.
74 * add "inuse/lock" bit (or ref. count) along with valid bit
77 #include <sys/param.h>
79 #include <sys/systm.h>
81 #include <sys/malloc.h>
83 #include <sys/socket.h>
85 #include <sys/kernel.h>
86 #include <sys/errno.h>
87 #include <sys/ioctl.h>
89 #include <sys/syslog.h>
96 #include <net/if_dl.h>
97 #include <net/route.h>
99 #include <netinet/in.h>
100 #include <netinet/in_systm.h>
101 #include <netinet/in_var.h>
102 #include <netinet/ip.h>
103 #include <netinet/if_ether.h>
105 #define SIN(s) ((struct sockaddr_in *)s)
106 #define SDL(s) ((struct sockaddr_dl *)s)
107 #define SRP(s) ((struct sockaddr_inarp *)s)
110 * ARP trailer negotiation. Trailer protocol is not IP specific,
111 * but ARP request/response use IP addresses.
113 #define ETHERTYPE_IPTRAILERS ETHERTYPE_TRAIL
116 int arpt_prune = (5*60*1); /* walk list every 5 minutes */
117 int arpt_keep = (20*60); /* once resolved, good for 20 more minutes */
118 int arpt_down = 20; /* once declared down, don't send for 20 secs */
119 #define rt_expire rt_rmx.rmx_expire
121 static void arprequest
122 __P((struct arpcom *, u_int32_t *, u_int32_t *, u_int8_t *));
123 static void arptfree __P((struct llinfo_arp *));
124 static void arptimer __P((void *));
125 static struct llinfo_arp *arplookup __P((u_int32_t, int, int));
126 static void in_arpinput __P((struct mbuf *));
128 extern struct ifnet loif;
129 LIST_HEAD(, llinfo_arp) llinfo_arp;
130 struct ifqueue arpintrq = {0, 0, 0, 50};
131 int arp_inuse, arp_allocated, arp_intimer;
132 int arp_maxtries = 5;
133 int useloopback = 1; /* use loopback interface for local traffic */
134 int arpinit_done = 0;
137 static struct in_addr myip, srv_ip;
138 static int myip_initialized = 0;
139 static int revarp_in_progress = 0;
140 struct ifnet *myip_ifp = NULL;
142 static void arptimer __P((void *));
143 static void arprequest __P((struct arpcom *, u_int32_t *, u_int32_t *,
145 static void in_arpinput __P((struct mbuf *));
146 static void arptfree __P((struct llinfo_arp *));
147 static struct llinfo_arp *arplookup __P((u_int32_t, int, int ));
151 static void db_print_sa __P((struct sockaddr *));
152 static void db_print_ifa __P((struct ifaddr *));
153 static void db_print_llinfo __P((caddr_t));
154 static int db_show_radix_node __P((struct radix_node *, void *));
158 * Timeout routine. Age arp_tab entries periodically.
166 register struct llinfo_arp *la, *nla;
169 timeout(arptimer, NULL, arpt_prune * hz);
170 for (la = llinfo_arp.lh_first; la != 0; la = nla) {
171 register struct rtentry *rt = la->la_rt;
173 nla = la->la_list.le_next;
174 if (rt->rt_expire && rt->rt_expire <= time.tv_sec)
175 arptfree(la); /* timer has expired; clear */
181 * Parallel to llc_rtrequest.
184 arp_rtrequest(req, rt, sa)
186 register struct rtentry *rt;
189 register struct sockaddr *gate = rt->rt_gateway;
190 register struct llinfo_arp *la = (struct llinfo_arp *)rt->rt_llinfo;
191 static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
196 * We generate expiration times from time.tv_sec
197 * so avoid accidently creating permanent routes.
199 if (time.tv_sec == 0) {
202 timeout(arptimer, (caddr_t)0, hz);
204 if (rt->rt_flags & RTF_GATEWAY)
210 * XXX: If this is a manually added route to interface
211 * such as older version of routed or gated might provide,
212 * restore cloning bit.
214 if ((rt->rt_flags & RTF_HOST) == 0 &&
215 SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff)
216 rt->rt_flags |= RTF_CLONING;
217 if (rt->rt_flags & RTF_CLONING) {
219 * Case 1: This route should come from a route to iface.
221 rt_setgate(rt, rt_key(rt),
222 (struct sockaddr *)&null_sdl);
223 gate = rt->rt_gateway;
224 SDL(gate)->sdl_type = rt->rt_ifp->if_type;
225 SDL(gate)->sdl_index = rt->rt_ifp->if_index;
227 * Give this route an expiration time, even though
228 * it's a "permanent" route, so that routes cloned
229 * from it do not need their expiration time set.
231 rt->rt_expire = time.tv_sec;
234 /* Announce a new entry if requested. */
235 if (rt->rt_flags & RTF_ANNOUNCE)
236 arprequest((struct arpcom *)rt->rt_ifp,
237 &SIN(rt_key(rt))->sin_addr.s_addr,
238 &SIN(rt_key(rt))->sin_addr.s_addr,
239 (u_char *)LLADDR(SDL(gate)));
242 if (gate->sa_family != AF_LINK ||
243 gate->sa_len < sizeof(null_sdl)) {
246 log(LOG_DEBUG, "arp_rtrequest: bad gateway value\n");
250 SDL(gate)->sdl_type = rt->rt_ifp->if_type;
251 SDL(gate)->sdl_index = rt->rt_ifp->if_index;
253 break; /* This happens on a route change */
255 * Case 2: This route may come from cloning, or a manual route
256 * add with a LL address.
258 R_Malloc(la, struct llinfo_arp *, sizeof(*la));
259 rt->rt_llinfo = (caddr_t)la;
263 log(LOG_DEBUG, "arp_rtrequest: malloc failed\n");
267 arp_inuse++, arp_allocated++;
268 Bzero(la, sizeof(*la));
270 rt->rt_flags |= RTF_LLINFO;
271 LIST_INSERT_HEAD(&llinfo_arp, la, la_list);
272 if (SIN(rt_key(rt))->sin_addr.s_addr ==
273 (IA_SIN(rt->rt_ifa))->sin_addr.s_addr) {
275 * This test used to be
276 * if (loif.if_flags & IFF_UP)
277 * It allowed local traffic to be forced through
278 * the hardware by configuring the loopback down.
279 * However, it causes problems during network
280 * configuration for boards that can't receive
281 * packets they send. It is now necessary to clear
282 * "useloopback" and remove the route to force
283 * traffic out to the hardware.
286 Bcopy(((struct arpcom *)rt->rt_ifp)->ac_enaddr,
288 SDL(gate)->sdl_alen = ETHER_ADDR_LEN);
298 LIST_REMOVE(la, la_list);
300 rt->rt_flags &= ~RTF_LLINFO;
302 m_freem(la->la_hold);
308 * Broadcast an ARP request. Caller specifies:
309 * - arp header source ip address
310 * - arp header target ip address
311 * - arp header source ethernet address
314 arprequest(ac, sip, tip, enaddr)
315 register struct arpcom *ac;
316 register u_int32_t *sip, *tip;
317 register u_int8_t *enaddr;
319 register struct mbuf *m;
320 register struct ether_header *eh;
321 register struct ether_arp *ea;
324 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
326 m->m_len = sizeof(*ea);
327 m->m_pkthdr.len = sizeof(*ea);
328 MH_ALIGN(m, sizeof(*ea));
329 ea = mtod(m, struct ether_arp *);
330 eh = (struct ether_header *)sa.sa_data;
331 bzero((caddr_t)ea, sizeof (*ea));
332 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
333 sizeof(eh->ether_dhost));
334 eh->ether_type = htons(ETHERTYPE_ARP); /* if_output will not swap */
335 ea->arp_hrd = htons(ARPHRD_ETHER);
336 ea->arp_pro = htons(ETHERTYPE_IP);
337 ea->arp_hln = sizeof(ea->arp_sha); /* hardware address length */
338 ea->arp_pln = sizeof(ea->arp_spa); /* protocol address length */
339 ea->arp_op = htons(ARPOP_REQUEST);
340 bcopy((caddr_t)enaddr, (caddr_t)eh->ether_shost,
341 sizeof(eh->ether_shost));
342 bcopy((caddr_t)enaddr, (caddr_t)ea->arp_sha, sizeof(ea->arp_sha));
343 bcopy((caddr_t)sip, (caddr_t)ea->arp_spa, sizeof(ea->arp_spa));
344 bcopy((caddr_t)tip, (caddr_t)ea->arp_tpa, sizeof(ea->arp_tpa));
345 sa.sa_family = AF_UNSPEC;
346 sa.sa_len = sizeof(sa);
347 (*ac->ac_if.if_output)(&ac->ac_if, m, &sa, (struct rtentry *)0);
351 * Resolve an IP address into an ethernet address. If success,
352 * desten is filled in. If there is no entry in arptab,
353 * set one up and broadcast a request for the IP address.
354 * Hold onto this mbuf and resend it once the address
355 * is finally resolved. A return value of 1 indicates
356 * that desten has been filled in and the packet should be sent
357 * normally; a 0 return indicates that the packet has been
358 * taken over here, either now or for later transmission.
361 arpresolve(ac, rt, m, dst, desten)
362 register struct arpcom *ac;
363 register struct rtentry *rt;
365 register struct sockaddr *dst;
366 register u_char *desten;
368 register struct llinfo_arp *la;
369 struct sockaddr_dl *sdl;
371 if (m->m_flags & M_BCAST) { /* broadcast */
372 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)desten,
373 sizeof(etherbroadcastaddr));
376 if (m->m_flags & M_MCAST) { /* multicast */
377 ETHER_MAP_IP_MULTICAST(&SIN(dst)->sin_addr, desten);
381 la = (struct llinfo_arp *)rt->rt_llinfo;
383 if ((la = arplookup(SIN(dst)->sin_addr.s_addr, 1, 0)) != NULL)
386 if (la == 0 || rt == 0) {
389 log(LOG_DEBUG, "arpresolve: can't allocate llinfo\n");
394 sdl = SDL(rt->rt_gateway);
396 * Check the address family and length is valid, the address
397 * is resolved; otherwise, try to resolve.
399 if ((rt->rt_expire == 0 || rt->rt_expire > time.tv_sec) &&
400 sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) {
401 bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
404 if (((struct ifnet *)ac)->if_flags & IFF_NOARP)
408 * There is an arptab entry, but no ethernet address
409 * response yet. Replace the held mbuf with this
413 m_freem(la->la_hold);
416 * Re-send the ARP request when appropriate.
419 if (rt->rt_expire == 0) {
420 /* This should never happen. (Should it? -gwr) */
421 printf("arpresolve: unresolved and rt_expire == 0\n");
422 /* Set expiration time to now (expired). */
423 rt->rt_expire = time.tv_sec;
427 rt->rt_flags &= ~RTF_REJECT;
428 if (la->la_asked == 0 || rt->rt_expire != time.tv_sec) {
429 rt->rt_expire = time.tv_sec;
430 if (la->la_asked++ < arp_maxtries)
432 &(SIN(rt->rt_ifa->ifa_addr)->sin_addr.s_addr),
433 &(SIN(dst)->sin_addr.s_addr),
436 rt->rt_flags |= RTF_REJECT;
437 rt->rt_expire += arpt_down;
446 * Common length and type checks are done here,
447 * then the protocol-specific routine is called.
452 register struct mbuf *m;
453 register struct arphdr *ar;
456 while (arpintrq.ifq_head) {
458 IF_DEQUEUE(&arpintrq, m);
460 if (m == 0 || (m->m_flags & M_PKTHDR) == 0)
462 if (m->m_len >= sizeof(struct arphdr) &&
463 (ar = mtod(m, struct arphdr *)) &&
464 ntohs(ar->ar_hrd) == ARPHRD_ETHER &&
466 sizeof(struct arphdr) + 2 * (ar->ar_hln + ar->ar_pln))
467 switch (ntohs(ar->ar_pro)) {
470 case ETHERTYPE_IPTRAILERS:
479 * ARP for Internet protocols on Ethernet.
480 * Algorithm is that given in RFC 826.
481 * In addition, a sanity check is performed on the sender
482 * protocol address, to catch impersonators.
483 * We no longer handle negotiations for use of trailer protocol:
484 * Formerly, ARP replied for protocol type ETHERTYPE_TRAIL sent
485 * along with IP replies if we wanted trailers sent to us,
486 * and also sent them in response to IP replies.
487 * This allowed either end to announce the desire to receive
489 * We no longer reply to requests for ETHERTYPE_TRAIL protocol either,
490 * but formerly didn't normally send requests.
496 register struct ether_arp *ea;
497 register struct arpcom *ac = (struct arpcom *)m->m_pkthdr.rcvif;
498 struct ether_header *eh;
499 register struct llinfo_arp *la = 0;
500 register struct rtentry *rt;
501 struct in_ifaddr *ia, *maybe_ia = 0;
502 struct sockaddr_dl *sdl;
504 struct in_addr isaddr, itaddr, myaddr;
507 ea = mtod(m, struct ether_arp *);
508 op = ntohs(ea->arp_op);
509 bcopy((caddr_t)ea->arp_spa, (caddr_t)&isaddr, sizeof (isaddr));
510 bcopy((caddr_t)ea->arp_tpa, (caddr_t)&itaddr, sizeof (itaddr));
511 for (ia = in_ifaddr.tqh_first; ia != 0; ia = ia->ia_list.tqe_next)
512 if (ia->ia_ifp == &ac->ac_if ||
513 (ia->ia_ifp->if_bridge &&
514 ia->ia_ifp->if_bridge == ac->ac_if.if_bridge)) {
516 if (itaddr.s_addr == ia->ia_addr.sin_addr.s_addr ||
517 isaddr.s_addr == ia->ia_addr.sin_addr.s_addr)
522 myaddr = ia ? ia->ia_addr.sin_addr : maybe_ia->ia_addr.sin_addr;
523 if (!bcmp((caddr_t)ea->arp_sha, (caddr_t)ac->ac_enaddr,
524 sizeof (ea->arp_sha)))
525 goto out; /* it's from me, ignore it. */
526 if (!bcmp((caddr_t)ea->arp_sha, (caddr_t)etherbroadcastaddr,
527 sizeof (ea->arp_sha))) {
531 "arp: ether address is broadcast for IP address %s!\n",
536 if (isaddr.s_addr == myaddr.s_addr) {
540 "duplicate IP address %s sent from ethernet address %s\n",
541 inet_ntoa(isaddr), ether_sprintf(ea->arp_sha));
546 la = arplookup(isaddr.s_addr, itaddr.s_addr == myaddr.s_addr, 0);
547 if (la && (rt = la->la_rt) && (sdl = SDL(rt->rt_gateway))) {
549 bcmp((caddr_t)ea->arp_sha, LLADDR(sdl), sdl->sdl_alen)) {
550 if (rt->rt_flags & RTF_PERMANENT_ARP) {
554 "arp: attempt to overwrite permanent "
555 "entry for %s by %s on %s\n",
557 ether_sprintf(ea->arp_sha),
558 (&ac->ac_if)->if_xname);
561 } else if (rt->rt_ifp != &ac->ac_if) {
565 "arp: attempt to overwrite entry for %s "
566 "on %s by %s on %s\n",
567 inet_ntoa(isaddr), rt->rt_ifp->if_xname,
568 ether_sprintf(ea->arp_sha),
569 (&ac->ac_if)->if_xname);
576 "arp info overwritten for %s by %s on %s\n",
578 ether_sprintf(ea->arp_sha),
579 (&ac->ac_if)->if_xname);
581 rt->rt_expire = 1; /* no longer static */
584 bcopy((caddr_t)ea->arp_sha, LLADDR(sdl),
585 sdl->sdl_alen = sizeof(ea->arp_sha));
587 rt->rt_expire = time.tv_sec + arpt_keep;
588 rt->rt_flags &= ~RTF_REJECT;
591 (*ac->ac_if.if_output)(&ac->ac_if, la->la_hold,
597 if (op != ARPOP_REQUEST) {
602 if (itaddr.s_addr == myaddr.s_addr) {
603 /* I am the target */
604 bcopy((caddr_t)ea->arp_sha, (caddr_t)ea->arp_tha,
605 sizeof(ea->arp_sha));
606 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_sha,
607 sizeof(ea->arp_sha));
609 la = arplookup(itaddr.s_addr, 0, SIN_PROXY);
613 bcopy((caddr_t)ea->arp_sha, (caddr_t)ea->arp_tha,
614 sizeof(ea->arp_sha));
615 sdl = SDL(rt->rt_gateway);
616 bcopy(LLADDR(sdl), (caddr_t)ea->arp_sha, sizeof(ea->arp_sha));
619 bcopy((caddr_t)ea->arp_spa, (caddr_t)ea->arp_tpa, sizeof(ea->arp_spa));
620 bcopy((caddr_t)&itaddr, (caddr_t)ea->arp_spa, sizeof(ea->arp_spa));
621 ea->arp_op = htons(ARPOP_REPLY);
622 ea->arp_pro = htons(ETHERTYPE_IP); /* let's be sure! */
623 eh = (struct ether_header *)sa.sa_data;
624 bcopy((caddr_t)ea->arp_tha, (caddr_t)eh->ether_dhost,
625 sizeof(eh->ether_dhost));
626 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost,
627 sizeof(eh->ether_shost));
628 eh->ether_type = htons(ETHERTYPE_ARP);
629 sa.sa_family = AF_UNSPEC;
630 sa.sa_len = sizeof(sa);
631 (*ac->ac_if.if_output)(&ac->ac_if, m, &sa, (struct rtentry *)0);
640 register struct llinfo_arp *la;
642 register struct rtentry *rt = la->la_rt;
643 register struct sockaddr_dl *sdl;
647 if (rt->rt_refcnt > 0 && (sdl = SDL(rt->rt_gateway)) &&
648 sdl->sdl_family == AF_LINK) {
651 rt->rt_flags &= ~RTF_REJECT;
654 rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0, rt_mask(rt),
655 0, (struct rtentry **)0);
659 * Lookup or enter a new address in arptab.
661 static struct llinfo_arp *
662 arplookup(addr, create, proxy)
666 register struct rtentry *rt;
667 static struct sockaddr_inarp sin;
669 sin.sin_len = sizeof(sin);
670 sin.sin_family = AF_INET;
671 sin.sin_addr.s_addr = addr;
672 sin.sin_other = proxy ? SIN_PROXY : 0;
673 rt = rtalloc1(sintosa(&sin), create);
677 if ((rt->rt_flags & RTF_GATEWAY) || (rt->rt_flags & RTF_LLINFO) == 0 ||
678 rt->rt_gateway->sa_family != AF_LINK) {
683 "arplookup: unable to enter address for %s\n",
684 inet_ntoa(sin.sin_addr));
688 return ((struct llinfo_arp *)rt->rt_llinfo);
706 /* Warn the user if another station has this IP address. */
708 &(IA_SIN(ifa)->sin_addr.s_addr),
709 &(IA_SIN(ifa)->sin_addr.s_addr),
711 ifa->ifa_rtrequest = arp_rtrequest;
712 ifa->ifa_flags |= RTF_CLONING;
716 * Called from Ethernet interrupt handlers
717 * when ether packet type ETHERTYPE_REVARP
718 * is received. Common length and type checks are done here,
719 * then the protocol-specific routine is called.
727 if (m->m_len < sizeof(struct arphdr))
729 ar = mtod(m, struct arphdr *);
730 if (ntohs(ar->ar_hrd) != ARPHRD_ETHER)
732 if (m->m_len < sizeof(struct arphdr) + 2 * (ar->ar_hln + ar->ar_pln))
734 switch (ntohs(ar->ar_pro)) {
737 case ETHERTYPE_IPTRAILERS:
749 * RARP for Internet protocols on Ethernet.
750 * Algorithm is that given in RFC 903.
751 * We are only using for bootstrap purposes to get an ip address for one of
752 * our interfaces. Thus we support no user-interface.
754 * Since the contents of the RARP reply are specific to the interface that
755 * sent the request, this code must ensure that they are properly associated.
757 * Note: also supports ARP via RARP packets, per the RFC.
764 struct ether_arp *ar;
767 ar = mtod(m, struct ether_arp *);
768 op = ntohs(ar->arp_op);
771 case ARPOP_REPLY: /* per RFC */
776 case ARPOP_REVREQUEST: /* handled by rarpd(8) */
780 if (!revarp_in_progress)
782 ifp = m->m_pkthdr.rcvif;
783 if (ifp != myip_ifp) /* !same interface */
785 if (myip_initialized)
787 if (bcmp(ar->arp_tha, ((struct arpcom *)ifp)->ac_enaddr,
788 sizeof(ar->arp_tha)))
790 bcopy((caddr_t)ar->arp_spa, (caddr_t)&srv_ip, sizeof(srv_ip));
791 bcopy((caddr_t)ar->arp_tpa, (caddr_t)&myip, sizeof(myip));
792 myip_initialized = 1;
793 wake: /* Do wakeup every time in case it was missed. */
794 wakeup((caddr_t)&myip);
801 * Send a RARP request for the ip address of the specified interface.
802 * The request should be RFC 903-compliant.
810 struct ether_header *eh;
811 struct ether_arp *ea;
812 struct arpcom *ac = (struct arpcom *)ifp;
814 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
816 m->m_len = sizeof(*ea);
817 m->m_pkthdr.len = sizeof(*ea);
818 MH_ALIGN(m, sizeof(*ea));
819 ea = mtod(m, struct ether_arp *);
820 eh = (struct ether_header *)sa.sa_data;
821 bzero((caddr_t)ea, sizeof(*ea));
822 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
823 sizeof(eh->ether_dhost));
824 eh->ether_type = htons(ETHERTYPE_REVARP);
825 ea->arp_hrd = htons(ARPHRD_ETHER);
826 ea->arp_pro = htons(ETHERTYPE_IP);
827 ea->arp_hln = sizeof(ea->arp_sha); /* hardware address length */
828 ea->arp_pln = sizeof(ea->arp_spa); /* protocol address length */
829 ea->arp_op = htons(ARPOP_REVREQUEST);
830 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost,
831 sizeof(ea->arp_tha));
832 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_sha,
833 sizeof(ea->arp_sha));
834 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_tha,
835 sizeof(ea->arp_tha));
836 sa.sa_family = AF_UNSPEC;
837 sa.sa_len = sizeof(sa);
838 ifp->if_output(ifp, m, &sa, (struct rtentry *)0);
842 * RARP for the ip address of the specified interface, but also
843 * save the ip address of the server that sent the answer.
844 * Timeout if no response is received.
847 revarpwhoarewe(ifp, serv_in, clnt_in)
849 struct in_addr *serv_in;
850 struct in_addr *clnt_in;
852 int result, count = 20;
854 if (myip_initialized)
858 revarp_in_progress = 1;
861 result = tsleep((caddr_t)&myip, PSOCK, "revarp", hz/2);
862 if (result != EWOULDBLOCK)
865 revarp_in_progress = 0;
866 if (!myip_initialized)
869 bcopy((caddr_t)&srv_ip, serv_in, sizeof(*serv_in));
870 bcopy((caddr_t)&myip, clnt_in, sizeof(*clnt_in));
874 /* For compatibility: only saves interface address. */
876 revarpwhoami(in, ifp)
880 struct in_addr server;
881 return (revarpwhoarewe(ifp, &server, in));
887 #include <machine/db_machdep.h>
888 #include <ddb/db_interface.h>
889 #include <ddb/db_output.h>
922 db_printf(" ifa_addr=");
923 db_print_sa(ifa->ifa_addr);
924 db_printf(" ifa_dsta=");
925 db_print_sa(ifa->ifa_dstaddr);
926 db_printf(" ifa_mask=");
927 db_print_sa(ifa->ifa_netmask);
928 db_printf(" flags=0x%x, refcnt=%d, metric=%d\n",
929 ifa->ifa_flags, ifa->ifa_refcnt, ifa->ifa_metric);
936 struct llinfo_arp *la;
940 la = (struct llinfo_arp *)li;
941 db_printf(" la_rt=%p la_hold=%p, la_asked=0x%lx\n",
942 la->la_rt, la->la_hold, la->la_asked);
946 * Function to pass to rn_walktree().
947 * Return non-zero error to abort walk.
950 db_show_radix_node(rn, w)
951 struct radix_node *rn;
954 struct rtentry *rt = (struct rtentry *)rn;
956 db_printf("rtentry=%p", rt);
958 db_printf(" flags=0x%x refcnt=%d use=%ld expire=%ld\n",
959 rt->rt_flags, rt->rt_refcnt, rt->rt_use, rt->rt_expire);
961 db_printf(" key="); db_print_sa(rt_key(rt));
962 db_printf(" mask="); db_print_sa(rt_mask(rt));
963 db_printf(" gw="); db_print_sa(rt->rt_gateway);
965 db_printf(" ifp=%p ", rt->rt_ifp);
967 db_printf("(%s)", rt->rt_ifp->if_xname);
971 db_printf(" ifa=%p\n", rt->rt_ifa);
972 db_print_ifa(rt->rt_ifa);
974 db_printf(" genmask="); db_print_sa(rt->rt_genmask);
976 db_printf(" gwroute=%p llinfo=%p\n", rt->rt_gwroute, rt->rt_llinfo);
977 db_print_llinfo(rt->rt_llinfo);
982 * Function to print all the route trees.
983 * Use this from ddb: "call db_show_arptab"
988 struct radix_node_head *rnh;
989 rnh = rt_tables[AF_INET];
990 db_printf("Route tree for AF_INET\n");
992 db_printf(" (not initialized)\n");
995 rn_walktree(rnh, db_show_radix_node, NULL);