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 1994 Apple Computer, Inc.
24 * All Rights Reserved.
26 * Tuyen A. Nguyen. (December 5, 1994)
27 * Modified, March 17, 1997 by Tuyen Nguyen for MacOSX.
30 #include <sys/errno.h>
31 #include <sys/types.h>
32 #include <sys/param.h>
33 #include <machine/spl.h>
34 #include <sys/systm.h>
35 #include <sys/kernel.h>
37 #include <sys/filedesc.h>
38 #include <sys/fcntl.h>
40 #include <sys/ioctl.h>
41 #include <sys/malloc.h>
42 #include <sys/socket.h>
43 #include <sys/socketvar.h>
44 #include <sys/sockio.h>
47 #include <net/if_types.h>
48 #include <net/if_dl.h>
49 #include <net/etherdefs.h>
50 #include <net/ethernet.h>
51 #include <net/tokendefs.h>
53 #include <netat/sysglue.h>
54 #include <netat/appletalk.h>
55 #include <netat/at_pcb.h>
56 #include <netat/at_var.h>
57 #include <netat/ddp.h>
58 #include <netat/at_aarp.h>
59 #include <netat/at_pat.h>
60 #include <netat/debug.h>
62 #define DSAP_SNAP 0xaa
64 extern void gref_init(), atp_init(), atp_link(), atp_unlink();
66 extern int adspInited
;
68 static llc_header_t snap_hdr_at
= SNAP_HDR_AT
;
69 static llc_header_t snap_hdr_aarp
= SNAP_HDR_AARP
;
70 static unsigned char snap_proto_ddp
[5] = SNAP_PROTO_AT
;
71 static unsigned char snap_proto_aarp
[5] = SNAP_PROTO_AARP
;
75 struct ifqueue atalkintrq
; /* appletalk and aarp packet input queue */
77 short appletalk_inited
= 0;
80 ddpall_lock
, ddpinp_lock
, arpinp_lock
, refall_lock
, nve_lock
,
81 aspall_lock
, asptmo_lock
, atpall_lock
, atptmo_lock
, atpgen_lock
;
83 extern int (*sys_ATsocket
)(), (*sys_ATgetmsg
)(), (*sys_ATputmsg
)();
84 extern int (*sys_ATPsndreq
)(), (*sys_ATPsndrsp
)();
85 extern int (*sys_ATPgetreq
)(), (*sys_ATPgetrsp
)();
89 extern int _ATsocket(), _ATgetmsg(), _ATputmsg();
90 extern int _ATPsndreq(), _ATPsndrsp(), _ATPgetreq(), _ATPgetrsp();
92 sys_ATsocket
= _ATsocket
;
93 sys_ATgetmsg
= _ATgetmsg
;
94 sys_ATputmsg
= _ATputmsg
;
95 sys_ATPsndreq
= _ATPsndreq
;
96 sys_ATPsndrsp
= _ATPsndrsp
;
97 sys_ATPgetreq
= _ATPgetreq
;
98 sys_ATPgetrsp
= _ATPgetrsp
;
100 ATLOCKINIT(ddpall_lock
);
101 ATLOCKINIT(ddpinp_lock
);
102 ATLOCKINIT(arpinp_lock
);
103 ATLOCKINIT(refall_lock
);
104 ATLOCKINIT(aspall_lock
);
105 ATLOCKINIT(asptmo_lock
);
106 ATLOCKINIT(atpall_lock
);
107 ATLOCKINIT(atptmo_lock
);
108 ATLOCKINIT(atpgen_lock
);
109 ATLOCKINIT(nve_lock
);
117 this happens in adsp_open and is undone on ADSP_UNLINK
121 /* Undo everything atalk_load() did. */
122 void atalk_unload() /* not currently used */
124 extern gbuf_t
*scb_resource_m
;
125 extern gbuf_t
*atp_resource_m
;
138 if (scb_resource_m
) {
139 gbuf_freem(scb_resource_m
);
143 /* allocated in atp_trans_alloc() */
144 if (atp_resource_m
) {
145 gbuf_freem(atp_resource_m
);
147 atp_trans_free_list
= 0;
151 appletalk_inited
= 0;
154 void appletalk_hack_start()
156 if (!appletalk_inited
) {
158 atalkintrq
.ifq_maxlen
= IFQ_MAXLEN
;
159 appletalk_inited
= 1;
161 } /* appletalk_hack_start */
163 int pat_output(patp
, mlist
, dst_addr
, type
)
165 struct mbuf
*mlist
; /* packet chain */
166 unsigned char *dst_addr
;
170 llc_header_t
*llc_header
;
173 if (! patp
->aa_ifp
) {
174 for (m
= mlist
; m
; m
= mlist
) {
175 mlist
= m
->m_nextpkt
;
182 /* this is for ether_output */
183 dst
.sa_family
= AF_APPLETALK
;
184 dst
.sa_len
= 2 + sizeof(struct etalk_addr
);
185 bcopy (dst_addr
, &dst
.sa_data
[0], sizeof(struct etalk_addr
));
187 /* packet chains are used on output and can be tested using aufs */
188 for (m
= mlist
; m
; m
= mlist
) {
189 mlist
= m
->m_nextpkt
;
192 M_PREPEND(m
, sizeof(llc_header_t
), M_DONTWAIT
)
197 llc_header
= mtod(m
, llc_header_t
*);
199 (type
== AARP_AT_TYPE
) ? snap_hdr_aarp
: snap_hdr_at
;
201 for (m
->m_pkthdr
.len
= 0, m1
= m
; m1
; m1
= m1
->m_next
)
202 m
->m_pkthdr
.len
+= m1
->m_len
;
203 m
->m_pkthdr
.rcvif
= 0;
205 /* *** Note: AT is sending out mbufs of type MSG_DATA,
207 #ifdef APPLETALK_DEBUG
209 !((m
->m_next
)->m_flags
& M_EXT
))
210 kprintf("po: mlen= %d, m2len= %d\n", m
->m_len
,
213 dlil_output(patp
->at_dl_tag
, m
, NULL
, &dst
, 0);
223 struct mbuf
*m
, *m1
, *mlist
= NULL
;
226 llc_header_t
*llc_header
;
229 enet_header_t
*enet_header
;
233 IF_DEQUEUE(&atalkintrq
, m
);
239 for ( ; m
; m
= mlist
) {
240 mlist
= m
->m_nextpkt
;
241 #ifdef APPLETALK_DEBUG
242 /* packet chains are not yet in use on input */
243 if (mlist
) kprintf("atalkintr: packet chain\n");
247 if (!appletalk_inited
) {
252 if ((m
->m_flags
& M_PKTHDR
) == 0) {
253 #ifdef APPLETALK_DEBUG
254 kprintf("atalkintr: no HDR on packet received");
260 /* make sure the interface this packet was received on is configured
262 ifp
= m
->m_pkthdr
.rcvif
;
263 TAILQ_FOREACH(ifID
, &at_ifQueueHd
, aa_link
) {
264 if (ifID
->aa_ifp
&& (ifID
->aa_ifp
== ifp
))
267 /* if we didn't find a matching interface */
270 continue; /* was EAFNOSUPPORT */
273 /* make sure the entire packet header is in the current mbuf */
274 if (m
->m_len
< ENET_LLC_SIZE
&&
275 (m
= m_pullup(m
, ENET_LLC_SIZE
)) == 0) {
276 #ifdef APPLETALK_DEBUG
277 kprintf("atalkintr: packet too small\n");
282 enet_header
= mtod(m
, enet_header_t
*);
284 /* Ignore multicast packets from local station */
285 /* *** Note: code for IFTYPE_TOKENTALK may be needed here. *** */
286 if (ifID
->aa_ifp
->if_type
== IFT_ETHER
) {
287 bcopy((char *)enet_header
->src
, src
, sizeof(src
));
289 #ifdef COMMENT /* In order to receive packets from the Blue Box, we cannot
290 reject packets whose source address matches our local address.
292 if ((enet_header
->dst
[0] & 1) &&
293 (bcmp(src
, ifID
->xaddr
, sizeof(src
)) == 0)) {
294 /* Packet rejected: think it's a local mcast. */
296 continue; /* was EAFNOSUPPORT */
300 llc_header
= (llc_header_t
*)(enet_header
+1);
302 /* advance the mbuf pointers past the ethernet header */
303 m
->m_data
+= ENET_LLC_SIZE
;
304 m
->m_len
-= ENET_LLC_SIZE
;
308 if (LLC_PROTO_EQUAL(llc_header
->protocol
,snap_proto_aarp
)) {
309 (void)aarp_rcv_pkt(mtod(m
, aarp_pkt_t
*), ifID
);
312 else if (LLC_PROTO_EQUAL(llc_header
->protocol
, snap_proto_ddp
)) {
313 /* if we're a router take all pkts */
315 if (aarp_chk_addr(mtod(m
, at_ddp_t
*), ifID
)
316 == AARP_ERR_NOT_OURS
) {
317 #ifdef APPLETALK_DEBUG
318 kprintf("pat_input: Packet Rejected: not for us? dest=%x.%x.%x.%x.%x.%x LLC_PROTO= %02x%02x\n",
319 enet_header
->dst
[0], enet_header
->dst
[1],
320 enet_header
->dst
[2], enet_header
->dst
[3],
321 enet_header
->dst
[4], enet_header
->dst
[5],
322 llc_header
->protocol
[3],
323 llc_header
->protocol
[4]);
326 continue; /* was EAFNOSUPPORT */
329 MCHTYPE(m
, MSG_DATA
); /* set the mbuf type */
331 ifID
->stats
.rcv_packets
++;
332 for (m1
= m
; m1
; m1
= m1
->m_next
)
333 ifID
->stats
.rcv_bytes
+= m1
->m_len
;
336 ddp_glean(m
, ifID
, src
);
340 #ifdef APPLETALK_DEBUG
341 kprintf("pat_input: Packet Rejected: wrong LLC_PROTO = %02x%02x\n",
342 llc_header
->protocol
[3],
343 llc_header
->protocol
[4]);