2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 1982, 1986, 1988, 1993
24 * The Regents of the University of California. All rights reserved.
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions
29 * 1. Redistributions of source code must retain the above copyright
30 * notice, this list of conditions and the following disclaimer.
31 * 2. Redistributions in binary form must reproduce the above copyright
32 * notice, this list of conditions and the following disclaimer in the
33 * documentation and/or other materials provided with the distribution.
34 * 3. All advertising materials mentioning features or use of this software
35 * must display the following acknowledgement:
36 * This product includes software developed by the University of
37 * California, Berkeley and its contributors.
38 * 4. Neither the name of the University nor the names of its contributors
39 * may be used to endorse or promote products derived from this software
40 * without specific prior written permission.
42 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
43 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
46 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
48 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
50 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
51 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * @(#)if_ether.c 8.1 (Berkeley) 6/10/93
58 * Ethernet address resolution protocol.
60 * add "inuse/lock" bit (or ref. count) along with valid bit
68 #include <sys/param.h>
69 #include <sys/kernel.h>
71 #include <sys/sysctl.h>
73 #include <sys/systm.h>
75 #include <sys/malloc.h>
76 #include <sys/socket.h>
77 #include <sys/syslog.h>
80 #include <net/if_dl.h>
81 #include <net/route.h>
82 #include <net/netisr.h>
84 #include <netinet/in.h>
85 #include <netinet/in_var.h>
86 #include <netinet/if_ether.h>
88 #define SIN(s) ((struct sockaddr_in *)s)
89 #define SDL(s) ((struct sockaddr_dl *)s)
91 SYSCTL_DECL(_net_link_ether
);
92 SYSCTL_NODE(_net_link_ether
, PF_INET
, inet
, CTLFLAG_RW
, 0, "");
95 static int arpt_prune
= (5*60*1); /* walk list every 5 minutes */
96 static int arpt_keep
= (20*60); /* once resolved, good for 20 more minutes */
97 static int arpt_down
= 20; /* once declared down, don't send for 20 sec */
99 /* Apple Hardware SUM16 checksuming */
100 int apple_hwcksum_tx
= 1;
101 int apple_hwcksum_rx
= 1;
103 SYSCTL_INT(_net_link_ether_inet
, OID_AUTO
, prune_intvl
, CTLFLAG_RW
,
105 SYSCTL_INT(_net_link_ether_inet
, OID_AUTO
, max_age
, CTLFLAG_RW
,
107 SYSCTL_INT(_net_link_ether_inet
, OID_AUTO
, host_down_time
, CTLFLAG_RW
,
109 SYSCTL_INT(_net_link_ether_inet
, OID_AUTO
, apple_hwcksum_tx
, CTLFLAG_RW
,
110 &apple_hwcksum_tx
, 0, "");
111 SYSCTL_INT(_net_link_ether_inet
, OID_AUTO
, apple_hwcksum_rx
, CTLFLAG_RW
,
112 &apple_hwcksum_rx
, 0, "");
114 #define rt_expire rt_rmx.rmx_expire
117 LIST_ENTRY(llinfo_arp
) la_le
;
118 struct rtentry
*la_rt
;
119 struct mbuf
*la_hold
; /* last packet until resolved/timeout */
120 long la_asked
; /* last time we QUERIED for this addr */
121 #define la_timer la_rt->rt_rmx.rmx_expire /* deletion time in seconds */
124 static LIST_HEAD(, llinfo_arp
) llinfo_arp
;
126 struct ifqueue arpintrq
= {0, 0, 0, 50};
127 static int arp_inuse
, arp_allocated
;
129 static int arp_maxtries
= 5;
130 static int useloopback
= 1; /* use loopback interface for local traffic */
131 static int arp_proxyall
= 0;
132 static int arp_init_called
= 0;
134 SYSCTL_INT(_net_link_ether_inet
, OID_AUTO
, maxtries
, CTLFLAG_RW
,
135 &arp_maxtries
, 0, "");
136 SYSCTL_INT(_net_link_ether_inet
, OID_AUTO
, useloopback
, CTLFLAG_RW
,
137 &useloopback
, 0, "");
138 SYSCTL_INT(_net_link_ether_inet
, OID_AUTO
, proxyall
, CTLFLAG_RW
,
139 &arp_proxyall
, 0, "");
141 void arp_rtrequest
__P((int, struct rtentry
*, struct sockaddr
*));
142 static void arprequest
__P((struct arpcom
*,
143 struct in_addr
*, struct in_addr
*, u_char
*));
144 void arpintr
__P((void));
145 static void arptfree
__P((struct llinfo_arp
*));
146 static void arptimer
__P((void *));
147 static u_char etherbroadcastaddr
[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
148 static struct llinfo_arp
149 *arplookup
__P((u_long
, int, int));
151 static void in_arpinput
__P((struct mbuf
*));
155 * Timeout routine. Age arp_tab entries periodically.
159 arptimer(ignored_arg
)
163 register struct llinfo_arp
*la
;
164 struct llinfo_arp
*ola
;
165 boolean_t funnel_state
;
168 funnel_state
= thread_funnel_set(network_flock
, TRUE
);
170 la
= llinfo_arp
.lh_first
;
172 timeout(arptimer
, (caddr_t
)0, arpt_prune
* hz
);
173 while ((ola
= la
) != 0) {
174 register struct rtentry
*rt
= la
->la_rt
;
175 la
= la
->la_le
.le_next
;
176 if (rt
->rt_expire
&& rt
->rt_expire
<= time_second
)
177 arptfree(ola
); /* timer has expired, clear */
180 (void) thread_funnel_set(network_flock
, FALSE
);
185 * Parallel to llc_rtrequest.
188 arp_rtrequest(req
, rt
, sa
)
190 register struct rtentry
*rt
;
193 register struct sockaddr
*gate
= rt
->rt_gateway
;
194 register struct llinfo_arp
*la
= (struct llinfo_arp
*)rt
->rt_llinfo
;
195 static struct sockaddr_dl null_sdl
= {sizeof(null_sdl
), AF_LINK
};
196 static int arpinit_done
;
200 LIST_INIT(&llinfo_arp
);
201 timeout(arptimer
, (caddr_t
)0, hz
);
203 if (rt
->rt_flags
& RTF_GATEWAY
)
209 * XXX: If this is a manually added route to interface
210 * such as older version of routed or gated might provide,
211 * restore cloning bit.
213 if ((rt
->rt_flags
& RTF_HOST
) == 0 &&
214 SIN(rt_mask(rt
))->sin_addr
.s_addr
!= 0xffffffff)
215 rt
->rt_flags
|= RTF_CLONING
;
216 if (rt
->rt_flags
& RTF_CLONING
) {
218 * Case 1: This route should come from a route to iface.
220 rt_setgate(rt
, rt_key(rt
),
221 (struct sockaddr
*)&null_sdl
);
222 gate
= rt
->rt_gateway
;
223 SDL(gate
)->sdl_type
= rt
->rt_ifp
->if_type
;
224 SDL(gate
)->sdl_index
= rt
->rt_ifp
->if_index
;
225 rt
->rt_expire
= time_second
;
228 /* Announce a new entry if requested. */
229 if (rt
->rt_flags
& RTF_ANNOUNCE
)
230 arprequest((struct arpcom
*)rt
->rt_ifp
,
231 &SIN(rt_key(rt
))->sin_addr
,
232 &SIN(rt_key(rt
))->sin_addr
,
233 (u_char
*)LLADDR(SDL(gate
)));
236 if (gate
->sa_family
!= AF_LINK
||
237 gate
->sa_len
< sizeof(null_sdl
)) {
238 log(LOG_DEBUG
, "arp_rtrequest: bad gateway value\n");
241 SDL(gate
)->sdl_type
= rt
->rt_ifp
->if_type
;
242 SDL(gate
)->sdl_index
= rt
->rt_ifp
->if_index
;
244 break; /* This happens on a route change */
246 * Case 2: This route may come from cloning, or a manual route
247 * add with a LL address.
249 R_Malloc(la
, struct llinfo_arp
*, sizeof(*la
));
250 rt
->rt_llinfo
= (caddr_t
)la
;
252 log(LOG_DEBUG
, "arp_rtrequest: malloc failed\n");
255 arp_inuse
++, arp_allocated
++;
256 Bzero(la
, sizeof(*la
));
258 rt
->rt_flags
|= RTF_LLINFO
;
259 LIST_INSERT_HEAD(&llinfo_arp
, la
, la_le
);
263 * This keeps the multicast addresses from showing up
264 * in `arp -a' listings as unresolved. It's not actually
265 * functional. Then the same for broadcast.
267 if (IN_MULTICAST(ntohl(SIN(rt_key(rt
))->sin_addr
.s_addr
))) {
268 ETHER_MAP_IP_MULTICAST(&SIN(rt_key(rt
))->sin_addr
,
270 SDL(gate
)->sdl_alen
= 6;
273 if (in_broadcast(SIN(rt_key(rt
))->sin_addr
, rt
->rt_ifp
)) {
274 memcpy(LLADDR(SDL(gate
)), etherbroadcastaddr
, 6);
275 SDL(gate
)->sdl_alen
= 6;
280 if (SIN(rt_key(rt
))->sin_addr
.s_addr
==
281 (IA_SIN(rt
->rt_ifa
))->sin_addr
.s_addr
) {
283 * This test used to be
284 * if (loif.if_flags & IFF_UP)
285 * It allowed local traffic to be forced
286 * through the hardware by configuring the loopback down.
287 * However, it causes problems during network configuration
288 * for boards that can't receive packets they send.
289 * It is now necessary to clear "useloopback" and remove
290 * the route to force traffic out to the hardware.
293 Bcopy(((struct arpcom
*)rt
->rt_ifp
)->ac_enaddr
,
294 LLADDR(SDL(gate
)), SDL(gate
)->sdl_alen
= 6);
305 LIST_REMOVE(la
, la_le
);
307 rt
->rt_flags
&= ~RTF_LLINFO
;
309 m_freem(la
->la_hold
);
318 * Broadcast an ARP packet, asking who has addr on interface ac.
322 register struct arpcom
*ac
;
323 register struct in_addr
*addr
;
324 { struct ifnet
*ifp
= (struct ifnet
*)ac
;
325 struct ifaddr
*ifa
= TAILQ_FIRST(&ifp
->if_addrhead
);
328 { if (ifa
->ifa_addr
->sa_family
== AF_INET
)
329 { arprequest(ac
, &SIN(ifa
->ifa_addr
)->sin_addr
, addr
, ac
->ac_enaddr
);
332 ifa
= TAILQ_NEXT(ifa
, ifa_link
);
340 * Broadcast an ARP request. Caller specifies:
341 * - arp header source ip address
342 * - arp header target ip address
343 * - arp header source ethernet address
346 arprequest(ac
, sip
, tip
, enaddr
)
347 register struct arpcom
*ac
;
348 register struct in_addr
*sip
, *tip
;
349 register u_char
*enaddr
;
351 register struct mbuf
*m
;
352 register struct ether_header
*eh
;
353 register struct ether_arp
*ea
;
356 if ((m
= m_gethdr(M_DONTWAIT
, MT_DATA
)) == NULL
)
358 m
->m_len
= sizeof(*ea
);
359 m
->m_pkthdr
.len
= sizeof(*ea
);
360 m
->m_pkthdr
.rcvif
= (struct ifnet
*)0;
361 MH_ALIGN(m
, sizeof(*ea
));
362 ea
= mtod(m
, struct ether_arp
*);
363 eh
= (struct ether_header
*)sa
.sa_data
;
364 bzero((caddr_t
)ea
, sizeof (*ea
));
365 (void)memcpy(eh
->ether_dhost
, etherbroadcastaddr
, sizeof(eh
->ether_dhost
));
366 eh
->ether_type
= htons(ETHERTYPE_ARP
); /* if_output will not swap */
367 ea
->arp_hrd
= htons(ARPHRD_ETHER
);
368 ea
->arp_pro
= htons(ETHERTYPE_IP
);
369 ea
->arp_hln
= sizeof(ea
->arp_sha
); /* hardware address length */
370 ea
->arp_pln
= sizeof(ea
->arp_spa
); /* protocol address length */
371 ea
->arp_op
= htons(ARPOP_REQUEST
);
372 (void)memcpy(ea
->arp_sha
, enaddr
, sizeof(ea
->arp_sha
));
373 (void)memcpy(ea
->arp_spa
, sip
, sizeof(ea
->arp_spa
));
374 (void)memcpy(ea
->arp_tpa
, tip
, sizeof(ea
->arp_tpa
));
375 sa
.sa_family
= AF_UNSPEC
;
376 sa
.sa_len
= sizeof(sa
);
377 dlil_output((u_long
) ac
, m
, 0, &sa
, 0);
381 * Resolve an IP address into an ethernet address. If success,
382 * desten is filled in. If there is no entry in arptab,
383 * set one up and broadcast a request for the IP address.
384 * Hold onto this mbuf and resend it once the address
385 * is finally resolved. A return value of 1 indicates
386 * that desten has been filled in and the packet should be sent
387 * normally; a 0 return indicates that the packet has been
388 * taken over here, either now or for later transmission.
391 arpresolve(ac
, rt
, m
, dst
, desten
, rt0
)
392 register struct arpcom
*ac
;
393 register struct rtentry
*rt
;
395 register struct sockaddr
*dst
;
396 register u_char
*desten
;
399 register struct llinfo_arp
*la
= 0;
400 struct sockaddr_dl
*sdl
;
402 if (m
->m_flags
& M_BCAST
) { /* broadcast */
403 (void)memcpy(desten
, etherbroadcastaddr
, sizeof(etherbroadcastaddr
));
406 if (m
->m_flags
& M_MCAST
) { /* multicast */
407 ETHER_MAP_IP_MULTICAST(&SIN(dst
)->sin_addr
, desten
);
411 la
= (struct llinfo_arp
*)rt
->rt_llinfo
;
413 la
= arplookup(SIN(dst
)->sin_addr
.s_addr
, 1, 0);
417 if (la
== 0 || rt
== 0) {
418 log(LOG_DEBUG
, "arpresolve: can't allocate llinfo for %s%s%s\n",
419 inet_ntoa(SIN(dst
)->sin_addr
), la
? "la" : "",
424 sdl
= SDL(rt
->rt_gateway
);
426 * Check the address family and length is valid, the address
427 * is resolved; otherwise, try to resolve.
429 if ((rt
->rt_expire
== 0 || rt
->rt_expire
> time_second
) &&
430 sdl
->sdl_family
== AF_LINK
&& sdl
->sdl_alen
!= 0) {
431 bcopy(LLADDR(sdl
), desten
, sdl
->sdl_alen
);
435 * There is an arptab entry, but no ethernet address
436 * response yet. Replace the held mbuf with this
440 m_freem(la
->la_hold
);
443 rt
->rt_flags
&= ~RTF_REJECT
;
444 if (la
->la_asked
== 0 || rt
->rt_expire
!= time_second
) {
445 rt
->rt_expire
= time_second
;
446 if (la
->la_asked
++ < arp_maxtries
)
448 &SIN(rt
->rt_ifa
->ifa_addr
)->sin_addr
,
449 &SIN(dst
)->sin_addr
, ac
->ac_enaddr
);
451 rt
->rt_flags
|= RTF_REJECT
;
452 rt
->rt_expire
+= arpt_down
;
462 * Common length and type checks are done here,
463 * then the protocol-specific routine is called.
468 register struct mbuf
*m
;
469 register struct arphdr
*ar
;
472 while (arpintrq
.ifq_head
) {
474 IF_DEQUEUE(&arpintrq
, m
);
476 if (m
== 0 || (m
->m_flags
& M_PKTHDR
) == 0)
478 if (m
->m_len
>= sizeof(struct arphdr
) &&
479 (ar
= mtod(m
, struct arphdr
*)) &&
480 ntohs(ar
->ar_hrd
) == ARPHRD_ETHER
&&
482 sizeof(struct arphdr
) + 2 * ar
->ar_hln
+ 2 * ar
->ar_pln
)
484 switch (ntohs(ar
->ar_pro
)) {
496 NETISR_SET(NETISR_ARP
, arpintr
);
501 * ARP for Internet protocols on 10 Mb/s Ethernet.
502 * Algorithm is that given in RFC 826.
503 * In addition, a sanity check is performed on the sender
504 * protocol address, to catch impersonators.
505 * We no longer handle negotiations for use of trailer protocol:
506 * Formerly, ARP replied for protocol type ETHERTYPE_TRAIL sent
507 * along with IP replies if we wanted trailers sent to us,
508 * and also sent them in response to IP replies.
509 * This allowed either end to announce the desire to receive
511 * We no longer reply to requests for ETHERTYPE_TRAIL protocol either,
512 * but formerly didn't normally send requests.
518 register struct ether_arp
*ea
;
519 register struct arpcom
*ac
= (struct arpcom
*)m
->m_pkthdr
.rcvif
;
520 struct ether_header
*eh
;
521 register struct llinfo_arp
*la
= 0;
522 register struct rtentry
*rt
;
523 struct in_ifaddr
*ia
, *maybe_ia
= 0;
524 struct sockaddr_dl
*sdl
;
526 struct in_addr isaddr
, itaddr
, myaddr
;
528 unsigned char buf
[18];
530 ea
= mtod(m
, struct ether_arp
*);
531 op
= ntohs(ea
->arp_op
);
532 (void)memcpy(&isaddr
, ea
->arp_spa
, sizeof (isaddr
));
533 (void)memcpy(&itaddr
, ea
->arp_tpa
, sizeof (itaddr
));
535 /* Don't respond to requests for 0.0.0.0 */
536 if (itaddr
.s_addr
== 0 && op
== ARPOP_REQUEST
) {
541 for (ia
= in_ifaddrhead
.tqh_first
; ia
; ia
= ia
->ia_link
.tqe_next
)
544 * For a bridge, we want to check the address irrespective
545 * of the receive interface. (This will change slightly
546 * when we have clusters of interfaces).
550 if (ia
->ia_ifp
== &ac
->ac_if
) {
553 if ((itaddr
.s_addr
== ia
->ia_addr
.sin_addr
.s_addr
) ||
554 (isaddr
.s_addr
== ia
->ia_addr
.sin_addr
.s_addr
))
561 myaddr
= ia
? ia
->ia_addr
.sin_addr
: maybe_ia
->ia_addr
.sin_addr
;
563 if (!bcmp((caddr_t
)ea
->arp_sha
, (caddr_t
)etherbroadcastaddr
,
564 sizeof (ea
->arp_sha
))) {
566 "arp: ether address is broadcast for IP address %s!\n",
571 if (isaddr
.s_addr
== myaddr
.s_addr
) {
573 "duplicate IP address %s sent from ethernet address %s\n",
574 inet_ntoa(isaddr
), ether_sprintf(buf
, ea
->arp_sha
));
578 la
= arplookup(isaddr
.s_addr
, itaddr
.s_addr
== myaddr
.s_addr
, 0);
579 if (la
&& (rt
= la
->la_rt
) && (sdl
= SDL(rt
->rt_gateway
))) {
580 #ifndef BRIDGE /* the following is not an error when doing bridging */
581 if (rt
->rt_ifp
!= &ac
->ac_if
) {
582 log(LOG_ERR
, "arp: %s is on %s%d but got reply from %6D on %s%d\n",
584 rt
->rt_ifp
->if_name
, rt
->rt_ifp
->if_unit
,
586 ac
->ac_if
.if_name
, ac
->ac_if
.if_unit
);
591 bcmp((caddr_t
)ea
->arp_sha
, LLADDR(sdl
), sdl
->sdl_alen
))
593 log(LOG_INFO
, "arp: %s moved from %6D to %6D on %s%d\n",
594 inet_ntoa(isaddr
), (u_char
*)LLADDR(sdl
), ":",
596 ac
->ac_if
.if_name
, ac
->ac_if
.if_unit
);
599 "arp: %6D attempts to modify permanent entry for %s on %s%d",
600 ea
->arp_sha
, ":", inet_ntoa(isaddr
),
601 ac
->ac_if
.if_name
, ac
->ac_if
.if_unit
);
604 (void)memcpy(LLADDR(sdl
), ea
->arp_sha
, sizeof(ea
->arp_sha
));
605 sdl
->sdl_alen
= sizeof(ea
->arp_sha
);
607 rt
->rt_expire
= time_second
+ arpt_keep
;
608 rt
->rt_flags
&= ~RTF_REJECT
;
611 dlil_output((u_long
) ac
, la
->la_hold
, rt
,
617 if (op
!= ARPOP_REQUEST
) {
621 if (itaddr
.s_addr
== myaddr
.s_addr
) {
622 /* I am the target */
623 (void)memcpy(ea
->arp_tha
, ea
->arp_sha
, sizeof(ea
->arp_sha
));
624 (void)memcpy(ea
->arp_sha
, ac
->ac_enaddr
, sizeof(ea
->arp_sha
));
626 la
= arplookup(itaddr
.s_addr
, 0, SIN_PROXY
);
628 struct sockaddr_in sin
;
635 bzero(&sin
, sizeof sin
);
636 sin
.sin_family
= AF_INET
;
637 sin
.sin_len
= sizeof sin
;
638 sin
.sin_addr
= itaddr
;
640 rt
= rtalloc1((struct sockaddr
*)&sin
, 0, 0UL);
646 * Don't send proxies for nodes on the same interface
647 * as this one came out of, or we'll get into a fight
648 * over who claims what Ether address.
650 if (rt
->rt_ifp
== &ac
->ac_if
) {
655 (void)memcpy(ea
->arp_tha
, ea
->arp_sha
, sizeof(ea
->arp_sha
));
656 (void)memcpy(ea
->arp_sha
, ac
->ac_enaddr
, sizeof(ea
->arp_sha
));
659 printf("arp: proxying for %s\n",
664 (void)memcpy(ea
->arp_tha
, ea
->arp_sha
, sizeof(ea
->arp_sha
));
665 sdl
= SDL(rt
->rt_gateway
);
666 (void)memcpy(ea
->arp_sha
, LLADDR(sdl
), sizeof(ea
->arp_sha
));
670 (void)memcpy(ea
->arp_tpa
, ea
->arp_spa
, sizeof(ea
->arp_spa
));
671 (void)memcpy(ea
->arp_spa
, &itaddr
, sizeof(ea
->arp_spa
));
672 ea
->arp_op
= htons(ARPOP_REPLY
);
673 ea
->arp_pro
= htons(ETHERTYPE_IP
); /* let's be sure! */
674 eh
= (struct ether_header
*)sa
.sa_data
;
675 if (IN_LINKLOCAL(ntohl(*((u_int32_t
*)ea
->arp_spa
))))
676 (void)memcpy(eh
->ether_dhost
, etherbroadcastaddr
, sizeof(eh
->ether_dhost
));
678 (void)memcpy(eh
->ether_dhost
, ea
->arp_tha
, sizeof(eh
->ether_dhost
));
679 eh
->ether_type
= htons(ETHERTYPE_ARP
);
680 sa
.sa_family
= AF_UNSPEC
;
681 sa
.sa_len
= sizeof(sa
);
682 dlil_output((u_long
) ac
, m
, 0, &sa
, 0);
692 register struct llinfo_arp
*la
;
694 register struct rtentry
*rt
= la
->la_rt
;
695 register struct sockaddr_dl
*sdl
;
698 if (rt
->rt_refcnt
> 0 && (sdl
= SDL(rt
->rt_gateway
)) &&
699 sdl
->sdl_family
== AF_LINK
) {
702 rt
->rt_flags
&= ~RTF_REJECT
;
705 rtrequest(RTM_DELETE
, rt_key(rt
), (struct sockaddr
*)0, rt_mask(rt
),
706 0, (struct rtentry
**)0);
709 * Lookup or enter a new address in arptab.
711 static struct llinfo_arp
*
712 arplookup(addr
, create
, proxy
)
716 register struct rtentry
*rt
;
717 static struct sockaddr_inarp sin
= {sizeof(sin
), AF_INET
};
720 sin
.sin_addr
.s_addr
= addr
;
721 sin
.sin_other
= proxy
? SIN_PROXY
: 0;
722 rt
= rtalloc1((struct sockaddr
*)&sin
, create
, 0UL);
727 if (rt
->rt_flags
& RTF_GATEWAY
)
728 why
= "host is not on local network";
729 else if ((rt
->rt_flags
& RTF_LLINFO
) == 0)
730 why
= "could not allocate llinfo";
731 else if (rt
->rt_gateway
->sa_family
!= AF_LINK
)
732 why
= "gateway route is not ours";
735 log(LOG_DEBUG
, "arplookup %s failed: %s\n",
736 inet_ntoa(sin
.sin_addr
), why
);
741 return ((struct llinfo_arp
*)rt
->rt_llinfo
);
749 if (ntohl(IA_SIN(ifa
)->sin_addr
.s_addr
) != INADDR_ANY
)
750 arprequest(ac
, &IA_SIN(ifa
)->sin_addr
,
751 &IA_SIN(ifa
)->sin_addr
, ac
->ac_enaddr
);
752 ifa
->ifa_rtrequest
= arp_rtrequest
;
753 ifa
->ifa_flags
|= RTF_CLONING
;