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