|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* ! 26: * Copyright 1994 Apple Computer, Inc. ! 27: * All Rights Reserved. ! 28: * ! 29: * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF APPLE COMPUTER, INC. ! 30: * The copyright notice above does not evidence any actual or ! 31: * intended publication of such source code. ! 32: * ! 33: */ ! 34: ! 35: #include <localglue.h> ! 36: #include <sysglue.h> ! 37: #include <at/appletalk.h> ! 38: #include <at/elap.h> ! 39: #include <at/at_lap.h> ! 40: #include <atlog.h> ! 41: #include <lap.h> ! 42: #include <at_elap.h> ! 43: #include <at_aarp.h> ! 44: #include <at_pat.h> ! 45: #include <routing_tables.h> ! 46: ! 47: #include <sys/socket.h> ! 48: #include <sys/socketvar.h> ! 49: #include <sys/sockio.h> ! 50: #include <net/if.h> ! 51: #include <net/if_dl.h> ! 52: #include <net/etherdefs.h> ! 53: #include <net/tokendefs.h> ! 54: ! 55: #define DSAP_SNAP 0xaa ! 56: ! 57: extern at_state_t *at_statep; ! 58: extern elap_specifics_t elap_specifics[]; ! 59: ! 60: static llc_header_t snap_hdr_at = SNAP_HDR_AT; ! 61: static llc_header_t snap_hdr_aarp = SNAP_HDR_AARP; ! 62: static unsigned char snap_proto_ddp[5] = SNAP_PROTO_AT; ! 63: static unsigned char snap_proto_aarp[5] = SNAP_PROTO_AARP; ! 64: /* static struct etalk_addr etalk_mcast_base = ! 65: {0x09,0x00,0x07,0x00,0x00,0x00}; *** not used *** ! 66: */ ! 67: int pktsIn, pktsOut; ! 68: int xpatcnt = 0; ! 69: ! 70: extern pat_unit_t pat_units[]; ! 71: ! 72: #ifndef _AIX ! 73: ! 74: /* struct ifnet atalkif[1]; *** not used *** */ ! 75: struct ifqueue atalkintrq; /* appletalk and aarp packet input queue */ ! 76: ! 77: /* xxdevcnt, xxtype, xxnddp tables are no longer needed since the ifp's ! 78: are being initialized as a result of actions taken by the drivers. ! 79: There was a bug in which "xxnddp" was indexed by count in one place, ! 80: and unit in another place. However upon closer examination we ! 81: determined that "xxnddp" is no longer needed. ! 82: Annette DeSchon ([email protected]) 11/20/97 ! 83: */ ! 84: ! 85: short appletalk_inited = 0; ! 86: ! 87: #define FETCH_AND_ADD(x,y) (*x += y) ! 88: ! 89: ! 90: extern int (*sys_ATsocket )(), (*sys_ATgetmsg)(), (*sys_ATputmsg)(); ! 91: extern int (*sys_ATPsndreq)(), (*sys_ATPsndrsp)(); ! 92: extern int (*sys_ATPgetreq)(), (*sys_ATPgetrsp)(); ! 93: ! 94: void atalk_load() ! 95: { ! 96: extern int _ATsocket(), _ATgetmsg(), _ATputmsg(); ! 97: extern int _ATPsndreq(), _ATPsndrsp(), _ATPgetreq(), _ATPgetrsp(); ! 98: ! 99: extern atlock_t ddpall_lock; ! 100: extern atlock_t ddpinp_lock; ! 101: extern atlock_t arpinp_lock; ! 102: ! 103: sys_ATsocket = _ATsocket; ! 104: sys_ATgetmsg = _ATgetmsg; ! 105: sys_ATputmsg = _ATputmsg; ! 106: sys_ATPsndreq = _ATPsndreq; ! 107: sys_ATPsndrsp = _ATPsndrsp; ! 108: sys_ATPgetreq = _ATPgetreq; ! 109: sys_ATPgetrsp = _ATPgetrsp; ! 110: ! 111: xpatcnt = 0; ! 112: ATLOCKINIT(ddpall_lock); ! 113: ATLOCKINIT(ddpinp_lock); ! 114: ATLOCKINIT(arpinp_lock); ! 115: gref_init(); ! 116: atp_init(); ! 117: /* adsp_init(); ! 118: for 2225395 ! 119: this happens in adsp_open and is undone on ADSP_UNLINK ! 120: */ ! 121: } /* atalk_load */ ! 122: ! 123: void atalk_unload() /* not currently used */ ! 124: { ! 125: extern gbuf_t *scb_resource_m; ! 126: extern gbuf_t *atp_resource_m; ! 127: ! 128: sys_ATsocket = 0; ! 129: sys_ATgetmsg = 0; ! 130: sys_ATputmsg = 0; ! 131: sys_ATPsndreq = 0; ! 132: sys_ATPsndrsp = 0; ! 133: sys_ATPgetreq = 0; ! 134: sys_ATPgetrsp = 0; ! 135: ! 136: if (scb_resource_m) { ! 137: gbuf_freem(scb_resource_m); ! 138: scb_resource_m = 0; ! 139: } ! 140: if (atp_resource_m) { ! 141: gbuf_freem(atp_resource_m); ! 142: atp_resource_m = 0; ! 143: } ! 144: /* CleanupGlobals() ! 145: this happens on ADSP_UNLINK for 2225395 */ ! 146: appletalk_inited = 0; ! 147: } /* atalk_unload */ ! 148: ! 149: void appletalk_hack_start(nddp) ! 150: struct ifnet *nddp; ! 151: { ! 152: if (!appletalk_inited) { ! 153: appletalk_inited =1 ; ! 154: atalk_load(); ! 155: atalkintrq.ifq_maxlen = IFQ_MAXLEN; ! 156: } ! 157: ! 158: /* Call to pat_attach(nddp) and the "xx" tables are no longer ! 159: needed since the ifp's are being initialized as a result ! 160: of actions taken by the drivers. AD 11/21/97 */ ! 161: } /* appletalk_hack_start */ ! 162: ! 163: /* return the unit number of this interface ! 164: return -1 if the interface is not found ! 165: */ ! 166: /* int pat_ifpresent(name) *** not used *** ! 167: char *name; ! 168: { ! 169: struct ifnet *ifp; ! 170: ! 171: if (ifp = (ifunit(name))) ! 172: return(ifp->if_unit); ! 173: else ! 174: return(-1); ! 175: } ! 176: */ ! 177: ! 178: int ! 179: pat_output(pat_id, mlist, dst_addr, type) ! 180: int pat_id; ! 181: gbuf_t *mlist; ! 182: unsigned char *dst_addr; ! 183: int type; ! 184: { ! 185: pat_unit_t *patp; ! 186: gbuf_t *m, *m_prev, *new_mlist; ! 187: llc_header_t *llc_header; ! 188: ! 189: struct sockaddr dst; ! 190: ! 191: /* this is for ether_output */ ! 192: ! 193: dst.sa_family = AF_APPLETALK; ! 194: dst.sa_len = sizeof(struct etalk_addr); ! 195: bcopy (dst_addr, &dst.sa_data[0], dst.sa_len); ! 196: patp = (pat_unit_t *)&pat_units[pat_id]; ! 197: if (patp->state != PAT_ONLINE) { ! 198: gbuf_freel(mlist); ! 199: return ENOTREADY; ! 200: } ! 201: ! 202: if (patp->xtype == IFTYPE_NULLTALK) { ! 203: gbuf_freel(mlist); ! 204: return 0; ! 205: } ! 206: new_mlist = 0; ! 207: ! 208: for (m = mlist; m; m = mlist) { ! 209: mlist = gbuf_next(m); ! 210: gbuf_next(m) = 0; ! 211: ! 212: gbuf_prepend(m,sizeof(llc_header_t)); ! 213: if (m == 0) { ! 214: if (mlist) ! 215: gbuf_freel(mlist); ! 216: if (new_mlist) ! 217: gbuf_freel(new_mlist); ! 218: return 0; ! 219: } ! 220: ! 221: llc_header = (llc_header_t *)gbuf_rptr(m); ! 222: *llc_header = (type == AARP_AT_TYPE) ? snap_hdr_aarp : snap_hdr_at; ! 223: ! 224: m->m_pkthdr.len = gbuf_msgsize(m); ! 225: m->m_pkthdr.rcvif = 0; ! 226: ! 227: if (new_mlist) ! 228: gbuf_next(m_prev) = m; ! 229: else ! 230: new_mlist = m; ! 231: m_prev = m; ! 232: pktsOut++; ! 233: } ! 234: ! 235: while ((m = new_mlist) != 0) { ! 236: new_mlist = gbuf_next(m); ! 237: gbuf_next(m) = 0; ! 238: ((struct ifnet *)patp->nddp)->if_output((void *)patp->nddp, m, &dst, NULL); ! 239: } ! 240: ! 241: return 0; ! 242: } /* pat_output */ ! 243: ! 244: int ! 245: pat_online (ifName, ifType) ! 246: char *ifName; ! 247: char *ifType; ! 248: { ! 249: /*###int pat_input();*/ ! 250: int pat_id; ! 251: pat_unit_t *patp; ! 252: register struct ifaddr *ifa; ! 253: register struct sockaddr_dl *sdl; ! 254: struct ifnet *nddp; ! 255: ! 256: if ((pat_id = pat_ID(ifName)) == -1) ! 257: return (-1); ! 258: patp = &pat_units[pat_id]; ! 259: ! 260: if (patp->xtype == IFTYPE_ETHERTALK) { ! 261: if ((nddp = ifunit(ifName)) == NULL) ! 262: return -1; ! 263: } else if (patp->xtype == IFTYPE_NULLTALK) { ! 264: patp->xaddrlen = 6; ! 265: bzero(patp->xaddr, patp->xaddrlen); ! 266: if (ifType) ! 267: *ifType = patp->xtype; ! 268: patp->nddp = (void *)0; ! 269: patp->state = PAT_ONLINE; ! 270: at_statep->flags |= AT_ST_IF_CHANGED; ! 271: return (pat_id); ! 272: } else ! 273: return -1; ! 274: ! 275: /*###********* No need to declare ourself as an if for now ! 276: if_attach(NULL, pat_input, 0, 0, 0, ! 277: if_name((void *)nddp), if_unit((void *)nddp), "AppleTalk", ! 278: 622, IFF_BROADCAST, NETIFCLASS_VIRTUAL, 0); ! 279: */ ! 280: ! 281: /* if_control((void *)nddp, IFCONTROL_GETADDR, patp->xaddr); */ ! 282: ! 283: for (ifa = nddp->if_addrlist; ifa; ifa = ifa->ifa_next) ! 284: if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) && ! 285: (sdl->sdl_family == AF_LINK)) { ! 286: bcopy(LLADDR(sdl), patp->xaddr, 6); ! 287: #ifdef APPLETALK_DEBUG ! 288: kprintf("pat_online: our local enet address is=%s\n", ! 289: ether_sprintf(patp->xaddr)); ! 290: #endif ! 291: break; ! 292: } ! 293: ! 294: patp->xaddrlen = 6; ! 295: ! 296: if (ifType) ! 297: *ifType = patp->xtype; ! 298: ! 299: patp->nddp = (void *)nddp; ! 300: patp->state = PAT_ONLINE; ! 301: at_statep->flags |= AT_ST_IF_CHANGED; ! 302: ! 303: return (pat_id); ! 304: } /* pat_online */ ! 305: ! 306: void ! 307: pat_offline(pat_id) ! 308: int pat_id; ! 309: { ! 310: pat_unit_t *patp = &pat_units[pat_id]; ! 311: ! 312: if (patp->state == PAT_ONLINE) { ! 313: /*##### ! 314: if (patp->xtype != IFTYPE_NULLTALK) { ! 315: ! 316: if_detach((void *)patp->nddp); ! 317: } ! 318: */ ! 319: at_statep->flags |= AT_ST_IF_CHANGED; ! 320: bzero(patp, sizeof(pat_unit_t)); ! 321: } ! 322: } /* pat_offline */ ! 323: ! 324: int ! 325: pat_mcast(pat_id, control, data) ! 326: int pat_id; ! 327: int control; ! 328: unsigned char *data; ! 329: { ! 330: struct ifnet *nddp; ! 331: struct ifreq request; ! 332: ! 333: /* this is for ether_output */ ! 334: ! 335: request.ifr_addr.sa_family = AF_UNSPEC; ! 336: request.ifr_addr.sa_len = 6; /* warning ### */ ! 337: bcopy (data, &request.ifr_addr.sa_data[0], 6); ! 338: ! 339: nddp = (struct ifnet *)pat_units[pat_id].nddp; ! 340: ! 341: /*### LD Direct access to the ifp->if_ioctl function */ ! 342: ! 343: if (nddp == 0) { ! 344: #ifdef APPLETALK_DEBUG ! 345: kprintf("pat_mcast: BAD ndpp\n"); ! 346: #endif ! 347: return(-1); ! 348: } ! 349: #ifdef APPLETALK_DEBUG ! 350: else kprintf("pat_mcast: register multicast for ifname=%s\n", nddp->if_name); ! 351: #endif ! 352: return (*nddp->if_ioctl)(nddp, (control == PAT_REG_MCAST) ? ! 353: SIOCADDMULTI : SIOCDELMULTI, &request); ! 354: } /* pat_mcast */ ! 355: ! 356: void ! 357: atalkintr() ! 358: { ! 359: struct mbuf *m; ! 360: struct ifnet *ifp; ! 361: int s, ret; ! 362: ! 363: next: ! 364: s = splimp(); ! 365: IF_DEQUEUE(&atalkintrq, m); ! 366: splx(s); ! 367: ! 368: if (m == 0) ! 369: return; ! 370: ! 371: if ((m->m_flags & M_PKTHDR) == 0) { ! 372: #ifdef APPLETALK_DEBUG ! 373: kprintf("atalkintr: no HDR on packet received"); ! 374: #endif ! 375: return; ! 376: } ! 377: ! 378: ifp = m->m_pkthdr.rcvif; ! 379: ! 380: /* do stuff */ ! 381: /* ! 382: if (m->m_len < ENET_LLC_SIZE && ! 383: (m = m_pullup(m, ENET_LLC_SIZE)) == 0) { ! 384: kprintf("atalkintr: packet too small\n"); ! 385: goto next; ! 386: } ! 387: */ ! 388: ! 389: ret = pat_input(NULL, ifp, m); ! 390: /* ! 391: if (ret) ! 392: kprintf("atalkintr: pat_input ret=%d\n", ret); ! 393: */ ! 394: goto next; ! 395: } /* atalkintr */ ! 396: ! 397: ! 398: int ! 399: pat_input(xddp, nddp, m) ! 400: void *xddp; ! 401: void *nddp; ! 402: gbuf_t *m; ! 403: { ! 404: #ifdef CHECK_DDPR_FLAG ! 405: extern int ddprunning_flag; ! 406: #endif ! 407: llc_header_t *llc_header; ! 408: int pat_id; ! 409: pat_unit_t *patp; ! 410: char src[6]; ! 411: enet_header_t *enet_header = (enet_header_t *)gbuf_rptr(m); ! 412: ! 413: for (pat_id=0, patp = &pat_units[pat_id]; ! 414: pat_id < xpatcnt; pat_id++, patp++) { ! 415: if ((patp->state == PAT_ONLINE) && (patp->nddp == nddp)) ! 416: break; ! 417: } ! 418: /* if we didn't find a matching interface */ ! 419: if (pat_id == xpatcnt) { ! 420: gbuf_freem(m); ! 421: #ifdef CHECK_DDPR_FLAG ! 422: FETCH_AND_ADD((atomic_p)&ddprunning_flag, -1); ! 423: #endif ! 424: return EAFNOSUPPORT; ! 425: } ! 426: ! 427: /* Ignore multicast packets from local station */ ! 428: if (patp->xtype == IFTYPE_ETHERTALK) { ! 429: bcopy((char *)enet_header->src, src, sizeof(src)); ! 430: /* ! 431: kprintf("pat_input: Packet received src addr=%s len=%x\n", ! 432: ether_sprintf(enet_header->src), enet_header->len); ! 433: */ ! 434: /* In order to receive packets from the Blue Box, we cannot reject packets ! 435: whose source address matches our local address. ! 436: if ((enet_header->dst[0] & 1) && ! 437: (bcmp(src, patp->xaddr, sizeof(src)) == 0)) { ! 438: #ifdef APPLETALK_DEBUG ! 439: kprintf("pat_input: Packet rejected: think it's a local mcast\n"); ! 440: #endif ! 441: gbuf_freem(m); ! 442: #ifdef CHECK_DDPR_FLAG ! 443: FETCH_AND_ADD((atomic_p)&ddprunning_flag, -1); ! 444: #endif ! 445: return EAFNOSUPPORT; ! 446: } ! 447: */ ! 448: ! 449: llc_header = (llc_header_t *)(enet_header+1); ! 450: ! 451: gbuf_rinc(m,(ENET_LLC_SIZE)); ! 452: #ifdef CHECK_DDPR_FLAG ! 453: FETCH_AND_ADD((atomic_p)&ddprunning_flag, 1); ! 454: #endif ! 455: pktsIn++; ! 456: /* ! 457: kprintf("pat_input: enet_header: dest=%s LLC_PROTO= %02x%02x\n", ! 458: ether_sprintf(enet_header->dst), ! 459: llc_header->protocol[3], ! 460: llc_header->protocol[4]); ! 461: */ ! 462: ! 463: if (LLC_PROTO_EQUAL(llc_header->protocol,snap_proto_aarp)) { ! 464: /* ! 465: kprintf("pat_input: Calling aarp_func dest=%s LLC_PROTO=%02x%02x\n", ! 466: ether_sprintf(enet_header->dst), ! 467: llc_header->protocol[3], ! 468: llc_header->protocol[4]); ! 469: */ ! 470: patp->aarp_func(gbuf_rptr(m), patp->context); ! 471: gbuf_freem(m); ! 472: } ! 473: else if (LLC_PROTO_EQUAL(llc_header->protocol,snap_proto_ddp)) { ! 474: /* if we're a router take all pkts */ ! 475: if (!ROUTING_MODE) { ! 476: if (patp->addr_check(gbuf_rptr(m), patp->context) ! 477: == AARP_ERR_NOT_OURS) { ! 478: /* ! 479: kprintf("pat_input: Packet Rejected: not for us? dest=%s LLC_PROTO= %02x%02x\n", ! 480: ether_sprintf(enet_header->dst), ! 481: llc_header->protocol[3], ! 482: llc_header->protocol[4]); ! 483: */ ! 484: gbuf_freem(m); ! 485: #ifdef CHECK_DDPR_FLAG ! 486: FETCH_AND_ADD((atomic_p)&ddprunning_flag, -1); ! 487: #endif ! 488: return EAFNOSUPPORT; ! 489: } ! 490: } ! 491: gbuf_set_type(m, MSG_DATA); ! 492: elap_input(m, patp->context, src); ! 493: } else { ! 494: gbuf_rdec(m,(ENET_LLC_SIZE)); ! 495: ! 496: #ifdef APPLETALK_DEBUG ! 497: kprintf("pat_input: Packet Rejected: wrong LLC_PROTO dest=%s LLC_PROTO= %02x%02x\n", ! 498: ether_sprintf(enet_header->dst), ! 499: llc_header->protocol[3], ! 500: llc_header->protocol[4]); ! 501: #endif ! 502: gbuf_freem(m); ! 503: #ifdef CHECK_DDPR_FLAG ! 504: FETCH_AND_ADD((atomic_p)&ddprunning_flag, -1); ! 505: #endif ! 506: return EAFNOSUPPORT; ! 507: } ! 508: } ! 509: #ifdef CHECK_DDPR_FLAG ! 510: FETCH_AND_ADD((atomic_p)&ddprunning_flag, -1); ! 511: #endif ! 512: return 0; ! 513: } /* pat_input */ ! 514: ! 515: #else /* AIX section to end of file (not supported) */ ! 516: ! 517: /* from beginning of file ... */ ! 518: #include <sys/cdli.h> ! 519: #include <sys/ndd.h> ! 520: static struct ns_8022 elap_link; /* The SNAP header description */ ! 521: static struct ns_user elap_user; /* The interface to the demuxer */ ! 522: ! 523: int ! 524: pat_ifpresent(name) /* AIX */ ! 525: char *name; ! 526: { ! 527: return (int)ifunit(name); ! 528: } ! 529: ! 530: int ! 531: pat_output(pat_id, mlist, dst_addr, type) /* AIX */ ! 532: int pat_id; ! 533: gbuf_t *mlist; ! 534: unsigned char *dst_addr; ! 535: int type; ! 536: { ! 537: int len; ! 538: pat_unit_t *patp; ! 539: gbuf_t *m, *m_prev, *new_mlist, *m_temp; ! 540: struct ndd *nddp; ! 541: short size; ! 542: enet_header_t *enet_header; ! 543: llc_header_t *llc_header; ! 544: ! 545: patp = (pat_unit_t *)&pat_units[pat_id]; ! 546: if (patp->state != PAT_ONLINE) { ! 547: gbuf_freel(mlist); ! 548: return ENOTREADY; ! 549: } ! 550: ! 551: if (patp->xtype == IFTYPE_NULLTALK) { ! 552: gbuf_freel(mlist); ! 553: return 0; ! 554: } ! 555: ! 556: nddp = (void *)patp->nddp; ! 557: new_mlist = 0; ! 558: ! 559: for (m = mlist; m; m = mlist) { ! 560: mlist = gbuf_next(m); ! 561: gbuf_next(m) = 0; ! 562: ! 563: gbuf_prepend(m,ENET_LLC_SIZE); ! 564: if (m == 0) { ! 565: if (mlist) ! 566: gbuf_freel(mlist); ! 567: if (new_mlist) ! 568: gbuf_freel(new_mlist); ! 569: return 0; ! 570: } ! 571: ! 572: enet_header = (enet_header_t *)gbuf_rptr(m); ! 573: bcopy(dst_addr, enet_header->dst, sizeof(enet_header->dst)); ! 574: bcopy(patp->xaddr, enet_header->src, sizeof(enet_header->src)); ! 575: size = gbuf_msgsize(m); ! 576: enet_header->len = size - sizeof(enet_header_t); ! 577: llc_header = (llc_header_t *)(gbuf_rptr(m)+sizeof(enet_header_t)); ! 578: *llc_header = (type == AARP_AT_TYPE) ? snap_hdr_aarp : snap_hdr_at; ! 579: ! 580: m->m_pkthdr.len = size; ! 581: m->m_pkthdr.rcvif = 0; ! 582: ! 583: if (new_mlist) ! 584: gbuf_next(m_prev) = m; ! 585: else ! 586: new_mlist = m; ! 587: m_prev = m; ! 588: pktsOut++; ! 589: } ! 590: ! 591: if (new_mlist) ! 592: (*nddp->ndd_output)(nddp, new_mlist); ! 593: ! 594: return 0; ! 595: } ! 596: ! 597: int ! 598: pat_online (ifName, ifType) /* AIX */ ! 599: char *ifName; ! 600: char *ifType; ! 601: { ! 602: void pat_input(); ! 603: int pat_id; ! 604: pat_unit_t *patp; ! 605: struct ndd *nddp; ! 606: char ns_name[8]; ! 607: ! 608: if ((pat_id = pat_ID(ifName)) == -1) ! 609: return (-1); ! 610: patp = &pat_units[pat_id]; ! 611: ! 612: if (patp->xtype == IFTYPE_ETHERTALK) { ! 613: ns_name[0] = ifName[0]; ! 614: ns_name[1] = 'n'; ! 615: strcpy(&ns_name[2], &ifName[1]); ! 616: } else if (patp->xtype == IFTYPE_NULLTALK) { ! 617: patp->xaddrlen = 6; ! 618: bzero(patp->xaddr, patp->xaddrlen); ! 619: if (ifType) ! 620: *ifType = patp->xtype; ! 621: patp->nddp = (void *)0; ! 622: patp->state = PAT_ONLINE; ! 623: at_statep->flags |= AT_ST_IF_CHANGED; ! 624: return (pat_id); ! 625: } else ! 626: return -1; ! 627: ! 628: if (ns_alloc(ns_name, &nddp)) ! 629: return -1; ! 630: ! 631: bzero(&elap_user, sizeof(elap_user)); ! 632: elap_user.isr = pat_input; ! 633: elap_user.pkt_format = NS_HANDLE_HEADERS|NS_INCLUDE_MAC; ! 634: ! 635: elap_link.filtertype = NS_8022_LLC_DSAP_SNAP; ! 636: elap_link.orgcode[0] = 0; ! 637: elap_link.orgcode[2] = 0; ! 638: elap_link.dsap = DSAP_SNAP; ! 639: elap_link.ethertype = 0x80f3; /* AARP SNAP code */ ! 640: if (ns_add_filter(nddp, &elap_link, sizeof(elap_link), &elap_user)) ! 641: return -1; ! 642: ! 643: elap_link.orgcode[0] = 0x08; ! 644: elap_link.orgcode[2] = 0x07; ! 645: elap_link.ethertype = 0x809b; /* DDP SNAP code */ ! 646: if (ns_add_filter(nddp, &elap_link, sizeof(elap_link), &elap_user)) { ! 647: elap_link.orgcode[0] = 0; ! 648: elap_link.orgcode[2] = 0; ! 649: elap_link.ethertype = 0x80f3; /* AARP SNAP code */ ! 650: (void)ns_del_filter(nddp, &elap_link, sizeof(elap_link)); ! 651: return -1; ! 652: } ! 653: ! 654: patp->xaddrlen = nddp->ndd_addrlen; ! 655: bcopy(nddp->ndd_physaddr, patp->xaddr, patp->xaddrlen); ! 656: ! 657: if (ifType) ! 658: *ifType = patp->xtype; ! 659: ! 660: patp->nddp = (void *)nddp; ! 661: patp->state = PAT_ONLINE; ! 662: at_statep->flags |= AT_ST_IF_CHANGED; ! 663: ! 664: return (pat_id); ! 665: } ! 666: ! 667: void ! 668: pat_offline(pat_id) /* AIX */ ! 669: int pat_id; ! 670: { ! 671: pat_unit_t *patp = &pat_units[pat_id]; ! 672: ! 673: if (patp->state == PAT_ONLINE) { ! 674: if (patp->xtype != IFTYPE_NULLTALK) { ! 675: elap_link.filtertype = NS_8022_LLC_DSAP_SNAP; ! 676: elap_link.orgcode[0] = 0; ! 677: elap_link.orgcode[2] = 0; ! 678: elap_link.dsap = DSAP_SNAP; ! 679: elap_link.ethertype = 0x80f3; /* AARP SNAP code */ ! 680: (void)ns_del_filter(patp->nddp, &elap_link, sizeof(elap_link)); ! 681: elap_link.orgcode[0] = 0x08; ! 682: elap_link.orgcode[2] = 0x07; ! 683: elap_link.ethertype = 0x809b; /* DDP SNAP code */ ! 684: (void)ns_del_filter(patp->nddp, &elap_link, sizeof(elap_link)); ! 685: ns_free(patp->nddp); ! 686: } ! 687: at_statep->flags |= AT_ST_IF_CHANGED; ! 688: bzero(patp, sizeof(pat_unit_t)); ! 689: } ! 690: } ! 691: ! 692: int ! 693: pat_mcast(pat_id, control, data) /* AIX */ ! 694: int pat_id; ! 695: int control; ! 696: unsigned char *data; ! 697: { ! 698: struct ndd *nddp; ! 699: ! 700: nddp = (struct ndd *)pat_units[pat_id].nddp; ! 701: return (*nddp->ndd_ctl)(nddp, (control == PAT_REG_MCAST) ? ! 702: NDD_ENABLE_ADDRESS : NDD_DISABLE_ADDRESS, ! 703: data, nddp->ndd_addrlen); ! 704: } ! 705: ! 706: void ! 707: pat_input(nddp, m, unused) /* AIX */ ! 708: struct ndd *nddp; ! 709: gbuf_t *m; ! 710: void *unused; ! 711: { ! 712: extern int ddprunning_flag; ! 713: llc_header_t *llc_header; ! 714: int pat_id; ! 715: pat_unit_t *patp; ! 716: char src[6]; ! 717: enet_header_t *enet_header = (enet_header_t *)gbuf_rptr(m); ! 718: ! 719: for (pat_id=0, patp = &pat_units[pat_id]; ! 720: pat_id < xpatcnt; pat_id++, patp++) { ! 721: if ((patp->state == PAT_ONLINE) && (patp->nddp == nddp)) ! 722: break; ! 723: } ! 724: if (pat_id == xpatcnt) { ! 725: gbuf_freem(m); ! 726: return; ! 727: } ! 728: ! 729: /* Ignore multicast packets from local station */ ! 730: if (patp->xtype == IFTYPE_ETHERTALK) { ! 731: bcopy((char *)enet_header->src, src, sizeof(src)); ! 732: if ((enet_header->dst[0] & 1) && ! 733: (bcmp(src, patp->xaddr, sizeof(src)) == 0)) { ! 734: gbuf_freem(m); ! 735: return; ! 736: } ! 737: llc_header = (llc_header_t *)(enet_header+1); ! 738: } ! 739: ! 740: gbuf_rinc(m,(ENET_LLC_SIZE)); ! 741: (void)fetch_and_add((atomic_p)&ddprunning_flag, 1); ! 742: pktsIn++; ! 743: if (LLC_PROTO_EQUAL(llc_header->protocol,snap_proto_aarp)) { ! 744: patp->aarp_func(gbuf_rptr(m), patp->context); ! 745: gbuf_freem(m); ! 746: } else if (LLC_PROTO_EQUAL(llc_header->protocol,snap_proto_ddp)) { ! 747: /* if we're a router take all pkts */ ! 748: if (!ROUTING_MODE) { ! 749: if (patp->addr_check(gbuf_rptr(m), patp->context) ! 750: == AARP_ERR_NOT_OURS) { ! 751: gbuf_freem(m); ! 752: (void)fetch_and_add((atomic_p)&ddprunning_flag, -1); ! 753: return; ! 754: } ! 755: } ! 756: gbuf_set_type(m, MSG_DATA); ! 757: elap_input(m, patp->context, src); ! 758: } else ! 759: gbuf_freem(m); ! 760: (void)fetch_and_add((atomic_p)&ddprunning_flag, -1); ! 761: } ! 762: #endif /* AIX */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.