Annotation of XNU/bsd/netat/ddp_lap.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  *     Copyright (c) 1988, 1989, 1993-1998 Apple Computer, Inc. 
                     24:  */
                     25: 
                     26: /* at_elap.c: 2.0, 1.29; 10/4/93; Apple Computer, Inc. */
                     27: 
                     28: /* This is the file which implements all the streams driver 
                     29:  * functionality required for EtherTalk.
                     30:  */
                     31: 
                     32: /* revision history 
                     33: 
                     34:  03-14-94  jjs         Changed all functions which assumed only one port would
                     35:                ever be used.  Added validate_msg_size, changed elap_online
                     36:                to work with the h/w name only (e.g. 'et2').
                     37: 
                     38:  Modified for MP, 1996 by Tuyen Nguyen
                     39:  Modified, March 17, 1997 by Tuyen Nguyen for MacOSX.
                     40: 
                     41: */
                     42: 
                     43: #define RESOLVE_DBG                            /* for debug.h global resolution */
                     44: #include <sys/errno.h>
                     45: #include <sys/types.h>
                     46: #include <sys/param.h>
                     47: #include <machine/spl.h>
                     48: #include <sys/systm.h>
                     49: #include <sys/kernel.h>
                     50: #include <sys/proc.h>
                     51: #include <sys/filedesc.h>
                     52: #include <sys/fcntl.h>
                     53: #include <sys/mbuf.h>
                     54: #include <sys/ioctl.h>
                     55: #include <sys/socket.h>
                     56: #include <sys/socketvar.h>
                     57: #include <sys/malloc.h>
                     58: #include <sys/sockio.h>
                     59: 
                     60: #include <net/if.h>
                     61: #include <net/if_types.h>
                     62: 
                     63: #include <netat/sysglue.h>
                     64: #include <netat/appletalk.h>
                     65: #include <netat/at_var.h>
                     66: #include <netat/ddp.h>
                     67: #include <netat/lap.h>
                     68: #include <netat/routing_tables.h>     /* rtmp+zip table structs  */
                     69: #include <netat/zip.h>
                     70: #include <netat/nbp.h>
                     71: #include <netat/at_snmp.h>
                     72: #include <netat/at_pcb.h>
                     73: #include <netat/at_aarp.h>
                     74: #include <netat/debug.h>
                     75: #include <netat/at_config.h>
                     76: 
                     77: /* globals */
                     78: 
                     79: at_ifaddr_t at_interfaces[IF_TOTAL_MAX];
                     80:        /* index for at_interfaces is not important */
                     81: at_ifaddr_t  *ifID_table[IF_TOTAL_MAX];
                     82:        /* the table of ifID structures, one per interface 
                     83:           (not just ethernet), indexed by DDP port
                     84:         * NOTE: for MH, entry 0 in this table is 
                     85:         *       now defined to be the default I/F
                     86:         */
                     87: at_ifaddr_t  *ifID_home;
                     88:        /* always ifID_table[IFID_HOME] for now, but will be used for
                     89:           dynamic "home port" assignment, later */
                     90: 
                     91: at_state_t     at_state;               /* global state of AT network */
                     92: if_types_t if_types[IF_TYPENO_CNT] = {{ IFT_ETHER, IF_TOTAL_MAX }};
                     93: 
                     94: snmpFlags_t snmpFlags;
                     95: 
                     96: int xpatcnt = 0;
                     97: 
                     98:        /* snmp defines */
                     99: #define MAX_BUFSIZE            8192   
                    100: #define MAX_RTMP               (MAX_BUFSIZE/sizeof(RT_entry)-1)
                    101: #define MAX_NBP                \
                    102:        ((MAX_BUFSIZE - SNMP_NBP_HEADER_SIZE)/sizeof(snmpNbpEntry_t)-1)
                    103: #define MAX_NBP_BYTES  (MAX_NBP * sizeof(snmpNbpEntry_t))
                    104: #define MAX_ZIP                        (MAX_BUFSIZE/sizeof(ZT_entry)-1)
                    105: #define MAX_RTMP_BYTES (MAX_RTMP * sizeof(RT_entry))
                    106: #define MAX_ZIP_BYTES  (MAX_ZIP * sizeof(ZT_entry))
                    107: 
                    108: /* externs */
                    109: extern TAILQ_HEAD(name_registry, _nve_) name_registry;
                    110: extern snmpStats_t     snmpStats;
                    111: extern atlock_t ddpinp_lock;
                    112: extern atlock_t arpinp_lock;
                    113: extern short appletalk_inited;
                    114: extern int adspInited;
                    115: extern struct atpcb ddp_head;
                    116: extern at_ddp_stats_t at_ddp_stats;
                    117: 
                    118: /* protos */
                    119: extern snmpAarpEnt_t * getAarp(int *);
                    120: extern int setLocalZones(at_nbptuple_t * , int);
                    121: extern int getRTRLocalZone(if_zone_t *);
                    122: extern void nbp_shutdown(), routershutdown(), ddp_brt_shutdown();
                    123: extern void ddp_brt_init(), rtmp_init(), rtmp_input();
                    124: extern rtmp_router_start(at_kern_err_t *);
                    125: static void getIfNames(if_name_t *);
                    126: static void add_route();
                    127: static int set_zones();
                    128: void elap_offline();
                    129: static int elap_online1(), re_aarp();
                    130: int at_reg_mcast(), at_unreg_mcast();
                    131: void  AARPwakeup(), ZIPwakeup();
                    132: void ddp_bit_reverse(), ddp_shutdown();
                    133: static void elap_hangup();
                    134: static getSnmpCfg();
                    135: 
                    136: at_ifaddr_t *find_ifID(if_name)
                    137:        char    *if_name;
                    138: {
                    139:        int pat_id;
                    140:          
                    141:        if (strlen(if_name))
                    142:                for (pat_id=0; pat_id < xpatcnt; pat_id++) {
                    143:                        if (!strcmp(at_interfaces[pat_id].ifName, if_name))
                    144:                                return(&at_interfaces[pat_id]);
                    145:                }
                    146: 
                    147:        return((at_ifaddr_t *)NULL);
                    148: }
                    149: 
                    150: static int validate_msg_size(m, gref, elapp)
                    151:        register gbuf_t *m;
                    152:        gref_t          *gref;
                    153:        at_ifaddr_t **elapp;
                    154: 
                    155: /* checks ioctl message type for minimum expected message size & 
                    156:    sends error back if size invalid
                    157: */
                    158: {
                    159:        register ioc_t *iocbp;
                    160:        register at_if_cfg_t *cfgp;
                    161:        int i, size = 1;
                    162:        
                    163:        *elapp = NULL;          
                    164:        iocbp = (ioc_t *) gbuf_rptr(m);
                    165: 
                    166:        dPrintf(D_M_ELAP, D_L_INFO, ("validate_msg_size: ioc_cmd = %d\n", 
                    167:                                     iocbp->ioc_cmd));
                    168:        switch (iocbp->ioc_cmd) {
                    169:                case LAP_IOC_ADD_ROUTE:
                    170:                        size = sizeof(RT_entry);
                    171:                        break;
                    172:                case LAP_IOC_ADD_ZONE:
                    173:                        size = sizeof(if_zone_info_t);
                    174:                        break;
                    175:                case LAP_IOC_GET_ROUTE:
                    176:                        size = sizeof(RT_entry);
                    177:                        break;
                    178:                case LAP_IOC_GET_ZONE:
                    179:                        size = sizeof(ZT_entryno);
                    180:                        break;
                    181:                case LAP_IOC_SNMP_GET_CFG:
                    182:                case LAP_IOC_SNMP_GET_AARP:
                    183:                case LAP_IOC_SNMP_GET_ZIP:
                    184:                case LAP_IOC_SNMP_GET_RTMP:
                    185:                case LAP_IOC_SNMP_GET_NBP:
                    186:                        size = sizeof(int);
                    187:                        break;
                    188:                case LAP_IOC_GET_LOCAL_ZONE:
                    189:                        size = sizeof(if_zone_t);
                    190:                        break;
                    191:                case LAP_IOC_CHECK_STATE:
                    192:                        size = 1;
                    193:                        break;
                    194: 
                    195:                case ELAP_IOC_GET_STATS:
                    196:                case LAP_IOC_SNMP_GET_DDP:
                    197:                case LAP_IOC_GET_IF_NAMES:
                    198:                        size = 0;
                    199:                        break;
                    200:                        
                    201:                /* these ioctls  send variable length data */
                    202:                case LAP_IOC_SET_LOCAL_ZONES:
                    203:                        size = -1;
                    204:                        break;
                    205:                default:
                    206:                        dPrintf(D_M_ELAP, D_L_ERROR, ("validate_msg_size: unknown ioctl\n"));
                    207:                        goto error;
                    208:        }
                    209: 
                    210:        if (size == 0) {                                /* a non-data ioctl */
                    211:                return(0);
                    212:        }
                    213: 
                    214:        if (gbuf_cont(m) != NULL) {
                    215:                i = gbuf_len(gbuf_cont(m));
                    216:                if (size == -1)
                    217:                        if (i >1)
                    218:                                return(0);
                    219:                        else
                    220:                                goto error;
                    221:        }
                    222:        if (iocbp->ioc_count < size || (gbuf_cont(m) == NULL) || i < size) {
                    223:                dPrintf(D_M_ELAP, D_L_ERROR,
                    224:                        ("ioctl msg error:s:%d c:%d bcont:%c delta:%d\n",
                    225:                         size, iocbp->ioc_count,
                    226:                         gbuf_cont(m)? 'Y' : 'N', i));
                    227:                goto error;
                    228:        }
                    229:        else
                    230:                return(0);
                    231: error:
                    232:        ioc_ack(EMSGSIZE, m, gref);
                    233:        return (EMSGSIZE);
                    234: } /* validate_msg_size */
                    235: 
                    236: int lap_online(elapp, cfgp)
                    237:      at_ifaddr_t *elapp;
                    238:      at_if_cfg_t *cfgp;
                    239: {
                    240:        int error;
                    241: 
                    242:        if (elapp->ifState != LAP_OFFLINE) {
                    243:                return(EALREADY);
                    244:        }
                    245: 
                    246:        elapp->flags = 0;
                    247:        if (cfgp->flags & ELAP_CFG_HOME) {
                    248:                if (ifID_home)  {
                    249:                        /* only 1 home allowed! */
                    250:                        return(EEXIST);
                    251:                }
                    252:                dPrintf(D_M_ELAP, D_L_STARTUP, 
                    253:                        ("elap_wput home I/F:%s\n", cfgp->ifr_name));
                    254:                elapp->flags |= ELAP_CFG_HOME;
                    255:        }
                    256: 
                    257:        if (MULTIPORT_MODE) {
                    258:                elapp->flags |= ELAP_CFG_ZONELESS;
                    259:                if (ROUTING_MODE && cfgp->netStart)
                    260:                        elapp->flags |= ELAP_CFG_SEED;
                    261:        }
                    262: 
                    263:        if (!DEFAULT_ZONE(&cfgp->zonename) &&
                    264:            (elapp->flags & ELAP_CFG_HOME) || MULTIHOME_MODE) {
                    265:                elapp->startup_zone = cfgp->zonename;
                    266:        }
                    267: 
                    268:        if (elapp->flags & ELAP_CFG_SEED) {
                    269:                dPrintf(D_M_ELAP, D_L_STARTUP_INFO,
                    270:                        ("elap_wput: found to be seed\n"));
                    271:                elapp->ifThisCableStart = cfgp->netStart;
                    272:                elapp->ifThisCableEnd   = cfgp->netEnd;
                    273:        }
                    274:        else {
                    275:                dPrintf(D_M_ELAP,D_L_ERROR, 
                    276:                        ("elap_wput: we believe we're not seed\n"));
                    277:                /* from ELAP_IOC_SET_CFG */
                    278:                if (ATALK_VALUE(cfgp->node)) {
                    279:                        u_short initial_net;
                    280:                        u_char  initial_node;
                    281: 
                    282:                        initial_node = cfgp->node.s_node;
                    283:                        initial_net = cfgp->node.s_net;
                    284:                        if ((initial_node<0xfe) && (initial_node>0) &&
                    285:                            !((initial_net == 0) ||
                    286:                              ((initial_net >= DDP_STARTUP_LOW)&&
                    287:                               (initial_net <= DDP_STARTUP_HIGH)))) {
                    288: 
                    289:                                elapp->initial_addr = cfgp->node;
                    290:                        }
                    291:                }
                    292:        }
                    293: 
                    294:        elapp->startup_error = 0;
                    295:        elapp->startup_inprogress = FALSE;
                    296:        if ((error = elap_online1(elapp)))
                    297:                ddp_rem_if(elapp);
                    298:        else 
                    299:                if (!(MULTIPORT_MODE) &&
                    300:                    elapp->ifZoneName.len == 1 &&
                    301:                    elapp->ifZoneName.str[0] == '*' &&
                    302:                    !DEFAULT_ZONE(&cfgp->zonename)) {
                    303:                        nbp_add_multicast(&cfgp->zonename, elapp);
                    304:                }
                    305:        return(error);
                    306: } /* lap_online */
                    307: 
                    308: /***********************************************************************
                    309:  * elap_wput()
                    310:  *
                    311:  **********************************************************************/
                    312: int elap_wput(gref, m)
                    313:      gref_t *gref;
                    314:      register gbuf_t   *m;
                    315: {
                    316:        at_ifaddr_t     *elapp;
                    317:        register ioc_t          *iocbp;
                    318:        register at_if_cfg_t    *cfgp;
                    319:        at_elap_stats_t         *statsp;
                    320:        int error, i;
                    321:        int                     (*func)();
                    322:        gbuf_t          *tmpm;
                    323:        at_ifaddr_t *patp;
                    324: 
                    325: 
                    326:        switch (gbuf_type(m)) {
                    327:        case MSG_DATA:
                    328:                gbuf_freem(m);
                    329:                dPrintf(D_M_ELAP,D_L_ERROR,
                    330:                        ("Output data to control channel is ignored\n"));
                    331:        break;
                    332: 
                    333:        case MSG_IOCTL:
                    334:                iocbp = (ioc_t *) gbuf_rptr(m);
                    335: 
                    336:                if (validate_msg_size(m, gref, &elapp))
                    337:                        break;  
                    338: 
                    339:                if (elapp)
                    340:                        cfgp = (at_if_cfg_t*) gbuf_rptr(gbuf_cont(m));
                    341: 
                    342:                if (LAP_IOC_MYIOCTL(iocbp->ioc_cmd) || 
                    343:                    ELAP_IOC_MYIOCTL(iocbp->ioc_cmd)) {
                    344: 
                    345:                        switch (iocbp->ioc_cmd) {
                    346: 
                    347:                        case LAP_IOC_CHECK_STATE:
                    348: #ifdef APPLETALK_DEBUG
                    349:                                kprintf("LAP_IOC_CHECK_STATE\n");
                    350: #endif
                    351:                                error = (!(at_state.flags & AT_ST_STARTED))?
                    352:                                                ENOTREADY : 0;
                    353:                                if (error == 0) {
                    354:                                        int size;
                    355:                                        dPrintf(D_M_ELAP,D_L_INFO,
                    356:                                                ("elap_wput: CHECK_STATE 1\n"));
                    357: 
                    358:                                        /* re-use gbuf */
                    359:                                        tmpm = gbuf_cont(m);
                    360:                                        gbuf_wset(tmpm, 0);
                    361: 
                    362:                                        size = list_pids((int *)gbuf_rptr(tmpm), 
                    363:                                                         10); /* *** 10 just for now *** */
                    364:                                        gbuf_wset(tmpm, (size * sizeof(int)));
                    365:                                        gbuf_set_type(tmpm, MSG_DATA);
                    366:                                        ((ioc_t *)gbuf_rptr(m))->ioc_count = gbuf_msgsize(tmpm);
                    367:                                        ioc_ack(0, m, gref);
                    368:                                } else {
                    369:                                        dPrintf(D_M_ELAP,D_L_INFO,
                    370:                                                ("elap_wput: CHECK_STATE 2\n"));
                    371:                                        ioc_ack(error, m, gref);
                    372:                                }
                    373:                                break;
                    374: 
                    375:                        case ELAP_IOC_GET_STATS:
                    376: #ifdef APPLETALK_DEBUG
                    377:                                kprintf("LAP_IOC_GET_STATS\n");
                    378: #endif
                    379:                                if ( (gbuf_cont(m) == NULL)
                    380:                                     || (elapp = find_ifID(gbuf_rptr(gbuf_cont(m)))) == NULL) {
                    381:                                        ioc_ack(EINVAL, m, gref);
                    382:                                        break;
                    383:                                }
                    384:                                gbuf_freem(gbuf_cont(m));
                    385:                                if ((gbuf_cont(m) =gbuf_alloc(sizeof(at_elap_stats_t), 
                    386:                                        PRI_MED)) == NULL) {
                    387:                                        ioc_ack(ENOBUFS, m, gref);
                    388:                                        break;
                    389:                                }
                    390:                                statsp = ((at_elap_stats_t *)gbuf_rptr(gbuf_cont(m)));
                    391:                                *statsp = elapp->stats;
                    392:                                gbuf_wset(gbuf_cont(m),sizeof(at_elap_stats_t));
                    393:                                iocbp->ioc_count = sizeof(at_elap_stats_t);
                    394:                                ioc_ack(0, m, gref);
                    395:                                break;
                    396: 
                    397:                        case LAP_IOC_ADD_ZONE:
                    398: #ifdef APPLETALK_DEBUG
                    399:                                kprintf("LAP_IOC_ADD_ZONE\n");
                    400: #endif
                    401:                                i = set_zones((if_zone_info_t *)gbuf_rptr(gbuf_cont(m)));
                    402:                                ioc_ack(i, m, gref);
                    403:                                break;
                    404: 
                    405:                        case LAP_IOC_ADD_ROUTE:
                    406: #ifdef APPLETALK_DEBUG
                    407:                                kprintf("LAP_IOC_ADD_ROUTE\n");
                    408: #endif
                    409:                                add_route((RT_entry *)gbuf_rptr(gbuf_cont(m)));
                    410:                                ioc_ack(0, m, gref);
                    411:                                break;
                    412: 
                    413:                        case LAP_IOC_GET_ZONE:
                    414: #ifdef APPLETALK_DEBUG
                    415:                          kprintf("LAP_IOC_GET_ZONE\n");
                    416: #endif
                    417:                          /* return next ZT_entryno from ZT_table 
                    418:                             a pointer to the struct ZT_entryno is passed down from
                    419:                             user space and the first byte is cast to a int, if
                    420:                             this int is non-zero, then the first ZT_entry is
                    421:                             returned and subsequent calls with a zero value
                    422:                             will return the next entry in the table. The next
                    423:                             read after the last valid entry will return EINVAL
                    424:                          */
                    425:                        {
                    426:                                ZT_entryno *pZTe;
                    427: 
                    428:                                i =  *(int *)gbuf_rptr(gbuf_cont(m));
                    429:                                gbuf_freem(gbuf_cont(m));
                    430:                                gbuf_cont(m) = NULL;
                    431: 
                    432:                                pZTe = zt_getNextZone(i);
                    433:                                if (pZTe) {
                    434:                                        if ((gbuf_cont(m) = gbuf_alloc(sizeof(ZT_entryno), PRI_MED)) == NULL) {
                    435:                                                ioc_ack(ENOBUFS, m, gref);
                    436:                                                break;
                    437:                                        }       
                    438:                                        *(ZT_entryno *)gbuf_rptr(gbuf_cont(m)) = *pZTe;
                    439:                                        gbuf_wset(gbuf_cont(m),sizeof(ZT_entryno));
                    440:                                        iocbp->ioc_count = sizeof(ZT_entryno);
                    441:                                        ioc_ack(0, m, gref);
                    442:                                }
                    443:                                else
                    444:                                        ioc_ack(EINVAL, m, gref);
                    445:                        }
                    446:                                break;
                    447:                        case LAP_IOC_GET_LOCAL_ZONE:
                    448: #ifdef APPLETALK_DEBUG
                    449:                                kprintf("LAP_IOC_GET_LOCAL_ZONE\n");
                    450: #endif
                    451:                                if (!MULTIPORT_MODE) {
                    452:                                        ioc_ack(EPERM, m, gref);
                    453:                                        break;
                    454:                                }
                    455:                        {
                    456:                                if_zone_t        *ifz;
                    457:                                int zone;
                    458: 
                    459:                                zone =  ((if_zone_t *)gbuf_rptr(gbuf_cont(m)))->ifzn.zone;
                    460:                                gbuf_freem(gbuf_cont(m));
                    461:                                gbuf_cont(m) = NULL;
                    462:                                if ((gbuf_cont(m) = gbuf_alloc(sizeof(if_zone_t), PRI_MED)) == NULL) {
                    463:                                        ioc_ack(ENOBUFS, m, gref);
                    464:                                        break;
                    465:                                }       
                    466:                                ifz = (if_zone_t *)gbuf_rptr(gbuf_cont(m));
                    467:                                ifz->ifzn.zone = zone;
                    468:                                getRTRLocalZone(ifz);
                    469:                                gbuf_wset(gbuf_cont(m),sizeof(*ifz));
                    470:                                iocbp->ioc_count = sizeof(*ifz);
                    471:                        }
                    472:                                ioc_ack(0, m, gref);
                    473:                                break;
                    474:                        case LAP_IOC_GET_ROUTE:
                    475: #ifdef APPLETALK_DEBUG
                    476:                                kprintf("LAP_IOC_GET_ROUTE\n");
                    477: #endif
                    478:                                /* return next RT_entry from RT_table 
                    479:                                 * a pointer to the struct RT_entry is
                    480:                                 * passed down from user space and the first
                    481:                                 * byte is cast to a int, if this int is
                    482:                                 * non-zero, then the first RT_entry is
                    483:                                 * returned and subsequent calls with a
                    484:                                 * zero value will return the next entry in
                    485:                                 * the table. The next read after the last
                    486:                                 * valid entry will return EINVAL
                    487:                                 */
                    488:                        {
                    489:                                RT_entry *pRT;
                    490: 
                    491:                                i =  *(int *)gbuf_rptr(gbuf_cont(m));
                    492:                                gbuf_freem(gbuf_cont(m));
                    493:                                gbuf_cont(m) = NULL;
                    494: 
                    495:                                pRT = rt_getNextRoute(i);
                    496:                                if (pRT) {
                    497:                                        if ((gbuf_cont(m) = gbuf_alloc(sizeof(RT_entry), PRI_MED)) == NULL) {
                    498:                                                ioc_ack(ENOBUFS, m, gref);
                    499:                                                break;
                    500:                                        }       
                    501:                                        *(RT_entry *)gbuf_rptr(gbuf_cont(m)) = *pRT;
                    502:                                        gbuf_wset(gbuf_cont(m),sizeof(RT_entry));
                    503:                                        iocbp->ioc_count = sizeof(RT_entry);
                    504:                                        ioc_ack(0, m, gref);
                    505:                                }
                    506:                                else
                    507:                                        ioc_ack(EINVAL, m, gref);
                    508:                        }
                    509:                                break;
                    510:                        
                    511:                        case LAP_IOC_SNMP_GET_DDP:
                    512: #ifdef APPLETALK_DEBUG
                    513:                                kprintf("LAP_IOC_SNMP_GET_DDP\n");
                    514: #endif
                    515:                                if (!(at_state.flags & AT_ST_STARTED)) {
                    516:                                        ioc_ack(ENOTREADY, m, gref);
                    517:                                        break;
                    518:                                }
                    519:                                if ((gbuf_cont(m) = gbuf_alloc(sizeof(snmpStats_t), 
                    520:                                                PRI_MED)) == NULL) {
                    521:                                        ioc_ack(ENOBUFS, m, gref);
                    522:                                        break;
                    523:                                }
                    524:                                
                    525:                                *(snmpStats_t *)gbuf_rptr(gbuf_cont(m)) = snmpStats;
                    526:                                gbuf_wset(gbuf_cont(m),sizeof(snmpStats));
                    527:                                iocbp->ioc_count = sizeof(snmpStats);
                    528:                                ioc_ack(0, m, gref);
                    529:                                break;
                    530:                        case LAP_IOC_SNMP_GET_CFG:
                    531: #ifdef APPLETALK_DEBUG
                    532:                                kprintf("LAP_IOC_SNMP_GET_CFG\n");
                    533: #endif
                    534:                        {
                    535:                                int i,size;
                    536:                                snmpCfg_t       snmp;
                    537: 
                    538:                                i =  *(int *)gbuf_rptr(gbuf_cont(m));
                    539:                                gbuf_freem(gbuf_cont(m));
                    540:                                gbuf_cont(m) = NULL;
                    541:                                if (!(at_state.flags & AT_ST_STARTED)) {
                    542:                                        /* if stack down */
                    543:                                        iocbp->ioc_count = 0;
                    544:                                        ioc_ack(ENOTREADY, m, gref);
                    545:                                        dPrintf(D_M_ELAP_LOW, D_L_INFO,
                    546:                                                ("elap_wput: cfg req, stack down\n"));
                    547:                                        break;
                    548:                                }
                    549:                                if (i == UPDATE_IF_CHANGED && 
                    550:                                        !(at_state.flags & AT_ST_IF_CHANGED)) {
                    551:                                        iocbp->ioc_count = 0;
                    552:                                        ioc_ack(0, m, gref);
                    553:                                        dPrintf(D_M_ELAP_LOW, D_L_INFO,
                    554:                                                ("elap_wput: cfg req, unchanged\n"));
                    555:                                        break;
                    556:                                }
                    557:                                dPrintf(D_M_ELAP_LOW, D_L_INFO,
                    558:                                        ("elap_wput: cfg req, changed\n"));
                    559: 
                    560:                                if (getSnmpCfg(&snmp)) {
                    561:                                        dPrintf(D_M_ELAP,D_L_ERROR,
                    562:                                                ("elap_wput:SNMP_GET_CFG error\n"));
                    563:                                        ioc_ack(EOPNOTSUPP, m, gref);
                    564:                                        break;
                    565:                                }
                    566:                                        /* send up only used part of table */
                    567:                                size = sizeof(snmp) - 
                    568:                                           sizeof(snmpIfCfg_t) * (MAX_IFS - snmp.cfg_ifCnt);
                    569: 
                    570:                                if ((gbuf_cont(m) = gbuf_alloc(size, PRI_MED)) == NULL) {
                    571:                                        ioc_ack(ENOBUFS, m, gref);
                    572:                                        break;
                    573:                                }
                    574:                                bcopy(&snmp,gbuf_rptr(gbuf_cont(m)),size);
                    575:                                gbuf_wset(gbuf_cont(m),size);
                    576:                                iocbp->ioc_count = size;
                    577:                                at_state.flags &= ~AT_ST_IF_CHANGED;
                    578:                                ioc_ack(0, m, gref);
                    579:                        }
                    580:                        break;
                    581: 
                    582:                        case LAP_IOC_SNMP_GET_AARP:
                    583:                        {
                    584:                                snmpAarpEnt_t *snmpp;
                    585:                                int bytes;
                    586: #ifdef APPLETALK_DEBUG
                    587:                                kprintf("LAP_IOC_SNMP_GET_AARP\n");
                    588: #endif
                    589:                                i =  *(int *)gbuf_rptr(gbuf_cont(m));
                    590:                                gbuf_freem(gbuf_cont(m));
                    591:                                gbuf_cont(m) = NULL;
                    592:                                dPrintf(D_M_ELAP,D_L_INFO,
                    593:                                        ("elap_wput:calling getarp,i=%d\n", i));
                    594:                                snmpp = getAarp(&i); 
                    595:                                bytes = i * sizeof(snmpAarpEnt_t);
                    596:                                dPrintf(D_M_ELAP,D_L_INFO,
                    597:                                        ("elap_wput:getarp returned, i=%d,bytes=%d\n", 
                    598:                                        i, bytes));
                    599:                                if (snmpp) {
                    600:                                        if ((gbuf_cont(m) = gbuf_alloc(bytes, PRI_MED)) == NULL) {
                    601:                                                ioc_ack(ENOBUFS, m, gref);
                    602:                                                break;
                    603:                                        }       
                    604:                                        bcopy(snmpp, gbuf_rptr(gbuf_cont(m)), bytes);
                    605:                                        gbuf_wset(gbuf_cont(m),bytes);
                    606:                                        iocbp->ioc_count = bytes;
                    607:                                        ioc_ack(0, m, gref);
                    608:                                }
                    609:                                else
                    610:                                        ioc_ack(EOPNOTSUPP, m, gref);
                    611:                        }
                    612:                        break;
                    613: 
                    614:                        case LAP_IOC_SNMP_GET_ZIP:
                    615: #ifdef APPLETALK_DEBUG
                    616:                                kprintf("LAP_IOC_SNMP_GET_ZIP\n");
                    617: #endif
                    618:                        { /* matching brace NOT in this case */
                    619:                                register int i,j;
                    620:                                register int size, total, tabsize;
                    621:                                gbuf_t  *mn;            /* new gbuf */
                    622:                                gbuf_t  *mo;            /* old gbuf */
                    623:                                gbuf_t  *mt;            /* temp */
                    624:                                snmpNbpTable_t          *nbp;
                    625: 
                    626:                                i =  *(int *)gbuf_rptr(gbuf_cont(m));
                    627:                                gbuf_freem(gbuf_cont(m));
                    628:                                gbuf_cont(m) = NULL;
                    629:                                if (!(at_state.flags & AT_ST_STARTED)) {
                    630:                                        ioc_ack(ENOTREADY, m, gref);
                    631:                                        break;
                    632:                                }
                    633:                                if (i == UPDATE_IF_CHANGED && 
                    634:                                        !(at_state.flags & AT_ST_ZT_CHANGED)) {
                    635:                                        iocbp->ioc_count = 0;
                    636:                                        ioc_ack(0, m, gref);
                    637:                                        break;
                    638:                                }
                    639:                                mo=(gbuf_t*)NULL;
                    640:                                tabsize = getZipTableSize();
                    641: 
                    642:                                        /* retrieve table into multiple gbufs */
                    643:                                for (i =0; i<tabsize;  i+=j) {
                    644:                                        j = tabsize - i > 
                    645:                                                MAX_ZIP ? MAX_ZIP : tabsize - i;
                    646:                                        size = j < MAX_ZIP ? sizeof(ZT_entry)*j : MAX_ZIP_BYTES;
                    647:                                        if ((mn = gbuf_alloc(size, PRI_MED)) == NULL) {
                    648:                                                if (gbuf_cont(m))
                    649:                                                        gbuf_freem(gbuf_cont(m));
                    650:                                                ioc_ack(ENOBUFS, m, gref);
                    651:                                                break;
                    652:                                        }
                    653:                                        if (!mo)        {               /* if first new one */
                    654:                                                mt = mn;
                    655:                                                total = size;
                    656:                                        }
                    657:                                        else {
                    658:                                                gbuf_cont(mo) = mn;
                    659:                                                total += size;
                    660:                                        }
                    661:                                        mo = mn;
                    662:                                        getZipTable((ZT_entry*)gbuf_rptr(mn),i,j); 
                    663:                                        gbuf_wset(mn,size);
                    664:                                }
                    665:                                if ((gbuf_cont(m) = gbuf_alloc(sizeof(int), PRI_MED)) == NULL) {
                    666:                                        if (mt)
                    667:                                                gbuf_freem(mt);
                    668:                                        iocbp->ioc_count = 0;
                    669:                                        ioc_ack(ENOBUFS, m, gref);
                    670:                                        break;
                    671:                                }
                    672:                                if (!tabsize) {
                    673:                                        dPrintf(D_M_ELAP,D_L_WARNING,
                    674:                                                ("elap_wput:snmp: empty zip table\n"));
                    675:                                        total = 0;
                    676:                                }
                    677:                                *(int*)gbuf_rptr(gbuf_cont(m)) = total;         /* return table size */
                    678:                                gbuf_wset(gbuf_cont(m),sizeof(int));
                    679:                                iocbp->ioc_count = sizeof(int);
                    680:                                ioc_ack(0, m, gref);
                    681:                                if (tabsize)
                    682:                                        atalk_putnext(gref,mt);         /* send up table */
                    683:                                at_state.flags &= ~AT_ST_ZT_CHANGED;
                    684:                                break;
                    685: 
                    686:                        case LAP_IOC_SNMP_GET_RTMP:
                    687: #ifdef APPLETALK_DEBUG
                    688:                                kprintf("LAP_IOC_SNMP_GET_RTMP\n");
                    689: #endif
                    690:                                i =  *(int *)gbuf_rptr(gbuf_cont(m));
                    691:                                gbuf_freem(gbuf_cont(m));
                    692:                                gbuf_cont(m) = NULL;
                    693:                                if (!(at_state.flags & AT_ST_STARTED)) {
                    694:                                        ioc_ack(ENOTREADY, m, gref);
                    695:                                        break;
                    696:                                }
                    697:                                if (i == UPDATE_IF_CHANGED && 
                    698:                                    !(at_state.flags & AT_ST_RT_CHANGED)) {
                    699:                                        iocbp->ioc_count = 0;
                    700:                                        ioc_ack(0, m, gref);
                    701:                                        break;
                    702:                                }
                    703: 
                    704:                                mo=(gbuf_t*)NULL;
                    705:                                tabsize = getRtmpTableSize();
                    706: 
                    707:                                        /* retrieve table into multiple gbufs */
                    708:                                for (i =0; i<tabsize;  i+=j) {
                    709:                                        j = tabsize - i > 
                    710:                                                MAX_RTMP ? MAX_RTMP : tabsize - i;
                    711:                                        size = j < MAX_RTMP ? sizeof(RT_entry)*j : MAX_RTMP_BYTES;
                    712:                                        if ((mn = gbuf_alloc(size, PRI_MED)) == NULL) {
                    713:                                                if (gbuf_cont(m))
                    714:                                                        gbuf_freem(gbuf_cont(m));
                    715:                                                ioc_ack(ENOBUFS, m, gref);
                    716:                                                break;
                    717:                                        }
                    718:                                        if (!mo)        {               /* if first new one */
                    719:                                                mt = mn;
                    720:                                                total = size;
                    721:                                        }
                    722:                                        else {
                    723:                                                gbuf_cont(mo) = mn;
                    724:                                                total += size;
                    725:                                        }
                    726:                                        mo = mn;
                    727:                                        getRtmpTable((RT_entry*)gbuf_rptr(mn),i,j); 
                    728:                                        gbuf_wset(mn,size);
                    729:                                }
                    730:                                if ((gbuf_cont(m) = gbuf_alloc(sizeof(int), PRI_MED)) == NULL) {
                    731:                                        if (mt)
                    732:                                                gbuf_freem(mt);
                    733:                                        iocbp->ioc_count = 0;
                    734:                                        ioc_ack(ENOBUFS, m, gref);
                    735:                                        break;
                    736:                                }
                    737:                                if (!tabsize)
                    738:                                        total = 0;
                    739:                                *(int*)gbuf_rptr(gbuf_cont(m)) = total; /* return table size */
                    740:                                gbuf_wset(gbuf_cont(m),sizeof(int));
                    741:                                iocbp->ioc_count = sizeof(int);
                    742:                                ioc_ack(0, m, gref);
                    743:                                if (tabsize)
                    744:                                        atalk_putnext(gref,mt);         /* send up table */
                    745:                                at_state.flags &= ~AT_ST_RT_CHANGED;
                    746:                                break;
                    747: 
                    748:                        case LAP_IOC_SNMP_GET_NBP:
                    749: #ifdef APPLETALK_DEBUG
                    750:                                kprintf("LAP_IOC_SNMP_GET_NBP\n");
                    751: #endif
                    752:                                i =  *(int *)gbuf_rptr(gbuf_cont(m));
                    753:                                gbuf_freem(gbuf_cont(m));
                    754:                                gbuf_cont(m) = NULL;
                    755:                                if (!(at_state.flags & AT_ST_STARTED)) {
                    756:                                        ioc_ack(ENOTREADY, m, gref);
                    757:                                        break;
                    758:                                }
                    759:                                if (i == UPDATE_IF_CHANGED && 
                    760:                                    !(at_state.flags & AT_ST_NBP_CHANGED)) {
                    761:                                        iocbp->ioc_count = 0;
                    762:                                        ioc_ack(0, m, gref);
                    763:                                        dPrintf(D_M_ELAP_LOW, D_L_INFO,
                    764:                                                ("elap_wput: nbp req denied, no change\n"));
                    765:                                        break;
                    766:                                }
                    767: 
                    768:                                mo=(gbuf_t*)NULL;
                    769:                                tabsize = getNbpTableSize();
                    770: 
                    771:                                        /* retrieve table into multiple gbufs */
                    772:                                for (i =0; i<tabsize;  i+=j) {
                    773:                                        j = tabsize - i > 
                    774:                                                MAX_NBP ? MAX_NBP : tabsize - i;
                    775:                                        size = j < MAX_NBP ? sizeof(snmpNbpEntry_t)*j : MAX_NBP_BYTES;
                    776:                                        if (!i)
                    777:                                                size += SNMP_NBP_HEADER_SIZE;
                    778:                                        if ((mn = gbuf_alloc(size, PRI_MED)) == NULL) {
                    779:                                                if (gbuf_cont(m))
                    780:                                                        gbuf_freem(gbuf_cont(m));
                    781:                                                ioc_ack(ENOBUFS, m, gref);
                    782:                                                break;
                    783:                                        }
                    784:                                        if (!mo)        {               /* if first new one */
                    785:                                                mt = mn;
                    786:                                                total = size;
                    787:                                                nbp = (snmpNbpTable_t*)gbuf_rptr(mn);
                    788:                                                nbp->nbpt_entries = tabsize;
                    789:                                                nbp->nbpt_zone = ifID_home->ifZoneName;
                    790:                                                getNbpTable(nbp->nbpt_table,i,j); 
                    791:                                        }
                    792:                                        else {
                    793:                                                gbuf_cont(mo) = mn;
                    794:                                                total += size;
                    795:                                                getNbpTable((snmpNbpEntry_t *)gbuf_rptr(mn),i,j); 
                    796:                                        }
                    797:                                        mo = mn;
                    798:                                        gbuf_wset(mn,size);
                    799:                                }
                    800:                                if ((gbuf_cont(m) = gbuf_alloc(sizeof(int), PRI_MED)) == NULL) {
                    801:                                        if (mt)
                    802:                                                gbuf_freem(mt);
                    803:                                        iocbp->ioc_count = 0;
                    804:                                        ioc_ack(ENOBUFS, m, gref);
                    805:                                        break;
                    806:                                }
                    807:                                if (!tabsize)
                    808:                                        total = 0;
                    809:                                *(int*)gbuf_rptr(gbuf_cont(m)) = total; /* return table size */
                    810:                                gbuf_wset(gbuf_cont(m),sizeof(int));
                    811:                                iocbp->ioc_count = sizeof(int);
                    812:                                ioc_ack(0, m, gref);
                    813:                                if (tabsize)
                    814:                                        atalk_putnext(gref,mt);         /* send up table */
                    815:                                at_state.flags &= ~AT_ST_NBP_CHANGED;
                    816:                                break;
                    817:                        }
                    818:                                
                    819:                        case LAP_IOC_SET_LOCAL_ZONES:
                    820:                                {
                    821:                                int i;
                    822: #ifdef APPLETALK_DEBUG
                    823:                                kprintf("LAP_IOC_SET_LOCAL_ZONES\n");
                    824: #endif
                    825:                                i = setLocalZones((at_nbptuple_t*)gbuf_rptr(gbuf_cont(m)),
                    826:                                                  gbuf_len(gbuf_cont(m)));
                    827:                                ioc_ack(i,m,gref);
                    828:                                }
                    829:                                break;
                    830:                        case LAP_IOC_GET_IF_NAMES:
                    831: #ifdef APPLETALK_DEBUG
                    832:                                kprintf("LAP_IOC_GET_IF_NAMES\n");
                    833: #endif
                    834:                                if ((gbuf_cont(m) = gbuf_alloc(sizeof(if_name_t) * IF_TOTAL_MAX, 
                    835:                                        PRI_MED)) == NULL) {
                    836:                                        ioc_ack(ENOBUFS, m, gref);
                    837:                                        break;
                    838:                                }
                    839:                                getIfNames((if_name_t *)gbuf_rptr(gbuf_cont(m)));
                    840:                                gbuf_wset(gbuf_cont(m),sizeof(if_name_t) * IF_TOTAL_MAX);
                    841:                                iocbp->ioc_count   = sizeof(if_name_t) * IF_TOTAL_MAX;
                    842:                                ioc_ack(0, m, gref);
                    843:                                break;
                    844:                        default:
                    845: #ifdef APPLETALK_DEBUG
                    846:                                kprintf("unknown ioctl %d\n", iocbp->ioc_cmd);
                    847: #endif
                    848:                                ioc_ack(ENOTTY, m, gref);
                    849:                                dPrintf(D_M_ELAP, D_L_WARNING,
                    850:                                        ("elap_wput: unknown ioctl (%d)\n", iocbp->ioc_cmd));
                    851: 
                    852:                                if (elapp)
                    853:                                        elapp->stats.unknown_mblks++;
                    854:                                break;
                    855:                        }
                    856:                }
                    857:                break;
                    858: 
                    859:        default:
                    860:                gbuf_freem(m);
                    861:                break;
                    862:        }
                    863: 
                    864:        return 0;
                    865: } /* elap_wput */
                    866: 
                    867: 
                    868: /* Called directly by ddp/zip.
                    869:  */
                    870: elap_dataput(m, elapp, addr_flag, addr)
                    871:      register  gbuf_t  *m;
                    872:      register at_ifaddr_t *elapp;
                    873:      u_char    addr_flag;
                    874:      char *addr;
                    875: {
                    876:        register int            size;
                    877:        int                     error;
                    878:        extern  int             zip_type_packet();
                    879:        struct  etalk_addr      dest_addr;
                    880:        struct  atalk_addr      dest_at_addr;
                    881:        extern  gbuf_t          *growmsg();
                    882:        int                     loop = TRUE;
                    883:                                /* flag to aarp to loopback (default) */
                    884: 
                    885:        /* the incoming frame is of the form {flag, address, ddp...}
                    886:         * where "flag" indicates whether the address is an 802.3
                    887:         * (link) address, or an appletalk address.  If it's an
                    888:         * 802.3 address, the packet can just go out to the network
                    889:         * through PAT, if it's an appletalk address, AT->802.3 address
                    890:         * resolution needs to be done.
                    891:         * If 802.3 address is known, strip off the flag and 802.3
                    892:         * address, and prepend 802.2 and 802.3 headers.
                    893:         */
                    894:        
                    895:        if (addr == NULL) {
                    896:                addr_flag = *(u_char *)gbuf_rptr(m);
                    897:                gbuf_rinc(m,1);
                    898:        }
                    899:        
                    900:        switch (addr_flag) {
                    901:        case AT_ADDR_NO_LOOP :
                    902:                loop = FALSE;
                    903:                /* pass thru */
                    904:        case AT_ADDR :
                    905:        if (addr == NULL) {
                    906:            dest_at_addr = *(struct atalk_addr *)gbuf_rptr(m);
                    907:            gbuf_rinc(m,sizeof(struct atalk_addr));
                    908:        } else
                    909:            dest_at_addr = *(struct atalk_addr *)addr;
                    910:            break;
                    911:        case ET_ADDR :
                    912:        if (addr == NULL) {
                    913:            dest_addr = *(struct etalk_addr *)gbuf_rptr(m);
                    914:            gbuf_rinc(m,sizeof(struct etalk_addr));
                    915:        } else
                    916:            dest_addr = *(struct etalk_addr *)addr;
                    917:            break;
                    918:        default :
                    919:            gbuf_freel(m);              /* unknown address type, chuck it */
                    920:            return(EINVAL);
                    921:         }
                    922: 
                    923:        m = gbuf_strip(m);
                    924: 
                    925:        /* At this point, rptr points to ddp header for sure */
                    926:        if (elapp->ifState == LAP_OFFLINE) {
                    927:            gbuf_freel(m);
                    928:                return(ENETDOWN);
                    929:        }
                    930: 
                    931:        if (elapp->ifState == LAP_ONLINE_FOR_ZIP) {
                    932:                /* see if this is a ZIP packet that we need
                    933:                 * to let through even though network is
                    934:                 * not yet alive!!
                    935:                 */
                    936:                if (zip_type_packet(m) == 0) {
                    937:                        gbuf_freel(m);
                    938:                        return(ENETDOWN);
                    939:                }
                    940:        }
                    941:        
                    942:        elapp->stats.xmit_packets++;
                    943:        size = gbuf_msgsize(m);
                    944:        elapp->stats.xmit_bytes += size;
                    945:        snmpStats.dd_outLong++;
                    946:        
                    947:        switch (addr_flag) {
                    948:        case AT_ADDR_NO_LOOP :
                    949:        case AT_ADDR :
                    950:            /*
                    951:             * we don't want elap to be looking into ddp header, so
                    952:             * it doesn't know net#, consequently can't do 
                    953:             * AMT_LOOKUP.  That task left to aarp now.
                    954:             */
                    955:            error = aarp_send_data(m,elapp,&dest_at_addr, loop);
                    956:            break;
                    957:        case ET_ADDR :
                    958:            error = pat_output(elapp, m, &dest_addr, 0);
                    959:            break;
                    960:         }
                    961:        return (error);
                    962: } /* elap_dataput */
                    963: 
                    964: /************************************************************************
                    965:  * elap_online()
                    966:  *
                    967:  ************************************************************************/
                    968: 
                    969: static int elap_online1(elapp)
                    970:      at_ifaddr_t *elapp;
                    971: {
                    972:        int errno;
                    973: 
                    974:        dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ("elap_online:%s elapp:0x%x\n",
                    975:                (elapp->ifName) ? &elapp->ifName[0] : "NULL interface", (u_int) elapp));
                    976:        if (elapp->ifState != LAP_OFFLINE)
                    977:                return (EALREADY);
                    978:        
                    979:        at_state.flags |= AT_ST_IF_CHANGED;
                    980: 
                    981:        if (elapp->flags & ELAP_CFG_HOME) /* tell ddp_add_if if this is home */
                    982:                elapp->ifFlags |= AT_IFF_DEFAULT;
                    983:                
                    984:        /* Get DDP started */
                    985:        if ((errno = ddp_add_if(elapp)))
                    986:                return(errno);
                    987: 
                    988:        /* set up multicast address for cable-wide broadcasts */
                    989:        (void)at_reg_mcast(elapp, (caddr_t)&elapp->cable_multicast_addr);
                    990: 
                    991:        elapp->startup_inprogress = TRUE;
                    992:        if (! (elapp->startup_error = re_aarp(elapp)))
                    993:                (void)tsleep(&elapp->startup_inprogress, PSOCK | PCATCH, 
                    994:                             "elap_online1", 0);
                    995: 
                    996:        /* then later, after some timeouts AARPwakeup() is called */
                    997: 
                    998:        return(elapp->startup_error);
                    999: } /* elap_online1 */
                   1000: 
                   1001: static int re_aarp(elapp)
                   1002:      at_ifaddr_t *elapp;
                   1003: {
                   1004:        int errno;
                   1005: 
                   1006:        /* We now call aarp_init() to assign an appletalk node addr */
                   1007:        errno = aarp_init1(elapp);
                   1008:                        /* aarp_init1() returns either -1 or ENOTREADY */
                   1009:        if (errno == ENOTREADY)
                   1010:                return(0);
                   1011:        else {
                   1012:                dPrintf(D_M_ELAP, D_L_STATE_CHG, 
                   1013:                        ("elap_online aarp_init for %s\n", elapp->ifName));
                   1014:                (void)at_unreg_mcast(elapp, (caddr_t)&elapp->cable_multicast_addr);
                   1015:                ddp_rem_if(elapp);
                   1016:                elapp->ifState = LAP_OFFLINE;
                   1017:                return(EADDRNOTAVAIL);
                   1018:        }
                   1019: }
                   1020: 
                   1021: /* called from AARPwakeup */
                   1022: static void elap_online2(elapp)
                   1023:      at_ifaddr_t *elapp;
                   1024: {
                   1025:        if (MULTIPORT_MODE) {
                   1026:                dPrintf(D_M_ELAP,D_L_STARTUP_INFO, 
                   1027:                        ("elap_online: re_aarp, we know it's a router...\n"));
                   1028: 
                   1029:                if (elapp->flags & ELAP_CFG_SEED) {
                   1030:                        /* add route table entry (zones to be added later) */
                   1031:                        dPrintf(D_M_ELAP, D_L_STARTUP_INFO,
                   1032:                                ("elap_online: rt_insert Cable %d-%d port =%d as SEED\n",
                   1033:                                elapp->ifThisCableStart, elapp->ifThisCableEnd, elapp->ifPort));
                   1034:                        rt_insert(elapp->ifThisCableEnd,
                   1035:                                  elapp->ifThisCableStart,
                   1036:                                  0,0,0,
                   1037:                                  elapp->ifPort,
                   1038:                                  RTE_STATE_PERMANENT | RTE_STATE_ZKNOWN | RTE_STATE_GOOD
                   1039:                                         );
                   1040:                        /* LD 081694: set the RTR_SEED_PORT flag for seed ports */
                   1041:                        elapp->ifFlags |= RTR_SEED_PORT;
                   1042:                }
                   1043:                else 
                   1044:                        dPrintf(D_M_ELAP,D_L_STARTUP_INFO,
                   1045:                                ("elap_online: it's a router, but non seed\n"));
                   1046:        }
                   1047: 
                   1048:        if (elapp->flags & ELAP_CFG_ZONELESS) {
                   1049:                /* ELAP_CFG_ZONELESS tells us that it is a router or in
                   1050:                       multihome mode, so we don't want to do the GetNetInfo
                   1051:                       exchange with the router.  */
                   1052: 
                   1053:                elapp->ifState = LAP_ONLINE_ZONELESS;
                   1054:                elapp->startup_inprogress = FALSE;
                   1055:                thread_wakeup(&elapp->startup_inprogress);
                   1056:                dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ("elap_online: ack 3\n"));
                   1057:                return;
                   1058:        }
                   1059: 
                   1060:        /* if we don't already have a zone and a multicast address */
                   1061:        if (*(int *)&elapp->ZoneMcastAddr == 0 || elapp->ifZoneName.len == 0) {
                   1062:                /* hzonehash is a global containing the nbp hash for the startup_zone */
                   1063:                sethzonehash(elapp);
                   1064: 
                   1065:                /* Get ZIP rolling to get zone multicast address, etc. */
                   1066:                elapp->ifState = LAP_ONLINE_FOR_ZIP;
                   1067:                (void)zip_control(elapp, ZIP_ONLINE);
                   1068:                /* zip_control (w. control == ZIP_ONLINE) always returns ENOTREADY */
                   1069: 
                   1070:                /* later, after some timeouts ZIPwakeup() is called. */
                   1071:        } else {
                   1072:                /* otherwise, we have the zone and the multicast already,
                   1073:                   so don't bother with another ZIP GetNetInfo request */
                   1074:                ZIPwakeup(elapp, 0);
                   1075:        }
                   1076: } /* elap_online2 */
                   1077: 
                   1078: /* called from rtmp_router_start */
                   1079: int elap_online3(elapp)
                   1080:      at_ifaddr_t       *elapp;
                   1081: {
                   1082:        elapp->startup_inprogress = TRUE;
                   1083: 
                   1084:        /* just reset the net range */
                   1085:        elapp->initial_addr.s_net = 0;
                   1086:        elapp->initial_addr.s_node = 0;
                   1087:        dPrintf(D_M_ELAP_LOW, D_L_STARTUP_INFO,
                   1088:                ("elap_online: goto re_aarp port=%d\n", elapp->ifPort));
                   1089: 
                   1090:        if ((elapp->startup_error = re_aarp(elapp)))
                   1091:                return(elapp->startup_error);
                   1092: 
                   1093:        /* then later, after some timeouts AARPwakeup() is called */
                   1094: 
                   1095:        (void)tsleep(&elapp->startup_inprogress, PSOCK | PCATCH, 
                   1096:                     "elap_online3", 0);
                   1097:        return(elapp->startup_error);
                   1098: } /* elap_online3 */
                   1099: 
                   1100: /****************************************************************************
                   1101:  * elap_offline()
                   1102:  *
                   1103:  ****************************************************************************/
                   1104: 
                   1105: void elap_offline(elapp)
                   1106:      register at_ifaddr_t *elapp;
                   1107: 
                   1108: {
                   1109:        void    zip_sched_getnetinfo(); /* forward reference */
                   1110:        int     errno;
                   1111:        int s;
                   1112: 
                   1113:        dPrintf(D_M_ELAP, D_L_SHUTDN_INFO, ("elap_offline:%s\n", elapp->ifName));
                   1114:        if (elapp->ifState != LAP_OFFLINE) {
                   1115: 
                   1116:                /* Since AppleTalk is going away, remove the cable
                   1117:                 * multicast address  and turn the interface off so that all 
                   1118:                 * AppleTalk packets are dropped in the driver itself.
                   1119:                 * Get rid of the zone multicast address prior to going Offline.
                   1120:                 */
                   1121:                (void)at_unreg_mcast(elapp, (caddr_t)&elapp->ZoneMcastAddr);
                   1122:                (void)at_unreg_mcast(elapp, (caddr_t)&elapp->cable_multicast_addr);
                   1123:                elapp->ifState = LAP_OFFLINE;
                   1124: 
                   1125:                ATDISABLE(s, ddpinp_lock);
                   1126:                if (MULTIPORT_MODE)
                   1127:                        RT_DELETE(elapp->ifThisCableEnd,
                   1128:                                  elapp->ifThisCableStart);
                   1129:                ATENABLE(s, ddpinp_lock);
                   1130: 
                   1131:                /* make sure no zip timeouts are left running */
                   1132:                untimeout(zip_sched_getnetinfo, elapp);
                   1133:        }
                   1134:        ddp_rem_if(elapp);
                   1135: } /* elap_offline */
                   1136: 
                   1137: /* called only in router mode */
                   1138: static int set_zones(ifz)
                   1139:        if_zone_info_t *ifz;
                   1140: 
                   1141: /* 1. adds zone to table
                   1142:    2. looks up each route entry from zone I/F bitmap
                   1143:    3. sets zone bit in each route entry
                   1144: 
                   1145:    returns  0 if successful
                   1146:                   -1 if error occurred
                   1147: */
                   1148: {
                   1149:        int type, iftype, i;
                   1150:        at_ifaddr_t *ifID;
                   1151:        short zno;
                   1152:        RT_entry *rte;
                   1153: 
                   1154:        zno = zt_add_zone(ifz->zone_name.str, ifz->zone_name.len);
                   1155: 
                   1156:        if (zno == ZT_MAXEDOUT) {
                   1157:                dPrintf(D_M_ELAP, D_L_ERROR, ("set_zones: error: table full\n"));
                   1158:                return(-1);
                   1159:        }
                   1160:        if (ifz->zone_home) {
                   1161:                ifID_home->ifZoneName = ifz->zone_name;
                   1162:                ifID_home->ifDefZone = zno;
                   1163:        }
                   1164: 
                   1165:        for (iftype=0; iftype< IF_TYPENO_CNT; iftype++) {
                   1166:                type = if_types[iftype].iftype;
                   1167:                for (i=0; i<IF_TOTAL_MAX; i++)  {
                   1168:                        if (ifz->zone_ifs[iftype] & 1<<i) {
                   1169:                                TAILQ_FOREACH(ifID, &at_ifQueueHd, aa_link) {
                   1170:                                        if (ifID->aa_ifp && 
                   1171:                                            ((ifID->aa_ifp)->if_type == type) &&
                   1172:                                            ((ifID->aa_ifp)->if_unit == i))
                   1173:                                                break;
                   1174:                                }
                   1175:                                if (ifID)  {
                   1176:                                        rte = rt_blookup(ifID->ifThisCableEnd);
                   1177:                                        if (!rte) {
                   1178:                                                dPrintf(D_M_ELAP, D_L_ERROR,
                   1179:                                                        ("set_zones: error: can't find route\n"));
                   1180:                                        }
                   1181:                                        zt_set_zmap(zno, rte->ZoneBitMap); 
                   1182: 
                   1183:                                        /* if first zone for this I/F, make default */
                   1184:                                        if (!ifID->ifDefZone)
                   1185:                                                 ifID->ifDefZone = zno;
                   1186:                                }
                   1187:                        }
                   1188:                }
                   1189:        }
                   1190:        return(0);
                   1191: }
                   1192: 
                   1193: static void add_route(rt)
                   1194: RT_entry       *rt;
                   1195: 
                   1196: /* support ioctl to manually add routes to table. 
                   1197:    this is really only for testing
                   1198: */
                   1199: {
                   1200:        rt_insert(      rt->NetStop, rt->NetStart, rt->NextIRNet, 
                   1201:                                rt->NextIRNode, rt->NetDist, rt->NetPort, 
                   1202:                                rt->EntryState);
                   1203:        dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ("adding route: %ud:%ud dist:%ud\n",
                   1204:                rt->NetStart, rt->NetStop,rt->NetDist));
                   1205: }
                   1206: 
                   1207: /*
                   1208:  * ddp_start()
                   1209:  *
                   1210:  * Initialization that takes place each time AppleTalk is restarted.
                   1211:  *
                   1212:  */
                   1213: void ddp_start()
                   1214: {
                   1215:        TAILQ_INIT(&at_ifQueueHd);
                   1216:        TAILQ_INIT(&name_registry);
                   1217:        bzero(at_interfaces, sizeof(at_interfaces));
                   1218:        bzero(ifID_table, sizeof(ifID_table));
                   1219:        bzero(&at_ddp_stats, sizeof(at_ddp_stats_t));
                   1220:        rtmp_init(); /* initialize trackedrouters */
                   1221: 
                   1222:        add_ddp_handler(RTMP_SOCKET, rtmp_input);
                   1223:        ifID_home = (at_ifaddr_t *)NULL;
                   1224:        xpatcnt = 0;
                   1225: }
                   1226: 
                   1227: void ddp_shutdown()
                   1228: {
                   1229:        at_ifaddr_t *ifID;
                   1230:        gref_t  *gref;
                   1231:        int i;
                   1232: 
                   1233:        if (MULTIPORT_MODE) {
                   1234:                 rtmp_shutdown();
                   1235:                 /* free memory allocated for the rtmp/zip tables */
                   1236:                if (ZT_table) {
                   1237:                        FREE(ZT_table, M_RTABLE);
                   1238:                        ZT_table = (ZT_entry *)NULL;
                   1239:                }
                   1240:                if (RT_table) {
                   1241:                        FREE(RT_table, M_RTABLE);
                   1242:                        RT_table = (RT_entry *)NULL;
                   1243:                }
                   1244:        }          
                   1245: 
                   1246:        at_state.flags = 0;     /* make sure inits are done on restart */
                   1247: 
                   1248:        /* from original ddp_shutdown() */
                   1249:        nbp_shutdown();         /* clear all known NVE */
                   1250:        routershutdown();
                   1251:        ddp_brt_shutdown();
                   1252: 
                   1253:        /* Network is shutting down... send error messages up on each open
                   1254:         * socket.  From ddps_shutdown().
                   1255:         */
                   1256:        for (gref = ddp_head.atpcb_next; gref != &ddp_head; gref = gref->atpcb_next)
                   1257:                atalk_notify(gref, ESHUTDOWN);
                   1258: 
                   1259:        if (adspInited) {
                   1260:                CleanupGlobals();
                   1261:                adspInited = 0;
                   1262:        }
                   1263:        dPrintf(D_M_DDP, D_L_VERBOSE, ("DDP shutdown completed"));
                   1264:          
                   1265:        /* *** after an SIOCSIFADDR and before an AIOCSIFADDR,
                   1266:               this is the only place to find the ifID *** */
                   1267:        for (i = 0; i < IF_TOTAL_MAX; i++) {
                   1268:                ifID = &at_interfaces[i];
                   1269:                /* do LAP_IOC_OFFLINE processing */
                   1270:                elap_offline(ifID);
                   1271:        }
                   1272:        ddp_start();
                   1273: } /* ddp_shutdown */
                   1274: 
                   1275: int routerStart(keP)
                   1276:      at_kern_err_t *keP;
                   1277: {
                   1278:        register at_ifaddr_t *ifID;
                   1279:        int error;
                   1280: 
                   1281:        if (! ifID_home)
                   1282:                return(EINVAL);
                   1283: 
                   1284:        /*
                   1285:         * this will cause the ports to glean from the net the relevant
                   1286:         * information before forwarding
                   1287:         */
                   1288:        TAILQ_FOREACH(ifID, &at_ifQueueHd, aa_link) {
                   1289:                dPrintf(D_M_ELAP, D_L_STARTUP_INFO, 
                   1290:                        ("routerStart Port %d (%s) set to activating\n",
                   1291:                         ifID->ifPort, ifID->ifName));
                   1292:                ifID->ifRoutingState = PORT_ACTIVATING;
                   1293:                ifID->ifFlags |= RTR_XNET_PORT;
                   1294:        }
                   1295: 
                   1296:        /*
                   1297:         * The next step is to check the information for each port before
                   1298:         * declaring the ports up and forwarding
                   1299:         */
                   1300:        dPrintf(D_M_ELAP, D_L_STARTUP_INFO,
                   1301:                ("router_start: waiting 20 sec before starting up\n"));
                   1302: 
                   1303:        /* sleep for 20 seconds */
                   1304:        if ((error = 
                   1305:             /* *** eventually this will be the ifID for the interface
                   1306:                being brought up in router mode *** */
                   1307:             tsleep(&ifID_home->startup_inprogress, 
                   1308:                    PSOCK | PCATCH, "routerStart", 20 * SYS_HZ))
                   1309:            != EWOULDBLOCK) {
                   1310: /*
                   1311:                if (!error)
                   1312:                        panic("routerStart: spurious interrupt");
                   1313: */
                   1314:                return(error);
                   1315:        }
                   1316: 
                   1317:        return(rtmp_router_start(keP));
                   1318:        /* was timeout(rtmp_router_start, 0, 20 * SYS_HZ);  */
                   1319: } /* routerStart */
                   1320: 
                   1321: void ZIPwakeup(elapp, ZipError)
                   1322:      at_ifaddr_t *elapp;
                   1323:      int ZipError;
                   1324: {
                   1325:        int s, error = ZipError;
                   1326: 
                   1327:        ATDISABLE(s, ddpinp_lock);
                   1328:        if ( (elapp != NULL) && elapp->startup_inprogress) {
                   1329:                ATENABLE(s, ddpinp_lock);
                   1330: 
                   1331:                /* was ZIPContinue */
                   1332:                /* was elapp_online() with jump to ZIP_sleep */
                   1333: 
                   1334:                /* instead of the goto ZIP_sleep ... */
                   1335:                switch (ZipError) {
                   1336:                        case 0 : /* success */
                   1337:                            elapp->ifState = LAP_ONLINE;
                   1338:                            break;
                   1339:                        case ZIP_RE_AARP :
                   1340:                            /* instead of goto re_aarp; */
                   1341:                            /* We now call aarp_init() to assign an 
                   1342:                               appletalk node addr */
                   1343:                            if ((elapp->startup_error = re_aarp(elapp))) {
                   1344:                                elapp->startup_inprogress = FALSE;
                   1345:                                thread_wakeup(&elapp->startup_inprogress);
                   1346:                                dPrintf(D_M_ELAP, D_L_STARTUP_INFO, 
                   1347:                                        ("elap_online: ack 2\n"));
                   1348:                            }
                   1349:                            break;
                   1350:                        default :
                   1351:                            break;
                   1352:                }
                   1353:                if (ZipError != ZIP_RE_AARP) {
                   1354:                        elapp->startup_error = error;
                   1355:                        elapp->startup_inprogress = FALSE;
                   1356:                        thread_wakeup(&elapp->startup_inprogress);
                   1357:                        dPrintf(D_M_ELAP, D_L_STARTUP_INFO,
                   1358:                                ("elap_online: ifZipError=%d\n", error));
                   1359:                }
                   1360:        } else
                   1361:                ATENABLE(s, ddpinp_lock);
                   1362: } /* ZIPwakeup */
                   1363: 
                   1364: void AARPwakeup(probe_cb)
                   1365:      aarp_amt_t *probe_cb;
                   1366: {
                   1367:        int s;
                   1368:        int errno;
                   1369:        at_ifaddr_t *elapp;
                   1370: 
                   1371:        ATDISABLE(s, arpinp_lock);
                   1372:        elapp = probe_cb->elapp;
                   1373:        if ( (elapp != NULL) && elapp->startup_inprogress ) {
                   1374:                ATENABLE(s, arpinp_lock);
                   1375: 
                   1376:                /* was AARPContinue */
                   1377:                errno = aarp_init2(elapp);
                   1378:                /* aarp_init2() returns either -1 or 0 */
                   1379:                if (errno != 0) {
                   1380:                        dPrintf(D_M_ELAP, D_L_STATE_CHG, 
                   1381:                                ("elap_online aarp_init for %s\n",
                   1382:                                 elapp->ifName));
                   1383:                        (void)at_unreg_mcast(elapp, (caddr_t)&elapp->ZoneMcastAddr);
                   1384:                        (void)at_unreg_mcast(elapp, (caddr_t)&elapp->cable_multicast_addr);
                   1385:                        elapp->ifState = LAP_OFFLINE;
                   1386:                        ddp_rem_if(elapp);
                   1387:                        elapp->startup_error = EADDRNOTAVAIL;
                   1388:                        elapp->startup_inprogress = FALSE;
                   1389:                        thread_wakeup(&elapp->startup_inprogress);
                   1390:                        dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ("elap_online: ack 2\n"));
                   1391:                } else {
                   1392:                        dPrintf(D_M_ELAP,D_L_STARTUP_INFO,
                   1393:                                ("elap_online: aarp_init returns zero\n"));
                   1394:                        elap_online2(elapp);
                   1395:                }
                   1396:        } else
                   1397:                ATENABLE(s, arpinp_lock);
                   1398: } /* AARPwakeup */
                   1399: 
                   1400: static void getIfNames(names)
                   1401:      if_name_t *names;
                   1402: {
                   1403:        int i;
                   1404:        at_ifaddr_t *ifID;
                   1405:        bzero(names,sizeof(if_name_t) * IF_TOTAL_MAX);
                   1406:        for (i=0, ifID=ifID_table[0]; ifID; ifID = ifID_table[++i], names++)
                   1407:                if(ifID)
                   1408:                        strncpy((char *)names,ifID->ifName,sizeof(*names));
                   1409: 
                   1410:        return;
                   1411: }
                   1412: 
                   1413: void ddp_bit_reverse(addr)
                   1414:        unsigned char *addr;
                   1415: {
                   1416: static unsigned char reverse_data[] = {
                   1417:        0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
                   1418:        0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
                   1419:        0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
                   1420:        0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
                   1421:        0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
                   1422:        0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
                   1423:        0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
                   1424:        0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
                   1425:        0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
                   1426:        0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
                   1427:        0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
                   1428:        0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
                   1429:        0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
                   1430:        0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
                   1431:        0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
                   1432:        0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
                   1433:        0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
                   1434:        0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
                   1435:        0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
                   1436:        0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
                   1437:        0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
                   1438:        0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
                   1439:        0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
                   1440:        0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
                   1441:        0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
                   1442:        0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
                   1443:        0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
                   1444:        0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
                   1445:        0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
                   1446:        0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
                   1447:        0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
                   1448:        0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
                   1449:        };
                   1450: 
                   1451:        unsigned char k;
                   1452: 
                   1453:        for (k=0; k < 6; k++)
                   1454:                addr[k] = reverse_data[addr[k]];
                   1455: }
                   1456: 
                   1457: static int elap_trackMcast(patp, func, addr)
                   1458:        at_ifaddr_t    *patp;
                   1459:        int func;
                   1460:        caddr_t addr;
                   1461: {
                   1462:        int i, loc=-1;
                   1463:        u_char c;
                   1464:        switch(patp->aa_ifp->if_type) {
                   1465:        case IFT_ETHER: 
                   1466:        case IFT_FDDI: 
                   1467:                /* set addr to point to unique part of addr */
                   1468:                c = addr[5];
                   1469: 
                   1470:                /* first try to find match */
                   1471:                /* *** save just one byte of the multicast address? *** */
                   1472:                for (i=0; i< MAX_MCASTS; i++) 
                   1473:                        if (c == patp->mcast[i]) {
                   1474:                                loc = i;
                   1475:                                break;
                   1476:                        }
                   1477:                                
                   1478:                switch (func) {
                   1479:                case MCAST_TRACK_DELETE:
                   1480:                        if (loc >= 0) 
                   1481:                                patp->mcast[loc] = 0;
                   1482: 
                   1483:                        break;
                   1484:                case MCAST_TRACK_ADD:
                   1485:                        dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add loc:%d\n", i));
                   1486:                        if (loc >= 0) {
                   1487:                                dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add, addr was there\n"));
                   1488:                                return(1);
                   1489:                                break;                  /* already there */
                   1490:                        }               
                   1491:                        for (i=0; i< MAX_MCASTS; i++) 
                   1492:                                if (patp->mcast[i] == 0) {
                   1493:                                        loc = i;
                   1494:                                        break;
                   1495:                                }
                   1496:                        dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add1 loc:%d\n", i));
                   1497:                        if (loc >= 0) {
                   1498:                                patp->mcast[loc] = c;
                   1499:                                dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add, adding(%x)\n",
                   1500:                                        (*(int*)addr)&0xffffff));
                   1501:                        }
                   1502:                        else {
                   1503:                                /*errno = ENOMEM; */ /*LD 5/7/97 nobody is using that */
                   1504:                                return(-1);
                   1505:                        }
                   1506:                        break;  
                   1507:                case MCAST_TRACK_CHECK:
                   1508:                        if (loc >= 0) {
                   1509:                                dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:check, addr was there\n"));
                   1510:                                return(0);
                   1511:                        }
                   1512:                        else {
                   1513:                                dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add, addr was NOT there\n"));
                   1514:                                return(-1);
                   1515:                        }
                   1516:                        
                   1517:                default:
                   1518:                        /*errno = EINVAL;*/ /*LD 5/7/97 nobody is using that */
                   1519:                        return(-1);
                   1520:                }
                   1521: 
                   1522:        case IFT_ISO88025: /* token ring */
                   1523:                /* we would use the lowest byte of the addr argument as a value
                   1524:                   to shift left a 1 to form the mcast mask for TR. We'll do this
                   1525:                   when the time comes
                   1526:                 */
                   1527:        default:
                   1528:                ;
                   1529:        }
                   1530:        return(0);
                   1531: }
                   1532: 
                   1533: 
                   1534: static getSnmpCfg(snmp)
                   1535:        snmpCfg_t *snmp;
                   1536: {
                   1537:        int i;
                   1538:        at_ifaddr_t     *elapp;
                   1539:        snmpIfCfg_t     *ifc;
                   1540: 
                   1541:        snmp->cfg_ifCnt = 0;
                   1542:        
                   1543:        bzero(snmp,sizeof(snmpCfg_t));
                   1544:        for (i=0, elapp=at_interfaces,ifc=snmp->cfg_ifCfg; 
                   1545:                 i<IF_TOTAL_MAX; i++, elapp++, ifc++) {
                   1546:                if (elapp->ifState != LAP_OFFLINE) {
                   1547:                        snmp->cfg_ifCnt++;
                   1548:                        strncpy(ifc->ifc_name,elapp->ifName, sizeof(ifc->ifc_name));
                   1549:                        ifc->ifc_aarpSize = getAarpTableSize(i);
                   1550:                        ifc->ifc_addrSize = getPhysAddrSize(i);
                   1551:                        switch (elapp->aa_ifp->if_type) {
                   1552:                                case IFT_ETHER:
                   1553:                                        ifc->ifc_type = SNMP_TYPE_ETHER2;
                   1554:                                        break;
                   1555:                                case IFT_ISO88025: /* token ring */
                   1556:                                        ifc->ifc_type = SNMP_TYPE_TOKEN;
                   1557:                                        break;
                   1558:                                case IFT_FDDI:
                   1559:                                default:
                   1560:                                        ifc->ifc_type = SNMP_TYPE_OTHER;
                   1561:                                        break;
                   1562:                        }
                   1563:                        ifc->ifc_start  = elapp->ifThisCableStart;
                   1564:                        ifc->ifc_end    = elapp->ifThisCableEnd;
                   1565:                        ifc->ifc_ddpAddr= elapp->ifThisNode;
                   1566:                        ifc->ifc_status = elapp->ifState == LAP_ONLINE ? 1 : 2;
                   1567:                        ifc->ifc_zoneName.len = 0;
                   1568:                        if (elapp->ifZoneName.len != 0) {
                   1569:                                ifc->ifc_zoneName = elapp->ifZoneName;
                   1570:                        }
                   1571:                        else if (elapp->ifDefZone) {
                   1572:                                ifc->ifc_zoneName = ZT_table[elapp->ifDefZone-1].Zone;
                   1573:                        }
                   1574:                        else    /* temp, debug only */
                   1575:                                ifc->ifc_zoneName = ZT_table[0].Zone;
                   1576:                        if (ROUTING_MODE) {
                   1577:                                if (elapp->ifFlags & RTR_SEED_PORT) {
                   1578:                                        ifc->ifc_netCfg  = SNMP_CFG_CONFIGURED;
                   1579:                                        ifc->ifc_zoneCfg = SNMP_CFG_CONFIGURED;
                   1580:                                }
                   1581:                                else {
                   1582:                                        ifc->ifc_netCfg  = SNMP_CFG_GARNERED;
                   1583:                                        ifc->ifc_zoneCfg = SNMP_CFG_GARNERED;
                   1584:                                }
                   1585:                        }
                   1586:                        else  {         /* single-port mode */
                   1587:                                if (elapp->ifRouterState == ROUTER_AROUND) {
                   1588:                                        ifc->ifc_netCfg = SNMP_CFG_GARNERED;
                   1589:                                }
                   1590:                                else {
                   1591:                                        ifc->ifc_netCfg = SNMP_CFG_GUESSED;
                   1592:                                        ifc->ifc_zoneCfg = SNMP_CFG_UNCONFIG;
                   1593:                                }
                   1594:                        }
                   1595:                }
                   1596:        } 
                   1597:        snmp->cfg_flags = at_state.flags;
                   1598: 
                   1599:                
                   1600:        return(0);
                   1601: }      
                   1602: 
                   1603: int at_reg_mcast(ifID, data)
                   1604:      at_ifaddr_t *ifID;
                   1605:      caddr_t data;
                   1606: {
                   1607:        struct ifnet *nddp = ifID->aa_ifp;
                   1608:        struct ifreq request;
                   1609: 
                   1610:        if (!nddp) {
                   1611:                dPrintf(D_M_PAT, D_L_STARTUP, ("pat_mcast: BAD ndpp\n"));
                   1612:                return(-1);
                   1613:        }
                   1614:        if (elap_trackMcast(ifID, MCAST_TRACK_ADD, data) == 1)
                   1615:                return(0);
                   1616: 
                   1617:        /* this is for ether_output */
                   1618:        request.ifr_addr.sa_family = AF_UNSPEC;
                   1619:        request.ifr_addr.sa_len = 2 + sizeof(struct etalk_addr);
                   1620:        bcopy (data, &request.ifr_addr.sa_data[0], sizeof(struct etalk_addr));
                   1621: 
                   1622:        /*### LD Direct access to the ifp->if_ioctl function */
                   1623: 
                   1624:        dPrintf(D_M_PAT, D_L_STARTUP,
                   1625:                ("pat_mcast: adding multicast %08x%04x ifID:0x%x\n",
                   1626:                 *(unsigned*)data, (*(unsigned *)(data+2))&0x0000ffff, 
                   1627:                 (unsigned)ifID));
                   1628: 
                   1629: /*
                   1630:        if ((*nddp->if_ioctl)(nddp, SIOCADDMULTI, (caddr_t)&request))
                   1631:                return(-1);
                   1632: */
                   1633:        if (if_addmulti(nddp, &request.ifr_addr, 0))
                   1634:            return -1;
                   1635:        else
                   1636:            return 0;
                   1637: 
                   1638: }
                   1639: 
                   1640: int at_unreg_mcast(ifID, data)
                   1641:      at_ifaddr_t *ifID;
                   1642:      caddr_t data;
                   1643: {
                   1644:        struct ifnet *nddp = ifID->aa_ifp;
                   1645:        struct ifreq request;
                   1646: 
                   1647: 
                   1648:        if (*(int *)data) {
                   1649:                if (!nddp) {
                   1650:                        dPrintf(D_M_PAT, D_L_STARTUP, ("pat_mcast: BAD ndpp\n"));
                   1651:                        return(-1);
                   1652:                }
                   1653: 
                   1654:                elap_trackMcast(ifID, MCAST_TRACK_DELETE, data);
                   1655: 
                   1656:                /* this is for ether_output */
                   1657:                request.ifr_addr.sa_family = AF_UNSPEC;
                   1658:                request.ifr_addr.sa_len = 2 + sizeof(struct etalk_addr);
                   1659:                bcopy (data, &request.ifr_addr.sa_data[0], sizeof(struct etalk_addr));
                   1660: 
                   1661:                /*### LD Direct access to the ifp->if_ioctl function */
                   1662:                dPrintf(D_M_PAT, D_L_STARTUP,
                   1663:                        ("pat_mcast: deleting multicast %08x%04x ifID:0x%x\n",
                   1664:                         *(unsigned*)data, (*(unsigned *)(data+2))&0x0000ffff, 
                   1665:                         (unsigned)ifID));
                   1666: /*
                   1667:                if ((*nddp->if_ioctl)(nddp, SIOCDELMULTI, (caddr_t)&request))
                   1668:                        return(-1);
                   1669: */
                   1670:                bzero(data, sizeof(struct etalk_addr));
                   1671:        }
                   1672: 
                   1673:        if (if_delmulti(nddp, &request.ifr_addr))
                   1674:            return -1;
                   1675:        else
                   1676:            return 0;
                   1677: }
                   1678: #ifdef NOT_YET
                   1679: /* *** at_reg_mcast() and at_unreg_mcast() should be replaced as soon as the
                   1680:        new code to allow an AF_LINK address family multicast to be (un)registered
                   1681:        using the SIOCADDMULTI / SIOCDELMULTI ioctls has been completed.
                   1682: 
                   1683:        The issue is that the "struct sockaddr_dl" needed for the AF_LINK does not 
                   1684:        fit in the "struct ifreq" that is used for these ioctls, and we do not want
                   1685:        Blue/Classic, which currently uses AF_UNSPEC, to use a different address 
                   1686:        family multicast address than Mac OS X uses.
                   1687:    *** */
                   1688: 
                   1689: int at_reg_mcast(ifID, data)
                   1690:      at_ifaddr_t *ifID;
                   1691:      caddr_t data;
                   1692: {
                   1693:        struct ifnet *nddp = ifID->aa_ifp;
                   1694:        struct sockaddr_dl sdl;
                   1695: 
                   1696:        if (*(int *)data) {
                   1697:                if (!nddp) {
                   1698:                        dPrintf(D_M_PAT, D_L_STARTUP, ("pat_mcast: BAD ndpp\n"));
                   1699:                        return(-1);
                   1700:                }
                   1701:                if (elap_trackMcast(ifID, MCAST_TRACK_ADD, data) == 1)
                   1702:                        return(0);
                   1703: 
                   1704:                sdl.sdl_len = sizeof(struct sockaddr_dl);
                   1705:                sdl.sdl_family = AF_LINK;
                   1706:                sdl.sdl_index = 0;
                   1707:                sdl.sdl_type = nddp->if_type;
                   1708:                sdl.sdl_alen = nddp->if_addrlen;
                   1709:                sdl.sdl_slen = 0;
                   1710:                sdl.sdl_nlen = sprintf(sdl.sdl_data, "%s%d", 
                   1711:                                       nddp->if_name , nddp->if_unit);
                   1712:                bcopy(data, LLADDR(&sdl), sdl.sdl_alen);
                   1713: 
                   1714:                dPrintf(D_M_PAT, D_L_STARTUP,
                   1715:                        ("pat_mcast: adding multicast %08x%04x ifID:0x%x\n",
                   1716:                         *(unsigned*)data, (*(unsigned *)(data+2))&0x0000ffff, 
                   1717:                         (unsigned)ifID));
                   1718: 
                   1719:                if (if_addmulti(nddp, (struct sockaddr *)&sdl, 0))
                   1720:                        return -1;
                   1721:        }
                   1722: 
                   1723:        return 0;
                   1724: }
                   1725: 
                   1726: int at_unreg_mcast(ifID, data)
                   1727:      at_ifaddr_t *ifID;
                   1728:      caddr_t data;
                   1729: {
                   1730:        struct ifnet *nddp = ifID->aa_ifp;
                   1731:        struct sockaddr_dl sdl;
                   1732: 
                   1733:        if (*(int *)data) {
                   1734:                if (!nddp) {
                   1735:                        dPrintf(D_M_PAT, D_L_STARTUP, ("pat_mcast: BAD ndpp\n"));
                   1736:                        return(-1);
                   1737:                }
                   1738: 
                   1739:                elap_trackMcast(ifID, MCAST_TRACK_DELETE, data);
                   1740: 
                   1741:                sdl.sdl_len = sizeof(struct sockaddr_dl);
                   1742:                sdl.sdl_family = AF_LINK;
                   1743:                sdl.sdl_index = 0;
                   1744:                sdl.sdl_type = nddp->if_type;
                   1745:                sdl.sdl_alen = nddp->if_addrlen;
                   1746:                sdl.sdl_slen = 0;
                   1747:                sdl.sdl_nlen = sprintf(sdl.sdl_data, "%s%d", 
                   1748:                                       nddp->if_name , nddp->if_unit);
                   1749: 
                   1750:                dPrintf(D_M_PAT, D_L_STARTUP,
                   1751:                        ("pat_mcast: deleting multicast %08x%04x ifID:0x%x\n",
                   1752:                         *(unsigned*)data, (*(unsigned *)(data+2))&0x0000ffff, 
                   1753:                         (unsigned)ifID));
                   1754:                bzero(data, ETHERNET_ADDR_LEN); 
                   1755: 
                   1756:                if (if_delmulti(nddp, (struct sockaddr *)&sdl))
                   1757:                        return(-1);
                   1758:        }
                   1759: 
                   1760:        return 0;
                   1761: }
                   1762: 
                   1763: #endif

unix.superglobalmegacorp.com

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