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