Annotation of kernel/bsd/netat/drv_dep.c, revision 1.1

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 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.