|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
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.
11: *
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
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
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.
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>
49: #include <net/etherdefs.h>
50: #include <net/ethernet.h>
51: #include <net/tokendefs.h>
52:
53: #include <netat/sysglue.h>
54: #include <netat/appletalk.h>
55: #include <netat/at_pcb.h>
56: #include <netat/at_var.h>
57: #include <netat/ddp.h>
58: #include <netat/at_aarp.h>
59: #include <netat/at_pat.h>
60: #include <netat/debug.h>
61:
62: #define DSAP_SNAP 0xaa
63:
64: extern void gref_init(), atp_init(), atp_link(), atp_unlink();
65:
66: extern int adspInited;
67:
68: static llc_header_t snap_hdr_at = SNAP_HDR_AT;
69: static llc_header_t snap_hdr_aarp = SNAP_HDR_AARP;
70: static unsigned char snap_proto_ddp[5] = SNAP_PROTO_AT;
71: static unsigned char snap_proto_aarp[5] = SNAP_PROTO_AARP;
72:
73: int pktsIn, pktsOut;
74:
75: struct ifqueue atalkintrq; /* appletalk and aarp packet input queue */
76:
77: short appletalk_inited = 0;
78:
79: extern atlock_t
80: ddpall_lock, ddpinp_lock, arpinp_lock, refall_lock, nve_lock,
81: aspall_lock, asptmo_lock, atpall_lock, atptmo_lock, atpgen_lock;
82:
83: extern int (*sys_ATsocket )(), (*sys_ATgetmsg)(), (*sys_ATputmsg)();
84: extern int (*sys_ATPsndreq)(), (*sys_ATPsndrsp)();
85: extern int (*sys_ATPgetreq)(), (*sys_ATPgetrsp)();
86:
87: void atalk_load()
88: {
89: extern int _ATsocket(), _ATgetmsg(), _ATputmsg();
90: extern int _ATPsndreq(), _ATPsndrsp(), _ATPgetreq(), _ATPgetrsp();
91:
92: sys_ATsocket = _ATsocket;
93: sys_ATgetmsg = _ATgetmsg;
94: sys_ATputmsg = _ATputmsg;
95: sys_ATPsndreq = _ATPsndreq;
96: sys_ATPsndrsp = _ATPsndrsp;
97: sys_ATPgetreq = _ATPgetreq;
98: sys_ATPgetrsp = _ATPgetrsp;
99:
100: ATLOCKINIT(ddpall_lock);
101: ATLOCKINIT(ddpinp_lock);
102: ATLOCKINIT(arpinp_lock);
103: ATLOCKINIT(refall_lock);
104: ATLOCKINIT(aspall_lock);
105: ATLOCKINIT(asptmo_lock);
106: ATLOCKINIT(atpall_lock);
107: ATLOCKINIT(atptmo_lock);
108: ATLOCKINIT(atpgen_lock);
109: ATLOCKINIT(nve_lock);
110:
111: atp_init();
112: atp_link();
113: adspInited = 0;
114:
115: /* adsp_init();
116: for 2225395
117: this happens in adsp_open and is undone on ADSP_UNLINK
118: */
119: } /* atalk_load */
120:
121: /* Undo everything atalk_load() did. */
122: void atalk_unload() /* not currently used */
123: {
124: extern gbuf_t *scb_resource_m;
125: extern gbuf_t *atp_resource_m;
126:
127: sys_ATsocket = 0;
128: sys_ATgetmsg = 0;
129: sys_ATputmsg = 0;
130: sys_ATPsndreq = 0;
131: sys_ATPsndrsp = 0;
132: sys_ATPgetreq = 0;
133: sys_ATPgetrsp = 0;
134:
135: atp_unlink();
136:
137: #ifdef NOT_YET
138: if (scb_resource_m) {
139: gbuf_freem(scb_resource_m);
140: scb_resource_m = 0;
141: scb_free_list = 0;
142: }
143: /* allocated in atp_trans_alloc() */
144: if (atp_resource_m) {
145: gbuf_freem(atp_resource_m);
146: atp_resource_m = 0;
147: atp_trans_free_list = 0;
148: }
149: #endif
150:
151: appletalk_inited = 0;
152: } /* atalk_unload */
153:
154: void appletalk_hack_start()
155: {
156: if (!appletalk_inited) {
157: atalk_load();
158: atalkintrq.ifq_maxlen = IFQ_MAXLEN;
159: appletalk_inited = 1;
160: }
161: } /* appletalk_hack_start */
162:
163: int pat_output(patp, mlist, dst_addr, type)
164: at_ifaddr_t *patp;
165: struct mbuf *mlist; /* packet chain */
166: unsigned char *dst_addr;
167: int type;
168: {
169: struct mbuf *m, *m1;
170: llc_header_t *llc_header;
171: struct sockaddr dst;
172:
173: if (! patp->aa_ifp) {
174: for (m = mlist; m; m = mlist) {
175: mlist = m->m_nextpkt;
176: m->m_nextpkt = 0;
177: m_freem(m);
178: }
179: return ENOTREADY;
180: }
181:
182: /* this is for ether_output */
183: dst.sa_family = AF_APPLETALK;
184: dst.sa_len = 2 + sizeof(struct etalk_addr);
185: bcopy (dst_addr, &dst.sa_data[0], sizeof(struct etalk_addr));
186:
187: /* packet chains are used on output and can be tested using aufs */
188: for (m = mlist; m; m = mlist) {
189: mlist = m->m_nextpkt;
190: m->m_nextpkt = 0;
191:
192: M_PREPEND(m, sizeof(llc_header_t), M_DONTWAIT)
193: if (m == 0) {
194: continue;
195: }
196:
197: llc_header = mtod(m, llc_header_t *);
198: *llc_header =
199: (type == AARP_AT_TYPE) ? snap_hdr_aarp : snap_hdr_at;
200:
201: for (m->m_pkthdr.len = 0, m1 = m; m1; m1 = m1->m_next)
202: m->m_pkthdr.len += m1->m_len;
203: m->m_pkthdr.rcvif = 0;
204:
205: /* *** Note: AT is sending out mbufs of type MSG_DATA,
206: not MT_DATA. *** */
207: #ifdef APPLETALK_DEBUG
208: if (m->m_next &&
209: !((m->m_next)->m_flags & M_EXT))
210: kprintf("po: mlen= %d, m2len= %d\n", m->m_len,
211: (m->m_next)->m_len);
212: #endif
213: dlil_output(patp->at_dl_tag, m, NULL, &dst, 0);
214:
215: pktsOut++;
216: }
217:
218: return 0;
219: } /* pat_output */
220:
221: void atalkintr()
222: {
223: struct mbuf *m, *m1, *mlist = NULL;
224: struct ifnet *ifp;
225: int s;
226: llc_header_t *llc_header;
227: at_ifaddr_t *ifID;
228: char src[6];
229: enet_header_t *enet_header;
230:
231: next:
232: s = splimp();
233: IF_DEQUEUE(&atalkintrq, m);
234: splx(s);
235:
236: if (m == 0)
237: return;
238:
239: for ( ; m ; m = mlist) {
240: mlist = m->m_nextpkt;
241: #ifdef APPLETALK_DEBUG
242: /* packet chains are not yet in use on input */
243: if (mlist) kprintf("atalkintr: packet chain\n");
244: #endif
245: m->m_nextpkt = 0;
246:
247: if (!appletalk_inited) {
248: m_freem(m);
249: continue;
250: }
251:
252: if ((m->m_flags & M_PKTHDR) == 0) {
253: #ifdef APPLETALK_DEBUG
254: kprintf("atalkintr: no HDR on packet received");
255: #endif
256: m_freem(m);
257: continue;
258: }
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);
270: continue; /* was EAFNOSUPPORT */
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);
280: continue;
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. *** */
286: if (ifID->aa_ifp->if_type == IFT_ETHER) {
287: bcopy((char *)enet_header->src, src, sizeof(src));
288:
289: #ifdef COMMENT /* In order to receive packets from the Blue Box, we cannot
290: reject packets whose source address matches our local address.
291: */
292: if ((enet_header->dst[0] & 1) &&
293: (bcmp(src, ifID->xaddr, sizeof(src)) == 0)) {
294: /* Packet rejected: think it's a local mcast. */
295: m_freem(m);
296: continue; /* was EAFNOSUPPORT */
297: }
298: #endif COMMENT
299:
300: llc_header = (llc_header_t *)(enet_header+1);
301:
302: /* advance the mbuf pointers past the ethernet header */
303: m->m_data += ENET_LLC_SIZE;
304: m->m_len -= ENET_LLC_SIZE;
305:
306: pktsIn++;
307:
308: if (LLC_PROTO_EQUAL(llc_header->protocol,snap_proto_aarp)) {
309: (void)aarp_rcv_pkt(mtod(m, aarp_pkt_t *), ifID);
310: m_freem(m);
311: }
312: else if (LLC_PROTO_EQUAL(llc_header->protocol, snap_proto_ddp)) {
313: /* if we're a router take all pkts */
314: if (!ROUTING_MODE) {
315: if (aarp_chk_addr(mtod(m, at_ddp_t *), ifID)
316: == AARP_ERR_NOT_OURS) {
317: #ifdef APPLETALK_DEBUG
318: kprintf("pat_input: Packet Rejected: not for us? dest=%x.%x.%x.%x.%x.%x LLC_PROTO= %02x%02x\n",
319: enet_header->dst[0], enet_header->dst[1],
320: enet_header->dst[2], enet_header->dst[3],
321: enet_header->dst[4], enet_header->dst[5],
322: llc_header->protocol[3],
323: llc_header->protocol[4]);
324: #endif
325: m_freem(m);
326: continue; /* was EAFNOSUPPORT */
327: }
328: }
329: MCHTYPE(m, MSG_DATA); /* set the mbuf type */
330:
331: ifID->stats.rcv_packets++;
332: for (m1 = m; m1; m1 = m1->m_next)
333: ifID->stats.rcv_bytes += m1->m_len;
334:
335: if (!MULTIPORT_MODE)
336: ddp_glean(m, ifID, src);
337:
338: ddp_input(m, ifID);
339: } else {
340: #ifdef APPLETALK_DEBUG
341: kprintf("pat_input: Packet Rejected: wrong LLC_PROTO = %02x%02x\n",
342: llc_header->protocol[3],
343: llc_header->protocol[4]);
344: #endif
345: m_freem(m);
346: }
347: }
348: }
349: goto next;
350: } /* atalkintr */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.