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, 1989, 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
58 #include <sys/param.h>
59 #include <sys/systm.h>
60 #include <sys/kernel.h>
61 #include <sys/malloc.h>
63 #include <sys/socket.h>
64 #include <sys/sockio.h>
65 #include <sys/sysctl.h>
68 #include <net/netisr.h>
69 #include <net/route.h>
70 #include <net/if_llc.h>
71 #include <net/if_dl.h>
72 #include <net/if_types.h>
74 #include <netinet/if_ether.h>
78 #include <netinet/in.h>
79 #include <netinet/in_var.h>
81 #include <netinet/in_systm.h>
82 #include <netinet/ip.h>
86 #include <sys/socketvar.h>
92 extern struct ifqueue pkintrq
;
95 /* General stuff from if_ethersubr.c - may not need some of it */
97 #include <netat/at_pat.h>
99 extern struct ifqueue atalkintrq
;
104 #include <net/bridge.h>
107 /* #include "vlan.h" */
109 #include <net/if_vlan_var.h>
110 #endif /* NVLAN > 0 */
112 static u_long lo_dlt
= 0;
113 static ivedonethis
= 0;
115 #define IFP2AC(IFP) ((struct arpcom *)IFP)
117 u_char etherbroadcastaddr
[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
120 #define DB_HEADER_SIZE 20
126 struct if_proto
*proto
;
127 u_long proto_id_length
;
128 u_long proto_id_data
[8]; /* probably less - proto-id and bitmasks */
131 #define LITMUS_SIZE 16
132 #define ETHER_DESC_BLK_SIZE 50
133 #define MAX_INTERFACES 50
136 * Statics for demux module
139 struct ether_desc_blk_str
{
144 struct dl_es_at_entry
152 static struct ether_desc_blk_str ether_desc_blk
[MAX_INTERFACES
];
153 static u_long litmus_mask
[LITMUS_SIZE
];
154 static u_long litmus_length
= 0;
158 * Temp static for protocol registration XXX
161 #define MAX_EN_COUNT 30
163 static struct dl_es_at_entry en_at_array
[MAX_EN_COUNT
];
166 * This could be done below in-line with heavy casting, but the pointer arithmetic is
171 int desc_in_bounds(block
, current_ptr
, offset_length
)
174 u_long offset_length
;
177 u_long current_ptr_tmp
;
179 current_ptr_tmp
= (u_long
) current_ptr
;
180 end_of_block
= (u_long
) ether_desc_blk
[block
].block_ptr
;
181 end_of_block
+= (ETHER_DESC_BLK_SIZE
* ether_desc_blk
[block
].n_blocks
);
182 if ((current_ptr_tmp
+ offset_length
) < end_of_block
)
190 * Release all descriptor entries owned by this dl_tag (there may be several).
191 * Setting the dl_tag to 0 releases the entry. Eventually we should compact-out
192 * the unused entries.
195 int ether_del_proto(struct if_proto
*proto
, u_long dl_tag
)
197 char *current_ptr
= (char *) ether_desc_blk
[proto
->ifp
->family_cookie
].block_ptr
;
202 ed
= (struct en_desc
*) current_ptr
;
204 while(ed
->total_len
) {
205 if (ed
->dl_tag
== dl_tag
) {
210 current_ptr
+= ed
->total_len
;
211 ed
= (struct en_desc
*) current_ptr
;
218 int ether_add_proto(struct ddesc_head_str
*desc_head
, struct if_proto
*proto
, u_long dl_tag
)
221 struct dlil_demux_desc
*desc
;
222 u_long id_length
; /* IN LONGWORDS!!! */
232 TAILQ_FOREACH(desc
, desc_head
, next
) {
236 id_length
= desc
->variants
.bitmask
.proto_id_length
;
239 case DLIL_DESC_802_2
:
243 case DLIL_DESC_802_2_SNAP
:
252 block_count
= ether_desc_blk
[proto
->ifp
->family_cookie
].n_blocks
;
253 current_ptr
= (char *) ether_desc_blk
[proto
->ifp
->family_cookie
].block_ptr
;
254 ed
= (struct en_desc
*) current_ptr
;
255 total_length
= ((id_length
<< 2) * 2) + DB_HEADER_SIZE
;
257 while ((ed
->total_len
) && (desc_in_bounds(proto
->ifp
->family_cookie
,
258 current_ptr
, total_length
))) {
259 if ((ed
->dl_tag
== 0) && (total_length
<= ed
->total_len
))
262 current_ptr
+= *(short *)current_ptr
;
264 ed
= (struct en_desc
*) current_ptr
;
267 if (!desc_in_bounds(proto
->ifp
->family_cookie
, current_ptr
, total_length
)) {
269 tmp
= _MALLOC((ETHER_DESC_BLK_SIZE
* (block_count
+ 1)),
273 * Remove any previous descriptors set in the call.
275 ether_del_proto(proto
, dl_tag
);
279 bzero(tmp
, ETHER_DESC_BLK_SIZE
* (block_count
+ 1));
280 bcopy(ether_desc_blk
[proto
->ifp
->family_cookie
].block_ptr
,
281 tmp
, (ETHER_DESC_BLK_SIZE
* block_count
));
282 FREE(ether_desc_blk
[proto
->ifp
->family_cookie
].block_ptr
, M_IFADDR
);
283 ether_desc_blk
[proto
->ifp
->family_cookie
].n_blocks
= block_count
+ 1;
284 ether_desc_blk
[proto
->ifp
->family_cookie
].block_ptr
= tmp
;
288 if (ed
->total_len
== 0)
289 ed
->total_len
= total_length
;
290 ed
->ethertype
= *((u_short
*) desc
->native_type
);
294 ed
->proto_id_length
= id_length
;
295 ed
->ifp
= proto
->ifp
;
300 bcopy(desc
->variants
.bitmask
.proto_id
, &ed
->proto_id_data
[0], (id_length
<< 2) );
301 bcopy(desc
->variants
.bitmask
.proto_id_mask
, &ed
->proto_id_data
[id_length
],
305 case DLIL_DESC_802_2
:
306 ed
->proto_id_data
[0] = 0;
307 bcopy(&desc
->variants
.desc_802_2
, &ed
->proto_id_data
[0], 3);
308 ed
->proto_id_data
[1] = 0xffffff00;
311 case DLIL_DESC_802_2_SNAP
:
312 /* XXX Add verification of fixed values here */
314 ed
->proto_id_data
[0] = 0;
315 ed
->proto_id_data
[1] = 0;
316 bcopy(&desc
->variants
.desc_802_2_SNAP
, &ed
->proto_id_data
[0], 8);
317 ed
->proto_id_data
[2] = 0xffffffff;
318 ed
->proto_id_data
[3] = 0xffffffff;;
323 proto_id
= (u_long
*) &ed
->proto_id_data
[0];
324 bitmask
= (u_long
*) &ed
->proto_id_data
[id_length
];
325 for (i
=0; i
< (id_length
); i
++) {
326 litmus_mask
[i
] &= bitmask
[i
];
327 litmus_mask
[i
] &= proto_id
[i
];
329 if (id_length
> litmus_length
)
330 litmus_length
= id_length
;
348 int ether_demux(ifp
, m
, frame_header
, proto
)
352 struct if_proto
**proto
;
355 register struct ether_header
*eh
= (struct ether_header
*)frame_header
;
357 char *current_ptr
= (char *) ether_desc_blk
[ifp
->family_cookie
].block_ptr
;
358 struct dlil_demux_desc
*desc
;
359 register u_long temp
;
361 register struct if_proto
*ifproto
;
366 if (eh
->ether_dhost
[0] & 1) {
367 if (bcmp((caddr_t
)etherbroadcastaddr
, (caddr_t
)eh
->ether_dhost
,
368 sizeof(etherbroadcastaddr
)) == 0)
369 m
->m_flags
|= M_BCAST
;
371 m
->m_flags
|= M_MCAST
;
374 ether_type
= ntohs(eh
->ether_type
);
377 * Search through the connected protocols for a match.
381 data
= mtod(m
, u_long
*);
382 ed
= (struct en_desc
*) current_ptr
;
383 while (desc_in_bounds(ifp
->family_cookie
, current_ptr
, DB_HEADER_SIZE
)) {
384 if (ed
->total_len
== 0)
387 if ((ed
->dl_tag
!= 0) && (ed
->ifp
== ifp
) &&
388 ((ed
->ethertype
== ntohs(eh
->ether_type
)) || (ed
->ethertype
== 0))) {
389 if (ed
->proto_id_length
) {
390 for (i
=0; i
< (ed
->proto_id_length
); i
++) {
391 temp
= ntohs(data
[i
]) & ed
->proto_id_data
[ed
->proto_id_length
+ i
];
392 if ((temp
^ ed
->proto_id_data
[i
]))
396 if (i
>= (ed
->proto_id_length
)) {
406 current_ptr
+= ed
->total_len
;
407 ed
= (struct en_desc
*) current_ptr
;
411 kprintf("ether_demux - No match for <%x><%x><%x><%x><%x><%x><%x<%x>\n",
412 eh->ether_type,data[0], data[1], data[2], data[3], data[4],data[5],data[6]);
421 * Ethernet output routine.
422 * Encapsulate a packet of type family for the local net.
423 * Use trailer local net encapsulation if enough data in first
424 * packet leaves a multiple of 512 bytes of data in remainder.
425 * Assumes that ifp is actually pointer to arpcom structure.
428 ether_frameout(ifp
, m
, ndest
, edst
, ether_type
)
429 register struct ifnet
*ifp
;
431 struct sockaddr
*ndest
;
435 register struct ether_header
*eh
;
436 int hlen
; /* link layer header lenght */
437 struct arpcom
*ac
= IFP2AC(ifp
);
440 hlen
= ETHER_HDR_LEN
;
443 * If a simplex interface, and the packet is being sent to our
444 * Ethernet address or a broadcast address, loopback a copy.
445 * XXX To make a simplex device behave exactly like a duplex
446 * device, we should copy in the case of sending to our own
447 * ethernet address (thus letting the original actually appear
448 * on the wire). However, we don't do that here for security
449 * reasons and compatibility with the original behavior.
451 if ((ifp
->if_flags
& IFF_SIMPLEX
) &&
452 ((*m
)->m_flags
& M_LOOP
)) {
454 dlil_find_dltag(APPLE_IF_FAM_LOOPBACK
, 0, PF_INET
, &lo_dlt
);
457 if ((*m
)->m_flags
& M_BCAST
) {
458 struct mbuf
*n
= m_copy(*m
, 0, (int)M_COPYALL
);
459 dlil_output(lo_dlt
, n
, 0, ndest
, 0);
463 if (bcmp(edst
, ac
->ac_enaddr
, ETHER_ADDR_LEN
) == 0) {
464 dlil_output(lo_dlt
, *m
, 0, ndest
, 0);
473 * Add local net header. If no space in first mbuf,
476 M_PREPEND(*m
, sizeof (struct ether_header
), M_DONTWAIT
);
478 return (EJUSTRETURN
);
482 eh
= mtod(*m
, struct ether_header
*);
483 (void)memcpy(&eh
->ether_type
, ether_type
,
484 sizeof(eh
->ether_type
));
485 (void)memcpy(eh
->ether_dhost
, edst
, 6);
486 (void)memcpy(eh
->ether_shost
, ac
->ac_enaddr
,
487 sizeof(eh
->ether_shost
));
494 int ether_add_if(struct ifnet
*ifp
)
498 ifp
->if_framer
= ether_frameout
;
499 ifp
->if_demux
= ether_demux
;
502 for (i
=0; i
< MAX_INTERFACES
; i
++)
503 if (ether_desc_blk
[i
].n_blocks
== 0)
506 if (i
== MAX_INTERFACES
)
509 ether_desc_blk
[i
].block_ptr
= _MALLOC(ETHER_DESC_BLK_SIZE
, M_IFADDR
, M_NOWAIT
);
510 if (ether_desc_blk
[i
].block_ptr
== 0)
513 ether_desc_blk
[i
].n_blocks
= 1;
514 bzero(ether_desc_blk
[i
].block_ptr
, ETHER_DESC_BLK_SIZE
);
516 ifp
->family_cookie
= i
;
522 int ether_del_if(struct ifnet
*ifp
)
524 if ((ifp
->family_cookie
< MAX_INTERFACES
) &&
525 (ether_desc_blk
[ifp
->family_cookie
].n_blocks
)) {
526 FREE(ether_desc_blk
[ifp
->family_cookie
].block_ptr
, M_IFADDR
);
527 ether_desc_blk
[ifp
->family_cookie
].n_blocks
= 0;
537 ether_ifmod_ioctl(ifp
, command
, data
)
542 struct rslvmulti_req
*rsreq
= (struct rslvmulti_req
*) data
;
544 struct sockaddr_dl
*sdl
;
545 struct sockaddr_in
*sin
;
552 switch(rsreq
->sa
->sa_family
)
555 /* AppleTalk uses AF_UNSPEC for multicast registration.
556 * No mapping needed. Just check that it's a valid MC address.
558 e_addr
= &rsreq
->sa
->sa_data
[0];
559 if ((e_addr
[0] & 1) != 1)
560 return EADDRNOTAVAIL
;
567 * No mapping needed. Just check that it's a valid MC address.
569 sdl
= (struct sockaddr_dl
*)rsreq
->sa
;
570 e_addr
= LLADDR(sdl
);
571 if ((e_addr
[0] & 1) != 1)
572 return EADDRNOTAVAIL
;
586 int ether_family_init()
589 struct dlil_ifmod_reg_str ifmod_reg
;
596 ifmod_reg
.add_if
= ether_add_if
;
597 ifmod_reg
.del_if
= ether_del_if
;
598 ifmod_reg
.add_proto
= ether_add_proto
;
599 ifmod_reg
.del_proto
= ether_del_proto
;
600 ifmod_reg
.ifmod_ioctl
= ether_ifmod_ioctl
;
601 ifmod_reg
.shutdown
= ether_shutdown
;
603 if (dlil_reg_if_modules(APPLE_IF_FAM_ETHERNET
, &ifmod_reg
)) {
604 printf("WARNING: ether_family_init -- Can't register if family modules\n");
608 for (i
=0; i
< (LITMUS_SIZE
/4); i
++)
609 litmus_mask
[i
] = 0xffffffff;
611 for (i
=0; i
< MAX_INTERFACES
; i
++)
612 ether_desc_blk
[i
].n_blocks
= 0;
614 for (i
=0; i
< MAX_EN_COUNT
; i
++)
615 en_at_array
[i
].ifp
= 0;