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