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