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