2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 * Copyright (c) 1982, 1989, 1993
27 * The Regents of the University of California. All rights reserved.
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions and the following disclaimer.
34 * 2. Redistributions in binary form must reproduce the above copyright
35 * notice, this list of conditions and the following disclaimer in the
36 * documentation and/or other materials provided with the distribution.
37 * 3. All advertising materials mentioning features or use of this software
38 * must display the following acknowledgement:
39 * This product includes software developed by the University of
40 * California, Berkeley and its contributors.
41 * 4. Neither the name of the University nor the names of its contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
45 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61 #include <sys/param.h>
62 #include <sys/systm.h>
63 #include <sys/kernel.h>
64 #include <sys/malloc.h>
66 #include <sys/socket.h>
67 #include <sys/sockio.h>
68 #include <sys/sysctl.h>
71 #include <net/netisr.h>
72 #include <net/route.h>
73 #include <net/if_llc.h>
74 #include <net/if_dl.h>
75 #include <net/if_types.h>
76 #include <netinet/if_ether.h>
77 #include <netinet/in.h> /* For M_LOOP */
81 #include <netinet/in.h>
82 #include <netinet/in_var.h>
84 #include <netinet/in_systm.h>
85 #include <netinet/ip.h>
89 #include <sys/socketvar.h>
90 #include <net/if_vlan_var.h>
94 extern int vlan_demux(struct ifnet
* ifp
, struct mbuf
*,
95 char * frame_header
, struct if_proto
* * proto
);
98 extern struct ifqueue pkintrq
;
101 /* General stuff from if_ethersubr.c - may not need some of it */
103 #include <netat/at_pat.h>
105 extern struct ifqueue atalkintrq
;
110 #include <net/bridge.h>
113 static u_long lo_dlt
= 0;
115 #define IFP2AC(IFP) ((struct arpcom *)IFP)
118 u_int16_t type
; /* Type of protocol stored in data */
119 struct if_proto
*proto
; /* Protocol structure */
120 u_long data
[2]; /* Protocol data */
123 #define ETHER_DESC_BLK_SIZE (10)
124 #define MAX_INTERFACES 50
127 * Statics for demux module
130 struct ether_desc_blk_str
{
133 struct en_desc
*block_ptr
;
137 static struct ether_desc_blk_str ether_desc_blk
[MAX_INTERFACES
];
140 /* from if_ethersubr.c */
141 int ether_resolvemulti
__P((struct ifnet
*, struct sockaddr
**,
145 * Release all descriptor entries owned by this dl_tag (there may be several).
146 * Setting the type to 0 releases the entry. Eventually we should compact-out
147 * the unused entries.
149 __private_extern__
int
150 ether_del_proto(struct if_proto
*proto
, u_long dl_tag
)
152 struct en_desc
* ed
= ether_desc_blk
[proto
->ifp
->family_cookie
].block_ptr
;
156 for (current
= ether_desc_blk
[proto
->ifp
->family_cookie
].n_max_used
;
157 current
> 0; current
--) {
158 if (ed
[current
- 1].proto
== proto
) {
160 ed
[current
- 1].type
= 0;
162 if (current
== ether_desc_blk
[proto
->ifp
->family_cookie
].n_max_used
) {
163 ether_desc_blk
[proto
->ifp
->family_cookie
].n_max_used
--;
174 __private_extern__
int
175 ether_add_proto(struct ddesc_head_str
*desc_head
, struct if_proto
*proto
, u_long dl_tag
)
178 struct dlil_demux_desc
*desc
;
180 struct en_desc
*last
;
189 TAILQ_FOREACH(desc
, desc_head
, next
) {
190 switch (desc
->type
) {
191 /* These types are supported */
192 /* Top three are preferred */
193 case DLIL_DESC_ETYPE2
:
194 if (desc
->variants
.native_type_length
!= 2)
199 if (desc
->variants
.native_type_length
!= 3)
204 if (desc
->variants
.native_type_length
!= 5)
208 case DLIL_DESC_802_2
:
209 case DLIL_DESC_802_2_SNAP
:
213 if (desc
->variants
.bitmask
.proto_id_length
== 0)
215 /* else fall through, bitmask variant not supported */
218 ether_del_proto(proto
, dl_tag
);
222 ed
= ether_desc_blk
[proto
->ifp
->family_cookie
].block_ptr
;
224 /* Find a free entry */
225 for (i
= 0; i
< ether_desc_blk
[proto
->ifp
->family_cookie
].n_count
; i
++) {
226 if (ed
[i
].type
== 0) {
231 if (i
>= ether_desc_blk
[proto
->ifp
->family_cookie
].n_count
) {
232 u_long new_count
= ETHER_DESC_BLK_SIZE
+
233 ether_desc_blk
[proto
->ifp
->family_cookie
].n_count
;
234 tmp
= _MALLOC((new_count
* (sizeof(*ed
))), M_IFADDR
, M_WAITOK
);
237 * Remove any previous descriptors set in the call.
239 ether_del_proto(proto
, dl_tag
);
243 bzero(tmp
, new_count
* sizeof(*ed
));
244 bcopy(ether_desc_blk
[proto
->ifp
->family_cookie
].block_ptr
,
245 tmp
, ether_desc_blk
[proto
->ifp
->family_cookie
].n_count
* sizeof(*ed
));
246 FREE(ether_desc_blk
[proto
->ifp
->family_cookie
].block_ptr
, M_IFADDR
);
247 ether_desc_blk
[proto
->ifp
->family_cookie
].n_count
= new_count
;
248 ether_desc_blk
[proto
->ifp
->family_cookie
].block_ptr
= (struct en_desc
*)tmp
;
249 ed
= ether_desc_blk
[proto
->ifp
->family_cookie
].block_ptr
;
252 /* Bump n_max_used if appropriate */
253 if (i
+ 1 > ether_desc_blk
[proto
->ifp
->family_cookie
].n_max_used
) {
254 ether_desc_blk
[proto
->ifp
->family_cookie
].n_max_used
= i
+ 1;
261 switch (desc
->type
) {
263 /* 2 byte ethernet raw protocol type is at native_type */
264 /* protocol is not in network byte order */
265 ed
[i
].type
= DLIL_DESC_ETYPE2
;
266 ed
[i
].data
[0] = htons(*(u_int16_t
*)desc
->native_type
);
269 case DLIL_DESC_ETYPE2
:
270 /* 2 byte ethernet raw protocol type is at native_type */
271 /* prtocol must be in network byte order */
272 ed
[i
].type
= DLIL_DESC_ETYPE2
;
273 ed
[i
].data
[0] = *(u_int16_t
*)desc
->native_type
;
276 case DLIL_DESC_802_2
:
277 ed
[i
].type
= DLIL_DESC_SAP
;
278 ed
[i
].data
[0] = *(u_int32_t
*)&desc
->variants
.desc_802_2
;
279 ed
[i
].data
[0] &= htonl(0xFFFFFF00);
283 ed
[i
].type
= DLIL_DESC_SAP
;
284 bcopy(desc
->native_type
, &ed
[i
].data
[0], 3);
287 case DLIL_DESC_802_2_SNAP
:
288 ed
[i
].type
= DLIL_DESC_SNAP
;
289 desc
->variants
.desc_802_2_SNAP
.protocol_type
=
290 htons(desc
->variants
.desc_802_2_SNAP
.protocol_type
);
291 bcopy(&desc
->variants
.desc_802_2_SNAP
, &ed
[i
].data
[0], 8);
292 ed
[i
].data
[0] &= htonl(0x000000FF);
293 desc
->variants
.desc_802_2_SNAP
.protocol_type
=
294 ntohs(desc
->variants
.desc_802_2_SNAP
.protocol_type
);
297 case DLIL_DESC_SNAP
: {
298 u_int8_t
* pDest
= ((u_int8_t
*)&ed
[i
].data
[0]) + 3;
299 ed
[i
].type
= DLIL_DESC_SNAP
;
300 bcopy(desc
->native_type
, pDest
, 5);
317 int ether_demux(ifp
, m
, frame_header
, proto
)
321 struct if_proto
**proto
;
324 register struct ether_header
*eh
= (struct ether_header
*)frame_header
;
325 u_short ether_type
= eh
->ether_type
;
326 u_short ether_type_host
;
330 u_long max
= ether_desc_blk
[ifp
->family_cookie
].n_max_used
;
331 struct en_desc
*ed
= ether_desc_blk
[ifp
->family_cookie
].block_ptr
;
332 u_int32_t extProto1
= 0;
333 u_int32_t extProto2
= 0;
335 if (eh
->ether_dhost
[0] & 1) {
336 /* Check for broadcast */
337 if (*(u_int32_t
*)eh
->ether_dhost
== 0xFFFFFFFF &&
338 *(u_int16_t
*)(eh
->ether_dhost
+ sizeof(u_int32_t
)) == 0xFFFF)
339 m
->m_flags
|= M_BCAST
;
341 m
->m_flags
|= M_MCAST
;
344 * When the driver is put into promiscuous mode we may receive unicast
345 * frames that are not intended for our interfaces. They are filtered
346 * here to keep them from traveling further up the stack to code that
347 * is not expecting them or prepared to deal with them. In the near
348 * future, the filtering done here will be moved even further down the
349 * stack into the IONetworkingFamily, preventing even interface
350 * filter NKE's from receiving promiscuous packets. Please use BPF.
352 #define ETHER_CMP(x, y) ( ((u_int16_t *) x)[0] != ((u_int16_t *) y)[0] || \
353 ((u_int16_t *) x)[1] != ((u_int16_t *) y)[1] || \
354 ((u_int16_t *) x)[2] != ((u_int16_t *) y)[2] )
356 if (ETHER_CMP(eh
->ether_dhost
, ((struct arpcom
*) ifp
)->ac_enaddr
)) {
361 ether_type_host
= ntohs(ether_type
);
362 if ((m
->m_pkthdr
.csum_flags
& CSUM_VLAN_TAG_VALID
)
363 || ether_type_host
== ETHERTYPE_VLAN
) {
364 return (vlan_demux(ifp
, m
, frame_header
, proto
));
366 data
= mtod(m
, u_int8_t
*);
369 * Determine the packet's protocol type and stuff the protocol into
370 * longs for quick compares.
372 if (ether_type_host
<= 1500) {
373 extProto1
= *(u_int32_t
*)data
;
376 if ((extProto1
& htonl(0xFFFFFF00)) == htonl(0xAAAA0300)) {
378 type
= DLIL_DESC_SNAP
;
379 extProto2
= *(u_int32_t
*)(data
+ sizeof(u_int32_t
));
380 extProto1
&= htonl(0x000000FF);
382 type
= DLIL_DESC_SAP
;
383 extProto1
&= htonl(0xFFFFFF00);
386 type
= DLIL_DESC_ETYPE2
;
390 * Search through the connected protocols for a match.
394 case DLIL_DESC_ETYPE2
:
395 for (i
= 0; i
< max
; i
++) {
396 if ((ed
[i
].type
== type
) && (ed
[i
].data
[0] == ether_type
)) {
397 *proto
= ed
[i
].proto
;
404 for (i
= 0; i
< max
; i
++) {
405 if ((ed
[i
].type
== type
) && (ed
[i
].data
[0] == extProto1
)) {
406 *proto
= ed
[i
].proto
;
413 for (i
= 0; i
< max
; i
++) {
414 if ((ed
[i
].type
== type
) && (ed
[i
].data
[0] == extProto1
) &&
415 (ed
[i
].data
[1] == extProto2
)) {
416 *proto
= ed
[i
].proto
;
429 * Ethernet output routine.
430 * Encapsulate a packet of type family for the local net.
431 * Use trailer local net encapsulation if enough data in first
432 * packet leaves a multiple of 512 bytes of data in remainder.
433 * Assumes that ifp is actually pointer to arpcom structure.
436 ether_frameout(ifp
, m
, ndest
, edst
, ether_type
)
437 register struct ifnet
*ifp
;
439 struct sockaddr
*ndest
;
443 register struct ether_header
*eh
;
444 int hlen
; /* link layer header length */
445 struct arpcom
*ac
= IFP2AC(ifp
);
448 hlen
= ETHER_HDR_LEN
;
451 * If a simplex interface, and the packet is being sent to our
452 * Ethernet address or a broadcast address, loopback a copy.
453 * XXX To make a simplex device behave exactly like a duplex
454 * device, we should copy in the case of sending to our own
455 * ethernet address (thus letting the original actually appear
456 * on the wire). However, we don't do that here for security
457 * reasons and compatibility with the original behavior.
459 if ((ifp
->if_flags
& IFF_SIMPLEX
) &&
460 ((*m
)->m_flags
& M_LOOP
)) {
462 dlil_find_dltag(APPLE_IF_FAM_LOOPBACK
, 0, PF_INET
, &lo_dlt
);
465 if ((*m
)->m_flags
& M_BCAST
) {
466 struct mbuf
*n
= m_copy(*m
, 0, (int)M_COPYALL
);
468 dlil_output(lo_dlt
, n
, 0, ndest
, 0);
472 if (bcmp(edst
, ac
->ac_enaddr
, ETHER_ADDR_LEN
) == 0) {
473 dlil_output(lo_dlt
, *m
, 0, ndest
, 0);
482 * Add local net header. If no space in first mbuf,
485 M_PREPEND(*m
, sizeof (struct ether_header
), M_DONTWAIT
);
487 return (EJUSTRETURN
);
491 eh
= mtod(*m
, struct ether_header
*);
492 (void)memcpy(&eh
->ether_type
, ether_type
,
493 sizeof(eh
->ether_type
));
494 (void)memcpy(eh
->ether_dhost
, edst
, 6);
495 (void)memcpy(eh
->ether_shost
, ac
->ac_enaddr
,
496 sizeof(eh
->ether_shost
));
503 __private_extern__
int
504 ether_add_if(struct ifnet
*ifp
)
508 ifp
->if_framer
= ether_frameout
;
509 ifp
->if_demux
= ether_demux
;
511 ifp
->if_resolvemulti
= ether_resolvemulti
;
514 for (i
=0; i
< MAX_INTERFACES
; i
++)
515 if (ether_desc_blk
[i
].n_count
== 0)
518 if (i
== MAX_INTERFACES
)
521 ether_desc_blk
[i
].block_ptr
= _MALLOC(ETHER_DESC_BLK_SIZE
* sizeof(struct en_desc
),
523 if (ether_desc_blk
[i
].block_ptr
== 0)
526 ether_desc_blk
[i
].n_count
= ETHER_DESC_BLK_SIZE
;
527 bzero(ether_desc_blk
[i
].block_ptr
, ETHER_DESC_BLK_SIZE
* sizeof(struct en_desc
));
529 ifp
->family_cookie
= i
;
534 __private_extern__
int
535 ether_del_if(struct ifnet
*ifp
)
537 if ((ifp
->family_cookie
< MAX_INTERFACES
) &&
538 (ether_desc_blk
[ifp
->family_cookie
].n_count
))
540 FREE(ether_desc_blk
[ifp
->family_cookie
].block_ptr
, M_IFADDR
);
541 ether_desc_blk
[ifp
->family_cookie
].block_ptr
= NULL
;
542 ether_desc_blk
[ifp
->family_cookie
].n_count
= 0;
543 ether_desc_blk
[ifp
->family_cookie
].n_max_used
= 0;
550 __private_extern__
int
551 ether_init_if(struct ifnet
*ifp
)
553 register struct ifaddr
*ifa
;
554 register struct sockaddr_dl
*sdl
;
556 ifa
= ifnet_addrs
[ifp
->if_index
- 1];
558 printf("ether_ifattach: no lladdr!\n");
561 sdl
= (struct sockaddr_dl
*)ifa
->ifa_addr
;
562 sdl
->sdl_type
= IFT_ETHER
;
563 sdl
->sdl_alen
= ifp
->if_addrlen
;
564 bcopy((IFP2AC(ifp
))->ac_enaddr
, LLADDR(sdl
), ifp
->if_addrlen
);
571 ether_ifmod_ioctl(ifp
, command
, data
)
576 struct rslvmulti_req
*rsreq
= (struct rslvmulti_req
*) data
;
578 struct sockaddr_dl
*sdl
;
579 struct sockaddr_in
*sin
;
585 switch(rsreq
->sa
->sa_family
) {
587 /* AppleTalk uses AF_UNSPEC for multicast registration.
588 * No mapping needed. Just check that it's a valid MC address.
590 e_addr
= &rsreq
->sa
->sa_data
[0];
591 if ((e_addr
[0] & 1) != 1)
592 return EADDRNOTAVAIL
;
599 * No mapping needed. Just check that it's a valid MC address.
601 sdl
= (struct sockaddr_dl
*)rsreq
->sa
;
602 e_addr
= LLADDR(sdl
);
603 if ((e_addr
[0] & 1) != 1)
604 return EADDRNOTAVAIL
;
618 extern int ether_attach_inet(struct ifnet
*ifp
, u_long
*dl_tag
);
619 extern int ether_detach_inet(struct ifnet
*ifp
, u_long dl_tag
);
620 extern int ether_attach_inet6(struct ifnet
*ifp
, u_long
*dl_tag
);
621 extern int ether_detach_inet6(struct ifnet
*ifp
, u_long dl_tag
);
622 int ether_family_init()
625 struct dlil_ifmod_reg_str ifmod_reg
;
626 struct dlil_protomod_reg_str enet_protoreg
;
627 extern int vlan_family_init(void);
629 /* ethernet family is built-in, called from bsd_init */
630 thread_funnel_switch(KERNEL_FUNNEL
, NETWORK_FUNNEL
);
632 bzero(&ifmod_reg
, sizeof(ifmod_reg
));
633 ifmod_reg
.add_if
= ether_add_if
;
634 ifmod_reg
.del_if
= ether_del_if
;
635 ifmod_reg
.init_if
= ether_init_if
;
636 ifmod_reg
.add_proto
= ether_add_proto
;
637 ifmod_reg
.del_proto
= ether_del_proto
;
638 ifmod_reg
.ifmod_ioctl
= ether_ifmod_ioctl
;
639 ifmod_reg
.shutdown
= ether_shutdown
;
641 if (dlil_reg_if_modules(APPLE_IF_FAM_ETHERNET
, &ifmod_reg
)) {
642 printf("WARNING: ether_family_init -- Can't register if family modules\n");
648 /* Register protocol registration functions */
650 bzero(&enet_protoreg
, sizeof(enet_protoreg
));
651 enet_protoreg
.attach_proto
= ether_attach_inet
;
652 enet_protoreg
.detach_proto
= ether_detach_inet
;
654 if (error
= dlil_reg_proto_module(PF_INET
, APPLE_IF_FAM_ETHERNET
, &enet_protoreg
) != 0) {
655 printf("ether_family_init: dlil_reg_proto_module failed for AF_INET error=%d\n", error
);
659 enet_protoreg
.attach_proto
= ether_attach_inet6
;
660 enet_protoreg
.detach_proto
= ether_detach_inet6
;
662 if (error
= dlil_reg_proto_module(PF_INET6
, APPLE_IF_FAM_ETHERNET
, &enet_protoreg
) != 0) {
663 printf("ether_family_init: dlil_reg_proto_module failed for AF_INET6 error=%d\n", error
);
669 thread_funnel_switch(NETWORK_FUNNEL
, KERNEL_FUNNEL
);