]> git.saurik.com Git - apple/xnu.git/blame - bsd/netat/drv_dep.c
xnu-1228.15.4.tar.gz
[apple/xnu.git] / bsd / netat / drv_dep.c
CommitLineData
1c79356b 1/*
5d5c5d0d
A
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
1c79356b 5 *
2d21ac55
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 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.
8f6c56a5 14 *
2d21ac55
A
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
8f6c56a5
A
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2d21ac55
A
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.
8f6c56a5 25 *
2d21ac55 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b
A
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>
2d21ac55 55#include <net/dlil.h>
1c79356b 56#include <net/ethernet.h>
2d21ac55 57#include <net/kpi_protocol.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>
2d21ac55 66#include <netat/atp.h>
1c79356b
A
67#include <netat/debug.h>
68
69#define DSAP_SNAP 0xaa
70
1c79356b
A
71extern int adspInited;
72
73static llc_header_t snap_hdr_at = SNAP_HDR_AT;
74static llc_header_t snap_hdr_aarp = SNAP_HDR_AARP;
75static unsigned char snap_proto_ddp[5] = SNAP_PROTO_AT;
76static unsigned char snap_proto_aarp[5] = SNAP_PROTO_AARP;
77
91447636
A
78static void at_input_packet(protocol_family_t protocol, mbuf_t m);
79
1c79356b
A
80struct ifqueue atalkintrq; /* appletalk and aarp packet input queue */
81
82short appletalk_inited = 0;
83
2d21ac55
A
84void atalk_load(void);
85void atalk_unload(void);
1c79356b 86
2d21ac55 87extern lck_mtx_t *domain_proto_mtx;
1c79356b 88
2d21ac55 89extern int pktsIn, pktsOut;
1c79356b 90
1c79356b 91
2d21ac55
A
92void atalk_load()
93{
1c79356b
A
94 atp_init();
95 atp_link();
96 adspInited = 0;
97
98/* adsp_init();
99 for 2225395
100 this happens in adsp_open and is undone on ADSP_UNLINK
101*/
91447636 102 lck_mtx_unlock(domain_proto_mtx);
2d21ac55 103 proto_register_input(PF_APPLETALK, at_input_packet, NULL, 0);
91447636 104 lck_mtx_lock(domain_proto_mtx);
1c79356b
A
105} /* atalk_load */
106
107/* Undo everything atalk_load() did. */
108void atalk_unload() /* not currently used */
109{
1c79356b
A
110 atp_unlink();
111
112#ifdef NOT_YET
2d21ac55
A
113 {
114 extern gbuf_t *scb_resource_m;
115 extern gbuf_t *atp_resource_m;
116 if (scb_resource_m) {
117 gbuf_freem(scb_resource_m);
118 scb_resource_m = 0;
119 scb_free_list = 0;
120 }
121 /* allocated in atp_trans_alloc() */
122 if (atp_resource_m) {
123 gbuf_freem(atp_resource_m);
124 atp_resource_m = 0;
125 atp_trans_free_list = 0;
126 }
1c79356b
A
127 }
128#endif
129
130 appletalk_inited = 0;
131} /* atalk_unload */
132
2d21ac55 133void appletalk_hack_start(void)
1c79356b
A
134{
135 if (!appletalk_inited) {
136 atalk_load();
137 atalkintrq.ifq_maxlen = IFQ_MAXLEN;
138 appletalk_inited = 1;
139 }
140} /* appletalk_hack_start */
141
142int pat_output(patp, mlist, dst_addr, type)
143 at_ifaddr_t *patp;
144 struct mbuf *mlist; /* packet chain */
0c530ab8 145 unsigned char *dst_addr; /* for atalk addr - net # must be in network byte order */
1c79356b
A
146 int type;
147{
148 struct mbuf *m, *m1;
149 llc_header_t *llc_header;
150 struct sockaddr dst;
151
152 if (! patp->aa_ifp) {
153 for (m = mlist; m; m = mlist) {
154 mlist = m->m_nextpkt;
155 m->m_nextpkt = 0;
156 m_freem(m);
157 }
158 return ENOTREADY;
159 }
160
161 /* this is for ether_output */
162 dst.sa_family = AF_APPLETALK;
163 dst.sa_len = 2 + sizeof(struct etalk_addr);
164 bcopy (dst_addr, &dst.sa_data[0], sizeof(struct etalk_addr));
165
166 /* packet chains are used on output and can be tested using aufs */
167 for (m = mlist; m; m = mlist) {
168 mlist = m->m_nextpkt;
169 m->m_nextpkt = 0;
170
9bccf70c 171 M_PREPEND(m, sizeof(llc_header_t), M_DONTWAIT);
1c79356b
A
172 if (m == 0) {
173 continue;
174 }
175
176 llc_header = mtod(m, llc_header_t *);
177 *llc_header =
178 (type == AARP_AT_TYPE) ? snap_hdr_aarp : snap_hdr_at;
179
180 for (m->m_pkthdr.len = 0, m1 = m; m1; m1 = m1->m_next)
181 m->m_pkthdr.len += m1->m_len;
182 m->m_pkthdr.rcvif = 0;
183
184 /* *** Note: AT is sending out mbufs of type MSG_DATA,
185 not MT_DATA. *** */
186#ifdef APPLETALK_DEBUG
187 if (m->m_next &&
188 !((m->m_next)->m_flags & M_EXT))
189 kprintf("po: mlen= %d, m2len= %d\n", m->m_len,
190 (m->m_next)->m_len);
191#endif
91447636
A
192 atalk_unlock();
193 dlil_output(patp->aa_ifp, PF_APPLETALK, m, NULL, &dst, 0);
194 atalk_lock();
1c79356b
A
195
196 pktsOut++;
197 }
198
199 return 0;
200} /* pat_output */
201
91447636
A
202static void
203at_input_packet(
204 __unused protocol_family_t protocol,
205 mbuf_t m)
1c79356b 206{
91447636 207 struct mbuf *m1;
1c79356b 208 struct ifnet *ifp;
1c79356b
A
209 llc_header_t *llc_header;
210 at_ifaddr_t *ifID;
211 char src[6];
212 enet_header_t *enet_header;
1c79356b 213
91447636 214 if (!appletalk_inited) {
1c79356b 215 m_freem(m);
91447636
A
216 return;
217 }
1c79356b 218
91447636 219 if ((m->m_flags & M_PKTHDR) == 0) {
1c79356b 220#ifdef APPLETALK_DEBUG
91447636 221 kprintf("atalkintr: no HDR on packet received");
1c79356b
A
222#endif
223 m_freem(m);
91447636
A
224 return;
225 }
1c79356b
A
226
227 /* make sure the interface this packet was received on is configured
228 for AppleTalk */
229 ifp = m->m_pkthdr.rcvif;
230 TAILQ_FOREACH(ifID, &at_ifQueueHd, aa_link) {
231 if (ifID->aa_ifp && (ifID->aa_ifp == ifp))
232 break;
233 }
234 /* if we didn't find a matching interface */
235 if (!ifID) {
236 m_freem(m);
91447636 237 return; /* was EAFNOSUPPORT */
1c79356b
A
238 }
239
240 /* make sure the entire packet header is in the current mbuf */
241 if (m->m_len < ENET_LLC_SIZE &&
242 (m = m_pullup(m, ENET_LLC_SIZE)) == 0) {
243#ifdef APPLETALK_DEBUG
244 kprintf("atalkintr: packet too small\n");
245#endif
246 m_freem(m);
91447636 247 return;
1c79356b
A
248 }
249 enet_header = mtod(m, enet_header_t *);
250
251 /* Ignore multicast packets from local station */
252 /* *** Note: code for IFTYPE_TOKENTALK may be needed here. *** */
91447636
A
253 if (ifID->aa_ifp->if_type == IFT_ETHER ||
254 ifID->aa_ifp->if_type == IFT_L2VLAN ||
255 ifID->aa_ifp->if_type == IFT_IEEE8023ADLAG) {
1c79356b
A
256 bcopy((char *)enet_header->src, src, sizeof(src));
257
258#ifdef COMMENT /* In order to receive packets from the Blue Box, we cannot
259 reject packets whose source address matches our local address.
260 */
261 if ((enet_header->dst[0] & 1) &&
262 (bcmp(src, ifID->xaddr, sizeof(src)) == 0)) {
263 /* Packet rejected: think it's a local mcast. */
264 m_freem(m);
91447636 265 return; /* was EAFNOSUPPORT */
1c79356b 266 }
55e303ae 267#endif /* COMMENT */
1c79356b
A
268
269 llc_header = (llc_header_t *)(enet_header+1);
270
271 /* advance the mbuf pointers past the ethernet header */
272 m->m_data += ENET_LLC_SIZE;
273 m->m_len -= ENET_LLC_SIZE;
274
275 pktsIn++;
276
277 if (LLC_PROTO_EQUAL(llc_header->protocol,snap_proto_aarp)) {
278 (void)aarp_rcv_pkt(mtod(m, aarp_pkt_t *), ifID);
279 m_freem(m);
280 }
281 else if (LLC_PROTO_EQUAL(llc_header->protocol, snap_proto_ddp)) {
282 /* if we're a router take all pkts */
283 if (!ROUTING_MODE) {
284 if (aarp_chk_addr(mtod(m, at_ddp_t *), ifID)
285 == AARP_ERR_NOT_OURS) {
286#ifdef APPLETALK_DEBUG
287 kprintf("pat_input: Packet Rejected: not for us? dest=%x.%x.%x.%x.%x.%x LLC_PROTO= %02x%02x\n",
288 enet_header->dst[0], enet_header->dst[1],
289 enet_header->dst[2], enet_header->dst[3],
290 enet_header->dst[4], enet_header->dst[5],
291 llc_header->protocol[3],
292 llc_header->protocol[4]);
293#endif
294 m_freem(m);
91447636 295 return; /* was EAFNOSUPPORT */
1c79356b
A
296 }
297 }
298 MCHTYPE(m, MSG_DATA); /* set the mbuf type */
299
300 ifID->stats.rcv_packets++;
301 for (m1 = m; m1; m1 = m1->m_next)
302 ifID->stats.rcv_bytes += m1->m_len;
303
304 if (!MULTIPORT_MODE)
2d21ac55 305 ddp_glean(m, ifID, (struct etalk_addr *)src);
1c79356b
A
306
307 ddp_input(m, ifID);
308 } else {
309#ifdef APPLETALK_DEBUG
310 kprintf("pat_input: Packet Rejected: wrong LLC_PROTO = %02x%02x\n",
311 llc_header->protocol[3],
312 llc_header->protocol[4]);
313#endif
314 m_freem(m);
315 }
1c79356b 316 }
91447636 317}