Annotation of kernel/bsd/netat/ddp_lap.c, revision 1.1.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.