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>
76 #include <netinet/in.h>
77 #include <netinet/in_var.h>
78 #include <netinet/if_ether.h>
79 #include <netinet/in_systm.h>
80 #include <netinet/ip.h>
83 #include <netinet6/nd6.h>
84 #include <netinet6/in6_ifattach.h>
88 #include <sys/socketvar.h>
89 #include <net/if_blue.h>
95 extern struct ifqueue pkintrq
;
98 /* General stuff from if_ethersubr.c - may not need some of it */
100 #include <netat/at_pat.h>
102 extern struct ifqueue atalkintrq
;
107 #include <net/bridge.h>
110 /* #include "vlan.h" */
112 #include <net/if_vlan_var.h>
113 #endif /* NVLAN > 0 */
116 extern struct ifnet_blue
*blue_if
;
117 extern struct mbuf
*splitter_input(struct mbuf
*, struct ifnet
*);
119 static u_long lo_dlt
= 0;
120 static ivedonethis
= 0;
121 static int ether_resolvemulti
__P((struct ifnet
*, struct sockaddr
**,
123 u_char etherbroadcastaddr
[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
125 #define IFP2AC(IFP) ((struct arpcom *)IFP)
127 /* This stuff is new */
129 #define DB_HEADER_SIZE 20
135 struct if_proto
*proto
;
136 u_long proto_id_length
;
137 u_long proto_id_data
[8]; /* probably less - proto-id and bitmasks */
140 #define LITMUS_SIZE 16
141 #define ETHER_DESC_BLK_SIZE 50
142 #define MAX_INTERFACES 50
145 * Statics for demux module
148 struct ether_desc_blk_str
{
153 struct dl_es_at_entry
161 static struct ether_desc_blk_str ether_desc_blk
[MAX_INTERFACES
];
162 static u_long litmus_mask
[LITMUS_SIZE
];
163 static u_long litmus_length
= 0;
167 * Temp static for protocol registration XXX
170 #define MAX_EN_COUNT 30
172 static struct dl_es_at_entry en_at_array
[MAX_EN_COUNT
];
175 * This could be done below in-line with heavy casting, but the pointer arithmetic is
180 int desc_in_bounds(block
, current_ptr
, offset_length
)
183 u_long offset_length
;
186 u_long current_ptr_tmp
;
188 current_ptr_tmp
= (u_long
) current_ptr
;
189 end_of_block
= (u_long
) ether_desc_blk
[block
].block_ptr
;
190 end_of_block
+= (ETHER_DESC_BLK_SIZE
* ether_desc_blk
[block
].n_blocks
);
191 if ((current_ptr_tmp
+ offset_length
) < end_of_block
)
199 * Release all descriptor entries owned by this dl_tag (there may be several).
200 * Setting the dl_tag to 0 releases the entry. Eventually we should compact-out
201 * the unused entries.
204 int ether_del_proto(struct if_proto
*proto
, u_long dl_tag
)
206 char *current_ptr
= (char *) ether_desc_blk
[proto
->ifp
->family_cookie
].block_ptr
;
211 ed
= (struct en_desc
*) current_ptr
;
213 while(ed
->total_len
) {
214 if (ed
->dl_tag
== dl_tag
) {
219 current_ptr
+= ed
->total_len
;
220 ed
= (struct en_desc
*) current_ptr
;
227 int ether_add_proto(struct ddesc_head_str
*desc_head
, struct if_proto
*proto
, u_long dl_tag
)
230 struct dlil_demux_desc
*desc
;
231 u_long id_length
; /* IN LONGWORDS!!! */
241 TAILQ_FOREACH(desc
, desc_head
, next
) {
245 id_length
= desc
->variants
.bitmask
.proto_id_length
;
248 case DLIL_DESC_802_2
:
252 case DLIL_DESC_802_2_SNAP
:
261 block_count
= ether_desc_blk
[proto
->ifp
->family_cookie
].n_blocks
;
262 current_ptr
= (char *) ether_desc_blk
[proto
->ifp
->family_cookie
].block_ptr
;
263 ed
= (struct en_desc
*) current_ptr
;
264 total_length
= ((id_length
<< 2) * 2) + DB_HEADER_SIZE
;
266 while ((ed
->total_len
) && (desc_in_bounds(proto
->ifp
->family_cookie
,
267 current_ptr
, total_length
))) {
268 if ((ed
->dl_tag
== 0) && (total_length
<= ed
->total_len
))
271 current_ptr
+= *(short *)current_ptr
;
273 ed
= (struct en_desc
*) current_ptr
;
276 if (!desc_in_bounds(proto
->ifp
->family_cookie
, current_ptr
, total_length
)) {
278 tmp
= _MALLOC((ETHER_DESC_BLK_SIZE
* (block_count
+ 1)),
282 * Remove any previous descriptors set in the call.
284 ether_del_proto(proto
, dl_tag
);
288 bzero(tmp
, ETHER_DESC_BLK_SIZE
* (block_count
+ 1));
289 bcopy(ether_desc_blk
[proto
->ifp
->family_cookie
].block_ptr
,
290 tmp
, (ETHER_DESC_BLK_SIZE
* block_count
));
291 FREE(ether_desc_blk
[proto
->ifp
->family_cookie
].block_ptr
, M_IFADDR
);
292 ether_desc_blk
[proto
->ifp
->family_cookie
].n_blocks
= block_count
+ 1;
293 ether_desc_blk
[proto
->ifp
->family_cookie
].block_ptr
= tmp
;
297 if (ed
->total_len
== 0)
298 ed
->total_len
= total_length
;
299 ed
->ethertype
= *((u_short
*) desc
->native_type
);
303 ed
->proto_id_length
= id_length
;
304 ed
->ifp
= proto
->ifp
;
309 bcopy(desc
->variants
.bitmask
.proto_id
, &ed
->proto_id_data
[0], (id_length
<< 2) );
310 bcopy(desc
->variants
.bitmask
.proto_id_mask
, &ed
->proto_id_data
[id_length
],
314 case DLIL_DESC_802_2
:
315 ed
->proto_id_data
[0] = 0;
316 bcopy(&desc
->variants
.desc_802_2
, &ed
->proto_id_data
[0], 3);
317 ed
->proto_id_data
[1] = 0xffffff00;
320 case DLIL_DESC_802_2_SNAP
:
321 /* XXX Add verification of fixed values here */
323 ed
->proto_id_data
[0] = 0;
324 ed
->proto_id_data
[1] = 0;
325 bcopy(&desc
->variants
.desc_802_2_SNAP
, &ed
->proto_id_data
[0], 8);
326 ed
->proto_id_data
[2] = 0xffffffff;
327 ed
->proto_id_data
[3] = 0xffffffff;;
332 proto_id
= (u_long
*) &ed
->proto_id_data
[0];
333 bitmask
= (u_long
*) &ed
->proto_id_data
[id_length
];
334 for (i
=0; i
< (id_length
); i
++) {
335 litmus_mask
[i
] &= bitmask
[i
];
336 litmus_mask
[i
] &= proto_id
[i
];
338 if (id_length
> litmus_length
)
339 litmus_length
= id_length
;
357 * Process a received Ethernet packet;
358 * the packet is in the mbuf chain m without
359 * the ether header, which is provided separately.
362 new_ether_input(m
, frame_header
, ifp
, dl_tag
, sync_ok
)
370 register struct ether_header
*eh
= (struct ether_header
*) frame_header
;
371 register struct ifqueue
*inq
=0;
374 u_int16_t ptype
= -1;
375 unsigned char buf
[18];
377 #if ISO || LLC || NETAT
378 register struct llc
*l
;
385 * Y-adapter input processing:
386 * - Don't split if coming from a dummy if
387 * - If coming from a real if, if splitting enabled,
388 * then filter the incoming packet
390 if (ifp
!= (struct ifnet
*)blue_if
)
391 { /* Is splitter turned on? */
392 if (ifp
->if_flags
&IFF_SPLITTER
)
393 { m
->m_data
-= sizeof(struct ether_header
);
394 m
->m_len
+= sizeof (struct ether_header
);
395 m
->m_pkthdr
.len
+= sizeof(struct ether_header
);
397 * Check to see if destined for BlueBox or Rhapsody
398 * If NULL return, mbuf's been consumed by the BlueBox.
399 * Otherwise, send on to Rhapsody
401 if ((m
= splitter_input(m
, ifp
)) == NULL
)
403 m
->m_data
+= sizeof(struct ether_header
);
404 m
->m_len
-= sizeof (struct ether_header
);
405 m
->m_pkthdr
.len
-= sizeof(struct ether_header
);
408 { /* Get the "real" IF */
409 ifp
= ((struct ndrv_cb
*)(blue_if
->ifb_so
->so_pcb
))->nd_if
;
410 m
->m_pkthdr
.rcvif
= ifp
;
411 blue_if
->pkts_looped_b2r
++;
415 if ((ifp
->if_flags
& IFF_UP
) == 0) {
420 ifp
->if_lastchange
= time
;
422 if (eh
->ether_dhost
[0] & 1) {
423 if (bcmp((caddr_t
)etherbroadcastaddr
, (caddr_t
)eh
->ether_dhost
,
424 sizeof(etherbroadcastaddr
)) == 0)
425 m
->m_flags
|= M_BCAST
;
427 m
->m_flags
|= M_MCAST
;
429 if (m
->m_flags
& (M_BCAST
|M_MCAST
))
432 ether_type
= ntohs(eh
->ether_type
);
435 if (ether_type
== vlan_proto
) {
436 if (vlan_input(eh
, m
) < 0)
437 ifp
->if_data
.ifi_noproto
++;
440 #endif /* NVLAN > 0 */
442 switch (ether_type
) {
445 if (ipflow_fastforward(m
))
447 ptype
= mtod(m
, struct ip
*)->ip_p
;
448 if ((sync_ok
== 0) ||
449 (ptype
!= IPPROTO_TCP
&& ptype
!= IPPROTO_UDP
)) {
450 schednetisr(NETISR_IP
);
457 schednetisr(NETISR_ARP
);
463 schednetisr(NETISR_IPV6
);
471 if (ether_type
> ETHERMTU
)
473 l
= mtod(m
, struct llc
*);
474 switch (l
->llc_dsap
) {
477 /* Temporary hack: check for AppleTalk and AARP packets */
478 /* WARNING we're checking only on the "ether_type" (the 2 bytes
479 * of the SNAP header. This shouldn't be a big deal,
480 * AppleTalk pat_input is making sure we have the right packets
481 * because it needs to discrimante AARP from EtherTalk packets.
484 if (l
->llc_ssap
== LLC_SNAP_LSAP
&&
485 l
->llc_un
.type_snap
.control
== 0x03) {
487 #ifdef APPLETALK_DEBUG
488 printf("new_ether_input: SNAP Cntrol type=0x%x Src=%s\n",
489 l
->llc_un
.type_snap
.ether_type
,
490 ether_sprintf(buf
, &eh
->ether_shost
));
492 ether_sprintf(buf
, &eh
->ether_dhost
));
493 #endif /* APPLETALK_DEBUG */
495 if ((l
->llc_un
.type_snap
.ether_type
== 0x809B) ||
496 (l
->llc_un
.type_snap
.ether_type
== 0x80F3)) {
500 * note: for AppleTalk we need to pass the enet header of the
501 * packet up stack. To do so, we made sure in that the FULL packet
502 * is copied in the mbuf by the mace driver, and only the m_data and
503 * length have been shifted to make IP and the other guys happy.
506 m
->m_data
-= sizeof(*eh
);
507 m
->m_len
+= sizeof(*eh
);
508 m
->m_pkthdr
.len
+= sizeof(*eh
);
509 #ifdef APPLETALK_DEBUG
510 l
== (struct llc
*)(eh
+1);
511 if (l
->llc_un
.type_snap
.ether_type
== 0x80F3) {
512 kprintf("new_ether_input: RCV AppleTalk type=0x%x Src=%s\n",
513 l
->llc_un
.type_snap
.ether_type
,
514 ether_sprintf(buf
, &eh
->ether_shost
));
516 ether_sprintf(buf
, &eh
->ether_dhost
));
518 #endif /* APPLETALK_DEBUG */
519 schednetisr(NETISR_APPLETALK
);
554 (ptype
== IPPROTO_TCP
|| ptype
== IPPROTO_UDP
)) {
555 extern void ipintr(void);
568 int ether_demux(ifp
, m
, frame_header
, proto
)
572 struct if_proto
**proto
;
575 register struct ether_header
*eh
= (struct ether_header
*)frame_header
;
577 char *current_ptr
= (char *) ether_desc_blk
[ifp
->family_cookie
].block_ptr
;
578 struct dlil_demux_desc
*desc
;
579 register u_long temp
;
581 register struct if_proto
*ifproto
;
586 if (eh
->ether_dhost
[0] & 1) {
587 if (bcmp((caddr_t
)etherbroadcastaddr
, (caddr_t
)eh
->ether_dhost
,
588 sizeof(etherbroadcastaddr
)) == 0)
589 m
->m_flags
|= M_BCAST
;
591 m
->m_flags
|= M_MCAST
;
594 ether_type
= ntohs(eh
->ether_type
);
597 * Search through the connected protocols for a match.
601 data
= mtod(m
, u_long
*);
602 ed
= (struct en_desc
*) current_ptr
;
603 while (desc_in_bounds(ifp
->family_cookie
, current_ptr
, DB_HEADER_SIZE
)) {
604 if (ed
->total_len
== 0)
607 if ((ed
->dl_tag
!= 0) && (ed
->ifp
== ifp
) &&
608 ((ed
->ethertype
== ntohs(eh
->ether_type
)) || (ed
->ethertype
== 0))) {
609 if (ed
->proto_id_length
) {
610 for (i
=0; i
< (ed
->proto_id_length
); i
++) {
611 temp
= ntohs(data
[i
]) & ed
->proto_id_data
[ed
->proto_id_length
+ i
];
612 if ((temp
^ ed
->proto_id_data
[i
]))
616 if (i
>= (ed
->proto_id_length
)) {
626 current_ptr
+= ed
->total_len
;
627 ed
= (struct en_desc
*) current_ptr
;
631 kprintf("ether_demux - No match for <%x><%x><%x><%x><%x><%x><%x<%x>\n",
632 eh->ether_type,data[0], data[1], data[2], data[3], data[4],data[5],data[6]);
641 * Ethernet output routine.
642 * Encapsulate a packet of type family for the local net.
643 * Use trailer local net encapsulation if enough data in first
644 * packet leaves a multiple of 512 bytes of data in remainder.
645 * Assumes that ifp is actually pointer to arpcom structure.
648 ether_frameout(ifp
, m
, ndest
, edst
, ether_type
)
649 register struct ifnet
*ifp
;
651 struct sockaddr
*ndest
;
655 register struct ether_header
*eh
;
656 int hlen
; /* link layer header lenght */
657 struct arpcom
*ac
= IFP2AC(ifp
);
660 hlen
= ETHER_HDR_LEN
;
663 * If a simplex interface, and the packet is being sent to our
664 * Ethernet address or a broadcast address, loopback a copy.
665 * XXX To make a simplex device behave exactly like a duplex
666 * device, we should copy in the case of sending to our own
667 * ethernet address (thus letting the original actually appear
668 * on the wire). However, we don't do that here for security
669 * reasons and compatibility with the original behavior.
671 if ((ifp
->if_flags
& IFF_SIMPLEX
) &&
672 ((*m
)->m_flags
& M_LOOP
)) {
674 dlil_find_dltag(APPLE_IF_FAM_LOOPBACK
, 0, PF_INET
, &lo_dlt
);
677 if ((*m
)->m_flags
& M_BCAST
) {
678 struct mbuf
*n
= m_copy(*m
, 0, (int)M_COPYALL
);
679 dlil_output(lo_dlt
, n
, 0, ndest
, 0);
683 if (bcmp(edst
, ac
->ac_enaddr
, ETHER_ADDR_LEN
) == 0) {
684 dlil_output(lo_dlt
, *m
, 0, ndest
, 0);
693 * Add local net header. If no space in first mbuf,
696 M_PREPEND(*m
, sizeof (struct ether_header
), M_DONTWAIT
);
698 return (EJUSTRETURN
);
702 eh
= mtod(*m
, struct ether_header
*);
703 (void)memcpy(&eh
->ether_type
, ether_type
,
704 sizeof(eh
->ether_type
));
705 (void)memcpy(eh
->ether_dhost
, edst
, 6);
706 (void)memcpy(eh
->ether_shost
, ac
->ac_enaddr
,
707 sizeof(eh
->ether_shost
));
711 * We're already to send. Let's check for the blue box...
713 if (ifp
->if_flags
&IFF_SPLITTER
)
715 (*m
)->m_flags
|= 0x10;
716 if ((*m
= splitter_input(*m
, ifp
)) == NULL
)
728 int ether_add_if(struct ifnet
*ifp
)
732 ifp
->if_framer
= ether_frameout
;
733 ifp
->if_demux
= ether_demux
;
735 for (i
=0; i
< MAX_INTERFACES
; i
++)
736 if (ether_desc_blk
[i
].n_blocks
== 0)
739 if (i
== MAX_INTERFACES
)
742 ether_desc_blk
[i
].block_ptr
= _MALLOC(ETHER_DESC_BLK_SIZE
, M_IFADDR
, M_WAITOK
);
743 if (ether_desc_blk
[i
].block_ptr
== 0)
746 ether_desc_blk
[i
].n_blocks
= 1;
747 bzero(ether_desc_blk
[i
].block_ptr
, ETHER_DESC_BLK_SIZE
);
749 ifp
->family_cookie
= i
;
755 int ether_del_if(struct ifnet
*ifp
)
757 if ((ifp
->family_cookie
< MAX_INTERFACES
) &&
758 (ether_desc_blk
[ifp
->family_cookie
].n_blocks
)) {
759 FREE(ether_desc_blk
[ifp
->family_cookie
].block_ptr
, M_IFADDR
);
760 ether_desc_blk
[ifp
->family_cookie
].n_blocks
= 0;
771 ether_pre_output(ifp
, m0
, dst_netaddr
, route
, type
, edst
, dl_tag
)
774 struct sockaddr
*dst_netaddr
;
780 struct rtentry
*rt0
= (struct rtentry
*) route
;
782 register struct mbuf
*m
= *m0
;
783 register struct rtentry
*rt
;
784 register struct ether_header
*eh
;
785 int off
, len
= m
->m_pkthdr
.len
;
786 int hlen
; /* link layer header lenght */
787 struct arpcom
*ac
= IFP2AC(ifp
);
791 if ((ifp
->if_flags
& (IFF_UP
|IFF_RUNNING
)) != (IFF_UP
|IFF_RUNNING
))
796 if ((rt
->rt_flags
& RTF_UP
) == 0) {
797 rt0
= rt
= rtalloc1(dst_netaddr
, 1, 0UL);
804 if (rt
->rt_flags
& RTF_GATEWAY
) {
805 if (rt
->rt_gwroute
== 0)
807 if (((rt
= rt
->rt_gwroute
)->rt_flags
& RTF_UP
) == 0) {
808 rtfree(rt
); rt
= rt0
;
809 lookup
: rt
->rt_gwroute
= rtalloc1(rt
->rt_gateway
, 1,
811 if ((rt
= rt
->rt_gwroute
) == 0)
812 return (EHOSTUNREACH
);
817 if (rt
->rt_flags
& RTF_REJECT
)
818 if (rt
->rt_rmx
.rmx_expire
== 0 ||
819 time_second
< rt
->rt_rmx
.rmx_expire
)
820 return (rt
== rt0
? EHOSTDOWN
: EHOSTUNREACH
);
823 hlen
= ETHER_HDR_LEN
;
826 * Tell ether_frameout it's ok to loop packet unless negated below.
828 m
->m_flags
|= M_LOOP
;
830 switch (dst_netaddr
->sa_family
) {
834 if (!arpresolve(ac
, rt
, m
, dst_netaddr
, edst
, rt0
))
835 return (EJUSTRETURN
); /* if not yet resolved */
836 off
= m
->m_pkthdr
.len
- m
->m_len
;
837 *(u_short
*)type
= htons(ETHERTYPE_IP
);
843 if (!nd6_storelladdr(&ac
->ac_if
, rt
, m
, dst_netaddr
, (u_char
*)edst
)) {
844 /* this must be impossible, so we bark */
845 kprintf("nd6_storelladdr failed\n");
848 off
= m
->m_pkthdr
.len
- m
->m_len
;
849 *(u_short
*)type
= htons(ETHERTYPE_IPV6
);
855 m
->m_flags
&= ~M_LOOP
;
856 eh
= (struct ether_header
*)dst_netaddr
->sa_data
;
857 (void)memcpy(edst
, eh
->ether_dhost
, 6);
858 *(u_short
*)type
= eh
->ether_type
;
864 eh
= (struct ether_header
*)dst_netaddr
->sa_data
;
865 bcopy((caddr_t
)eh
->ether_dhost
, (caddr_t
)edst
, 6);
867 *(u_short
*)type
= m
->m_pkthdr
.len
;
874 kprintf("%s%d: can't handle af%d\n", ifp
->if_name
, ifp
->if_unit
,
875 dst_netaddr
->sa_family
);
888 ether_ioctl(dl_tag
, ifp
, command
, data
)
894 struct ifaddr
*ifa
= (struct ifaddr
*) data
;
895 struct ifreq
*ifr
= (struct ifreq
*) data
;
897 boolean_t funnel_state
;
899 funnel_state
= thread_funnel_set(TRUE
);
903 ifp
->if_flags
|= IFF_UP
;
905 switch (ifa
->ifa_addr
->sa_family
) {
910 ifp
->if_init(ifp
->if_softc
); /* before arpwhohas */
913 arp_ifinit(IFP2AC(ifp
), ifa
);
927 sa
= (struct sockaddr
*) & ifr
->ifr_data
;
928 bcopy(IFP2AC(ifp
)->ac_enaddr
,
929 (caddr_t
) sa
->sa_data
, ETHER_ADDR_LEN
);
935 * Set the interface MTU.
937 if (ifr
->ifr_mtu
> ETHERMTU
) {
940 ifp
->if_mtu
= ifr
->ifr_mtu
;
945 (void) thread_funnel_set(funnel_state
);
954 * Y-adapter filter check
958 * Not for Rhap: return -1
959 * Multicast/Broadcast => For Both
960 * Atalk address registered
961 * filter matches => For Rhap else Not For Rhap
962 * IP address registered
963 * filter matches => For Rhap else Not For Rhap
965 * Note this is *not* a general filter mechanism in that we know
966 * what we *could* be looking for.
967 * WARNING: this is a big-endian routine.
968 * Note: ARP and AARP packets are implicitly accepted for "both"
971 Filter_check(struct mbuf
**m0
)
972 { register struct BlueFilter
*bf
;
973 register unsigned char *p
;
974 register unsigned short *s
;
975 register unsigned long *l
;
978 extern struct mbuf
*m_pullup(struct mbuf
*, int);
979 extern void kprintf( const char *, ...);
980 #define FILTER_LEN 32
984 if (FILTER_LEN
> m
->m_pkthdr
.len
)
986 while ((FILTER_LEN
> m
->m_len
) && m
->m_next
) {
987 total
= m
->m_len
+ (m
->m_next
)->m_len
;
988 if ((m
= m_pullup(m
, min(FILTER_LEN
, total
))) == 0)
993 p
= mtod(m
, unsigned char *); /* Point to destination media addr */
994 if (p
[0] & 0x01) /* Multicast/broadcast */
996 s
= (unsigned short *)p
;
997 bf
= &RhapFilter
[BFS_ATALK
];
999 kprintf("!PKT: %x, %x, %x\n", s
[6], s
[7], s
[8]);
1002 if (bf
->BF_flags
) /* Filtering Appletalk */
1004 l
= (unsigned long *)&s
[8];
1006 kprintf("!AT: %x, %x, %x, %x, %x, %x\n", s
[6], s
[7],
1007 *l
, s
[10], s
[13], p
[30]);
1009 if (s
[6] <= ETHERMTU
)
1010 { if (s
[7] == 0xaaaa) /* Could be Atalk */
1011 { /* Verify SNAP header */
1012 if (*l
== 0x03080007 && s
[10] == 0x809b)
1013 { if (s
[13] == bf
->BF_address
&&
1014 p
[30] == bf
->BF_node
)
1016 } else if (*l
== 0x03000000 && s
[10] == 0x80f3)
1017 /* AARP pkts aren't net-addressed */
1020 } else /* Not for us? */
1022 } /* Fall through */
1023 } /* Fall through */
1024 bf
++; /* Look for IP next */
1025 if (bf
->BF_flags
) /* Filtering IP */
1027 l
= (unsigned long *)&s
[15];
1029 kprintf("!IP: %x, %x\n", s
[6], *l
);
1031 if (s
[6] > ETHERMTU
)
1032 { if (s
[6] == 0x800) /* Is IP */
1033 { /* Verify IP address */
1034 if (*l
== bf
->BF_address
)
1036 else /* Not for us */
1038 } else if (s
[6] == 0x806)
1039 /* ARP pkts aren't net-addressed */
1043 return(0); /* No filters => Accept */
1048 int ether_family_init()
1059 if (dlil_reg_if_modules(APPLE_IF_FAM_ETHERNET
, ether_add_if
, ether_del_if
,
1060 ether_add_proto
, ether_del_proto
,
1062 printf("WARNING: ether_family_init -- Can't register if family modules\n");
1066 for (i
=0; i
< (LITMUS_SIZE
/4); i
++)
1067 litmus_mask
[i
] = 0xffffffff;
1069 for (i
=0; i
< MAX_INTERFACES
; i
++)
1070 ether_desc_blk
[i
].n_blocks
= 0;
1072 for (i
=0; i
< MAX_EN_COUNT
; i
++)
1073 en_at_array
[i
].ifp
= 0;
1080 u_long
ether_attach_inet(struct ifnet
*ifp
)
1082 struct dlil_proto_reg_str reg
;
1083 struct dlil_demux_desc desc
;
1084 struct dlil_demux_desc desc2
;
1086 struct dlil_demux_desc desc3
;
1089 u_short en_native
=ETHERTYPE_IP
;
1090 u_short arp_native
=ETHERTYPE_ARP
;
1092 u_short en_6native
=ETHERTYPE_IPV6
;
1098 stat
= dlil_find_dltag(ifp
->if_family
, ifp
->if_unit
, PF_INET
, &ip_dl_tag
);
1102 TAILQ_INIT(®
.demux_desc_head
);
1103 desc
.type
= DLIL_DESC_RAW
;
1104 desc
.variants
.bitmask
.proto_id_length
= 0;
1105 desc
.variants
.bitmask
.proto_id
= 0;
1106 desc
.variants
.bitmask
.proto_id_mask
= 0;
1107 desc
.native_type
= (char *) &en_native
;
1108 TAILQ_INSERT_TAIL(®
.demux_desc_head
, &desc
, next
);
1109 reg
.interface_family
= ifp
->if_family
;
1110 reg
.unit_number
= ifp
->if_unit
;
1111 reg
.input
= new_ether_input
;
1112 reg
.pre_output
= ether_pre_output
;
1115 reg
.ioctl
= ether_ioctl
;
1116 reg
.default_proto
= 1;
1117 reg
.protocol_family
= PF_INET
;
1120 desc2
.native_type
= (char *) &arp_native
;
1121 TAILQ_INSERT_TAIL(®
.demux_desc_head
, &desc2
, next
);
1125 desc3
.native_type
= (char *) &en_6native
;
1126 TAILQ_INSERT_TAIL(®
.demux_desc_head
, &desc3
, next
);
1129 stat
= dlil_attach_protocol(®
, &ip_dl_tag
);
1131 printf("WARNING: ether_attach_inet can't attach ip to interface\n");
1138 void ether_attach_at(struct ifnet
*ifp
, u_long
*at_dl_tag
, u_long
*aarp_dl_tag
)
1140 struct dlil_proto_reg_str reg
;
1141 struct dlil_demux_desc desc
;
1142 struct dlil_demux_desc desc2
;
1143 u_short native
= 0; /* 802.2 frames use a length here */
1149 first_empty
= MAX_EN_COUNT
;
1150 for (i
=0; i
< MAX_EN_COUNT
; i
++) {
1151 if (en_at_array
[i
].ifp
== 0)
1154 if (en_at_array
[i
].ifp
== ifp
) {
1155 en_at_array
[i
].ref_count
++;
1156 *at_dl_tag
= *aarp_dl_tag
= en_at_array
[i
].dl_tag
;
1161 if (first_empty
== MAX_EN_COUNT
)
1164 TAILQ_INIT(®
.demux_desc_head
);
1165 desc
.type
= DLIL_DESC_802_2_SNAP
;
1166 desc
.variants
.desc_802_2_SNAP
.dsap
= LLC_SNAP_LSAP
;
1167 desc
.variants
.desc_802_2_SNAP
.ssap
= LLC_SNAP_LSAP
;
1168 desc
.variants
.desc_802_2_SNAP
.control_code
= 0x03;
1169 desc
.variants
.desc_802_2_SNAP
.org
[0] = 0x08;
1170 desc
.variants
.desc_802_2_SNAP
.org
[1] = 0x00;
1171 desc
.variants
.desc_802_2_SNAP
.org
[2] = 0x07;
1172 desc
.variants
.desc_802_2_SNAP
.protocol_type
= 0x809B;
1173 desc
.native_type
= (char *) &native
;
1174 TAILQ_INSERT_TAIL(®
.demux_desc_head
, &desc
, next
);
1175 reg
.interface_family
= ifp
->if_family
;
1176 reg
.unit_number
= ifp
->if_unit
;
1177 reg
.input
= new_ether_input
;
1178 reg
.pre_output
= ether_pre_output
;
1181 reg
.ioctl
= ether_ioctl
;
1182 reg
.default_proto
= 0;
1183 reg
.protocol_family
= PF_APPLETALK
;
1186 desc2
.variants
.desc_802_2_SNAP
.protocol_type
= 0x80F3;
1187 desc2
.variants
.desc_802_2_SNAP
.org
[0] = 0;
1188 desc2
.variants
.desc_802_2_SNAP
.org
[1] = 0;
1189 desc2
.variants
.desc_802_2_SNAP
.org
[2] = 0;
1191 TAILQ_INSERT_TAIL(®
.demux_desc_head
, &desc2
, next
);
1193 stat
= dlil_attach_protocol(®
, at_dl_tag
);
1195 printf("WARNING: ether_attach_at can't attach at to interface\n");
1199 *aarp_dl_tag
= *at_dl_tag
;
1201 en_at_array
[first_empty
].ifp
= ifp
;
1202 en_at_array
[first_empty
].dl_tag
= *at_dl_tag
;
1203 en_at_array
[first_empty
].ref_count
= 1;
1205 } /* ether_attach_at */
1208 void ether_detach_at(struct ifnet
*ifp
)
1212 for (i
=0; i
< MAX_EN_COUNT
; i
++) {
1213 if (en_at_array
[i
].ifp
== ifp
)
1217 if (i
< MAX_EN_COUNT
) {
1218 if (en_at_array
[i
].ref_count
> 1)
1219 en_at_array
[i
].ref_count
--;
1221 if (en_at_array
[i
].ref_count
== 1) {
1222 dlil_detach_protocol(en_at_array
[i
].dl_tag
);
1223 en_at_array
[i
].ifp
= 0;