Annotation of kernel/bsd/netat/ddp_lap.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 (c) 1988, 1989, 1993-1998 Apple Computer, Inc. 
        !            27:  *
        !            28:  *     The information contained herein is subject to change without
        !            29:  *     notice and  should not be  construed as a commitment by Apple
        !            30:  *     Computer, Inc. Apple Computer, Inc. assumes no responsibility
        !            31:  *     for any errors that may appear.
        !            32:  *
        !            33:  *     Confidential and Proprietary to Apple Computer, Inc.
        !            34:  */
        !            35: 
        !            36: /* at_elap.c: 2.0, 1.29; 10/4/93; Apple Computer, Inc. */
        !            37: 
        !            38: /* This is the file which implements all the streams driver 
        !            39:  * functionality required for EtherTalk.
        !            40:  */
        !            41: 
        !            42: 
        !            43: 
        !            44: #define RESOLVE_DBG                            /* for debug.h global resolution */
        !            45: #include <sysglue.h>
        !            46: #include <sys/malloc.h>
        !            47: #include <at/appletalk.h>
        !            48: #include <at/ddp.h>
        !            49: #include <at/elap.h>
        !            50: #include <lap.h>  /* for at_statep */
        !            51: #include <routing_tables.h>     /* rtmp+zip table structs  */
        !            52: 
        !            53: #include <at/at_lap.h>
        !            54: #include <at_pat.h>
        !            55: #include <at_elap.h>
        !            56: #include <at_aarp.h>
        !            57: #include <at_ddp.h>
        !            58: #include <at_zip.h>
        !            59: #include <nbp.h>
        !            60: #include <at_snmp.h>
        !            61: #include <atlog.h>
        !            62: 
        !            63: #ifndef NULL
        !            64: #define NULL 0
        !            65: #endif
        !            66: 
        !            67:        /* globals */
        !            68: 
        !            69: elap_specifics_t       elap_specifics[IF_TYPE_ET_MAX];
        !            70: at_state_t     at_state;               /* global state of AT network */
        !            71: at_state_t *at_statep = &at_state;
        !            72: char *if_types[] = { IF_TYPE_1, IF_TYPE_2, IF_TYPE_3, IF_TYPE_4, IF_TYPE_5};
        !            73: gref_t *shutdown_gref = NULL;
        !            74: gref_t *at_qioctl = NULL;
        !            75: gbuf_t *at_mioctl = NULL;
        !            76: gbuf_t *at_delay_m = NULL;
        !            77: gref_t *at_delay_gref = NULL;
        !            78: int (*at_delay_func)() = NULL;
        !            79: int at_delay_errno = 0;
        !            80: char at_delay_flag = 0;
        !            81: char at_ddp_debug;
        !            82: int RoutingMix= 2000; /* default for nbr of ppsec */
        !            83: snmpFlags_t            snmpFlags;
        !            84: 
        !            85: void ddp_bit_reverse();
        !            86: 
        !            87:        /* snmp defines */
        !            88: #define MAX_BUFSIZE            8192   
        !            89: #define MAX_RTMP               (MAX_BUFSIZE/sizeof(RT_entry)-1)
        !            90: #define MAX_NBP                \
        !            91:        ((MAX_BUFSIZE - SNMP_NBP_HEADER_SIZE)/sizeof(snmpNbpEntry_t)-1)
        !            92: #define MAX_NBP_BYTES  (MAX_NBP * sizeof(snmpNbpEntry_t))
        !            93: #define MAX_ZIP                        (MAX_BUFSIZE/sizeof(ZT_entry)-1)
        !            94: #define MAX_RTMP_BYTES (MAX_RTMP * sizeof(RT_entry))
        !            95: #define MAX_ZIP_BYTES  (MAX_ZIP * sizeof(ZT_entry))
        !            96: 
        !            97:        /* externs */
        !            98: extern at_if_t                 *ifID_table[];
        !            99: extern at_if_t         at_ifQueueHead;
        !           100: extern int xpatcnt;
        !           101: extern snmpStats_t     snmpStats;
        !           102: extern atlock_t ddpinp_lock;
        !           103: extern atlock_t arpinp_lock;
        !           104: extern short appletalk_inited;
        !           105: pat_unit_t pat_units[IF_TOTAL_MAX];
        !           106: 
        !           107: 
        !           108:        /* protos */
        !           109: extern snmpAarpEnt_t * getAarp(int *);
        !           110: extern RT_entry *rt_getNextRoute(int);
        !           111: extern ZT_entryno *zt_getNextZone(int);
        !           112: extern int setLocalZones(at_nbptuple_t * , int);
        !           113: extern int getRTRLocalZone(if_zone_t *);
        !           114: extern at_nvestr_t *getDefZone(int);
        !           115: StaticProc void getIfNames(if_name_t *);
        !           116: StaticProc void get_ifs_stat();
        !           117: StaticProc void add_route();
        !           118: StaticProc int set_zones();
        !           119: StaticProc void pat_init();
        !           120: StaticProc void dodefer();
        !           121: StaticProc int domcast();
        !           122: StaticProc int elap_offline();
        !           123: StaticProc void routerShutdown();
        !           124: StaticProc void elap_hangup();
        !           125: static getSnmpCfg();
        !           126:        /* temp globals, etc. */
        !           127: 
        !           128: #define        NDEFERS 20
        !           129: /* *** static int ndefers = NDEFERS;   not currently used *** */
        !           130: static int deferno = 0;
        !           131: static int gotIfs = 0;
        !           132: 
        !           133: #define ZT_BAD ZT_MAXENTRY +1
        !           134: 
        !           135: 
        !           136: 
        !           137: /***********************************************************************
        !           138:  * lap_close()
        !           139:  *
        !           140:  **********************************************************************/
        !           141: int lap_close(gref)
        !           142:        gref_t *gref;
        !           143: {
        !           144: #ifdef CHECK_DDPR_FLAG
        !           145:        extern int ddprunning_flag;
        !           146: #endif
        !           147:        int s;
        !           148: 
        !           149:        ddp_close(gref); /* for 2225395 */
        !           150:        ATDISABLE(s, ddpinp_lock);
        !           151:        if (gref == shutdown_gref) {
        !           152: #ifdef CHECK_DDPR_FLAG
        !           153:                while (ddprunning_flag)
        !           154:                        ;
        !           155: #endif
        !           156:                if (at_mioctl != NULL) {
        !           157:                        gbuf_freem(at_mioctl);
        !           158:                        at_mioctl = NULL;
        !           159:                }
        !           160:                shutdown_gref = NULL;
        !           161:                xpatcnt = 0;
        !           162:                at_statep->flags = 0;
        !           163:        }
        !           164:        ATENABLE(s, ddpinp_lock);
        !           165: 
        !           166:        return 0;
        !           167: }
        !           168: 
        !           169: StaticProc
        !           170: validate_msg_size(m, gref, elapp)
        !           171:        register gbuf_t *m;
        !           172:        gref_t          *gref;
        !           173:        elap_specifics_t **elapp;
        !           174: 
        !           175: /* checks ioctl message type for minimum expected message size & 
        !           176:    sends error back if size invalid
        !           177: */
        !           178: {
        !           179:        register ioc_t          *iocbp;
        !           180:        register at_elap_cfg_t          *cfgp;
        !           181:        int i, size = 1;
        !           182:        int if_specific = FALSE;
        !           183:        
        !           184:        *elapp = NULL;          
        !           185:        iocbp = (ioc_t *) gbuf_rptr(m);
        !           186: 
        !           187:        switch (iocbp->ioc_cmd) {
        !           188:            case LAP_IOC_ONLINE:
        !           189:                case LAP_IOC_OFFLINE:
        !           190:                case ELAP_IOC_SWITCHZONE:
        !           191:                case ELAP_IOC_SET_CFG:
        !           192:                case ELAP_IOC_SET_ZONE :
        !           193:                        size = sizeof(at_elap_cfg_t);
        !           194:                        if_specific = TRUE;
        !           195:                        break;
        !           196:                case LAP_IOC_ADD_ROUTE:
        !           197:                        size = sizeof(RT_entry);
        !           198:                        break;
        !           199:                case LAP_IOC_ADD_ZONE:
        !           200:                        size = sizeof(if_zone_info_t);
        !           201:                        break;
        !           202:                case LAP_IOC_GET_ROUTE:
        !           203:                        size = sizeof(RT_entry);
        !           204:                        break;
        !           205:                case LAP_IOC_GET_ZONE:
        !           206:                        size = sizeof(ZT_entryno);
        !           207:                        break;
        !           208:                case LAP_IOC_GET_IFID:
        !           209:                        size = sizeof(at_if_name_t);
        !           210:                        break;
        !           211:                case LAP_IOC_SET_DBG:
        !           212:                        size = sizeof(dbgBits_t);
        !           213:                        break;
        !           214:                case LAP_IOC_SNMP_GET_CFG:
        !           215:                case LAP_IOC_SNMP_GET_AARP:
        !           216:                case LAP_IOC_SNMP_GET_ZIP:
        !           217:                case LAP_IOC_SNMP_GET_RTMP:
        !           218:                case LAP_IOC_GET_DEFAULT_ZONE:
        !           219:                case LAP_IOC_SNMP_GET_NBP:
        !           220:                        size = sizeof(int);
        !           221:                        break;
        !           222:                case LAP_IOC_SET_MIX:
        !           223:                        size = sizeof(short);
        !           224:                        break;
        !           225:                case LAP_IOC_GET_LOCAL_ZONE:
        !           226:                        size = sizeof(if_zone_t);
        !           227:                        break;
        !           228:                case LAP_IOC_IS_ZONE_LOCAL:
        !           229:                        size = sizeof(at_nvestr_t);
        !           230:                        break;
        !           231:                case LAP_IOC_CHECK_STATE:
        !           232:                        size = 1;
        !           233:                        break;
        !           234:                case LAP_IOC_SET_DEFAULT_ZONES:
        !           235:                        size = sizeof(int) * IF_TOTAL_MAX;
        !           236:                        break;
        !           237: 
        !           238:                case ELAP_IOC_GET_STATS:
        !           239:                case ELAP_IOC_GET_CFG:
        !           240:                case LAP_IOC_GET_DBG:
        !           241:                case LAP_IOC_GET_IFS_STAT: 
        !           242:                case LAP_IOC_ROUTER_START:
        !           243:                case LAP_IOC_ROUTER_SHUTDOWN:
        !           244:                case LAP_IOC_ROUTER_INIT:
        !           245:                case LAP_IOC_DO_DEFER:
        !           246:                case LAP_IOC_DO_DELAY:
        !           247:                case LAP_IOC_SHUT_DOWN:
        !           248:                case LAP_IOC_SNMP_GET_DDP:
        !           249:                case LAP_IOC_GET_MODE:
        !           250:                case LAP_IOC_GET_IF_NAMES:
        !           251:                        size = 0;
        !           252:                        break;
        !           253:                                                /* these ioctls  send variable length data */
        !           254:                case LAP_IOC_SET_LOCAL_ZONES:
        !           255:                        size = -1;
        !           256:                        break;
        !           257:                default:
        !           258:                        dPrintf(D_M_ELAP, D_L_ERROR, ("elap_wput: unknown ioctl\n"));
        !           259:                        goto error;
        !           260:        }
        !           261: 
        !           262:        if (size == 0) {                                /* a non-data ioctl */
        !           263:                return(0);
        !           264:        }
        !           265: 
        !           266:        /* if I/F related, validate further */
        !           267:        if (if_specific) {
        !           268:                /* get elapp from msg */
        !           269:                int lap_id;
        !           270:                cfgp = (at_elap_cfg_t * ) gbuf_rptr(gbuf_cont(m));
        !           271:                lap_id = pat_ID(cfgp->if_name);
        !           272:                if (lap_id < 0 ||  IF_ANY_MAX <= lap_id)  {
        !           273:                        ioc_ack(EINVAL, m, gref); 
        !           274:                        dPrintf(D_M_ELAP, D_L_ERROR, ("validate_msg:bad cmd (%x) for %s\n",
        !           275:                                iocbp->ioc_cmd, cfgp->if_name));
        !           276:                        return(EINVAL);
        !           277:                }
        !           278:                *elapp = &elap_specifics[lap_id]; 
        !           279:        }       
        !           280: 
        !           281:        if (gbuf_cont(m) != NULL) {
        !           282:                i = gbuf_len(gbuf_cont(m));
        !           283:                if (size == -1)
        !           284:                        if (i >1)
        !           285:                                return(0);
        !           286:                        else
        !           287:                                goto error;
        !           288:        }
        !           289:        if (iocbp->ioc_count < size || (gbuf_cont(m) == NULL) || i < size) {
        !           290:                        dPrintf(D_M_ELAP, D_L_ERROR,
        !           291:                                ("ioctl msg error:s:%d c:%d bcont:%c delta:%d\n",
        !           292:                                   size, iocbp->ioc_count,
        !           293:                                   gbuf_cont(m)? 'Y' : 'N', i));
        !           294:           goto error;
        !           295:        }
        !           296:        else
        !           297:                return(0);
        !           298: error:
        !           299:        ioc_ack(EMSGSIZE, m, gref);
        !           300:        return (EMSGSIZE);
        !           301: } /* validate_msg_size */
        !           302: 
        !           303: void
        !           304: elap_input(mp, elapp, src)
        !           305: register elap_specifics_t *elapp;
        !           306: register gbuf_t                *mp;
        !           307: register char *src;
        !           308: {
        !           309:        /* Let ddp glean link address if it wishes to */
        !           310:        elapp->stats.rcv_packets++;
        !           311:        elapp->stats.rcv_bytes += gbuf_msgsize(mp);
        !           312: 
        !           313:        if (!MULTIPORT_MODE)
        !           314:                ddp_glean (mp, &elapp->elap_if, src);
        !           315:        gbuf_next(mp) = 0;
        !           316:        ddp_input(mp, &elapp->elap_if);
        !           317: } /* elap_input */
        !           318: 
        !           319: 
        !           320: /***********************************************************************
        !           321:  * elap_wput()
        !           322:  *
        !           323:  **********************************************************************/
        !           324: int
        !           325: elap_wput(gref, m)
        !           326: gref_t                 *gref;
        !           327: register       gbuf_t  *m;
        !           328: {
        !           329:        elap_specifics_t        *elapp;
        !           330:        register ioc_t          *iocbp;
        !           331:        register at_elap_cfg_t  *cfgp;
        !           332:        at_elap_stats_t         *statsp;
        !           333:        static int              ifID_entry = 0;
        !           334:        int                     elap_online();
        !           335:        int                     error;
        !           336:        int                     i;
        !           337:        int                     (*func)();
        !           338:        gbuf_t          *tmpm;
        !           339:        pat_unit_t *patp;
        !           340: 
        !           341: 
        !           342:        switch (gbuf_type(m)) {
        !           343:        case MSG_DATA:
        !           344:                        gbuf_freem(m);
        !           345:                        dPrintf(D_M_ELAP,D_L_ERROR,
        !           346:                                ("Output data to control channel is ignored\n"));
        !           347:        break;
        !           348: 
        !           349:        case MSG_IOCTL:
        !           350:                iocbp = (ioc_t *) gbuf_rptr(m);
        !           351:                if (!xpatcnt) {
        !           352:                        gotIfs = 0;
        !           353:                        if (!(at_statep->flags & AT_ST_PAT_INIT)) {
        !           354:                                bzero(elap_specifics, sizeof(elap_specifics));
        !           355:                                pat_init();
        !           356:                                at_statep->flags |= AT_ST_PAT_INIT;
        !           357:                                at_ddp_debug = 0;
        !           358:                        }
        !           359:                }
        !           360: 
        !           361:                switch (iocbp->ioc_cmd) {
        !           362:                case LAP_IOC_ADD_IFNAME:
        !           363:                        /* Has this interface already been added? */
        !           364:                        if ((i = pat_ID(gbuf_rptr(gbuf_cont(m)))) != -1) {
        !           365:                           ioc_ack(0, m, gref);
        !           366:                           return 0;
        !           367:                        }
        !           368: 
        !           369:                        shutdown_gref = gref;
        !           370:                        patp = &pat_units[xpatcnt];
        !           371:                        bcopy(gbuf_rptr(gbuf_cont(m)), patp->xname, sizeof(patp->xname));
        !           372:                        patp->xname[sizeof(patp->xname)-1] = '\0';
        !           373:                        patp->xunit = (char)IF_UNIT(patp->xname);
        !           374:                        if (strncmp(IF_TYPE_1, patp->xname, 2) == 0)
        !           375:                                patp->xtype = IFTYPE_ETHERTALK;
        !           376:                        else if (strncmp(IF_TYPE_3, patp->xname, 2) == 0)
        !           377:                                patp->xtype = IFTYPE_FDDITALK;
        !           378:                        else if (strncmp(IF_TYPE_4, patp->xname, 2) == 0)
        !           379:                                patp->xtype = IFTYPE_TOKENTALK;
        !           380:                        else if (strncmp(IF_TYPE_5, patp->xname, 2) == 0)
        !           381:                                patp->xtype = IFTYPE_NULLTALK;
        !           382:                        else
        !           383:                                patp->xtype = IFTYPE_LOCALTALK;
        !           384:                        ioc_ack(0, m, gref);
        !           385:                        xpatcnt++;
        !           386:                        return 0;
        !           387: 
        !           388:                /* *** fix this later: this code may no longer be needed *** */
        !           389:                case LAP_IOC_DEL_IFNAME:
        !           390:                        if ((i = pat_ID(gbuf_rptr(gbuf_cont(m)))) != -1) {
        !           391:                                patp = &pat_units[i];
        !           392:                                patp->xname[0] = '\0';
        !           393:                        }
        !           394:                        ioc_ack(0, m, gref);
        !           395:                        return 0;
        !           396:                }
        !           397:                /* *** end of code that may no longer be needed *** */
        !           398: 
        !           399:                if (validate_msg_size(m, gref, &elapp))
        !           400:                        break;  
        !           401: 
        !           402:                if (elapp)
        !           403:                        cfgp = (at_elap_cfg_t*) gbuf_rptr(gbuf_cont(m));
        !           404: 
        !           405:                if (LAP_IOC_MYIOCTL(iocbp->ioc_cmd) || 
        !           406:                        ELAP_IOC_MYIOCTL(iocbp->ioc_cmd)) {
        !           407: 
        !           408:                        switch (iocbp->ioc_cmd) {
        !           409: 
        !           410:                        case LAP_IOC_CHECK_STATE:
        !           411: #ifdef APPLETALK_DEBUG
        !           412: kprintf("LAP_IOC_CHECK_STATE\n");
        !           413: #endif
        !           414:                                error = (shutdown_gref == NULL) ? ENOTREADY : 0;
        !           415:                                if (error == 0) {
        !           416:                                        dPrintf(D_M_ELAP,D_L_INFO,
        !           417:                                                ("elap_wput: CHECK_STATE 1\n"));
        !           418: //### LD 7/23 was 0x1000: too big for 2K cluster size
        !           419:                                        if ((tmpm = gbuf_alloc(0x512, PRI_HI)) == NULL)
        !           420:                                                ioc_ack(ENOBUFS, m, gref);
        !           421:                                        else {
        !           422:                                                *gbuf_rptr(tmpm) = *gbuf_rptr(gbuf_cont(m));
        !           423:                                                gbuf_wset(tmpm,sizeof(int));
        !           424:                                                gbuf_freeb(gbuf_cont(m));
        !           425:                                                gbuf_cont(m) = tmpm;
        !           426:                                                ddp_stop(m, gref);
        !           427:                                        }
        !           428:                                } else {
        !           429:                                        dPrintf(D_M_ELAP,D_L_INFO,
        !           430:                                                ("elap_wput: CHECK_STATE 2\n"));
        !           431:                                        ioc_ack(error, m, gref);
        !           432:                                }
        !           433:                                break;
        !           434: 
        !           435:                        /* *** fix this later: this code may no longer be needed *** */
        !           436:                        case LAP_IOC_SHUT_DOWN:
        !           437: #ifdef APPLETALK_DEBUG
        !           438: kprintf("LAP_IOC_SHUT_DOWN\n");
        !           439: #endif
        !           440:                                if (shutdown_gref != NULL) {
        !           441:                                        if ((tmpm = gbuf_alloc(1, PRI_HI)) == NULL) {
        !           442:                                                ioc_ack(ENOBUFS, m, gref);
        !           443:                                                break;
        !           444:                                        }
        !           445:                                        gbuf_wset(tmpm,1);
        !           446:                                        *gbuf_rptr(tmpm) = ESHUTDOWN;
        !           447:                                        gbuf_set_type(tmpm, MSG_ERROR);
        !           448:                                        atalk_putnext(shutdown_gref, tmpm);
        !           449:                                }
        !           450:                                ioc_ack(0, m, gref);
        !           451:                                break;
        !           452:                        /* *** end of code that may no longer be needed *** */
        !           453: 
        !           454:                        case LAP_IOC_DO_DEFER:
        !           455: #ifdef APPLETALK_DEBUG
        !           456: kprintf("LAP_IOC_DO_DEFER\n");
        !           457: #endif
        !           458:                        if (gbuf_cont(m) == NULL) {
        !           459:                                dodefer();
        !           460:                                ioc_ack(0, m, gref);
        !           461:                        } else {
        !           462:                                ioc_ack(EINVAL, m, gref);
        !           463:                        }
        !           464:                                break;
        !           465:                        case LAP_IOC_DO_DELAY:
        !           466: #ifdef APPLETALK_DEBUG
        !           467: kprintf("LAP_IOC_DO_DELAY\n");
        !           468: #endif
        !           469:                                dodefer();
        !           470:                                if ((func = at_delay_func) != NULL) {
        !           471:                                        at_delay_func = NULL;
        !           472:                                        error = (*func)(at_delay_flag, m, gref);
        !           473:                                        if (error != ENOTREADY)
        !           474:                                                ioc_ack(error, m, gref);
        !           475:                                } else
        !           476:                                        ioc_ack(0, m, gref);
        !           477:                                break;
        !           478: 
        !           479:                    case LAP_IOC_ONLINE:
        !           480: #ifdef APPLETALK_DEBUG
        !           481: kprintf("LAP_IOC_ONLINE\n");
        !           482: #endif
        !           483:                                if ( elapp->elap_if.ifState == LAP_ONLINE ||
        !           484:                                     (elapp->elap_if.ifState == LAP_ONLINE_ZONELESS &&
        !           485:                                           !(cfgp->flags & ELAP_CFG_SET_RANGE)
        !           486:                                         )
        !           487:                                   ) {
        !           488:                                        /* This don't make much sense...
        !           489:                                         * we're already ONLINE!
        !           490:                                         */
        !           491:                                        ioc_ack(EALREADY, m, gref);
        !           492:                                        break;
        !           493:                                }
        !           494:                                elapp->flags = cfgp->flags;
        !           495:                                if (elapp->flags & ELAP_CFG_HOME) {
        !           496:                                        /* copy over the configured zone if any */
        !           497:                                        if (cfgp->zonename.len)
        !           498:                                                bcopy((caddr_t) &cfgp->zonename,
        !           499:                                                      (caddr_t) &elapp->elap_if.ifZoneName, 
        !           500:                                                      cfgp->zonename.len+1);
        !           501:                                        if  (ifID_table[IFID_HOME])  {
        !           502:                                                /* if home flag is set, and
        !           503:                                                 * there is already a home
        !           504:                                                 * ifID, it better be us!
        !           505:                                                 */
        !           506:                                                if (&elapp->elap_if !=
        !           507:                                                    ifID_table[IFID_HOME] ) {
        !           508:                                                        /* only 1 home allowed! */
        !           509:                                                        ioc_ack(EEXIST, m, gref);
        !           510:                                                        break;
        !           511:                                                }
        !           512:                                                dPrintf(D_M_ELAP, D_L_STARTUP, ("elap_wput home I/F:%s\n",
        !           513:                                                        cfgp->if_name));
        !           514:                                        }
        !           515:                                        else {
        !           516:                                                /* home port designation not
        !           517:                                                 * allowed unless
        !           518:                                                 * i/f is off line
        !           519:                                                 */
        !           520:                                                if ( elapp->elap_if.ifState != LAP_OFFLINE) {
        !           521:                                                ioc_ack(EPERM, m, gref);                        
        !           522:                                                        break;
        !           523:                                                }
        !           524:                                        }
        !           525:                                } /* if CFG_HOME */
        !           526: 
        !           527:                                if (elapp->elap_if.ifState == LAP_OFFLINE)
        !           528:                                        bzero ((caddr_t) &elapp->elap_if, sizeof(at_if_t));
        !           529: 
        !           530:                                if (elapp->flags & ELAP_CFG_SET_RANGE ||
        !           531:                                    elapp->flags & ELAP_CFG_SEED) {
        !           532: 
        !           533:                                        if ( elapp->elap_if.ifState != LAP_ONLINE_ZONELESS &&
        !           534:                                             elapp->elap_if.ifState != LAP_OFFLINE
        !           535:                                           ) {                          /* can't change range if ONLINE */
        !           536:                                        ioc_ack(EFAULT, m, gref);                       
        !           537:                                                break;
        !           538:                                        }
        !           539:                                        dPrintf(D_M_ELAP, D_L_STARTUP_INFO,
        !           540:                                                ("elap_wput: found to be seed/set range\n"));
        !           541: 
        !           542: 
        !           543:                                        ATALK_ASSIGN(elapp->cfg.initial_addr, 0, 0, 0);
        !           544:                                        elapp->elap_if.ifThisCableStart = cfgp->netStart;
        !           545:                                        elapp->elap_if.ifThisCableEnd   = cfgp->netEnd;
        !           546:                                }
        !           547:                                else {
        !           548:                                        dPrintf(D_M_ELAP,D_L_ERROR, 
        !           549:                                                ("elap_wput: we believe we're not seed\n"));
        !           550:                                }
        !           551: 
        !           552:                                at_delay_errno = 0;
        !           553:                                error = elap_online (gref, cfgp->if_name, NULL, m); 
        !           554: 
        !           555:                                if (error != ENOTREADY)
        !           556:                                        ioc_ack(error, m, gref);
        !           557:                                break;
        !           558: 
        !           559:                        case LAP_IOC_OFFLINE:
        !           560: #ifdef APPLETALK_DEBUG
        !           561: kprintf("LAP_IOC_OFFLINE\n");
        !           562: #endif
        !           563:                                if (!xpatcnt) {
        !           564:                                        ioc_ack(0, m, gref);
        !           565:                                        break;
        !           566:                                }
        !           567:                                error = elap_offline(elapp);
        !           568:                                ioc_ack(error, m, gref);
        !           569:                                break;
        !           570: 
        !           571:                        case LAP_IOC_GET_IFS_STAT:
        !           572: #ifdef APPLETALK_DEBUG
        !           573: kprintf("LAP_IOC_GET_IFS_STAT\n");
        !           574: #endif
        !           575:                                if ((gbuf_cont(m) = gbuf_alloc(sizeof(if_cfg_t), 
        !           576:                                        PRI_MED)) == NULL) {
        !           577:                                        ioc_ack(ENOBUFS, m, gref);
        !           578:                                        break;
        !           579:                                }
        !           580:                                get_ifs_stat(gbuf_rptr(gbuf_cont(m)));
        !           581:                                gbuf_wset(gbuf_cont(m),sizeof(if_cfg_t));
        !           582:                                iocbp->ioc_count = sizeof(if_cfg_t);
        !           583:                                ioc_ack(0, m, gref);
        !           584:                                ifID_entry = 0;
        !           585:                                break;
        !           586:                                
        !           587:                        case ELAP_IOC_GET_CFG:
        !           588: #ifdef APPLETALK_DEBUG
        !           589: kprintf("ELAP_IOC_GET_CFG\n");
        !           590: #endif
        !           591:                                /* an at_elap_cfg_t is passed down with this
        !           592:                                   ioctl, the elapp is obtained from it via
        !           593:                                   the if_name we then send back a copy of the
        !           594:                                   current at_elap_cfg_t by gbuf_alloc'ing a new
        !           595:                                   message 
        !           596:                                 */
        !           597:                                gbuf_freem(gbuf_cont(m));
        !           598:                                gbuf_cont(m) = NULL;
        !           599:                                if ((gbuf_cont(m) = gbuf_alloc(sizeof(at_elap_cfg_t), 
        !           600:                                        PRI_MED)) == NULL) {
        !           601:                                        ioc_ack(ENOBUFS, m, gref);
        !           602:                                        break;
        !           603:                                }
        !           604:                                cfgp = (at_elap_cfg_t *) gbuf_rptr(gbuf_cont(m));
        !           605:                                 if  (ifID_table[IFID_HOME])  {
        !           606:                                   elapp = (elap_specifics_t *)ifID_table[IFID_HOME]->ifLapp;
        !           607:                                   if (elapp) {
        !           608:                                        *cfgp = elapp->cfg;
        !           609:                                        gbuf_wset(gbuf_cont(m),sizeof(at_elap_cfg_t));
        !           610:                                        iocbp->ioc_count = sizeof(at_elap_cfg_t);
        !           611:                                        ioc_ack(0, m, gref);
        !           612:                                        }
        !           613:                                   else
        !           614:                                        ioc_ack(EINVAL, m, gref);
        !           615:                                   }
        !           616:                                 else
        !           617:                                   ioc_ack(EINVAL, m, gref);
        !           618:                                break;
        !           619: 
        !           620:                        case LAP_IOC_GET_IFID:
        !           621: #ifdef APPLETALK_DEBUG
        !           622: kprintf("LAP_IOC_GET_IFID\n");
        !           623: #endif
        !           624:                                /* return at_if_t struct for requested interface */
        !           625:                        {
        !           626:                                at_if_name_t *ifIN;
        !           627:                                at_if_t *ifID;
        !           628:                                int lap_id;
        !           629: 
        !           630:                                ifIN = (at_if_name_t *)gbuf_rptr(gbuf_cont(m));
        !           631:                                lap_id = pat_ID(ifIN->if_name);
        !           632:                                {
        !           633:                                        if (lap_id < 0 || IF_ANY_MAX <= lap_id)  {
        !           634:                                                ioc_ack(EINVAL, m, gref);
        !           635:                                                break;
        !           636:                                        }
        !           637:                                        else {
        !           638:                                                ifID = &elap_specifics[lap_id].elap_if;
        !           639:                                                gbuf_freem(gbuf_cont(m));
        !           640:                                                gbuf_cont(m) = NULL;
        !           641: 
        !           642:                                                if ((gbuf_cont(m) = gbuf_alloc(sizeof(at_if_name_t), 
        !           643:                                                PRI_MED)) == NULL) {
        !           644:                                                        ioc_ack(ENOBUFS, m, gref);
        !           645:                                                        break;
        !           646:                                                }
        !           647:                                                ifID = &elap_specifics[lap_id].elap_if; 
        !           648:                                                ifIN = (at_if_name_t *)gbuf_rptr(gbuf_cont(m));
        !           649:                                                ifIN->ifID = *ifID; 
        !           650:                                                gbuf_wset(gbuf_cont(m),sizeof(at_if_name_t));
        !           651:                                                iocbp->ioc_count = sizeof(at_if_name_t);
        !           652:                                        }
        !           653:                                }
        !           654:                                ioc_ack(0, m, gref);
        !           655:                        }
        !           656:                        break;
        !           657:                                
        !           658: 
        !           659:                        case ELAP_IOC_GET_STATS:
        !           660: #ifdef APPLETALK_DEBUG
        !           661: kprintf("LAP_IOC_GET_STATS\n");
        !           662: #endif
        !           663:                                if ( (gbuf_cont(m) == NULL)
        !           664:                                                || ((i = pat_ID(gbuf_rptr(gbuf_cont(m)))) == -1) ) {
        !           665:                                        ioc_ack(EINVAL, m, gref);
        !           666:                                        break;
        !           667:                                }
        !           668:                                gbuf_freem(gbuf_cont(m));
        !           669:                                if ((gbuf_cont(m) =gbuf_alloc(sizeof(at_elap_stats_t), 
        !           670:                                        PRI_MED)) == NULL) {
        !           671:                                        ioc_ack(ENOBUFS, m, gref);
        !           672:                                        break;
        !           673:                                }
        !           674:                                statsp = ((at_elap_stats_t *)gbuf_rptr(gbuf_cont(m)));
        !           675:                                elapp = &elap_specifics[i]; 
        !           676:                                if (elapp) {
        !           677:                                        *statsp = elapp->stats;
        !           678:                                        gbuf_wset(gbuf_cont(m),sizeof(at_elap_stats_t));
        !           679:                                        iocbp->ioc_count = sizeof(at_elap_stats_t);
        !           680:                                        ioc_ack(0, m, gref);
        !           681:                                }
        !           682:                                else 
        !           683:                                        ioc_ack(EINVAL, m, gref);
        !           684:                                break;
        !           685:                        case ELAP_IOC_SET_CFG:
        !           686: #ifdef APPLETALK_DEBUG
        !           687: kprintf("ELAP_IOC_SET_CFG\n");
        !           688: #endif
        !           689:                                if (elapp->elap_if.ifState == LAP_ONLINE) {
        !           690:                                        /* Can not allow setting config after
        !           691:                                         * we're already ONLINE
        !           692:                                         */
        !           693:                                        ioc_ack(EALREADY, m, gref);
        !           694:                                        break;
        !           695:                                }
        !           696:                                ATALK_ASSIGN(elapp->cfg.initial_addr, 0, 0, 0);
        !           697:                
        !           698:                                bcopy ((caddr_t) cfgp->if_name, (caddr_t) elapp->cfg.if_name, AT_IF_NAME_LEN);
        !           699:                                if (ATALK_VALUE(cfgp->initial_addr)) {
        !           700:                                        at_net_al       initial_net;
        !           701:                                        at_node initial_node;
        !           702: 
        !           703:                                        initial_node = *(at_node *)&cfgp->
        !           704:                                                        initial_addr.atalk_node;
        !           705:                                        initial_net = NET_VALUE(cfgp->
        !           706:                                                        initial_addr.atalk_net);
        !           707:                                        /*
        !           708:                                         * The net effect of the code that was here after A/UX
        !           709:                                         * version 29 was to ignore the prior node number settings. 
        !           710:                                         * As a result * Barracuda 3.0.1 machines cannot "remember" 
        !           711:                                         * their AppleTalk node number from the last AppleTalk 
        !           712:                                         * session.
        !           713:                                         * The following code reverts this code back to pre version 
        !           714:                                         * 29 style.
        !           715:                                         * The problem that version 29 was fixing really happens because
        !           716:                                         * readxpram (and writexpram)  in lap_init was returning a -1 
        !           717:                                         * instead of 0 on failure.
        !           718:                                         * Madan Valluri. May 12, 1993.
        !           719:                                         */
        !           720:                                        if ((initial_node<0xfe) && (initial_node>0) &&
        !           721:                                            !((initial_net == 0) ||
        !           722:                                                ((initial_net >= DDP_STARTUP_LOW)&&
        !           723:                                                (initial_net <= DDP_STARTUP_HIGH))))
        !           724:                                                elapp->cfg.initial_addr = 
        !           725:                                                    cfgp->initial_addr;
        !           726:                                }
        !           727:                                ioc_ack(0, m, gref);
        !           728:                                break;
        !           729: 
        !           730:                        case ELAP_IOC_SET_ZONE :
        !           731: #ifdef APPLETALK_DEBUG
        !           732: kprintf("ELAP_IOC_SET_ZONE\n");
        !           733: #endif
        !           734:                                /* ioctl to set the desired zone name for the 
        !           735:                                 * interface and when no router is present, to set
        !           736:                                 * multicast addr for pram zone for when router returns
        !           737:                                 */
        !           738:                                cfgp = (at_elap_cfg_t * ) gbuf_rptr(gbuf_cont(m));
        !           739: 
        !           740:                                if (cfgp->flags & ELAP_CFG_ZONE_MCAST) {
        !           741:                                        nbp_add_multicast(&cfgp->zonename, &elapp->elap_if);
        !           742:                                }
        !           743:                                else  {
        !           744:                                        if (elapp->elap_if.ifState == LAP_ONLINE) {
        !           745:                                                /* Can not allow setting zonename
        !           746:                                                * after we're already ONLINE
        !           747:                                                 */
        !           748:                                                ioc_ack(EALREADY, m, gref);
        !           749:                                                break;
        !           750:                                        }
        !           751:                                }
        !           752: 
        !           753:                                if (cfgp->zonename.len)
        !           754:                                        bcopy((caddr_t) &cfgp->zonename, 
        !           755:                                                (caddr_t) &elapp->cfg.zonename, 
        !           756:                                                cfgp->zonename.len+1);
        !           757:                                ioc_ack(0, m, gref);
        !           758:                                break;
        !           759:                        case LAP_IOC_ADD_ZONE:
        !           760: #ifdef APPLETALK_DEBUG
        !           761: kprintf("LAP_IOC_ADD_ZONE\n");
        !           762: #endif
        !           763:                                i = set_zones((if_zone_info_t *)gbuf_rptr(gbuf_cont(m)));
        !           764:                                ioc_ack(i, m, gref);
        !           765:                                break;
        !           766: 
        !           767:                        case LAP_IOC_ADD_ROUTE:
        !           768: #ifdef APPLETALK_DEBUG
        !           769: kprintf("LAP_IOC_ADD_ROUTE\n");
        !           770: #endif
        !           771:                                add_route((RT_entry *)gbuf_rptr(gbuf_cont(m)));
        !           772:                                ioc_ack(0, m, gref);
        !           773:                                break;
        !           774: 
        !           775:                        case LAP_IOC_ROUTER_INIT:       /* set routing tables sizes*/
        !           776: #ifdef APPLETALK_DEBUG
        !           777: kprintf("LAP_IOC_ROUTER_INIT\n");
        !           778: #endif
        !           779:                        {
        !           780:                                router_init_t *p = (router_init_t *)gbuf_rptr(gbuf_cont(m));
        !           781: 
        !           782:                                at_state.flags = p->flags;
        !           783:                                if (rt_table_init(p) == ENOBUFS) {
        !           784:                                        ioc_ack(ENOBUFS, m, gref);
        !           785:                                        break;
        !           786:                                }
        !           787:                                ioc_ack(0, m, gref);
        !           788:                        }
        !           789:                                break;
        !           790:                        case LAP_IOC_ROUTER_START:
        !           791: #ifdef APPLETALK_DEBUG
        !           792: kprintf("LAP_IOC_ROUTER_START\n");
        !           793: #endif
        !           794:                                gbuf_freem(gbuf_cont(m));
        !           795:                                gbuf_cont(m) = NULL;
        !           796:                                routerStart(0, m, gref);
        !           797:                                break;
        !           798: 
        !           799:                        case LAP_IOC_ROUTER_SHUTDOWN:
        !           800:                        { 
        !           801:                                int i, lap_id;
        !           802:                                gbuf_t *tmpm;
        !           803: 
        !           804: #ifdef APPLETALK_DEBUG
        !           805: kprintf("LAP_IOC_ROUTER_SHUTDOWN\n");
        !           806: #endif
        !           807: 
        !           808:                                routerShutdown(); 
        !           809: 
        !           810:                                /* go through ifID_table */
        !           811:                                for (i = 0; i < IF_TOTAL_MAX; i++)
        !           812:                                    if (ifID_table[i] && ifID_table[i]->ifName) {
        !           813:                                          lap_id = pat_ID(ifID_table[i]->ifName);
        !           814: 
        !           815:                                          /* was LAP_IOC_OFFLINE processing */
        !           816:                                          elap_offline(&elap_specifics[lap_id]);
        !           817: 
        !           818:                                          /* was LAP_IOC_DEL_IFNAME processing */
        !           819:                                          pat_units[lap_id].xname[0] = '\0';
        !           820:                                    }
        !           821: 
        !           822:                                /* was LAP_IOC_SHUT_DOWN processing */
        !           823:                                if (shutdown_gref != NULL) {
        !           824:                                        if ((tmpm = gbuf_alloc(1, PRI_HI)) == NULL) {
        !           825:                                                ioc_ack(ENOBUFS, m, gref);
        !           826:                                                break;
        !           827:                                        }
        !           828:                                        gbuf_wset(tmpm,1);
        !           829:                                        *gbuf_rptr(tmpm) = ESHUTDOWN;
        !           830:                                        gbuf_set_type(tmpm, MSG_ERROR);
        !           831:                                        atalk_putnext(shutdown_gref, tmpm);
        !           832:                                }
        !           833:                                ioc_ack(0, m, gref);
        !           834:                        }
        !           835:                                break;
        !           836: 
        !           837: 
        !           838:                        case LAP_IOC_SET_DBG :
        !           839: #ifdef APPLETALK_DEBUG
        !           840: kprintf("LAP_IOC_SET_DBG\n");
        !           841: #endif
        !           842:                                dbgBits = *(dbgBits_t *)gbuf_rptr(gbuf_cont(m));
        !           843:                                ioc_ack(0, m, gref);
        !           844:                                break;
        !           845: 
        !           846: 
        !           847:                        case LAP_IOC_GET_DBG:
        !           848: #ifdef APPLETALK_DEBUG
        !           849: kprintf("LAP_IOC_GET_DBG\n");
        !           850: #endif
        !           851:                                if ((gbuf_cont(m) = gbuf_alloc(sizeof(dbgBits_t), 
        !           852:                                        PRI_MED)) == NULL) {
        !           853:                                        ioc_ack(ENOBUFS, m, gref);
        !           854:                                        break;
        !           855:                                }
        !           856:                                 *(dbgBits_t *)gbuf_rptr(gbuf_cont(m)) = dbgBits;
        !           857:                                gbuf_wset(gbuf_cont(m),sizeof(dbgBits_t));
        !           858:                                iocbp->ioc_count = sizeof(dbgBits_t);
        !           859:                                ioc_ack(0, m, gref);
        !           860:                                break;
        !           861: 
        !           862:                        case LAP_IOC_GET_ZONE:
        !           863: #ifdef APPLETALK_DEBUG
        !           864: kprintf("LAP_IOC_GET_ZONE\n");
        !           865: #endif
        !           866:                                                /* return next ZT_entryno from ZT_table 
        !           867:                                                   a pointer to the struct ZT_entryno is passed down from
        !           868:                                                   user space and the first byte is cast to a int, if
        !           869:                                                   this int is non-zero, then the first ZT_entry is
        !           870:                                                   returned and subsequent calls with a zero value
        !           871:                                                   will return the next entry in the table. The next
        !           872:                                                   read after the last valid entry will return ENOMSG
        !           873:                                                 */
        !           874:                        {
        !           875:                                ZT_entryno *pZTe;
        !           876: 
        !           877:                                i =  *(int *)gbuf_rptr(gbuf_cont(m));
        !           878:                                gbuf_freem(gbuf_cont(m));
        !           879:                                gbuf_cont(m) = NULL;
        !           880: 
        !           881:                                pZTe = zt_getNextZone(i);
        !           882:                                if (pZTe) {
        !           883:                                        if ((gbuf_cont(m) = gbuf_alloc(sizeof(ZT_entryno), PRI_MED)) == NULL) {
        !           884:                                                ioc_ack(ENOBUFS, m, gref);
        !           885:                                                break;
        !           886:                                        }       
        !           887:                                        *(ZT_entryno *)gbuf_rptr(gbuf_cont(m)) = *pZTe;
        !           888:                                        gbuf_wset(gbuf_cont(m),sizeof(ZT_entryno));
        !           889:                                        iocbp->ioc_count = sizeof(ZT_entryno);
        !           890:                                        ioc_ack(0, m, gref);
        !           891:                                }
        !           892:                                else
        !           893:                                        ioc_ack(ENOMSG, m, gref);
        !           894:                        }
        !           895:                                break;
        !           896:                                
        !           897:                        case LAP_IOC_GET_DEFAULT_ZONE:
        !           898: #ifdef APPLETALK_DEBUG
        !           899: kprintf("LAP_IOC_GET_DEFAULT_ZONE\n");
        !           900: #endif
        !           901:                                {
        !           902:                                at_nvestr_t      *pnve;
        !           903: 
        !           904:                                i =  *(int *)gbuf_rptr(gbuf_cont(m));
        !           905:                                gbuf_freem(gbuf_cont(m));
        !           906:                                gbuf_cont(m) = NULL;
        !           907:                                pnve = getDefZone(i);
        !           908:                                if (pnve) {
        !           909:                                        if ((gbuf_cont(m) = gbuf_alloc(sizeof(*pnve), PRI_MED)) == NULL) {
        !           910:                                                ioc_ack(ENOBUFS, m, gref);
        !           911:                                                break;
        !           912:                                        }       
        !           913:                                        *(at_nvestr_t *)gbuf_rptr(gbuf_cont(m)) = *pnve;
        !           914:                                        gbuf_wset(gbuf_cont(m),sizeof(*pnve));
        !           915:                                        iocbp->ioc_count = sizeof(*pnve);
        !           916:                                }
        !           917:                                else 
        !           918:                                        iocbp->ioc_count = 0;
        !           919:                                }
        !           920:                                ioc_ack(0, m, gref);
        !           921:                                break;
        !           922:                        case LAP_IOC_GET_LOCAL_ZONE:
        !           923: #ifdef APPLETALK_DEBUG
        !           924: kprintf("LAP_IOC_GET_LOCAL_ZONE\n");
        !           925: #endif
        !           926:                                if (!(ROUTING_MODE || MULTIHOME_MODE)) {
        !           927:                                        ioc_ack(EPERM, m, gref);
        !           928:                                        break;
        !           929:                                }
        !           930:                        {
        !           931:                                if_zone_t        *ifz;
        !           932:                                int zone;
        !           933: 
        !           934:                                zone =  ((if_zone_t *)gbuf_rptr(gbuf_cont(m)))->ifzn.zone;
        !           935:                                gbuf_freem(gbuf_cont(m));
        !           936:                                gbuf_cont(m) = NULL;
        !           937:                                if ((gbuf_cont(m) = gbuf_alloc(sizeof(if_zone_t), PRI_MED)) == NULL) {
        !           938:                                        ioc_ack(ENOBUFS, m, gref);
        !           939:                                        break;
        !           940:                                }       
        !           941:                                ifz = (if_zone_t *)gbuf_rptr(gbuf_cont(m));
        !           942:                                ifz->ifzn.zone = zone;
        !           943:                                getRTRLocalZone(ifz);
        !           944:                                gbuf_wset(gbuf_cont(m),sizeof(*ifz));
        !           945:                                iocbp->ioc_count = sizeof(*ifz);
        !           946:                        }
        !           947:                                ioc_ack(0, m, gref);
        !           948:                                break;
        !           949:                        case LAP_IOC_GET_ROUTE:
        !           950: #ifdef APPLETALK_DEBUG
        !           951: kprintf("LAP_IOC_GET_ROUTE\n");
        !           952: #endif
        !           953:                                /* return next RT_entry from RT_table 
        !           954:                                 * a pointer to the struct RT_entry is
        !           955:                                 * passed down from user space and the first
        !           956:                                 * byte is cast to a int, if this int is
        !           957:                                 * non-zero, then the first RT_entry is
        !           958:                                 * returned and subsequent calls with a
        !           959:                                 * zero value will return the next entry in
        !           960:                                 * the table. The next read after the last
        !           961:                                 * valid entry will return ENOMSG
        !           962:                                 */
        !           963:                        {
        !           964:                                RT_entry *pRT;
        !           965: 
        !           966:                                i =  *(int *)gbuf_rptr(gbuf_cont(m));
        !           967:                                gbuf_freem(gbuf_cont(m));
        !           968:                                gbuf_cont(m) = NULL;
        !           969: 
        !           970:                                pRT = rt_getNextRoute(i);
        !           971:                                if (pRT) {
        !           972:                                        if ((gbuf_cont(m) = gbuf_alloc(sizeof(RT_entry), PRI_MED)) == NULL) {
        !           973:                                                ioc_ack(ENOBUFS, m, gref);
        !           974:                                                break;
        !           975:                                        }       
        !           976:                                        *(RT_entry *)gbuf_rptr(gbuf_cont(m)) = *pRT;
        !           977:                                        gbuf_wset(gbuf_cont(m),sizeof(RT_entry));
        !           978:                                        iocbp->ioc_count = sizeof(RT_entry);
        !           979:                                        ioc_ack(0, m, gref);
        !           980:                                }
        !           981:                                else
        !           982:                                        ioc_ack(ENOMSG, m, gref);
        !           983:                        }
        !           984:                                break;
        !           985:                        
        !           986:                        case LAP_IOC_SNMP_GET_DDP:
        !           987: #ifdef APPLETALK_DEBUG
        !           988: kprintf("LAP_IOC_SNMP_GET_DDP\n");
        !           989: #endif
        !           990:                                if (!shutdown_gref) {
        !           991:                                        ioc_ack(ENOTREADY, m, gref);
        !           992:                                        break;
        !           993:                                }
        !           994:                                if ((gbuf_cont(m) = gbuf_alloc(sizeof(snmpStats_t), 
        !           995:                                                PRI_MED)) == NULL) {
        !           996:                                        ioc_ack(ENOBUFS, m, gref);
        !           997:                                        break;
        !           998:                                }
        !           999:                                
        !          1000:                                *(snmpStats_t *)gbuf_rptr(gbuf_cont(m)) = snmpStats;
        !          1001:                                gbuf_wset(gbuf_cont(m),sizeof(snmpStats));
        !          1002:                                iocbp->ioc_count = sizeof(snmpStats);
        !          1003:                                ioc_ack(0, m, gref);
        !          1004:                                break;
        !          1005:                        case LAP_IOC_SNMP_GET_CFG:
        !          1006: #ifdef APPLETALK_DEBUG
        !          1007: kprintf("LAP_IOC_SNMP_GET_CFG\n");
        !          1008: #endif
        !          1009:                        {
        !          1010:                                int i,size;
        !          1011:                                snmpCfg_t       snmp;
        !          1012: 
        !          1013:                                i =  *(int *)gbuf_rptr(gbuf_cont(m));
        !          1014:                                gbuf_freem(gbuf_cont(m));
        !          1015:                                gbuf_cont(m) = NULL;
        !          1016:                                if (!shutdown_gref) {           /* if stack down */
        !          1017:                                        iocbp->ioc_count = 0;
        !          1018:                                        ioc_ack(ENOTREADY, m, gref);
        !          1019:                                        dPrintf(D_M_ELAP_LOW, D_L_INFO,
        !          1020:                                                ("elap_wput: cfg req, stack down\n"));
        !          1021:                                        break;
        !          1022:                                }
        !          1023:                                if (i == UPDATE_IF_CHANGED && 
        !          1024:                                        !(at_statep->flags & AT_ST_IF_CHANGED)) {
        !          1025:                                        iocbp->ioc_count = 0;
        !          1026:                                        ioc_ack(0, m, gref);
        !          1027:                                        dPrintf(D_M_ELAP_LOW, D_L_INFO,
        !          1028:                                                ("elap_wput: cfg req, unchanged\n"));
        !          1029:                                        break;
        !          1030:                                }
        !          1031:                                dPrintf(D_M_ELAP_LOW, D_L_INFO,
        !          1032:                                        ("elap_wput: cfg req, changed\n"));
        !          1033: 
        !          1034:                                if (getSnmpCfg(&snmp)) {
        !          1035:                                        dPrintf(D_M_ELAP,D_L_ERROR,
        !          1036:                                                ("elap_wput:SNMP_GET_CFG error\n"));
        !          1037:                                        ioc_ack(ENOMSG, m, gref);
        !          1038:                                        break;
        !          1039:                                }
        !          1040:                                        /* send up only used part of table */
        !          1041:                                size = sizeof(snmp) - 
        !          1042:                                           sizeof(snmpIfCfg_t) * (MAX_IFS - snmp.cfg_ifCnt);
        !          1043: 
        !          1044:                                if ((gbuf_cont(m) = gbuf_alloc(size, PRI_MED)) == NULL) {
        !          1045:                                        ioc_ack(ENOBUFS, m, gref);
        !          1046:                                        break;
        !          1047:                                }
        !          1048:                                bcopy(&snmp,gbuf_rptr(gbuf_cont(m)),size);
        !          1049:                                gbuf_wset(gbuf_cont(m),size);
        !          1050:                                iocbp->ioc_count = size;
        !          1051:                                at_statep->flags &= ~AT_ST_IF_CHANGED;
        !          1052:                                ioc_ack(0, m, gref);
        !          1053:                        }
        !          1054:                        break;
        !          1055: 
        !          1056:                        case LAP_IOC_SNMP_GET_AARP:
        !          1057:                        {
        !          1058:                                snmpAarpEnt_t *snmpp;
        !          1059:                                int bytes;
        !          1060: #ifdef APPLETALK_DEBUG
        !          1061: kprintf("LAP_IOC_SNMP_GET_AARP\n");
        !          1062: #endif
        !          1063:                                i =  *(int *)gbuf_rptr(gbuf_cont(m));
        !          1064:                                gbuf_freem(gbuf_cont(m));
        !          1065:                                gbuf_cont(m) = NULL;
        !          1066:                                dPrintf(D_M_ELAP,D_L_INFO,
        !          1067:                                        ("elap_wput:calling getarp,i=%d\n", i));
        !          1068:                                snmpp = getAarp(&i); 
        !          1069:                                bytes = i * sizeof(snmpAarpEnt_t);
        !          1070:                                dPrintf(D_M_ELAP,D_L_INFO,
        !          1071:                                        ("elap_wput:getarp returned, i=%d,bytes=%d\n", 
        !          1072:                                        i, bytes));
        !          1073:                                if (snmpp) {
        !          1074:                                        if ((gbuf_cont(m) = gbuf_alloc(bytes, PRI_MED)) == NULL) {
        !          1075:                                                ioc_ack(ENOBUFS, m, gref);
        !          1076:                                                break;
        !          1077:                                        }       
        !          1078:                                        bcopy(snmpp, gbuf_rptr(gbuf_cont(m)), bytes);
        !          1079:                                        gbuf_wset(gbuf_cont(m),bytes);
        !          1080:                                        iocbp->ioc_count = bytes;
        !          1081:                                        ioc_ack(0, m, gref);
        !          1082:                                }
        !          1083:                                else
        !          1084:                                        ioc_ack(ENOMSG, m, gref);
        !          1085:                        }
        !          1086:                        break;
        !          1087: 
        !          1088:                        case LAP_IOC_SNMP_GET_ZIP:
        !          1089: #ifdef APPLETALK_DEBUG
        !          1090: kprintf("LAP_IOC_SNMP_GET_ZIP\n");
        !          1091: #endif
        !          1092:                        { /* matching brace NOT in this case */
        !          1093:                                register int i,j;
        !          1094:                                register int size, total, tabsize;
        !          1095:                                gbuf_t  *mn;            /* new gbuf */
        !          1096:                                gbuf_t  *mo;            /* old gbuf */
        !          1097:                                gbuf_t  *mt;            /* temp */
        !          1098:                                snmpNbpTable_t          *nbp;
        !          1099: 
        !          1100:                                i =  *(int *)gbuf_rptr(gbuf_cont(m));
        !          1101:                                gbuf_freem(gbuf_cont(m));
        !          1102:                                gbuf_cont(m) = NULL;
        !          1103:                                if (!shutdown_gref) {
        !          1104:                                        ioc_ack(ENOTREADY, m, gref);
        !          1105:                                        break;
        !          1106:                                }
        !          1107:                                if (i == UPDATE_IF_CHANGED && 
        !          1108:                                        !(at_statep->flags & AT_ST_ZT_CHANGED)) {
        !          1109:                                        iocbp->ioc_count = 0;
        !          1110:                                        ioc_ack(0, m, gref);
        !          1111:                                        break;
        !          1112:                                }
        !          1113:                                mo=(gbuf_t*)NULL;
        !          1114:                                tabsize = getZipTableSize();
        !          1115: 
        !          1116:                                        /* retrieve table into multiple gbufs */
        !          1117:                                for (i =0; i<tabsize;  i+=j) {
        !          1118:                                        j = tabsize - i > 
        !          1119:                                                MAX_ZIP ? MAX_ZIP : tabsize - i;
        !          1120:                                        size = j < MAX_ZIP ? sizeof(ZT_entry)*j : MAX_ZIP_BYTES;
        !          1121:                                        if ((mn = gbuf_alloc(size, PRI_MED)) == NULL) {
        !          1122:                                                if (gbuf_cont(m))
        !          1123:                                                        gbuf_freem(gbuf_cont(m));
        !          1124:                                                ioc_ack(ENOBUFS, m, gref);
        !          1125:                                                break;
        !          1126:                                        }
        !          1127:                                        if (!mo)        {               /* if first new one */
        !          1128:                                                mt = mn;
        !          1129:                                                total = size;
        !          1130:                                        }
        !          1131:                                        else {
        !          1132:                                                gbuf_cont(mo) = mn;
        !          1133:                                                total += size;
        !          1134:                                        }
        !          1135:                                        mo = mn;
        !          1136:                                        getZipTable((ZT_entry*)gbuf_rptr(mn),i,j); 
        !          1137:                                        gbuf_wset(mn,size);
        !          1138:                                }
        !          1139:                                if ((gbuf_cont(m) = gbuf_alloc(sizeof(int), PRI_MED)) == NULL) {
        !          1140:                                        if (mt)
        !          1141:                                                gbuf_freem(mt);
        !          1142:                                        iocbp->ioc_count = 0;
        !          1143:                                        ioc_ack(ENOBUFS, m, gref);
        !          1144:                                        break;
        !          1145:                                }
        !          1146:                                if (!tabsize) {
        !          1147:                                        dPrintf(D_M_ELAP,D_L_WARNING,
        !          1148:                                                ("elap_wput:snmp: empty zip table\n"));
        !          1149:                                        total = 0;
        !          1150:                                }
        !          1151:                                *(int*)gbuf_rptr(gbuf_cont(m)) = total;         /* return table size */
        !          1152:                                gbuf_wset(gbuf_cont(m),sizeof(int));
        !          1153:                                iocbp->ioc_count = sizeof(int);
        !          1154:                                ioc_ack(0, m, gref);
        !          1155:                                if (tabsize)
        !          1156:                                        atalk_putnext(gref,mt);         /* send up table */
        !          1157:                                at_statep->flags &= ~AT_ST_ZT_CHANGED;
        !          1158:                                break;
        !          1159: 
        !          1160:                        case LAP_IOC_SNMP_GET_RTMP:
        !          1161: #ifdef APPLETALK_DEBUG
        !          1162: kprintf("LAP_IOC_SNMP_GET_RTMP\n");
        !          1163: #endif
        !          1164:                                i =  *(int *)gbuf_rptr(gbuf_cont(m));
        !          1165:                                gbuf_freem(gbuf_cont(m));
        !          1166:                                gbuf_cont(m) = NULL;
        !          1167:                                if (!shutdown_gref) {
        !          1168:                                        ioc_ack(ENOTREADY, m, gref);
        !          1169:                                        break;
        !          1170:                                }
        !          1171:                                if (i == UPDATE_IF_CHANGED && 
        !          1172:                                        !(at_statep->flags & AT_ST_RT_CHANGED)) {
        !          1173:                                        iocbp->ioc_count = 0;
        !          1174:                                        ioc_ack(0, m, gref);
        !          1175:                                        break;
        !          1176:                                }
        !          1177: 
        !          1178:                                mo=(gbuf_t*)NULL;
        !          1179:                                tabsize = getRtmpTableSize();
        !          1180: 
        !          1181:                                        /* retrieve table into multiple gbufs */
        !          1182:                                for (i =0; i<tabsize;  i+=j) {
        !          1183:                                        j = tabsize - i > 
        !          1184:                                                MAX_RTMP ? MAX_RTMP : tabsize - i;
        !          1185:                                        size = j < MAX_RTMP ? sizeof(RT_entry)*j : MAX_RTMP_BYTES;
        !          1186:                                        if ((mn = gbuf_alloc(size, PRI_MED)) == NULL) {
        !          1187:                                                if (gbuf_cont(m))
        !          1188:                                                        gbuf_freem(gbuf_cont(m));
        !          1189:                                                ioc_ack(ENOBUFS, m, gref);
        !          1190:                                                break;
        !          1191:                                        }
        !          1192:                                        if (!mo)        {               /* if first new one */
        !          1193:                                                mt = mn;
        !          1194:                                                total = size;
        !          1195:                                        }
        !          1196:                                        else {
        !          1197:                                                gbuf_cont(mo) = mn;
        !          1198:                                                total += size;
        !          1199:                                        }
        !          1200:                                        mo = mn;
        !          1201:                                        getRtmpTable((RT_entry*)gbuf_rptr(mn),i,j); 
        !          1202:                                        gbuf_wset(mn,size);
        !          1203:                                }
        !          1204:                                if ((gbuf_cont(m) = gbuf_alloc(sizeof(int), PRI_MED)) == NULL) {
        !          1205:                                        if (mt)
        !          1206:                                                gbuf_freem(mt);
        !          1207:                                        iocbp->ioc_count = 0;
        !          1208:                                        ioc_ack(ENOBUFS, m, gref);
        !          1209:                                        break;
        !          1210:                                }
        !          1211:                                if (!tabsize)
        !          1212:                                        total = 0;
        !          1213:                                *(int*)gbuf_rptr(gbuf_cont(m)) = total; /* return table size */
        !          1214:                                gbuf_wset(gbuf_cont(m),sizeof(int));
        !          1215:                                iocbp->ioc_count = sizeof(int);
        !          1216:                                ioc_ack(0, m, gref);
        !          1217:                                if (tabsize)
        !          1218:                                        atalk_putnext(gref,mt);         /* send up table */
        !          1219:                                at_statep->flags &= ~AT_ST_RT_CHANGED;
        !          1220:                                break;
        !          1221: 
        !          1222:                        case LAP_IOC_SNMP_GET_NBP:
        !          1223: #ifdef APPLETALK_DEBUG
        !          1224: kprintf("LAP_IOC_SNMP_GET_NBP\n");
        !          1225: #endif
        !          1226:                                i =  *(int *)gbuf_rptr(gbuf_cont(m));
        !          1227:                                gbuf_freem(gbuf_cont(m));
        !          1228:                                gbuf_cont(m) = NULL;
        !          1229:                                if (!shutdown_gref) {
        !          1230:                                        ioc_ack(ENOTREADY, m, gref);
        !          1231:                                        break;
        !          1232:                                }
        !          1233:                                if (i == UPDATE_IF_CHANGED && 
        !          1234:                                        !(at_statep->flags & AT_ST_NBP_CHANGED)) {
        !          1235:                                        iocbp->ioc_count = 0;
        !          1236:                                        ioc_ack(0, m, gref);
        !          1237:                                        dPrintf(D_M_ELAP_LOW, D_L_INFO,
        !          1238:                                                ("elap_wput: nbp req denied, no change\n"));
        !          1239:                                        break;
        !          1240:                                }
        !          1241: 
        !          1242:                                mo=(gbuf_t*)NULL;
        !          1243:                                tabsize = getNbpTableSize();
        !          1244: 
        !          1245:                                        /* retrieve table into multiple gbufs */
        !          1246:                                for (i =0; i<tabsize;  i+=j) {
        !          1247:                                        j = tabsize - i > 
        !          1248:                                                MAX_NBP ? MAX_NBP : tabsize - i;
        !          1249:                                        size = j < MAX_NBP ? sizeof(snmpNbpEntry_t)*j : MAX_NBP_BYTES;
        !          1250:                                        if (!i)
        !          1251:                                                size += SNMP_NBP_HEADER_SIZE;
        !          1252:                                        if ((mn = gbuf_alloc(size, PRI_MED)) == NULL) {
        !          1253:                                                if (gbuf_cont(m))
        !          1254:                                                        gbuf_freem(gbuf_cont(m));
        !          1255:                                                ioc_ack(ENOBUFS, m, gref);
        !          1256:                                                break;
        !          1257:                                        }
        !          1258:                                        if (!mo)        {               /* if first new one */
        !          1259:                                                mt = mn;
        !          1260:                                                total = size;
        !          1261:                                                nbp = (snmpNbpTable_t*)gbuf_rptr(mn);
        !          1262:                                                nbp->nbpt_entries = tabsize;
        !          1263:                                                nbp->nbpt_zone = 
        !          1264:                                                        ifID_table[IFID_HOME]->ifZoneName;
        !          1265:                                                getNbpTable(nbp->nbpt_table,i,j); 
        !          1266:                                        }
        !          1267:                                        else {
        !          1268:                                                gbuf_cont(mo) = mn;
        !          1269:                                                total += size;
        !          1270:                                                getNbpTable((snmpNbpEntry_t *)gbuf_rptr(mn),i,j); 
        !          1271:                                        }
        !          1272:                                        mo = mn;
        !          1273:                                        gbuf_wset(mn,size);
        !          1274:                                }
        !          1275:                                if ((gbuf_cont(m) = gbuf_alloc(sizeof(int), PRI_MED)) == NULL) {
        !          1276:                                        if (mt)
        !          1277:                                                gbuf_freem(mt);
        !          1278:                                        iocbp->ioc_count = 0;
        !          1279:                                        ioc_ack(ENOBUFS, m, gref);
        !          1280:                                        break;
        !          1281:                                }
        !          1282:                                if (!tabsize)
        !          1283:                                        total = 0;
        !          1284:                                *(int*)gbuf_rptr(gbuf_cont(m)) = total; /* return table size */
        !          1285:                                gbuf_wset(gbuf_cont(m),sizeof(int));
        !          1286:                                iocbp->ioc_count = sizeof(int);
        !          1287:                                ioc_ack(0, m, gref);
        !          1288:                                if (tabsize)
        !          1289:                                        atalk_putnext(gref,mt);         /* send up table */
        !          1290:                                at_statep->flags &= ~AT_ST_NBP_CHANGED;
        !          1291:                                break;
        !          1292:                        }
        !          1293:                                
        !          1294:                        case LAP_IOC_SET_MIX:
        !          1295: #ifdef APPLETALK_DEBUG
        !          1296: kprintf("LAP_IOC_SET_MIX\n");
        !          1297: #endif
        !          1298:                                RoutingMix = (*(short *)gbuf_rptr(gbuf_cont(m)) & 0xFFFF) * 2;
        !          1299:                                ioc_ack(0, m, gref);
        !          1300:                                break;
        !          1301:                        case LAP_IOC_SET_LOCAL_ZONES:
        !          1302:                                {       int i;
        !          1303: #ifdef APPLETALK_DEBUG
        !          1304: kprintf("LAP_IOC_SET_LOCAL_ZONES\n");
        !          1305: #endif
        !          1306:                                        i = setLocalZones((at_nbptuple_t*)gbuf_rptr(gbuf_cont(m)),
        !          1307:                                                gbuf_len(gbuf_cont(m)));
        !          1308:                                        ioc_ack(i,m,gref);
        !          1309:                                }
        !          1310:                                break;
        !          1311:                                
        !          1312:                        case LAP_IOC_IS_ZONE_LOCAL:
        !          1313:                                {
        !          1314:                                        at_nvestr_t *zone;
        !          1315: #ifdef APPLETALK_DEBUG
        !          1316: kprintf("LAP_IOC_IS_ZONE_LOCAL\n");
        !          1317: #endif
        !          1318:                                        zone = (at_nvestr_t *)gbuf_rptr(gbuf_cont(m));
        !          1319:                                        if (isZoneLocal(zone))
        !          1320:                                                ioc_ack(0,m,gref);
        !          1321:                                        else
        !          1322:                                                ioc_ack(ENOENT,m,gref);
        !          1323:                                }
        !          1324:                                break;
        !          1325:                        case LAP_IOC_GET_MODE:
        !          1326: #ifdef APPLETALK_DEBUG
        !          1327: kprintf("LAP_IOC_GET_MODE\n");
        !          1328: #endif
        !          1329:                                if ((gbuf_cont(m) = gbuf_alloc(sizeof(int), 
        !          1330:                                        PRI_MED)) == NULL) {
        !          1331:                                        ioc_ack(ENOBUFS, m, gref);
        !          1332:                                        break;
        !          1333:                                }
        !          1334:                                if (MULTIHOME_MODE)
        !          1335:                                        *(int *)gbuf_rptr(gbuf_cont(m)) =  AT_MODE_MHOME;
        !          1336:                                else if (ROUTING_MODE) 
        !          1337:                                        *(int *)gbuf_rptr(gbuf_cont(m)) =  AT_MODE_ROUTER; 
        !          1338:                                else
        !          1339:                                        *(int*)gbuf_rptr(gbuf_cont(m)) =  AT_MODE_SPORT;
        !          1340:                                gbuf_wset(gbuf_cont(m),sizeof(int));
        !          1341:                                iocbp->ioc_count = sizeof(int);
        !          1342:                                ioc_ack(0, m, gref);
        !          1343:                                break;
        !          1344:                        case LAP_IOC_GET_IF_NAMES:
        !          1345: #ifdef APPLETALK_DEBUG
        !          1346: kprintf("LAP_IOC_GET_IF_NAMES\n");
        !          1347: #endif
        !          1348:                                if ((gbuf_cont(m) = gbuf_alloc(sizeof(if_name_t) * IF_ANY_MAX, 
        !          1349:                                        PRI_MED)) == NULL) {
        !          1350:                                        ioc_ack(ENOBUFS, m, gref);
        !          1351:                                        break;
        !          1352:                                }
        !          1353:                                getIfNames((if_name_t *)gbuf_rptr(gbuf_cont(m)));
        !          1354:                                gbuf_wset(gbuf_cont(m),sizeof(if_name_t) * IF_ANY_MAX);
        !          1355:                                iocbp->ioc_count   = sizeof(if_name_t) * IF_ANY_MAX;
        !          1356:                                ioc_ack(0, m, gref);
        !          1357:                                break;
        !          1358:                        case LAP_IOC_SET_DEFAULT_ZONES:
        !          1359: #ifdef APPLETALK_DEBUG
        !          1360: kprintf("LAP_IOC_SET_DEFAULT_ZONES\n");
        !          1361: #endif
        !          1362:                                setDefaultZones((int*)gbuf_rptr(gbuf_cont(m)));
        !          1363:                                ioc_ack(0, m, gref);
        !          1364:                                break;
        !          1365: 
        !          1366:                        default:
        !          1367: #ifdef APPLETALK_DEBUG
        !          1368: kprintf("unknown ioctl %d\n", iocbp->ioc_cmd);
        !          1369: #endif
        !          1370:                                ioc_ack(ENOTTY, m, gref);
        !          1371:                                dPrintf(D_M_ELAP, D_L_WARNING,
        !          1372:                                        ("elap_wput: unknown ioctl (%d)\n", iocbp->ioc_cmd));
        !          1373: 
        !          1374:                                if (elapp)
        !          1375:                                        elapp->stats.unknown_mblks++;
        !          1376:                                break;
        !          1377:                        }
        !          1378:                }
        !          1379:                break;
        !          1380: 
        !          1381:        default:
        !          1382:                gbuf_freem(m);
        !          1383:                break;
        !          1384:        }
        !          1385: 
        !          1386:        return 0;
        !          1387: } /* elap_wput */
        !          1388: 
        !          1389: 
        !          1390: /* Called directly by ddp/zip.
        !          1391:  */
        !          1392: elap_dataput(m, elapp, addr_flag, addr)
        !          1393: register       gbuf_t  *m;
        !          1394: register elap_specifics_t *elapp;
        !          1395: u_char                 addr_flag;
        !          1396: char *addr;
        !          1397: {
        !          1398:        register int            size;
        !          1399:        int                     error;
        !          1400:        extern  int             zip_type_packet();
        !          1401:        struct  etalk_addr      dest_addr;
        !          1402:        struct  atalk_addr      dest_at_addr;
        !          1403:        gbuf_t                  *tmp;
        !          1404:        extern  gbuf_t          *growmsg();
        !          1405:        int             loop = TRUE;            /* flag to aarp to loopback (default) */
        !          1406: 
        !          1407:        /* the incoming frame is of the form {flag, address, ddp...}
        !          1408:         * where "flag" indicates whether the address is an 802.3
        !          1409:         * (link) address, or an appletalk address.  If it's an
        !          1410:         * 802.3 address, the packet can just go out to the network
        !          1411:         * through PAT, if it's an appletalk address, AT->802.3 address
        !          1412:         * resolution needs to be done.
        !          1413:         * If 802.3 address is known, strip off the flag and 802.3
        !          1414:         * address, and prepend 802.2 and 802.3 headers.
        !          1415:         */
        !          1416:        
        !          1417:        if (addr == NULL) {
        !          1418:                addr_flag = *(u_char *)gbuf_rptr(m);
        !          1419:                gbuf_rinc(m,1);
        !          1420:        }
        !          1421:        
        !          1422:        switch (addr_flag) {
        !          1423:        case AT_ADDR_NO_LOOP :
        !          1424:                loop = FALSE;
        !          1425:                /* pass thru */
        !          1426:        case AT_ADDR :
        !          1427:        if (addr == NULL) {
        !          1428:            dest_at_addr = *(struct atalk_addr *)gbuf_rptr(m);
        !          1429:            gbuf_rinc(m,sizeof(struct atalk_addr));
        !          1430:        } else
        !          1431:            dest_at_addr = *(struct atalk_addr *)addr;
        !          1432:            break;
        !          1433:        case ET_ADDR :
        !          1434:        if (addr == NULL) {
        !          1435:            dest_addr = *(struct etalk_addr *)gbuf_rptr(m);
        !          1436:            gbuf_rinc(m,sizeof(struct etalk_addr));
        !          1437:        } else
        !          1438:            dest_addr = *(struct etalk_addr *)addr;
        !          1439:            break;
        !          1440:        default :
        !          1441:            gbuf_freel(m);              /* unknown address type, chuck it */
        !          1442:            return(EINVAL);
        !          1443:         }
        !          1444: 
        !          1445:        while (gbuf_len(m) == 0) {
        !          1446:                tmp = m;
        !          1447:                m = gbuf_cont(m);
        !          1448:                gbuf_freeb(tmp); 
        !          1449:        }
        !          1450: 
        !          1451:        /* At this point, rptr points to ddp header for sure */
        !          1452: 
        !          1453:        if (elapp->elap_if.ifState == LAP_OFFLINE) {
        !          1454:            gbuf_freel(m);
        !          1455:                return(ENETDOWN);
        !          1456:        }
        !          1457: 
        !          1458:        if (elapp->elap_if.ifState == LAP_ONLINE_FOR_ZIP) {
        !          1459:                /* see if this is a ZIP packet that we need
        !          1460:                 * to let through even though network is
        !          1461:                 * not yet alive!!
        !          1462:                 */
        !          1463:                if (zip_type_packet(m) == 0) {
        !          1464:                gbuf_freel(m);
        !          1465:                        return(ENETDOWN);
        !          1466:                }
        !          1467:        }
        !          1468:        
        !          1469:        elapp->stats.xmit_packets++;
        !          1470:        size = gbuf_msgsize(m);
        !          1471:        elapp->stats.xmit_bytes += size;
        !          1472:        snmpStats.dd_outLong++;
        !          1473:        
        !          1474:        switch (addr_flag) {
        !          1475:        case AT_ADDR_NO_LOOP :
        !          1476:        case AT_ADDR :
        !          1477:            /*
        !          1478:             * we don't want elap to be looking into ddp header, so
        !          1479:             * it doesn't know net#, consequently can't do 
        !          1480:             * AMT_LOOKUP.  That task left to aarp now.
        !          1481:             */
        !          1482:            error = aarp_send_data(m,elapp,&dest_at_addr, loop);
        !          1483:            break;
        !          1484:        case ET_ADDR :
        !          1485:            error = pat_output(elapp->pat_id, m, &dest_addr, 0);
        !          1486:            break;
        !          1487:         }
        !          1488:        return (error);
        !          1489: } /* elap_dataput */
        !          1490: 
        !          1491: 
        !          1492: /************************************************************************
        !          1493:  * elap_online()
        !          1494:  *
        !          1495:  ************************************************************************/
        !          1496: 
        !          1497: int    elap_online (gref, if_name, aerr, m)
        !          1498: gref_t *gref;
        !          1499: char   *if_name;       /* name of h/w interface (e.g. en2) */
        !          1500: int    *aerr;
        !          1501: gbuf_t *m;
        !          1502: 
        !          1503: {
        !          1504:        register elap_specifics_t       *elapp;
        !          1505:        int                     errno;
        !          1506:        int i,j;
        !          1507: 
        !          1508:        if (if_name == NULL) {
        !          1509:                elapp = (elap_specifics_t *)gref;
        !          1510:                gref = elapp->wait_q;
        !          1511:                if (aerr != NULL)
        !          1512:                        goto AARP_sleep;
        !          1513:                if (elapp->elap_if.ifZipError != ZIP_RE_AARP) {
        !          1514:                        errno = at_delay_errno ? at_delay_errno : elapp->elap_if.ifZipError;
        !          1515:                        at_delay_errno = 0;
        !          1516:                        ioc_ack(errno, m, gref);
        !          1517:                        elapp->wait_p = 0; elapp->wait_q = 0;
        !          1518:                        dPrintf(D_M_ELAP, D_L_STARTUP_INFO,
        !          1519:                                ("elap_online: ifZipError=%d\n",
        !          1520:                                elapp->elap_if.ifZipError));
        !          1521:                }
        !          1522:                goto ZIP_sleep;
        !          1523:        }
        !          1524: 
        !          1525:        if ((i = pat_ID(if_name)) == -1)
        !          1526:                return(EINVAL);
        !          1527:        elapp = &elap_specifics[i];
        !          1528:        elapp->wait_p = elap_online; elapp->wait_q = gref; elapp->wait_m = m;
        !          1529:        if (elapp->elap_if.ifState == LAP_ONLINE_FOR_ZIP) {
        !          1530:                dPrintf(D_M_ELAP, D_L_STARTUP_INFO, 
        !          1531:                        ("elap_online: goto zip_online_only\n"));
        !          1532:                goto zip_online_only;
        !          1533:        }
        !          1534:        if (elapp->elap_if.ifState == LAP_ONLINE_ZONELESS) {
        !          1535:                ATALK_ASSIGN(elapp->cfg.initial_addr, 0, 0, 0);
        !          1536:                dPrintf(D_M_ELAP_LOW, D_L_STARTUP_INFO,
        !          1537:                        ("elap_online: goto re_aarp port=%d\n", elapp->elap_if.ifPort));
        !          1538:                goto re_aarp;                           /* just reset the net range */
        !          1539:        }
        !          1540: 
        !          1541:        if (!xpatcnt && !(at_statep->flags & AT_ST_PAT_INIT)) {
        !          1542:                pat_init();
        !          1543:            at_statep->flags |= AT_ST_PAT_INIT;
        !          1544:        }
        !          1545: 
        !          1546:        dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ("elap_online:%s elapp:0x%x\n",
        !          1547:                if_name[0] ? if_name : "NULL interface", (u_int) elapp));
        !          1548:        
        !          1549:        elapp->pat_id = pat_online(if_name, &elapp->elap_if.ifType);
        !          1550:        if (elapp->pat_id == -1) {
        !          1551:                /* pat_online returned in error, interface name must be bad */
        !          1552:                elapp->wait_m = 0;
        !          1553:                return(EINVAL);
        !          1554:        }
        !          1555:        if (elapp->elap_if.ifType == IFTYPE_TOKENTALK)
        !          1556:        {
        !          1557:                elapp->cable_multicast_addr = ttalk_multicast_addr;
        !          1558:                ddp_bit_reverse(&elapp->cable_multicast_addr);
        !          1559:        }
        !          1560:        else
        !          1561:        {
        !          1562:                elapp->cable_multicast_addr = etalk_multicast_addr;
        !          1563:                if (elapp->elap_if.ifType == IFTYPE_FDDITALK)
        !          1564:                        ddp_bit_reverse(&elapp->cable_multicast_addr);
        !          1565:        }
        !          1566:        bcopy((caddr_t) if_name, (caddr_t) elapp->cfg.if_name, AT_IF_NAME_LEN);
        !          1567:        bcopy((caddr_t) if_name, (caddr_t) elapp->elap_if.ifName, AT_IF_NAME_LEN);
        !          1568:        elapp->elap_if.ifUnit = IF_UNIT(if_name);
        !          1569: 
        !          1570:        if (elapp->elap_if.ifState != LAP_OFFLINE) {
        !          1571:                /* the network must be up already or hanging 
        !          1572:                 * up! 
        !          1573:                 */
        !          1574:                elapp->wait_m = 0;
        !          1575:                return (elapp->elap_if.ifState == LAP_HANGING_UP?EAGAIN:EALREADY);
        !          1576:        }
        !          1577:        
        !          1578:        bzero ((caddr_t) &elapp->stats, sizeof(at_elap_stats_t));
        !          1579:        elapp->elap_if.ifFlags = AT_IFF_ETHERTALK;
        !          1580:        if (elapp->flags & ELAP_CFG_HOME)       /* tell ddp_add_if if this is home */
        !          1581:                elapp->elap_if.ifFlags |= AT_IFF_DEFAULT;
        !          1582:                
        !          1583:        elapp->elap_if.ifLapp = (void*)elapp;
        !          1584: 
        !          1585:        /* ELAP/DDP interface is not streams based anymore */
        !          1586: 
        !          1587:        /* Get DDP started */
        !          1588:        if (errno = ddp_add_if(&elapp->elap_if)) {
        !          1589:                elapp->wait_m = 0;
        !          1590:                return (errno);
        !          1591:        }
        !          1592: 
        !          1593:                /* set up multicast address for cable-wide broadcasts */
        !          1594:        i = pat_control(elapp->pat_id, PAT_REG_MCAST, &elapp->cable_multicast_addr);
        !          1595:        j = pat_control(elapp->pat_id, PAT_REG_CONTEXT, (caddr_t)elapp);
        !          1596: 
        !          1597: 
        !          1598: re_aarp :
        !          1599:        /* We now call aarp_init() to assign an apple
        !          1600:         * talk node addr 
        !          1601:         */
        !          1602:        ATALK_ASSIGN(elapp->cfg.node, 0, 0, 0);
        !          1603: AARP_sleep :
        !          1604:        if (aerr != NULL)
        !          1605:                errno = *aerr;
        !          1606:        else
        !          1607:                errno = aarp_init(elapp, 0);
        !          1608:        if (errno != 0) {
        !          1609:                if (errno == ENOTREADY)
        !          1610:                        return (errno);
        !          1611:                dPrintf(D_M_ELAP, D_L_STATE_CHG, ("elap_online aarp_init for %s\n",
        !          1612:                        elapp->elap_if.ifName));
        !          1613:                pat_control(elapp->pat_id, PAT_UNREG_MCAST, &elapp->cable_multicast_addr);
        !          1614:                pat_offline(elapp->pat_id);
        !          1615:                ddp_rem_if (&elapp->elap_if);
        !          1616:                elapp->elap_if.ifState = LAP_OFFLINE;
        !          1617:                if ((aerr != NULL) || (elapp->elap_if.ifZipError == ZIP_RE_AARP)) {
        !          1618:                        ioc_ack(EADDRNOTAVAIL, m, gref);
        !          1619:                        elapp->wait_p = 0; elapp->wait_q = 0; elapp->wait_m = 0;
        !          1620:                        dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ("elap_online: ack 2\n"));
        !          1621:                }
        !          1622:                return (EADDRNOTAVAIL);
        !          1623:        }
        !          1624:        else 
        !          1625:                dPrintf(D_M_ELAP,D_L_STARTUP_INFO,
        !          1626:                        ("elap_online: aarp_init returns zero\n"));
        !          1627: 
        !          1628:        if (ROUTING_MODE)
        !          1629:        {
        !          1630:                dPrintf(D_M_ELAP,D_L_STARTUP_INFO, 
        !          1631:                        ("elap_online: re_aarp, we know it's a router...\n"));
        !          1632: 
        !          1633:                if (elapp->flags & ELAP_CFG_SEED) {
        !          1634:                                        /* add route table entry (zones to be added later) */
        !          1635:                        at_if_t *ifID;
        !          1636:                        ifID = &elapp->elap_if;
        !          1637:                        dPrintf(D_M_ELAP, D_L_STARTUP_INFO,
        !          1638:                                ("elap_online: rt_insert Cable %d-%d port =%d as SEED\n",
        !          1639:                                ifID->ifThisCableStart, ifID->ifThisCableEnd, ifID->ifPort));
        !          1640:                        rt_insert(      ifID->ifThisCableEnd,
        !          1641:                                                ifID->ifThisCableStart,
        !          1642:                                                0,0,0,
        !          1643:                                                ifID->ifPort,
        !          1644:                                                RTE_STATE_PERMANENT | RTE_STATE_ZKNOWN | RTE_STATE_GOOD
        !          1645:                                         );
        !          1646:                        /* LD 081694: set the RTR_SEED_PORT flag for seed ports */
        !          1647:                        ifID->ifFlags |= RTR_SEED_PORT;
        !          1648:                }
        !          1649:                else 
        !          1650:                        dPrintf(D_M_ELAP,D_L_STARTUP_INFO,
        !          1651:                                ("elap_online: it's a router, but non seed\n"));
        !          1652:        }
        !          1653:        if (elapp->flags & ELAP_CFG_ZONELESS) {
        !          1654:                elapp->elap_if.ifState = LAP_ONLINE_ZONELESS;
        !          1655:                if (aerr != NULL) {
        !          1656:                        errno = at_delay_errno;
        !          1657:                        at_delay_errno = 0;
        !          1658:                        ioc_ack(errno, m, gref);
        !          1659:                        elapp->wait_p = 0; elapp->wait_q = 0; elapp->wait_m = 0;
        !          1660:                        dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ("elap_online: ack 3\n"));
        !          1661:                }
        !          1662:                return(0);              /* if not home, it's zoneless */
        !          1663:        }
        !          1664: 
        !          1665: zip_online_only:
        !          1666:        if (ifID_table[IFID_HOME]) {
        !          1667:                {
        !          1668:                        char str[35];
        !          1669:                        at_nvestr_t *nve = &ifID_table[IFID_HOME]->ifZoneName;
        !          1670:                        strncpy(str,nve->str,nve->len);
        !          1671:                        str[nve->len] = '\0';
        !          1672:                }
        !          1673:        }
        !          1674:        sethzonehash(elapp);
        !          1675: 
        !          1676:        /* Get ZIP rolling to get zone multicast address, etc. */
        !          1677: 
        !          1678:        elapp->elap_if.ifState = LAP_ONLINE_FOR_ZIP;
        !          1679:        elapp->cfg.network_up = LAP_ONLINE_FOR_ZIP;
        !          1680:        elapp->wait_m = m;
        !          1681:        if ((errno = zip_control(&elapp->elap_if, ZIP_ONLINE)) != 0) {
        !          1682:                if (errno == ENOTREADY) 
        !          1683:                        return (ENOTREADY);
        !          1684:                
        !          1685: ZIP_sleep:
        !          1686:                switch (elapp->elap_if.ifZipError) {
        !          1687:                case 0 :
        !          1688:                        break;
        !          1689:                case ENOTREADY :
        !          1690:                        elapp->elap_if.ifZipError = 0;
        !          1691:                        return (ENOTREADY);
        !          1692:                case ZIP_RE_AARP :
        !          1693:                        elapp->wait_m = m;
        !          1694:                        goto re_aarp;
        !          1695:                case ENODEV :
        !          1696:                        /* return ENODEV to /etc/appletalk and let the 
        !          1697:                         * network be ONLINE.... this is to tackle the 
        !          1698:                         * case where zone name resolution is not 
        !          1699:                         * complete.
        !          1700:                         */
        !          1701:                        elapp->elap_if.ifState = LAP_ONLINE_FOR_ZIP;
        !          1702:                        elapp->cfg.network_up = LAP_ONLINE_FOR_ZIP;
        !          1703:                        return (ENODEV);
        !          1704:                default :
        !          1705:                        return (elapp->elap_if.ifZipError);
        !          1706:                }
        !          1707:        }
        !          1708: 
        !          1709:        elapp->elap_if.ifState = LAP_ONLINE;
        !          1710:        elapp->cfg.network_up = LAP_ONLINE;
        !          1711: 
        !          1712:        return (0);
        !          1713: } /* elap_online */
        !          1714: 
        !          1715: 
        !          1716: /****************************************************************************
        !          1717:  * elap_offline()
        !          1718:  *
        !          1719:  ****************************************************************************/
        !          1720: 
        !          1721: StaticProc
        !          1722: int    elap_offline(elapp)
        !          1723: register elap_specifics_t *elapp;
        !          1724: 
        !          1725: {
        !          1726:        void    zip_sched_getnetinfo(); /* forward reference */
        !          1727:        int     errno;
        !          1728:        int s;
        !          1729: 
        !          1730:        if (elapp->elap_if.ifState == LAP_OFFLINE) {
        !          1731: #ifdef APPLETALK_DEBUG
        !          1732: kprintf("elap_offline: network is down already.\n");
        !          1733: #endif
        !          1734:                /* the network must be down already! */
        !          1735:                return (EALREADY);
        !          1736:              }
        !          1737: 
        !          1738:        elapp->elap_if.ifState = LAP_HANGING_UP;
        !          1739:        elap_hangup(elapp);
        !          1740: 
        !          1741:        ATDISABLE(s, ddpinp_lock);
        !          1742:        if (MULTIPORT_MODE)
        !          1743:                RT_DELETE(elapp->elap_if.ifThisCableEnd,
        !          1744:                          elapp->elap_if.ifThisCableStart);
        !          1745:        ATENABLE(s, ddpinp_lock);
        !          1746: 
        !          1747:        if (errno = ddp_rem_if(&elapp->elap_if)) {
        !          1748: #ifdef APPLETALK_DEBUG
        !          1749: kprintf("elap_offline: ddp_rem_if ret %d\n", errno);
        !          1750: #endif
        !          1751:                return (errno);
        !          1752:        }
        !          1753: 
        !          1754:        dPrintf(D_M_ELAP, D_L_SHUTDN_INFO, ("elap_offline:%s\n", elapp->cfg.if_name));
        !          1755: 
        !          1756:        /* make sure no zip timeouts are left running */
        !          1757:        atalk_untimeout (zip_sched_getnetinfo, &elapp->elap_if,
        !          1758:                ((at_if_t *)&elapp->elap_if)->tmo_3);
        !          1759: 
        !          1760:        /* clean up the elapp-> and elapp->cfg structures.
        !          1761:         * initializing with 0 is okay,(state LAP_OFFLINE == 0).
        !          1762:         */
        !          1763:        bzero ((caddr_t) elapp, sizeof(elap_specifics_t));
        !          1764:        /* Deal with deferred multicast requests */
        !          1765:        dodefer();
        !          1766: 
        !          1767:        /* *** all of the static variables (and more globals?) should
        !          1768:           be reinitialized. *** */
        !          1769:        deferno = 0;
        !          1770:        gotIfs = 0;
        !          1771: 
        !          1772:        /* reset this as the last operation in the shutdown */
        !          1773:        /* *** appletalk_inited cannot be reinitialized until such time as
        !          1774:           AppleTalk is no longer permanently linked into the kernel.
        !          1775:           appletalk_inited = 0;
        !          1776:           */
        !          1777: 
        !          1778:        return (0);
        !          1779: } /* elap_offline */
        !          1780: 
        !          1781: StaticProc
        !          1782: void elap_hangup(elapp)
        !          1783: register elap_specifics_t      *elapp;
        !          1784: {
        !          1785:        /* Since AppleTalk is going away, remove the cable
        !          1786:         * multicast address  and turn the interface off so that all AppleTalk
        !          1787:         * packets are dropped in the driver itself.
        !          1788:         */
        !          1789:        /* Get rid of the zone multicast address prior to going Offline. */
        !          1790:        if (zone_multicast_addr.etalk_addr_octet[0] &&  
        !          1791:            (elapp->flags & ELAP_CFG_HOME)) {
        !          1792:            /* if zone is set && if this is the home port */
        !          1793:                pat_control(elapp->pat_id, PAT_UNREG_MCAST, 
        !          1794:                            &zone_multicast_addr);
        !          1795:                bzero((caddr_t) &zone_multicast_addr, AARP_ETHER_ADDR_LEN);
        !          1796:        }
        !          1797:        else if (*(int*)&elapp->ZoneMcastAddr)
        !          1798:                pat_control(elapp->pat_id, PAT_REG_MCAST, &elapp->ZoneMcastAddr);
        !          1799:        pat_control(elapp->pat_id, PAT_UNREG_MCAST, &elapp->cable_multicast_addr);
        !          1800:        pat_offline(elapp->pat_id);
        !          1801: 
        !          1802:        elapp->elap_if.ifState = LAP_OFFLINE;
        !          1803:        return;
        !          1804: }
        !          1805: 
        !          1806: 
        !          1807: int    elap_control (ifID, control, data)
        !          1808: register at_if_t  *ifID;
        !          1809: int              control;
        !          1810: u_char           *data;
        !          1811: {
        !          1812:        register elap_specifics_t       *elapp;
        !          1813: 
        !          1814:        /* extract elapp & verify */
        !          1815:        dPrintf(D_M_ELAP, D_L_INFO, ("elap_control:%d\n", control));
        !          1816:        if (!( elapp = (elap_specifics_t *) ifID->ifLapp)) {
        !          1817:                return(ENXIO);
        !          1818:        }
        !          1819: 
        !          1820:        switch (control) {
        !          1821:        case ELAP_CABLE_BROADCAST_FOR_ZONE :
        !          1822:                /* the cable-broadcast address is to be used as
        !          1823:                 * zone-multicast address.
        !          1824:                 */
        !          1825:                zone_multicast_addr = elapp->cable_multicast_addr;
        !          1826:                pat_control(elapp->pat_id, PAT_REG_MCAST, &zone_multicast_addr);
        !          1827:                break;
        !          1828:        case ELAP_REG_ZONE_MCAST :
        !          1829:                bcopy((caddr_t) data, (caddr_t) &zone_multicast_addr, AARP_ETHER_ADDR_LEN);
        !          1830:                pat_control(elapp->pat_id, PAT_REG_MCAST, &zone_multicast_addr);
        !          1831:                break;
        !          1832:        case ELAP_UNREG_ZONE_MCAST :
        !          1833:                if (*(int *)&zone_multicast_addr) {
        !          1834:                        pat_control(elapp->pat_id, PAT_UNREG_MCAST, 
        !          1835:                                &zone_multicast_addr);
        !          1836:                        bzero((caddr_t) &zone_multicast_addr, AARP_ETHER_ADDR_LEN);
        !          1837:                }
        !          1838:                break;
        !          1839:        case ELAP_RESET_INITNODE :
        !          1840:                ATALK_ASSIGN(elapp->cfg.initial_addr, 0, 0, 0);
        !          1841:                break;
        !          1842:        case ELAP_DESIRED_ZONE :
        !          1843:                if (elapp->cfg.zonename.len)
        !          1844:                        bcopy((caddr_t) &elapp->cfg.zonename, (caddr_t) data, 
        !          1845:                                elapp->cfg.zonename.len+1);
        !          1846:                break;
        !          1847:        default :
        !          1848:                dPrintf(D_M_ELAP, D_L_ERROR, ("elap_control:invalid control:%d\n",
        !          1849:                        control));
        !          1850:                break;
        !          1851:        }
        !          1852:        return (0);
        !          1853: }
        !          1854: 
        !          1855: StaticProc 
        !          1856: void get_ifs_stat(ifcfgp)
        !          1857: if_cfg_t       *ifcfgp;
        !          1858: {
        !          1859:        static if_cfg_t         ifcfg;
        !          1860:        int                             ifType, ifMax, i;
        !          1861:        char                            xtype, ifTypeNameBuf[4], ifName[5], *ifTypeName;
        !          1862: 
        !          1863:        bzero(&ifcfg.state[0][0], sizeof(ifcfg.state));
        !          1864:        for (ifType=0; ifType<IF_TYPENO_CNT; ifType++) {
        !          1865:                        
        !          1866:                        /* first get reference info on this specific type then status */
        !          1867:                ifTypeName = NULL;
        !          1868:                if (!strcmp(if_types[ifType], IF_TYPE_1)) {
        !          1869:                        ifMax = IF_TYPE_ET_MAX;
        !          1870:                        xtype = IFTYPE_ETHERTALK;
        !          1871:                } else if (!strcmp(if_types[ifType], IF_TYPE_3)) {
        !          1872:                        ifMax = IF_TYPE_TR_MAX;
        !          1873:                        xtype = IFTYPE_TOKENTALK;
        !          1874:                } else if (!strcmp(if_types[ifType], IF_TYPE_4)) {
        !          1875:                        ifMax = IF_TYPE_FD_MAX;
        !          1876:                        xtype = IFTYPE_FDDITALK;
        !          1877:                } else if (!strcmp(if_types[ifType], IF_TYPE_5)) {
        !          1878:                        ifMax = IF_TYPE_NT_MAX;
        !          1879:                        xtype = IFTYPE_NULLTALK;
        !          1880:                } else
        !          1881:                        continue;
        !          1882: 
        !          1883:                for (i=0; i<ifMax; i++) {
        !          1884:                        if (pat_units[i].xtype == xtype) {
        !          1885:                                ifcfg.state[ifType][pat_units[i].xunit] =
        !          1886:                                        elap_specifics[i].elap_if.ifState;
        !          1887:                                if (ifTypeName == NULL) {
        !          1888:                                        strcpy(ifTypeNameBuf, pat_units[i].xname);
        !          1889:                                        ifTypeName = ifTypeNameBuf;
        !          1890:                                        for (; *ifTypeName != '\0'; ifTypeName++) {
        !          1891:                                                if ( (*ifTypeName >= '0') && (*ifTypeName <= '9') )
        !          1892:                                                        break;
        !          1893:                                        }
        !          1894:                                        *ifTypeName = '\0';
        !          1895:                                        ifTypeName = ifTypeNameBuf;
        !          1896:                                }
        !          1897:                        }
        !          1898:                }
        !          1899:                
        !          1900:                /* here we query the OS for each possible I/F type in the system
        !          1901:                 * we only do this one time and keep the results in the static struct 
        !          1902:                 */
        !          1903:                if (!gotIfs && ifTypeName) {
        !          1904:                        for (i=0; i<ifMax; i++) {
        !          1905:                          sprintf(ifName,"%s%d",ifTypeName,i);
        !          1906:                          if (!strcmp(ifName, "nt0"))
        !          1907:                                /* set corresponding bit for I/F */
        !          1908:                                ifcfg.avail[ifType] |= 1<<i;
        !          1909:                          else if (ifunit(ifName))
        !          1910:                                   /* was (pat_ifpresent(ifName) != -1) */
        !          1911:                                /* set corresponding bit for I/F */
        !          1912:                                ifcfg.avail[ifType] |= 1<<i;    
        !          1913:                        }
        !          1914:                } /* if !gotIfs */
        !          1915:        } /* for ifType */
        !          1916:        ifcfg.ver_minor = AT_VERSION_MINOR;
        !          1917:        ifcfg.ver_major = AT_VERSION_MAJOR;
        !          1918:        ifcfg.ver_date  = AT_VERSION_DATE;
        !          1919:        bcopy(&ifcfg, ifcfgp, sizeof(if_cfg_t));
        !          1920:        gotIfs = 1;
        !          1921: } /* get_ifs_stat */
        !          1922:        
        !          1923: 
        !          1924: ifName2Port(name)
        !          1925:        char *name;
        !          1926: 
        !          1927: /* returns DDP port number of given interface name. to get ifID,
        !          1928:    use port number as index in ifID_table[]
        !          1929: 
        !          1930:    returns -1 if interface has no ifID entry.
        !          1931: */
        !          1932: 
        !          1933: {
        !          1934:        int i;
        !          1935: 
        !          1936:        for (i=0; i< IF_TOTAL_MAX; i++) {
        !          1937:                if (!ifID_table[i])                             /* if we reached end of entries */
        !          1938:                        return(-1);
        !          1939:                if (!strcmp(IFID2IFNAME(ifID_table[i]), name))
        !          1940:                        return(i);                                      /* got a match */
        !          1941:        }       
        !          1942:        return(-1);                                                     /* no luck, searched all entries */
        !          1943: }
        !          1944: 
        !          1945: StaticProc int set_zones(ifz)
        !          1946:        if_zone_info_t *ifz;
        !          1947: 
        !          1948: /* 1. adds zone to table
        !          1949:    2. looks up each route entry from zone I/F bitmap
        !          1950:    3. sets zone bit in each route entry
        !          1951: 
        !          1952:    returns  0 if successful
        !          1953:                   -1 if error occurred
        !          1954: */
        !          1955: {
        !          1956:        int type, iftype,i,j;
        !          1957:        short zno;
        !          1958:        RT_entry *rte;
        !          1959: 
        !          1960:        zno = zt_add_zone(ifz->zone_name.str, ifz->zone_name.len);
        !          1961: 
        !          1962:        if (zno == ZT_MAXEDOUT) {
        !          1963:                dPrintf(D_M_ELAP, D_L_ERROR, ("set_zones: error: table full\n"));
        !          1964:                return(-1);
        !          1965:        }
        !          1966:        if (!IFID_VALID(ifID_table[IFID_HOME])) {
        !          1967:                dPrintf(D_M_ELAP, D_L_ERROR, ("set_zones: home ifID is invalid\n"));
        !          1968:                return(-1);
        !          1969:        }
        !          1970:        if (ifz->zone_home)
        !          1971:                ifID_table[IFID_HOME]->ifZoneName = ifz->zone_name;
        !          1972: 
        !          1973:        for (iftype=0; iftype< IF_TYPENO_CNT; iftype++) {
        !          1974:                if (!strcmp(if_types[iftype], IF_TYPE_1))
        !          1975:                        type = IFTYPE_ETHERTALK;
        !          1976:                else if (!strcmp(if_types[iftype], IF_TYPE_3))
        !          1977:                        type = IFTYPE_TOKENTALK;
        !          1978:                else if (!strcmp(if_types[iftype], IF_TYPE_4))
        !          1979:                        type = IFTYPE_FDDITALK;
        !          1980:                else if (!strcmp(if_types[iftype], IF_TYPE_5))
        !          1981:                        type = IFTYPE_NULLTALK;
        !          1982:                else
        !          1983:                        continue;
        !          1984:                for (i=0; i<IF_ANY_MAX; i++)  {
        !          1985:                        if (ifz->zone_ifs[iftype] & 1<<i) {
        !          1986:                                for (j=0; j<IF_ANY_MAX; j++)  {
        !          1987:                                        if ( (elap_specifics[j].elap_if.ifType == type)
        !          1988:                                                        && (elap_specifics[j].elap_if.ifUnit == i) )
        !          1989:                                                break;
        !          1990:                                }
        !          1991:                                if (j < IF_ANY_MAX)  {
        !          1992:                                        rte = rt_blookup(ELAP_UNIT2NETSTOP(j));
        !          1993:                                        if (!rte) {
        !          1994:                                                dPrintf(D_M_ELAP, D_L_ERROR,
        !          1995:                                                        ("set_zones: error: can't find route\n"));
        !          1996:                                        }
        !          1997:                                        zt_set_zmap(zno, rte->ZoneBitMap); 
        !          1998: 
        !          1999:                                                        /* if first zone for this I/F, make default */
        !          2000:                                        if (!elap_specifics[j].elap_if.ifDefZone)
        !          2001:                                                 elap_specifics[j].elap_if.ifDefZone = zno;
        !          2002:                                }
        !          2003:                        }
        !          2004:                }
        !          2005:        }
        !          2006:        return(0);
        !          2007: }
        !          2008: 
        !          2009: StaticProc void add_route(rt)
        !          2010: RT_entry       *rt;
        !          2011: 
        !          2012: /* support ioctl to manually add routes to table. 
        !          2013:    this is really only for testing
        !          2014: */
        !          2015: {
        !          2016:        rt_insert(      rt->NetStop, rt->NetStart, rt->NextIRNet, 
        !          2017:                                rt->NextIRNode, rt->NetDist, rt->NetPort, 
        !          2018:                                rt->EntryState);
        !          2019:        dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ("adding route: %ud:%ud dist:%ud\n",
        !          2020:                rt->NetStart, rt->NetStop,rt->NetDist));
        !          2021: }
        !          2022: 
        !          2023: StaticProc void routerShutdown()
        !          2024: {
        !          2025:        dPrintf(D_M_ELAP, D_L_SHUTDN, ("routerShutdown called\n"));
        !          2026: 
        !          2027:         if (ROUTING_MODE) {
        !          2028: 
        !          2029:                 rtmp_shutdown();
        !          2030: 
        !          2031:                 /* free memory allocated for the rtmp/zip tables only at this point */
        !          2032:                FREE(ZT_table, M_RTABLE);
        !          2033:                 FREE(RT_table, M_RTABLE);
        !          2034:         }             
        !          2035:         nbp_shutdown();         /* clear all known NVE */
        !          2036:         at_state.flags = 0;     /* make sure inits are done on restart */
        !          2037: }
        !          2038: 
        !          2039: routerStart(flag, m, gref)
        !          2040: int flag;
        !          2041: gbuf_t *m;
        !          2042: gref_t *gref;
        !          2043: {
        !          2044:        register short i;
        !          2045:        register at_if_t *ifID;
        !          2046:        extern rtmp_router_start();
        !          2047: 
        !          2048:        if (flag) {
        !          2049:                if ((m = at_delay_m) != NULL) {
        !          2050:                        at_delay_m = NULL;
        !          2051:                        at_delay_func = rtmp_router_start;
        !          2052:                        at_delay_flag = 0;
        !          2053:                        ioc_ack(ENOTREADY, m, at_delay_gref); 
        !          2054:                }
        !          2055:                return (0);
        !          2056:        }
        !          2057: 
        !          2058:        /*
        !          2059:         * this will cause the ports to glean from the net the relevant
        !          2060:         * information before forwarding
        !          2061:         */
        !          2062:        for (i = 0 ; i < IF_TOTAL_MAX; i++) {
        !          2063:                        ifID = ifID_table[i];
        !          2064:                        if (ifID) {
        !          2065:                                dPrintf(D_M_ELAP, D_L_STARTUP_INFO, 
        !          2066:                                        ("routerStart Port %d (%s) set to activating\n",
        !          2067:                                        ifID->ifPort, ifID->ifName));
        !          2068:                                ifID->ifRoutingState = PORT_ACTIVATING;
        !          2069:                                ifID->ifFlags |= RTR_XNET_PORT;
        !          2070:                        }
        !          2071:                        else 
        !          2072:                                break;
        !          2073:        }
        !          2074: 
        !          2075:        /*
        !          2076:         * The next step is to check the information for each port before
        !          2077:         * declaring the ports up and forwarding
        !          2078:         */
        !          2079:        dPrintf(D_M_ELAP, D_L_STARTUP_INFO,
        !          2080:                ("router_start: waiting 20 sec before starting up\n"));
        !          2081: 
        !          2082:        at_delay_m = m; at_delay_gref = gref;
        !          2083:        atalk_timeout(routerStart, 1, 20 * SYS_HZ); 
        !          2084:        return (0);
        !          2085: }
        !          2086: 
        !          2087: StaticProc
        !          2088: void ZIPContinue(elapp, m)
        !          2089: elap_specifics_t *elapp;
        !          2090: gbuf_t *m;
        !          2091: {
        !          2092:        if (elapp->wait_p == NULL)
        !          2093:                gbuf_freem(m);
        !          2094:        else {
        !          2095:                (*elapp->wait_p)((void *)elapp, NULL, NULL, m);
        !          2096:        }
        !          2097: }
        !          2098: 
        !          2099: void ZIPwakeup(ifID)
        !          2100: at_if_t *ifID;
        !          2101: {
        !          2102:        int s;
        !          2103:        gbuf_t *m;
        !          2104:        elap_specifics_t *elapp;
        !          2105: 
        !          2106:        ATDISABLE(s, ddpinp_lock);
        !          2107:        elapp = (elap_specifics_t *)ifID->ifLapp;
        !          2108:        if ( (elapp != NULL) && ((m = elapp->wait_m) != NULL) ) {
        !          2109:                elapp->wait_m = NULL;
        !          2110:                ATENABLE(s, ddpinp_lock);
        !          2111:                ZIPContinue(elapp, m);
        !          2112:        } else
        !          2113:                ATENABLE(s, ddpinp_lock);
        !          2114: }
        !          2115: 
        !          2116: StaticProc
        !          2117: void AARPContinue(elapp, m)
        !          2118: elap_specifics_t *elapp;
        !          2119: gbuf_t *m;
        !          2120: {
        !          2121:        int aerr;
        !          2122: 
        !          2123:        if (elapp->wait_p == NULL)
        !          2124:                gbuf_freem(m);
        !          2125:        else {
        !          2126:                aerr = aarp_init(elapp, 1);
        !          2127:                (*elapp->wait_p)((void *)elapp, NULL, &aerr, m);
        !          2128:        }
        !          2129: }
        !          2130: 
        !          2131: void AARPwakeup(probe_cb)
        !          2132: aarp_amt_t *probe_cb;
        !          2133: {
        !          2134:        int s;
        !          2135:        gbuf_t *m;
        !          2136:        elap_specifics_t *elapp;
        !          2137: 
        !          2138:        ATDISABLE(s, arpinp_lock);
        !          2139:        elapp = probe_cb->elapp;
        !          2140:        if ( (elapp != NULL) && ((m = elapp->wait_m) != NULL) ) {
        !          2141:                elapp->wait_m = NULL;
        !          2142:                ATENABLE(s, arpinp_lock);
        !          2143:                AARPContinue(elapp, m);
        !          2144:        } else
        !          2145:                ATENABLE(s, arpinp_lock);
        !          2146: }
        !          2147: 
        !          2148: IF_UNIT(if_name)
        !          2149: char *if_name;          
        !          2150: {       
        !          2151:         for (; *if_name != '\0'; if_name++)
        !          2152:                 if ((*if_name >= '0') && (*if_name <= '9'))
        !          2153:                         return strtol(if_name, (char *)NULL, 10);
        !          2154:         return -1;
        !          2155: }               
        !          2156: 
        !          2157: 
        !          2158: StaticProc void getIfNames(names)
        !          2159: if_name_t *names;
        !          2160: {
        !          2161:        int i;
        !          2162:        at_if_t *ifID;
        !          2163:        bzero(names,sizeof(if_name_t) * IF_TOTAL_MAX);
        !          2164:        for (i=0, ifID=ifID_table[0]; ifID; ifID = ifID_table[++i], names++)
        !          2165:                if(ifID)
        !          2166:                        strncpy((char *)names,ifID->ifName,sizeof(*names));
        !          2167: 
        !          2168:        return;
        !          2169: }
        !          2170: 
        !          2171: void ddp_bit_reverse(addr)
        !          2172:        unsigned char *addr;
        !          2173: {
        !          2174: static unsigned char reverse_data[] = {
        !          2175:        0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
        !          2176:        0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
        !          2177:        0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
        !          2178:        0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
        !          2179:        0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
        !          2180:        0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
        !          2181:        0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
        !          2182:        0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
        !          2183:        0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
        !          2184:        0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
        !          2185:        0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
        !          2186:        0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
        !          2187:        0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
        !          2188:        0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
        !          2189:        0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
        !          2190:        0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
        !          2191:        0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
        !          2192:        0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
        !          2193:        0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
        !          2194:        0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
        !          2195:        0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
        !          2196:        0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
        !          2197:        0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
        !          2198:        0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
        !          2199:        0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
        !          2200:        0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
        !          2201:        0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
        !          2202:        0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
        !          2203:        0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
        !          2204:        0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
        !          2205:        0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
        !          2206:        0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
        !          2207:        };
        !          2208: 
        !          2209:        unsigned char k;
        !          2210: 
        !          2211:        for (k=0; k < 6; k++)
        !          2212:                addr[k] = reverse_data[addr[k]];
        !          2213: }
        !          2214: 
        !          2215: int elap_trackMcast(pat_id,func,addr)
        !          2216:        int pat_id;
        !          2217:        int func;
        !          2218:        caddr_t addr;
        !          2219: {
        !          2220:        int i, loc=-1;
        !          2221:        u_char c;
        !          2222:        switch(elap_specifics[pat_id].elap_if.ifType) {
        !          2223:        case IFTYPE_ETHERTALK: 
        !          2224:        case IFTYPE_FDDITALK: 
        !          2225:        case IFTYPE_NULLTALK: 
        !          2226:                                                /* set addr to point to unique part of addr */
        !          2227:                c = addr[5];
        !          2228:                                                /* first try to find match */
        !          2229:                for (i=0; i< MAX_MCASTS; i++) 
        !          2230:                        if (c == pat_units[pat_id].mcast[i]) {
        !          2231:                                loc = i;
        !          2232:                                break;
        !          2233:                        }
        !          2234:                                
        !          2235:                switch (func) {
        !          2236:                case MCAST_TRACK_DELETE:
        !          2237:                        if (loc >= 0) 
        !          2238:                                pat_units[pat_id].mcast[loc] = 0;
        !          2239: 
        !          2240:                        break;
        !          2241:                case MCAST_TRACK_ADD:
        !          2242:                        dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add loc:%d\n", i));
        !          2243:                        if (loc >= 0) {
        !          2244:                                dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add, addr was there\n"));
        !          2245:                                return(1);
        !          2246:                                break;                  /* already there */
        !          2247:                        }               
        !          2248:                        for (i=0; i< MAX_MCASTS; i++) 
        !          2249:                                if ( pat_units[pat_id].mcast[i] == 0) {
        !          2250:                                        loc = i;
        !          2251:                                        break;
        !          2252:                                }
        !          2253:                        dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add1 loc:%d\n", i));
        !          2254:                        if (loc >= 0) {
        !          2255:                                pat_units[pat_id].mcast[loc] = c;
        !          2256:                                dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add, adding(%x)\n",
        !          2257:                                        (*(int*)addr)&0xffffff));
        !          2258:                        }
        !          2259:                        else {
        !          2260:                                /*errno = ENOMEM; */ /*LD 5/7/97 nobody is using that */
        !          2261:                                return(-1);
        !          2262:                        }
        !          2263:                        break;  
        !          2264:                case MCAST_TRACK_CHECK:
        !          2265:                        if (loc >= 0) {
        !          2266:                                dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:check, addr was there\n"));
        !          2267:                                return(0);
        !          2268:                        }
        !          2269:                        else {
        !          2270:                                dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add, addr was NOT there\n"));
        !          2271:                                return(-1);
        !          2272:                        }
        !          2273:                        
        !          2274:                default:
        !          2275:                        /*errno = EINVAL;*/ /*LD 5/7/97 nobody is using that */
        !          2276:                        return(-1);
        !          2277:                }
        !          2278: 
        !          2279:        case IFTYPE_TOKENTALK:
        !          2280:                /* we would use the lowest byte of the addr argument as a value
        !          2281:                   to shift left a 1 to form the mcast mask for TR. We'll do this
        !          2282:                   when the time comes
        !          2283:                 */
        !          2284:        default:
        !          2285:                ;
        !          2286:        }
        !          2287:        return(0);
        !          2288: }
        !          2289: 
        !          2290: 
        !          2291: static 
        !          2292: getSnmpCfg(snmp)
        !          2293:        snmpCfg_t *snmp;
        !          2294: {
        !          2295:        int i;
        !          2296:        elap_specifics_t        *elapp;
        !          2297:        snmpIfCfg_t                     *ifc;
        !          2298:        at_if_t                         *ifID;
        !          2299: 
        !          2300:        snmp->cfg_ifCnt = 0;
        !          2301:        
        !          2302:        bzero(snmp,sizeof(snmpCfg_t));
        !          2303:        for (i=0, elapp=elap_specifics,ifc=snmp->cfg_ifCfg; 
        !          2304:                 i<IF_TYPE_ET_MAX; i++, elapp++, ifc++) {
        !          2305:                        ifID = &elap_specifics[i].elap_if;
        !          2306:                if (ifID->ifState != LAP_OFFLINE) {
        !          2307:                        snmp->cfg_ifCnt++;
        !          2308:                        strncpy(ifc->ifc_name,elapp->cfg.if_name,IF_NAME_SIZE);
        !          2309:                        ifc->ifc_aarpSize = getAarpTableSize(i);
        !          2310:                        ifc->ifc_addrSize = getPhysAddrSize(i);
        !          2311:                        switch (ifID->ifType) {
        !          2312:                                case IFTYPE_ETHERTALK:
        !          2313:                                        ifc->ifc_type = SNMP_TYPE_ETHER2;
        !          2314:                                        break;
        !          2315:                                case IFTYPE_TOKENTALK:
        !          2316:                                        ifc->ifc_type = SNMP_TYPE_TOKEN;
        !          2317:                                        break;
        !          2318:                                case IFTYPE_LOCALTALK:
        !          2319:                                        ifc->ifc_type = SNMP_TYPE_LOCAL;
        !          2320:                                        break;
        !          2321:                                case IFTYPE_FDDITALK:
        !          2322:                                case IFTYPE_NULLTALK:
        !          2323:                                default:
        !          2324:                                        ifc->ifc_type = SNMP_TYPE_OTHER;
        !          2325:                                        break;
        !          2326:                        }
        !          2327:                        ifc->ifc_start  = ifID->ifThisCableStart;
        !          2328:                        ifc->ifc_end    = ifID->ifThisCableEnd;
        !          2329:                        ifc->ifc_ddpAddr= ifID->ifThisNode;
        !          2330:                        ifc->ifc_status = ifID->ifState == LAP_ONLINE ? 1 : 2;
        !          2331:                        ifc->ifc_zoneName.len = 0;
        !          2332:                        if (ifID->ifZoneName.len != 0) {
        !          2333:                                ifc->ifc_zoneName = ifID->ifZoneName;
        !          2334:                        }
        !          2335:                        else if (ifID->ifDefZone) {
        !          2336:                                ifc->ifc_zoneName = ZT_table[ifID->ifDefZone-1].Zone;
        !          2337:                        }
        !          2338:                        else    /* temp, debug only */
        !          2339:                                ifc->ifc_zoneName = ZT_table[0].Zone;
        !          2340:                        if (ROUTING_MODE) {
        !          2341:                                if (ifID->ifFlags & RTR_SEED_PORT) {
        !          2342:                                        ifc->ifc_netCfg  = SNMP_CFG_CONFIGURED;
        !          2343:                                        ifc->ifc_zoneCfg = SNMP_CFG_CONFIGURED;
        !          2344:                                }
        !          2345:                                else {
        !          2346:                                        ifc->ifc_netCfg  = SNMP_CFG_GARNERED;
        !          2347:                                        ifc->ifc_zoneCfg = SNMP_CFG_GARNERED;
        !          2348:                                }
        !          2349:                        }
        !          2350:                        else  {         /* single-port mode */
        !          2351:                                if (ifID->ifRouterState == ROUTER_AROUND) {
        !          2352:                                        ifc->ifc_netCfg = SNMP_CFG_GARNERED;
        !          2353:                                }
        !          2354:                                else {
        !          2355:                                        ifc->ifc_netCfg = SNMP_CFG_GUESSED;
        !          2356:                                        ifc->ifc_zoneCfg = SNMP_CFG_UNCONFIG;
        !          2357:                                }
        !          2358:                        }
        !          2359:                }
        !          2360:        } 
        !          2361:        snmp->cfg_flags = at_statep->flags;
        !          2362: 
        !          2363:                
        !          2364:        return(0);
        !          2365: }      
        !          2366: 
        !          2367: void
        !          2368: elap_get_addr(pat_id, addr)
        !          2369:        int pat_id;
        !          2370:        unsigned char *addr; /* pointer to buffer where the address is returned */
        !          2371: {
        !          2372:        bcopy(pat_units[pat_id].xaddr, addr, pat_units[pat_id].xaddrlen);
        !          2373: }
        !          2374: 
        !          2375: int
        !          2376: pat_ID(if_name)
        !          2377:        char    *if_name;
        !          2378: {
        !          2379:        int pat_id;
        !          2380: 
        !          2381:        for (pat_id=0; pat_id < xpatcnt; pat_id++) {
        !          2382:                if (!strcmp(pat_units[pat_id].xname, if_name))
        !          2383:                        return(pat_id);
        !          2384:        }
        !          2385: 
        !          2386:        return(-1);
        !          2387: }
        !          2388: 
        !          2389: int
        !          2390: pat_control(pat_id, control, data)
        !          2391:        int pat_id;
        !          2392:        int control;
        !          2393:        void *data;
        !          2394: {
        !          2395:        typedef int (*procptr)();
        !          2396: 
        !          2397:        switch(control) {
        !          2398:        case PAT_REG_CONTEXT :
        !          2399:                pat_units[pat_id].context = data;
        !          2400:                break;
        !          2401:        case PAT_REG_AARP_UPSTREAM :
        !          2402:                pat_units[pat_id].aarp_func = (procptr)data;
        !          2403:                break;
        !          2404:        case PAT_REG_CHECKADDR :
        !          2405:                pat_units[pat_id].addr_check = (procptr)data;
        !          2406:                break;
        !          2407:        case PAT_REG_MCAST :
        !          2408:                if (elap_trackMcast(pat_id, MCAST_TRACK_ADD,data) == 1)
        !          2409:                        return(0);
        !          2410:                return(domcast(pat_id, control, data) == 0? 0 : -1);
        !          2411:        case PAT_UNREG_MCAST :
        !          2412:                elap_trackMcast(pat_id, MCAST_TRACK_DELETE, data);
        !          2413:                return(domcast(pat_id, control, data) == 0? 0 : -1);
        !          2414:        default :
        !          2415:                return(-1);
        !          2416:        }
        !          2417: 
        !          2418:        return(0);
        !          2419: }
        !          2420: 
        !          2421: StaticProc void
        !          2422: pat_init()
        !          2423: {
        !          2424: #ifdef CHECK_DDPR_FLAG
        !          2425:        extern int ddprunning_flag;
        !          2426: #endif
        !          2427:        /* zeroing the struct is okay since PAT_OFFLINE is zero */
        !          2428:        bzero(pat_units, sizeof(pat_units));
        !          2429: #ifdef CHECK_DDPR_FLAG
        !          2430:        ddprunning_flag = 0;
        !          2431: #endif
        !          2432: }
        !          2433: 
        !          2434: /*
        !          2435:  * Hopefully temporary hackery to deal with the need to
        !          2436:  *  register/deregister multicast addresses at interrupt level
        !          2437:  *  (as a result of incoming ZIP info).  ioctl routines can't
        !          2438:  *  be called at interrupt level due to locking constraints (MP
        !          2439:  *  and all that)
        !          2440:  * Unfortunately, I can't find a better way.
        !          2441:  */
        !          2442: 
        !          2443: static struct multidefer {
        !          2444:        int pat_id;
        !          2445:        int control;
        !          2446:        unsigned char addr[6];
        !          2447: } defer[NDEFERS];
        !          2448: 
        !          2449: StaticProc int
        !          2450: domcast(pat_id, control, data)
        !          2451:        int pat_id;
        !          2452:        int control;
        !          2453:        unsigned char *data;
        !          2454: {
        !          2455:        if (pat_units[pat_id].xtype == IFTYPE_NULLTALK)
        !          2456:                return 0;
        !          2457: #ifdef _AIX
        !          2458:        if  (getpid() == -1) {
        !          2459:                if (deferno < NDEFERS)  {
        !          2460:                        defer[deferno].pat_id = pat_id;
        !          2461:                        defer[deferno].control = control;
        !          2462:                        bcopy(data, defer[deferno].addr, sizeof(defer[deferno].addr));
        !          2463:                        deferno++;
        !          2464:                        return 0;
        !          2465:                        
        !          2466:                }
        !          2467:                else    
        !          2468:                        return EINVAL;
        !          2469:        }
        !          2470: #endif
        !          2471: 
        !          2472:        dPrintf(D_M_PAT, D_L_STARTUP, ("domcast:%s multicast %08x%04x pat_id:%d\n",
        !          2473:                        (control == PAT_REG_MCAST) ? "adding" : "deleting",
        !          2474:                        *(unsigned*)data, (*(unsigned *)(data+2))&0x0000ffff, pat_id));
        !          2475: 
        !          2476:        return pat_mcast(pat_id, control, data);
        !          2477: }
        !          2478: 
        !          2479: /*
        !          2480:  * Handle any backed-up requests to register/unregister multicasts.
        !          2481:  * Should not be called at interrupt level!
        !          2482:  */
        !          2483: StaticProc void
        !          2484: dodefer()
        !          2485: {
        !          2486:        unsigned char *data;
        !          2487:        while (deferno > 0)
        !          2488:        {       --deferno;
        !          2489:                data = (unsigned char *)defer[deferno].addr;
        !          2490: 
        !          2491:                dPrintf(D_M_PAT, D_L_STARTUP,
        !          2492:                        ("dodefer:%s multicast %08x%04x pat_id:%d defno:%d\n",
        !          2493:                        (defer[deferno].control == PAT_REG_MCAST) ? "adding" : "deleting",
        !          2494:                        *(unsigned*)data,
        !          2495:                        (*(unsigned *)(data+2))&0x0000ffff,
        !          2496:                        defer[deferno].pat_id,
        !          2497:                        deferno));
        !          2498:                
        !          2499:                domcast(defer[deferno].pat_id, defer[deferno].control,
        !          2500:                        defer[deferno].addr);
        !          2501:        }
        !          2502: }

unix.superglobalmegacorp.com

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