]> git.saurik.com Git - apple/xnu.git/blame - bsd/netat/drv_dep.c
xnu-517.3.15.tar.gz
[apple/xnu.git] / bsd / netat / drv_dep.c
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
43866e37 6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
1c79356b 7 *
43866e37
A
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
13 * file.
14 *
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
1c79356b
A
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
43866e37
A
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.
1c79356b
A
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25/*
26 * Copyright 1994 Apple Computer, Inc.
27 * All Rights Reserved.
28 *
29 * Tuyen A. Nguyen. (December 5, 1994)
30 * Modified, March 17, 1997 by Tuyen Nguyen for MacOSX.
31 */
32
33#include <sys/errno.h>
34#include <sys/types.h>
35#include <sys/param.h>
36#include <machine/spl.h>
37#include <sys/systm.h>
38#include <sys/kernel.h>
39#include <sys/proc.h>
40#include <sys/filedesc.h>
41#include <sys/fcntl.h>
42#include <sys/mbuf.h>
43#include <sys/ioctl.h>
44#include <sys/malloc.h>
45#include <sys/socket.h>
46#include <sys/socketvar.h>
47#include <sys/sockio.h>
48
49#include <net/if.h>
50#include <net/if_types.h>
51#include <net/if_dl.h>
1c79356b 52#include <net/ethernet.h>
1c79356b
A
53
54#include <netat/sysglue.h>
55#include <netat/appletalk.h>
56#include <netat/at_pcb.h>
57#include <netat/at_var.h>
58#include <netat/ddp.h>
59#include <netat/at_aarp.h>
60#include <netat/at_pat.h>
61#include <netat/debug.h>
62
63#define DSAP_SNAP 0xaa
64
65extern void gref_init(), atp_init(), atp_link(), atp_unlink();
66
67extern int adspInited;
68
69static llc_header_t snap_hdr_at = SNAP_HDR_AT;
70static llc_header_t snap_hdr_aarp = SNAP_HDR_AARP;
71static unsigned char snap_proto_ddp[5] = SNAP_PROTO_AT;
72static unsigned char snap_proto_aarp[5] = SNAP_PROTO_AARP;
73
74int pktsIn, pktsOut;
75
76struct ifqueue atalkintrq; /* appletalk and aarp packet input queue */
77
78short appletalk_inited = 0;
79
80extern atlock_t
81 ddpall_lock, ddpinp_lock, arpinp_lock, refall_lock, nve_lock,
82 aspall_lock, asptmo_lock, atpall_lock, atptmo_lock, atpgen_lock;
83
84extern int (*sys_ATsocket )(), (*sys_ATgetmsg)(), (*sys_ATputmsg)();
85extern int (*sys_ATPsndreq)(), (*sys_ATPsndrsp)();
86extern int (*sys_ATPgetreq)(), (*sys_ATPgetrsp)();
87
88void atalk_load()
89{
90 extern int _ATsocket(), _ATgetmsg(), _ATputmsg();
91 extern int _ATPsndreq(), _ATPsndrsp(), _ATPgetreq(), _ATPgetrsp();
92
93 sys_ATsocket = _ATsocket;
94 sys_ATgetmsg = _ATgetmsg;
95 sys_ATputmsg = _ATputmsg;
96 sys_ATPsndreq = _ATPsndreq;
97 sys_ATPsndrsp = _ATPsndrsp;
98 sys_ATPgetreq = _ATPgetreq;
99 sys_ATPgetrsp = _ATPgetrsp;
100
101 ATLOCKINIT(ddpall_lock);
102 ATLOCKINIT(ddpinp_lock);
103 ATLOCKINIT(arpinp_lock);
104 ATLOCKINIT(refall_lock);
105 ATLOCKINIT(aspall_lock);
106 ATLOCKINIT(asptmo_lock);
107 ATLOCKINIT(atpall_lock);
108 ATLOCKINIT(atptmo_lock);
109 ATLOCKINIT(atpgen_lock);
110 ATLOCKINIT(nve_lock);
111
112 atp_init();
113 atp_link();
114 adspInited = 0;
115
116/* adsp_init();
117 for 2225395
118 this happens in adsp_open and is undone on ADSP_UNLINK
119*/
120} /* atalk_load */
121
122/* Undo everything atalk_load() did. */
123void atalk_unload() /* not currently used */
124{
125 extern gbuf_t *scb_resource_m;
126 extern gbuf_t *atp_resource_m;
127
128 sys_ATsocket = 0;
129 sys_ATgetmsg = 0;
130 sys_ATputmsg = 0;
131 sys_ATPsndreq = 0;
132 sys_ATPsndrsp = 0;
133 sys_ATPgetreq = 0;
134 sys_ATPgetrsp = 0;
135
136 atp_unlink();
137
138#ifdef NOT_YET
139 if (scb_resource_m) {
140 gbuf_freem(scb_resource_m);
141 scb_resource_m = 0;
142 scb_free_list = 0;
143 }
144 /* allocated in atp_trans_alloc() */
145 if (atp_resource_m) {
146 gbuf_freem(atp_resource_m);
147 atp_resource_m = 0;
148 atp_trans_free_list = 0;
149 }
150#endif
151
152 appletalk_inited = 0;
153} /* atalk_unload */
154
155void appletalk_hack_start()
156{
157 if (!appletalk_inited) {
158 atalk_load();
159 atalkintrq.ifq_maxlen = IFQ_MAXLEN;
160 appletalk_inited = 1;
161 }
162} /* appletalk_hack_start */
163
164int pat_output(patp, mlist, dst_addr, type)
165 at_ifaddr_t *patp;
166 struct mbuf *mlist; /* packet chain */
167 unsigned char *dst_addr;
168 int type;
169{
170 struct mbuf *m, *m1;
171 llc_header_t *llc_header;
172 struct sockaddr dst;
173
174 if (! patp->aa_ifp) {
175 for (m = mlist; m; m = mlist) {
176 mlist = m->m_nextpkt;
177 m->m_nextpkt = 0;
178 m_freem(m);
179 }
180 return ENOTREADY;
181 }
182
183 /* this is for ether_output */
184 dst.sa_family = AF_APPLETALK;
185 dst.sa_len = 2 + sizeof(struct etalk_addr);
186 bcopy (dst_addr, &dst.sa_data[0], sizeof(struct etalk_addr));
187
188 /* packet chains are used on output and can be tested using aufs */
189 for (m = mlist; m; m = mlist) {
190 mlist = m->m_nextpkt;
191 m->m_nextpkt = 0;
192
9bccf70c 193 M_PREPEND(m, sizeof(llc_header_t), M_DONTWAIT);
1c79356b
A
194 if (m == 0) {
195 continue;
196 }
197
198 llc_header = mtod(m, llc_header_t *);
199 *llc_header =
200 (type == AARP_AT_TYPE) ? snap_hdr_aarp : snap_hdr_at;
201
202 for (m->m_pkthdr.len = 0, m1 = m; m1; m1 = m1->m_next)
203 m->m_pkthdr.len += m1->m_len;
204 m->m_pkthdr.rcvif = 0;
205
206 /* *** Note: AT is sending out mbufs of type MSG_DATA,
207 not MT_DATA. *** */
208#ifdef APPLETALK_DEBUG
209 if (m->m_next &&
210 !((m->m_next)->m_flags & M_EXT))
211 kprintf("po: mlen= %d, m2len= %d\n", m->m_len,
212 (m->m_next)->m_len);
213#endif
214 dlil_output(patp->at_dl_tag, m, NULL, &dst, 0);
215
216 pktsOut++;
217 }
218
219 return 0;
220} /* pat_output */
221
222void atalkintr()
223{
224 struct mbuf *m, *m1, *mlist = NULL;
225 struct ifnet *ifp;
226 int s;
227 llc_header_t *llc_header;
228 at_ifaddr_t *ifID;
229 char src[6];
230 enet_header_t *enet_header;
231
232next:
233 s = splimp();
234 IF_DEQUEUE(&atalkintrq, m);
235 splx(s);
236
237 if (m == 0)
238 return;
239
240 for ( ; m ; m = mlist) {
241 mlist = m->m_nextpkt;
242#ifdef APPLETALK_DEBUG
243 /* packet chains are not yet in use on input */
244 if (mlist) kprintf("atalkintr: packet chain\n");
245#endif
246 m->m_nextpkt = 0;
247
248 if (!appletalk_inited) {
249 m_freem(m);
250 continue;
251 }
252
253 if ((m->m_flags & M_PKTHDR) == 0) {
254#ifdef APPLETALK_DEBUG
255 kprintf("atalkintr: no HDR on packet received");
256#endif
257 m_freem(m);
258 continue;
259 }
260
261 /* make sure the interface this packet was received on is configured
262 for AppleTalk */
263 ifp = m->m_pkthdr.rcvif;
264 TAILQ_FOREACH(ifID, &at_ifQueueHd, aa_link) {
265 if (ifID->aa_ifp && (ifID->aa_ifp == ifp))
266 break;
267 }
268 /* if we didn't find a matching interface */
269 if (!ifID) {
270 m_freem(m);
271 continue; /* was EAFNOSUPPORT */
272 }
273
274 /* make sure the entire packet header is in the current mbuf */
275 if (m->m_len < ENET_LLC_SIZE &&
276 (m = m_pullup(m, ENET_LLC_SIZE)) == 0) {
277#ifdef APPLETALK_DEBUG
278 kprintf("atalkintr: packet too small\n");
279#endif
280 m_freem(m);
281 continue;
282 }
283 enet_header = mtod(m, enet_header_t *);
284
285 /* Ignore multicast packets from local station */
286 /* *** Note: code for IFTYPE_TOKENTALK may be needed here. *** */
287 if (ifID->aa_ifp->if_type == IFT_ETHER) {
288 bcopy((char *)enet_header->src, src, sizeof(src));
289
290#ifdef COMMENT /* In order to receive packets from the Blue Box, we cannot
291 reject packets whose source address matches our local address.
292 */
293 if ((enet_header->dst[0] & 1) &&
294 (bcmp(src, ifID->xaddr, sizeof(src)) == 0)) {
295 /* Packet rejected: think it's a local mcast. */
296 m_freem(m);
297 continue; /* was EAFNOSUPPORT */
298 }
55e303ae 299#endif /* COMMENT */
1c79356b
A
300
301 llc_header = (llc_header_t *)(enet_header+1);
302
303 /* advance the mbuf pointers past the ethernet header */
304 m->m_data += ENET_LLC_SIZE;
305 m->m_len -= ENET_LLC_SIZE;
306
307 pktsIn++;
308
309 if (LLC_PROTO_EQUAL(llc_header->protocol,snap_proto_aarp)) {
310 (void)aarp_rcv_pkt(mtod(m, aarp_pkt_t *), ifID);
311 m_freem(m);
312 }
313 else if (LLC_PROTO_EQUAL(llc_header->protocol, snap_proto_ddp)) {
314 /* if we're a router take all pkts */
315 if (!ROUTING_MODE) {
316 if (aarp_chk_addr(mtod(m, at_ddp_t *), ifID)
317 == AARP_ERR_NOT_OURS) {
318#ifdef APPLETALK_DEBUG
319 kprintf("pat_input: Packet Rejected: not for us? dest=%x.%x.%x.%x.%x.%x LLC_PROTO= %02x%02x\n",
320 enet_header->dst[0], enet_header->dst[1],
321 enet_header->dst[2], enet_header->dst[3],
322 enet_header->dst[4], enet_header->dst[5],
323 llc_header->protocol[3],
324 llc_header->protocol[4]);
325#endif
326 m_freem(m);
327 continue; /* was EAFNOSUPPORT */
328 }
329 }
330 MCHTYPE(m, MSG_DATA); /* set the mbuf type */
331
332 ifID->stats.rcv_packets++;
333 for (m1 = m; m1; m1 = m1->m_next)
334 ifID->stats.rcv_bytes += m1->m_len;
335
336 if (!MULTIPORT_MODE)
337 ddp_glean(m, ifID, src);
338
339 ddp_input(m, ifID);
340 } else {
341#ifdef APPLETALK_DEBUG
342 kprintf("pat_input: Packet Rejected: wrong LLC_PROTO = %02x%02x\n",
343 llc_header->protocol[3],
344 llc_header->protocol[4]);
345#endif
346 m_freem(m);
347 }
348 }
349 }
350 goto next;
351} /* atalkintr */