|
|
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.