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