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

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: 
        !            25: /*
        !            26:  *     Copyright (c) 1988, 1989, 1997, 1998 Apple Computer, Inc. 
        !            27:  *
        !            28:  *     The information contained herein is subject to change without
        !            29:  *     notice and  should not be  construed as a commitment by Apple
        !            30:  *     Computer, Inc. Apple Computer, Inc. assumes no responsibility
        !            31:  *     for any errors that may appear.
        !            32:  *
        !            33:  *     Confidential and Proprietary to Apple Computer, Inc.
        !            34:  */
        !            35: 
        !            36: 
        !            37: #include <sysglue.h>
        !            38: 
        !            39: /* reaching for DDP and NBP headers in the datagram */
        !            40: #define DATA_DDP(mp)   ((at_ddp_t *)(gbuf_rptr(mp)))
        !            41: #define        DATA_NBP(mp)    ((at_nbp_t *)((DATA_DDP(mp))->data))
        !            42: 
        !            43: /* Get to the nve_entry_t part ofthe buffer */
        !            44: #define        NVE_ENTRY(mp)   (nve_entry_t *)(gbuf_rptr(mp))
        !            45: 
        !            46: #include <string.h>
        !            47: #include <at/appletalk.h>
        !            48: #include <at/ddp.h>
        !            49: #include <at/nbp.h>
        !            50: #include <at/zip.h>
        !            51: #include <rtmp.h>
        !            52: #include <lap.h>
        !            53: #include <at/elap.h> /* router */
        !            54: #include <at/at_lap.h>
        !            55: #include <routing_tables.h>    /* router */
        !            56: #include <at_elap.h>           /* router */
        !            57: #include <at_ddp.h>                    /* for FROM_US */
        !            58: #include <at_snmp.h>
        !            59: 
        !            60: #ifndef        MIN
        !            61: #define        MIN(a,b)        ((a)>(b)?(b):(a))
        !            62: #endif
        !            63: 
        !            64: #include "nbp.h"
        !            65: 
        !            66: #define        errno   nbperrno
        !            67: #define NBP_DEBUG  0
        !            68: 
        !            69:        /* externs */
        !            70: extern at_state_t      at_state, *at_statep;
        !            71: extern at_if_t                 *ifID_table[];
        !            72: 
        !            73: 
        !            74:        /* statics */
        !            75: static nve_entry_t     name_registry = {&name_registry, &name_registry};
        !            76: static at_nvestr_t     this_zone;
        !            77: static int             Extended_net;
        !            78: static int             errno;
        !            79: static  gbuf_t  *lzones=0;     /* head of local zones list */
        !            80: static int     lzonecnt=0;             /* # zones stored in lzones     */
        !            81: static u_int  hzonehash=0;     /* hash val of home zone */
        !            82: atlock_t       nve_lock;
        !            83: static int     nve_lock_pri;
        !            84: 
        !            85: static int     nbp_lkup_reply(nbp_req_t *, nve_entry_t *);
        !            86: static int     nbp_strcmp(at_nvestr_t *, at_nvestr_t *, u_char);
        !            87: static int     nbp_setup_resp(nbp_req_t *, int);
        !            88: static int     nbp_send_resp(nbp_req_t *);
        !            89: static int     nbp_insert_entry(nve_entry_t *);
        !            90: static int     nbp_enum_gen(nve_entry_t *);
        !            91: 
        !            92:        /* macros */
        !            93: #define NBP2ENTITY(nbp)  &nbp->tuple[0].en_u.en_se.entity
        !            94: #define NVE_LOCK nve_lock
        !            95: 
        !            96:        /* prototypes */
        !            97: at_nvestr_t *getRTRLocalZone(if_zone_t *);
        !            98: at_nvestr_t *getSPLocalZone(int);
        !            99: at_nvestr_t *getLocalZone(int);
        !           100: int nbp_add_multicast( at_nvestr_t     *, at_if_t *);
        !           101: int isZoneLocal(at_nvestr_t *);
        !           102: u_int  nbp_strhash (at_nvestr_t *);
        !           103: 
        !           104: int sethzonehash(elapp)
        !           105: elap_specifics_t *elapp;
        !           106: {
        !           107:        if (elapp->cfg.zonename.len)  {
        !           108:                hzonehash = nbp_strhash(&elapp->cfg.zonename);
        !           109:        }
        !           110: }
        !           111: 
        !           112: 
        !           113: int    nbp_init ()
        !           114: {
        !           115:        void            nbp_input();
        !           116:        at_ddp_cfg_t    ddp_cfg;
        !           117: 
        !           118:        /* Initialize Extended_net */
        !           119:        ddp_get_cfg (&ddp_cfg, 0);
        !           120:        if (ddp_cfg.flags & AT_IFF_LOCALTALK)
        !           121:                Extended_net = 0;
        !           122:        else
        !           123:                Extended_net = 1;
        !           124: 
        !           125:        ATLOCKINIT(nve_lock);
        !           126:        return ((int)nbp_input);
        !           127: }
        !           128: 
        !           129: void   nbp_shutdown()
        !           130: {
        !           131:        /* delete all NVE's and release buffers */
        !           132:        register nve_entry_t    *nve_entry, *next_nve;
        !           133:        extern   void   nbp_delete_entry();
        !           134: 
        !           135:        ATDISABLE(nve_lock_pri,NVE_LOCK);
        !           136:        for (nve_entry = name_registry.fwd, next_nve = nve_entry->fwd;
        !           137:                nve_entry != &name_registry;
        !           138:                nve_entry = next_nve, next_nve = nve_entry->fwd) {
        !           139:                nbp_delete_entry(nve_entry);
        !           140:        }
        !           141:        ATENABLE(nve_lock_pri,NVE_LOCK);
        !           142: 
        !           143:        if (lzones) {
        !           144:                gbuf_freem(lzones);
        !           145:                lzones = NULL; 
        !           146:        }
        !           147: } /* nbp_shutdown */
        !           148: 
        !           149: void   nbp_input (m, ifID)
        !           150: register gbuf_t        *m;
        !           151: register at_if_t *ifID;
        !           152: {
        !           153:        void            zip_handler(), nbp_handler(), rtmp_handler();
        !           154: 
        !           155:        switch (gbuf_type(m)) {
        !           156: 
        !           157:        /* *** fix this later: this code may no longer be needed *** */
        !           158:        case MSG_ERROR :
        !           159:                if (*gbuf_rptr(m) == ESHUTDOWN) {
        !           160:                        /* DDP shutting down, clean up the name registry */
        !           161:                        nbp_shutdown();
        !           162:                }
        !           163:                break;
        !           164:        /* *** end code that may no longer be needed *** */
        !           165: 
        !           166:        case MSG_DATA :
        !           167:                switch (((at_ddp_t *)(DATA_DDP(m)))->type) {
        !           168:                case NBP_DDP_TYPE :
        !           169:                        nbp_handler (m, ifID);
        !           170:                        return;
        !           171:                case ZIP_DDP_TYPE :
        !           172:                        dPrintf(D_M_NBP_LOW, D_L_WARNING,
        !           173:                                ("nbp_input: calling zip_handler\n"));
        !           174:                        zip_handler (m);
        !           175:                        break;
        !           176:                case RTMP_DDP_TYPE :  /* applicable only in case of LocalTalk */
        !           177:                        dPrintf(D_M_NBP_LOW,D_L_WARNING,
        !           178:                                ("nbp_input: calling rtmp_handler\n"));
        !           179:                        rtmp_handler (m);
        !           180:                        break;
        !           181:                }
        !           182:                break;
        !           183:        default :
        !           184:                dPrintf(D_M_NBP, D_L_WARNING,
        !           185:                        ("nbp_input: default_handler type=%d\n", gbuf_type(m)));
        !           186:                break;
        !           187:        }
        !           188:        gbuf_freem(m);
        !           189: }
        !           190: 
        !           191: static
        !           192: u_char *nbp2zone(nbp, maxp)
        !           193:        at_nbp_t *nbp;
        !           194:        u_char *maxp;
        !           195: {
        !           196: 
        !           197:        u_char *p;
        !           198: 
        !           199:        p = (u_char*)NBP2ENTITY(nbp);   /* p -> object */
        !           200:        if (p >= maxp) return NULL;
        !           201:        p += (*p +1);                                   /* p -> type   */
        !           202:        if (p >= maxp) return NULL;
        !           203:        p += (*p +1);                                   /* p -> zone   */
        !           204:        if (p >= maxp) return NULL;
        !           205:        if ((p + *p) >= maxp) return NULL;
        !           206:        return(p);
        !           207: }
        !           208: 
        !           209: static void    nbp_handler (m, ifID)
        !           210: register gbuf_t        *m;
        !           211: register at_if_t *ifID;
        !           212: 
        !           213: {
        !           214:        register at_nbp_t       *nbp = DATA_NBP(m);
        !           215:        register nve_entry_t    *nve_entry, *next_nve;
        !           216:        register RT_entry       *rt;
        !           217:        register int ddpSent = FALSE;   /* true if we re-sent this pkt (don't free) */
        !           218:        struct etalk_addr mcastAddr;
        !           219:        nbp_req_t       nbp_req;
        !           220:        nve_entry_t     *nbp_search_nve();
        !           221:        void            nbp_delete_entry();
        !           222:        at_ddp_t        *ddp;
        !           223:        u_char *p;
        !           224:        
        !           225:        /* Some initializations */
        !           226:        nbp_req.response = NULL;
        !           227:        nbp_req.request = m;
        !           228:        nbp_req.space_unused = nbp_req.flags = 0;
        !           229: 
        !           230: 
        !           231:        dPrintf(D_M_NBP_LOW, D_L_USR1,
        !           232:                ("nbp_handler control:%d tuplecount:%d id:%d\n",
        !           233:                nbp->control, nbp->tuple_count, nbp->at_nbp_id));
        !           234:        switch (nbp->control) {
        !           235:        case NBP_LKUP :
        !           236:          {
        !           237:                at_net_al dst_net;
        !           238:                ddp = DATA_DDP(m);
        !           239:                dst_net = NET_VALUE(ddp->dst_net);
        !           240:                dPrintf(D_M_NBP_LOW, D_L_USR2, (" LKUP %s\n",
        !           241:                        ifID != ifID_table[0] ? "non-home" : "home"));
        !           242:                if ( ROUTING_MODE && (NET_VALUE(ddp->dst_net) != 0)
        !           243:                        && ((dst_net < ifID->ifThisCableStart)
        !           244:                                || (dst_net > ifID->ifThisCableEnd)) ) {
        !           245:                        routing_needed(m, ifID, TRUE);
        !           246:                        ddpSent = TRUE;
        !           247:                        break;
        !           248:                }
        !           249:          }
        !           250: 
        !           251:                if (nbp_validate_n_hash (&nbp_req, TRUE, FALSE) == 0) {
        !           252:                        nbp_req.func = nbp_lkup_reply;
        !           253:                        (void) nbp_search_nve(&nbp_req, ifID);
        !           254:                        if (nbp_req.response) {
        !           255:                                nbp_send_resp(&nbp_req);
        !           256:                        }
        !           257:                }
        !           258: #ifdef NBP_DEBUG
        !           259:        {
        !           260:                char zone[35],object[35],type[35];
        !           261:                strncpy(zone,nbp_req.nve.zone.str, nbp_req.nve.zone.len);
        !           262:                strncpy(object,nbp_req.nve.object.str, nbp_req.nve.object.len);
        !           263:                strncpy(type,nbp_req.nve.type.str, nbp_req.nve.type.len);
        !           264:                object[nbp_req.nve.object.len] = '\0';
        !           265:                zone[nbp_req.nve.zone.len] = '\0';
        !           266:                type[nbp_req.nve.type.len] = '\0';
        !           267:                if (ifID != ifID_table[0]) 
        !           268:                        dPrintf(D_M_NBP_LOW,D_L_USR2,
        !           269:                                ("nbp_LKUP for:%s:%s@%s", object, type, zone));
        !           270:        }
        !           271: #endif /* NBP_DEBUG */
        !           272: 
        !           273:                break;
        !           274:        case NBP_REGISTER :
        !           275:                /* Whatever the outcome of this operation, we need to return
        !           276:                 * a response to the requester; so set up the response buffers 
        !           277:                 */
        !           278: #ifdef NBP_DEBUG
        !           279:        {
        !           280:                at_net_al dst_net,src_net;
        !           281:                int src_node, dst_node, src_skt, dst_skt;
        !           282:                ddp = DATA_DDP(m);
        !           283:                dst_net = NET_VALUE(ddp->dst_net);
        !           284:                src_net = NET_VALUE(ddp->src_net);
        !           285:                src_node = ddp->src_node;       
        !           286:                dst_node = ddp->dst_node;       
        !           287:                src_skt = ddp->src_socket;      
        !           288:                dst_skt = ddp->dst_socket;      
        !           289:                dPrintf(D_M_NBP_LOW,D_L_USR2,
        !           290:                        ("nbp reg ddp src:%d.%d.%d ",src_net,src_node,src_skt));
        !           291:                dPrintf(D_M_NBP_LOW,D_L_USR2,
        !           292:                        ("dst: %d.%d.%d\n",dst_net,dst_node,dst_skt));
        !           293:        }
        !           294: #endif /* NBP_DEBUG */
        !           295:                (void) nbp_setup_resp(&nbp_req, 0);
        !           296:                if (nbp_validate_n_hash (&nbp_req, FALSE, TRUE) != 0) {
        !           297:                        /* bad tuple... send an error message */
        !           298:                        goto bad;
        !           299:                }
        !           300: 
        !           301: 
        !           302: 
        !           303:                nbp_req.func = NULL;
        !           304:                if ((nve_entry =  nbp_search_nve(&nbp_req, NULL)) != NULL) {
        !           305:                        /* We have an entry for the same name in the registry.
        !           306:                         * This is either a duplicate request (client 
        !           307:                         * retransmission) or another request. If this is a 
        !           308:                         * retransmitted request (ie it's for the same socket),
        !           309:                         * then return ok; else return error.
        !           310:                         */
        !           311:                        if (*(int *)&nve_entry->address == 
        !           312:                                *(int *)&nbp_req.nve.address) {
        !           313:                                /* Send ok response */
        !           314:                                DATA_NBP(nbp_req.response)->tuple_count = 0;
        !           315:                                nbp_send_resp(&nbp_req);
        !           316:                                break;
        !           317:                        } else {
        !           318:                                errno = EADDRNOTAVAIL;
        !           319:                                goto bad;
        !           320:                        }
        !           321:                } else {
        !           322:                        /* Normal case; no tuple found for this name, so insert
        !           323:                         * this tuple in the registry and return ok response.
        !           324:                         */
        !           325: #ifdef NBP_DEBUG
        !           326:                {
        !           327:                        char str[35];
        !           328:                        char object[35];
        !           329:                        strncpy(str,nbp_req.nve.zone.str,nbp_req.nve.zone.len);
        !           330:                        str[nbp_req.nve.zone.len] = '\0';
        !           331:                        strncpy(object,nbp_req.nve.object.str,nbp_req.nve.object.len);
        !           332:                        object[nbp_req.nve.object.len] = '\0';
        !           333:                        dPrintf(D_M_NBP_LOW, D_L_USR4,
        !           334:                                ("nbp_register for zone %s (len:%d) obj:%s (len:%d)\n",
        !           335:                                str, nbp_req.nve.zone.len, object,
        !           336:                                nbp_req.nve.object.len));
        !           337:                }
        !           338: #endif /* NBP_DEBUG */
        !           339:   
        !           340:                        if ((nbp_enum_gen(&nbp_req.nve) != 0) || 
        !           341:                                nbp_insert_entry(&nbp_req.nve) != 0)
        !           342:                                goto bad;
        !           343:                        else {
        !           344:                                /* Send okay response */
        !           345:                                DATA_NBP(nbp_req.response)->tuple_count = 0;
        !           346:                                nbp_send_resp(&nbp_req);
        !           347:                                break;
        !           348:                        }
        !           349:                }
        !           350: bad:
        !           351:                DATA_NBP(nbp_req.response)->tuple_count = errno;
        !           352:                nbp_send_resp(&nbp_req);
        !           353:                break;
        !           354:        case NBP_DELETE :
        !           355:                /* Whatever the outcome of this operation, we need to return
        !           356:                 * a response to the requester; so set up the response buffers 
        !           357:                 */
        !           358:                (void) nbp_setup_resp(&nbp_req, 0);
        !           359:                if (nbp_validate_n_hash (&nbp_req, FALSE, TRUE) != 0) {
        !           360:                        /* bad tuple... send an error message */
        !           361:                        DATA_NBP(nbp_req.response)->tuple_count = errno;
        !           362:                        nbp_send_resp(&nbp_req);
        !           363:                        break;
        !           364:                }
        !           365: 
        !           366:                nbp_req.func = NULL;
        !           367:                if (MULTIHOME_MODE &&
        !           368:                    nbp_req.nve.zone.len == 1 && 
        !           369:             nbp_req.nve.zone.str[0] == '*'
        !           370:            ) { /* if mhome & *, remove nve from all default zones */
        !           371: 
        !           372:                        int                     found = FALSE;  /* if any found & deleted */
        !           373:                        at_if_t         **ifID;
        !           374: 
        !           375:                        for (ifID=ifID_table; *ifID; ifID++) {
        !           376:                                nbp_req.nve.zone = (*ifID)->ifZoneName;
        !           377:                                if ((nve_entry = nbp_search_nve(&nbp_req, NULL)) == NULL) 
        !           378:                                        continue;
        !           379:                                ATDISABLE(nve_lock_pri,NVE_LOCK);
        !           380:                                nbp_delete_entry(nve_entry);
        !           381:                                ATENABLE(nve_lock_pri,NVE_LOCK);
        !           382:                                found = TRUE;
        !           383:                        }
        !           384:                    nbp_req.nve.zone.len = 1;
        !           385:             nbp_req.nve.zone.str[0] = '*';
        !           386:                        if (found) 
        !           387:                                DATA_NBP(nbp_req.response)->tuple_count = 0;
        !           388:                        else
        !           389:                                DATA_NBP(nbp_req.response)->tuple_count = EADDRNOTAVAIL;
        !           390:                        nbp_send_resp(&nbp_req);
        !           391:                        break;
        !           392:                } else {
        !           393:                        if ((nve_entry = nbp_search_nve(&nbp_req, NULL)) == NULL) {
        !           394:                                /* Can't find the tuple we're looking for, send error*/
        !           395:                                DATA_NBP(nbp_req.response)->tuple_count = EADDRNOTAVAIL;
        !           396:                                nbp_send_resp(&nbp_req);
        !           397:                        } else {
        !           398:                                /* Normal case; tuple found for this name, so delete
        !           399:                                 * the entry from the registry and return ok response.
        !           400:                                 */
        !           401:                                ATDISABLE(nve_lock_pri,NVE_LOCK);
        !           402:                                nbp_delete_entry(nve_entry);
        !           403:                                ATENABLE(nve_lock_pri,NVE_LOCK);
        !           404:                                DATA_NBP(nbp_req.response)->tuple_count = 0;
        !           405:                                nbp_send_resp(&nbp_req);
        !           406:                        }
        !           407:                }
        !           408:                break;
        !           409:        case NBP_CLOSE_NOTE :
        !           410:                ATDISABLE(nve_lock_pri,NVE_LOCK);
        !           411:                for (nve_entry = name_registry.fwd, next_nve = nve_entry->fwd;
        !           412:                        nve_entry != &name_registry;
        !           413:                        nve_entry = next_nve, next_nve = nve_entry->fwd) {
        !           414:                        if ( DATA_DDP(m)->src_socket == nve_entry->address.socket       &&
        !           415:                                 (*(int *)gbuf_wptr(m) == nve_entry->pid)                               &&
        !           416:                                 ot_ddp_check_socket(nve_entry->address.socket, 
        !           417:                                        nve_entry->pid) < 2) {
        !           418:                                        nbp_delete_entry(nve_entry);
        !           419:                        }
        !           420:                }
        !           421:                ATENABLE(nve_lock_pri,NVE_LOCK);
        !           422:                break;
        !           423:        case NBP_FWDRQ: 
        !           424:                {
        !           425:                register int    zhome=0;                /* true if home zone == destination zone */
        !           426:                register int    zno, i;
        !           427:                register  gbuf_t        *m2;
        !           428:                register error_found =0;
        !           429:                register at_if_t *ifIDorig;
        !           430: 
        !           431:                if (MULTIHOME_MODE || !ROUTING_MODE)                            /* for routers only! */
        !           432:                        break;
        !           433: 
        !           434:                ddp = DATA_DDP(m);
        !           435: 
        !           436:                ifIDorig = ifID;
        !           437:                ifID= NULL;
        !           438:                for (i = 0 ; i < RT_MAXENTRY; i++) {
        !           439:                        rt = &RT_table[i];
        !           440:                        if ((rt->EntryState & RTE_STATE_PERMANENT) &&
        !           441:                                NET_VALUE(ddp->dst_net) >= rt->NetStart && 
        !           442:                                NET_VALUE(ddp->dst_net) <=      rt->NetStop
        !           443:                           ) {
        !           444:                                /* sanity check */
        !           445:                                if (rt->NetPort >= IF_TOTAL_MAX) {
        !           446:                                        dPrintf(D_M_NBP,D_L_ERROR,
        !           447:                                                ("nbp_handler:FWDREQ: bad port# from RT_table\n"));
        !           448:                                        error_found = TRUE;
        !           449:                                        break;
        !           450:                                }
        !           451:                                ifID = ifID_table[rt->NetPort];
        !           452:                                if (!ifID || !IFID_VALID(ifID)) {
        !           453:                                        dPrintf(D_M_NBP,D_L_ERROR,
        !           454:                                                ("nbp_handler:FWDREQ: ifID %s\n", 
        !           455:                                                !ifID ? "not found" : "invalid"));
        !           456:                                        error_found = TRUE;
        !           457:                                        break;
        !           458:                                }
        !           459:                                if (ifID->ifState == LAP_OFFLINE) {
        !           460:                                        dPrintf(D_M_NBP,D_L_ERROR,
        !           461:                                                ("nbp_handler:FWDREQ: ifID offline (port %d)\n",
        !           462:                                                rt->NetPort));
        !           463:                                        error_found = TRUE;
        !           464:                                        break;
        !           465:                                }
        !           466:                           break;
        !           467:                        }
        !           468:                }
        !           469:                if (error_found) /* the port is not correct */
        !           470:                        break;
        !           471: 
        !           472:                if (!ifID) { /* this packet is not for us, let the routing engine handle it  */
        !           473:                        routing_needed(m, ifIDorig, TRUE);
        !           474:                        ddpSent= TRUE;
        !           475:                        break;
        !           476:                }
        !           477: 
        !           478:                /* 
        !           479:                 * At this point, we have a valid Forward request for one of our 
        !           480:                 * direclty connected port. Convert it to a NBP Lookup
        !           481:                 */
        !           482: 
        !           483:                nbp->control = NBP_LKUP;
        !           484:                NET_ASSIGN(ddp->dst_net, 0);
        !           485:                ddp->dst_node = 255;
        !           486: 
        !           487: 
        !           488:  /*### LD 01/18/94 Check if the dest is also the home zone. */
        !           489:  
        !           490:                p = nbp2zone(nbp, gbuf_wptr(m));
        !           491:                if ((p == NULL) || !(zno = zt_find_zname(p))) {
        !           492:                        dPrintf(D_M_NBP,D_L_WARNING,
        !           493:                                ("nbp_handler: FWDRQ:zone not found\n"));
        !           494:                        break;
        !           495:                }
        !           496:                if (isZoneLocal((at_nvestr_t*)p)) 
        !           497:                        zhome = TRUE;                           /* one of our  ports is in destination zone */
        !           498:                if (!zt_get_zmcast(ifID, p, &mcastAddr)) {
        !           499:                        dPrintf(D_M_NBP,D_L_ERROR,
        !           500:                                ("nbp_handler: FDWREQ:zt_get_zmcast error\n"));
        !           501:                        break;
        !           502:                }
        !           503:                        
        !           504: 
        !           505:                if (zhome) { /*### LD 01/18/95  In case our home is here, call back nbp */
        !           506:  
        !           507:                        if (!(m2 = (gbuf_t *)gbuf_copym((gbuf_t *)m))) {
        !           508:                                dPrintf(D_M_NBP,D_L_ERROR, 
        !           509:                                        ("nbp_handler: FWDRQ:gbuf_copym failed\n"));
        !           510:                                break;
        !           511:                        }
        !           512:  
        !           513:                        ddp = DATA_DDP(m2);
        !           514:                        nbp = DATA_NBP(m2);
        !           515:                        nbp->control  = NBP_LKUP;
        !           516:                        NET_ASSIGN(ddp->dst_net, 0);
        !           517:                        ddp->dst_node = 255;
        !           518:                        dPrintf(D_M_NBP,D_L_INFO, 
        !           519:                                ("nbp_handler: FWDRQ:loop back for us\n"));
        !           520:                        nbp_handler(m2, ifID_table[IFID_HOME]);
        !           521:                }
        !           522:  
        !           523:                if ((ifID->ifType == IFTYPE_FDDITALK)
        !           524:                        || (ifID->ifType == IFTYPE_TOKENTALK))
        !           525:                        ddp_bit_reverse(&mcastAddr);
        !           526:                ddp_router_output(m, ifID, ET_ADDR,NULL,NULL, &mcastAddr);
        !           527:                ddpSent = TRUE;
        !           528:                }
        !           529:                break;
        !           530: 
        !           531:        case NBP_BRRQ:
        !           532:                {
        !           533:                register int    zno;                    /* zone table entry numb */
        !           534:                register int    ztind;                  /* zone bitmap index into RT_entry */
        !           535:                register int    ztbit;                  /* zone bit to check within above index */
        !           536:                register int    zhome=0;                /* true if home zone == destination zone */
        !           537:                register int    i;
        !           538:                register  gbuf_t        *m2, *m3;
        !           539:                register int fromUs = FALSE;
        !           540:                register at_socket ourSkt;                      /* originating skt */
        !           541: 
        !           542:                ddp = DATA_DDP(m);                              /* for router & MH local only */
        !           543:                if ((MULTIHOME_MODE && !FROM_US(ddp))&& !ROUTING_MODE) {
        !           544:                        dPrintf(D_M_NBP,D_L_USR2,
        !           545:                                ("nbp_handler: BRREQ:non router or MH local\n"));
        !           546: 
        !           547:                        break;
        !           548:                }
        !           549:                p = nbp2zone(nbp, gbuf_wptr(m));
        !           550:                if ((p == NULL) || !(zno = zt_find_zname(p))) {
        !           551:                        break;
        !           552:                }
        !           553:                if (MULTIHOME_MODE && ifID->ifRouterState == NO_ROUTER) {
        !           554:                        ((at_nvestr_t*)p)->len = 1;
        !           555:                        ((at_nvestr_t*)p)->str[0] = '*';
        !           556:                }
        !           557:                if (isZoneLocal((at_nvestr_t*)p)) {
        !           558:                        zhome = TRUE;                           /* one of our  ports is in destination zone */
        !           559:                }
        !           560:                if (FROM_US(ddp)){      /* save, before we munge it */
        !           561:                        fromUs = TRUE;
        !           562:                        ourSkt = ddp->src_socket;
        !           563:                        dPrintf(D_M_NBP,D_L_USR2,
        !           564:                                ("nbp_handler:BRRQ from us net:%d\n",
        !           565:                                (int)NET_VALUE(ddp->src_net)));
        !           566:                }
        !           567:                        /* from ZT_CLR_ZMAP */
        !           568:                i = zno - 1;
        !           569:                ztind = i >> 3;
        !           570:                ztbit = 0x80 >> (i % 8);
        !           571:                for (i=0,rt=RT_table; i<RT_MAXENTRY; i++,rt++) {
        !           572:                        if (!(rt->ZoneBitMap[ztind] & ztbit))           /* if zone not in route, skip*/
        !           573:                                continue;
        !           574: /*             dPrintf(D_M_NBP, D_L_USR3,
        !           575:                        ("nbp_handler: BRREQ: port:%d, entry %d\n",
        !           576:                                rt->NetPort, i));
        !           577: */
        !           578: 
        !           579:                        ifID = ifID_table[rt->NetPort];
        !           580:                        if (!ifID || !IFID_VALID(ifID)) {
        !           581:                                dPrintf(D_M_NBP, D_L_ERROR, 
        !           582:                                        ("nbp_handler:BRRQ: ifID %s\n", 
        !           583:                                        !ifID ? "not found" : "invalid"));
        !           584:                                break;
        !           585:                        }
        !           586: 
        !           587:                        ddp = DATA_DDP(m);
        !           588:                        ddp->src_node = ifID->ifThisNode.atalk_node;
        !           589:                        NET_NET(ddp->src_net,  ifID->ifThisNode.atalk_net);
        !           590:                        ddp->src_socket = NBP_SOCKET;
        !           591:                        if (!(m2 = (gbuf_t *)gbuf_copym((gbuf_t *)m))) {
        !           592:                                dPrintf(D_M_NBP,D_L_ERROR, 
        !           593:                                        ("nbp_handler: BRREQ:gbuf_copym failed\n"));
        !           594:                                break;
        !           595:                        }
        !           596: 
        !           597:                        ddp = DATA_DDP(m2);
        !           598:                        nbp = DATA_NBP(m2);
        !           599: /*                     nbp->tuple[0].enu_addr.socket = NBP_SOCKET; */
        !           600:                        if (MULTIHOME_MODE && fromUs ) {
        !           601:                                /* set the return address of the lookup to that of the
        !           602:                                   interface it's going out on so that replies come back
        !           603:                                   on that net */
        !           604:                                dPrintf(D_M_NBP,D_L_USR3, 
        !           605:                                   ("nbp_handler: BRREQ: src changed to %d.%d.%d\n",
        !           606:                                        NET_VALUE(ifID->ifThisNode.atalk_net),
        !           607:                                        ifID->ifThisNode.atalk_node, ourSkt));
        !           608:                                NET_NET(nbp->tuple[0].enu_addr.net,ifID->ifThisNode.atalk_net);
        !           609:                                nbp->tuple[0].enu_addr.node = ifID->ifThisNode.atalk_node;
        !           610:                                nbp->tuple[0].enu_addr.socket = ourSkt; 
        !           611:                                ddp->src_socket = NBP_SOCKET;
        !           612:                        }
        !           613:                        else
        !           614:                                dPrintf(D_M_NBP, D_L_USR3, 
        !           615:                                   ("nbp_handler: BRREQ: not from us\n"));
        !           616: 
        !           617:                        dPrintf(D_M_NBP, D_L_USR3,
        !           618:                                ("nbp_handler dist:%d\n", rt->NetDist));
        !           619:                        if (rt->NetDist == 0) {                 /* if direct connect, *we* do the LKUP */
        !           620:                                nbp->control  = NBP_LKUP;
        !           621:                                NET_ASSIGN(ddp->dst_net, 0);
        !           622:                                ddp->dst_node = 255;
        !           623:                                if (!zt_get_zmcast(ifID, p, &mcastAddr)) {
        !           624:                                        dPrintf(D_M_NBP,D_L_ERROR, 
        !           625:                                                ("nbp_handler: BRRQ:zt_get_zmcast error\n"));
        !           626:                                        break;
        !           627:                                }
        !           628:                                if ((ifID->ifType == IFTYPE_FDDITALK)
        !           629:                                        || (ifID->ifType == IFTYPE_TOKENTALK))
        !           630:                                        ddp_bit_reverse(&mcastAddr);
        !           631:                                ddp_router_output(m2, ifID, ET_ADDR, NULL, NULL, &mcastAddr); 
        !           632:                        }
        !           633:                        else {                                                  /* else fwd to router */
        !           634:                                ddp->dst_node = 0;
        !           635:                                if (rt->NetStart == 0)          /* if Ltalk */
        !           636:                                        NET_ASSIGN(ddp->dst_net, rt->NetStop);
        !           637:                                else    
        !           638:                                        NET_ASSIGN(ddp->dst_net, rt->NetStart);
        !           639:                                nbp->control  = NBP_FWDRQ;
        !           640:                                ddp_router_output(m2, ifID, AT_ADDR, rt->NextIRNet, rt->NextIRNode, NULL); 
        !           641:                        }
        !           642:                }
        !           643:                if (!zhome)
        !           644:                        break;
        !           645: 
        !           646:                if (!(m3 = (gbuf_t *)gbuf_copym((gbuf_t *)m))) {
        !           647:                        dPrintf(D_M_NBP,D_L_ERROR, 
        !           648:                                ("nbp_handler: BRREQ:gbuf_copym failed\n"));
        !           649:                        break;
        !           650:                }
        !           651: 
        !           652:                ddp = DATA_DDP(m3);
        !           653:                nbp = DATA_NBP(m3);
        !           654:                                
        !           655:                nbp->control  = NBP_LKUP;
        !           656:                NET_ASSIGN(ddp->dst_net, 0);
        !           657:                ddp->dst_node = 255;
        !           658:                dPrintf(D_M_NBP,D_L_INFO, 
        !           659:                        ("nbp_handler: BRRQ:loop back for us\n"));
        !           660:                nbp_handler(m3, ifID_table[IFID_HOME]);
        !           661:                break;
        !           662:                }
        !           663: 
        !           664:                case NBP_LKUP_REPLY:
        !           665:                
        !           666:                if (MULTIHOME_MODE || !ROUTING_MODE)                            /* for routers only! */
        !           667:                                break;
        !           668: 
        !           669:                        ddp = DATA_DDP(m);
        !           670:                        
        !           671:                        dPrintf(D_M_NBP,D_L_WARNING, 
        !           672:                                ("nbp_handler: routing needed for LKUP_REPLY: from %d.%d\n",
        !           673:                                NET_VALUE(ddp->src_net), ddp->src_node));
        !           674:                        routing_needed(m, ifID, TRUE);
        !           675:                        ddpSent = TRUE;
        !           676:                        break;
        !           677:                
        !           678:        default :
        !           679: 
        !           680:                dPrintf(D_M_NBP,D_L_ERROR, 
        !           681:                        ("nbp_handler: unhandled pkt: type:%d\n", nbp->control));
        !           682: 
        !           683:                routing_needed(m, ifID, TRUE);
        !           684:                ddpSent = TRUE;
        !           685:                break;
        !           686:        } /* switch control */
        !           687:        if (!ddpSent)
        !           688:                gbuf_freem(m);
        !           689:        return;
        !           690: }
        !           691: 
        !           692: 
        !           693: static void    zip_handler (m)
        !           694: gbuf_t *m;
        !           695: {
        !           696:        at_ddp_t           *ddp = DATA_DDP(m);
        !           697:        register at_zip_t  *zip = ZIP_ZIP(ddp);
        !           698:        register char   old_zone_len;
        !           699:        register char   new_zone_len;
        !           700:        register char   mcast_len;
        !           701:        char            *new_zone;
        !           702: 
        !           703:        switch (zip->command) {
        !           704:        case ZIP_NOTIFY :
        !           705:                /* ZipNotify packet forwarded by ZIP module...
        !           706:                 * change the zone name this_zone.
        !           707:                 */
        !           708:                old_zone_len = zip->data[4];
        !           709:                mcast_len = zip->data[4+old_zone_len+1];
        !           710:                new_zone_len = zip->data[4+old_zone_len+1+mcast_len+1];
        !           711:                new_zone = &zip->data[4+old_zone_len+1+mcast_len+1];
        !           712:                bcopy(new_zone, &this_zone, new_zone_len + 1);
        !           713:                break;
        !           714:        default :
        !           715:                /* ignore all the packets we don't know about */
        !           716:                break;
        !           717:        } /* switch command */
        !           718:        return;
        !           719: }
        !           720: 
        !           721: 
        !           722: static void    rtmp_handler (m)
        !           723: gbuf_t *m;
        !           724: {
        !           725:        at_ddp_t        *ddp = DATA_DDP(m);
        !           726:        at_rtmp         *rtmp = (at_rtmp *)ddp->data;
        !           727:        at_net          new_net;
        !           728:        register nve_entry_t    *nve_entry;
        !           729: 
        !           730:        NET_NET(new_net, rtmp->at_rtmp_this_net);
        !           731:        for (nve_entry = name_registry.fwd; nve_entry != &name_registry ;
        !           732:                nve_entry = nve_entry->fwd)
        !           733:                NET_NET(nve_entry->address.net, new_net);
        !           734: }
        !           735: 
        !           736: 
        !           737: static int     nbp_validate_n_hash (nbp_req, wild_ok, checkLocal)
        !           738: register nbp_req_t     *nbp_req;
        !           739: register int           wild_ok;
        !           740: register int           checkLocal;     /* if true check if local zone */
        !           741: {
        !           742:         register at_nvestr_t   *object, *type, *zone;
        !           743:        at_nbptuple_t   *tuple;
        !           744:        register int    i, part_wild;
        !           745:        u_int           nbp_strhash();
        !           746: 
        !           747:        tuple = DATA_NBP(nbp_req->request)->tuple;
        !           748:        nbp_req->flags = 0;
        !           749: #ifdef COMMENTED_OUT
        !           750:        {
        !           751:                int net,node,skt;
        !           752:                net = NET_VALUE(tuple->enu_addr.net);
        !           753:                node = tuple->enu_addr.node;
        !           754:                skt = tuple->enu_addr.socket;
        !           755:                dPrintf(D_M_NBP_LOW,D_L_USR4,
        !           756:                        ("nbp_validate: tuple addr:%d:%d:%d\n",net,node,skt));
        !           757:        }
        !           758: #endif /* COMMENTED_OUT */
        !           759: 
        !           760:        object = (at_nvestr_t *)tuple->enu_name;
        !           761:        type = (at_nvestr_t *)(&object->str[object->len]);
        !           762:        zone = (at_nvestr_t *)(&type->str[type->len]);
        !           763:        
        !           764:        if (object->len > NBP_NVE_STR_SIZE || type->len > NBP_NVE_STR_SIZE || 
        !           765:                zone->len > NBP_NVE_STR_SIZE) {
        !           766:                errno = EINVAL;
        !           767:                return (-1);
        !           768:        }
        !           769:        
        !           770: #ifdef NBP_DEBUG
        !           771:        {
        !           772:                char xzone[35],xobject[35],xtype[35];
        !           773:                strncpy(xzone,zone->str, zone->len);
        !           774:                strncpy(xobject,object->str, object->len);
        !           775:                strncpy(xtype,type->str, type->len);
        !           776:                xobject[object->len] = '\0';
        !           777:                xzone[zone->len] = '\0';
        !           778:                xtype[type->len] = '\0';
        !           779:                dPrintf(D_M_NBP_LOW, D_L_USR4,
        !           780:                        ("nbp_validate: looking for %s:%s@%s\n",
        !           781:                        xobject, xtype, xzone));
        !           782:        }
        !           783: #endif /* NBP_DEBUG */
        !           784:        /* Is this request for our zone ?? */
        !           785:        nbp_req->nve.zone.len = zone->len;
        !           786:        nbp_req->nve.zone_hash = 0;
        !           787:        bcopy(zone->str,nbp_req->nve.zone.str, zone->len);
        !           788:     if (checkLocal && !isZoneLocal(zone)) {
        !           789:        char str[35];
        !           790:        strncpy(str,zone->str,zone->len);
        !           791:        str[zone->len] = '\0';
        !           792:        dPrintf(D_M_NBP_LOW,D_L_WARNING,
        !           793:                ("nbp_val_n_hash bad zone: %s\n", str));
        !           794:        errno = EINVAL;
        !           795:        return(-1);
        !           796:      }
        !           797:        if (Extended_net) {
        !           798:                /* EtherTalk...
        !           799:                 * The zone name in the request must match either "*" or
        !           800:                 * our zone name (this_zone).  Zero length zone field is the
        !           801:                 * same as "*".
        !           802:                 */
        !           803:                if (zone->len != 0) {
        !           804:                        if (!(zone->len == 1 && zone->str[0] == '*')) {
        !           805:                                nbp_req->nve.zone_hash = 
        !           806:                                        nbp_strhash(& nbp_req->nve.zone);
        !           807:                }
        !           808: #ifdef COMMENTED_OUT 
        !           809:                                /* we allow multi-zone registration now, so
        !           810:                                   the actual zone name will be checked in
        !           811:                                   nbp_search_nve() */
        !           812:                                if (nbp_strcmp(zone, &this_zone, NULL) != 0) {
        !           813:                                        errno = EINVAL;
        !           814:                                        return (-1);
        !           815:                                }
        !           816: #endif /* COMMENTED_OUT */
        !           817:                }
        !           818:        } else {
        !           819:                /* LocalTalk... 
        !           820:                 * "this_zone" variable will not have been initialized, since
        !           821:                 * there's no interaction between NBP and ZIP for LocalTalk.
        !           822:                 * We are assuming that the zone name field in a lookup 
        !           823:                 * request packet will always contain a legal value.  
        !           824:                 * One check that could be performed here (but is not) is : 
        !           825:                 * make sure that if there's no router around on the
        !           826:                 * net, the zone name in the lookup request must be "*".  If
        !           827:                 * it's anything else, reject the packet.
        !           828:                 */
        !           829:        }
        !           830: 
        !           831:        nbp_req->nve.address = tuple->enu_addr;
        !           832:        nbp_req->nve.object.len = object->len;
        !           833:        nbp_req->nve.object_hash = 0;
        !           834:        if (object->len == 1 && (object->str[0] == NBP_ORD_WILDCARD ||
        !           835:                object->str[0] == NBP_SPL_WILDCARD)) {
        !           836:                if (wild_ok)
        !           837:                        nbp_req->flags |= NBP_WILD_OBJECT;
        !           838:                else {
        !           839:                        errno = EINVAL;
        !           840:                        return (-1);
        !           841:                }
        !           842:        } else{
        !           843:                for (i = part_wild = 0; (unsigned) i<object->len; i++) {
        !           844:                        if (object->str[i] == NBP_SPL_WILDCARD)
        !           845:                                if (wild_ok)
        !           846:                                        if (part_wild) {
        !           847:                                                errno = EINVAL;
        !           848:                                                return (-1);
        !           849:                                        } else
        !           850:                                                part_wild++;
        !           851:                                else {
        !           852:                                        errno = EINVAL;
        !           853:                                        return (-1);
        !           854:                                }
        !           855:                        nbp_req->nve.object.str[i] = object->str[i];
        !           856:                }
        !           857:                if (!part_wild)
        !           858:                        nbp_req->nve.object_hash = 
        !           859:                                nbp_strhash(&nbp_req->nve.object);
        !           860:        }
        !           861: 
        !           862:        nbp_req->nve.type.len = type->len;
        !           863:        nbp_req->nve.type_hash = 0;
        !           864:        if (type->len == 1 && (type->str[0] == NBP_ORD_WILDCARD ||
        !           865:                type->str[0] == NBP_SPL_WILDCARD)) {
        !           866:                if (wild_ok)
        !           867:                        nbp_req->flags |= NBP_WILD_TYPE;
        !           868:                else {
        !           869:                        errno = EINVAL;
        !           870:                        return (-1);
        !           871:                }
        !           872:        } else {
        !           873:                for (i = part_wild = 0; (unsigned) i<type->len; i++) {
        !           874:                        if (type->str[i] == NBP_SPL_WILDCARD)
        !           875:                                if (wild_ok)
        !           876:                                        if (part_wild) {
        !           877:                                                errno = EINVAL;
        !           878:                                                return (-1);
        !           879:                                        } else
        !           880:                                                part_wild++;
        !           881:                                else {
        !           882:                                        errno = EINVAL;
        !           883:                                        return (-1);
        !           884:                                }
        !           885:                        nbp_req->nve.type.str[i] = type->str[i];
        !           886:                }
        !           887:                if (!part_wild)
        !           888:                        nbp_req->nve.type_hash = 
        !           889:                                nbp_strhash(&nbp_req->nve.type);
        !           890:        }
        !           891: #ifdef NBP_DEBUG
        !           892:        {
        !           893:                char zone[35],object[35],type[35];
        !           894:                strncpy(zone,nbp_req->nve.zone.str, nbp_req->nve.zone.len);
        !           895:                strncpy(object,nbp_req->nve.object.str, nbp_req->nve.object.len);
        !           896:                strncpy(type,nbp_req->nve.type.str, nbp_req->nve.type.len);
        !           897:                object[nbp_req->nve.object.len] = '\0';
        !           898:                zone[nbp_req->nve.zone.len] = '\0';
        !           899:                type[nbp_req->nve.type.len] = '\0';
        !           900:                dPrintf(D_M_NBP_LOW,D_L_USR4,
        !           901:                        ("nbp_validate: after hash: %s:%s@%s\n",
        !           902:                        object, type, zone));
        !           903:        }
        !           904: #endif /* NBP_DEBUG */
        !           905:        return(0);
        !           906: }
        !           907: 
        !           908: 
        !           909: /* Upshifts in place */
        !           910: static void    nbp_upshift (str, count)
        !           911: register u_char        *str;
        !           912: register int   count;
        !           913: {
        !           914:        register int    i, j;
        !           915:        register u_char ch;
        !           916:        static  unsigned char   lower_case[] =
        !           917:                {0x8a, 0x8c, 0x8d, 0x8e, 0x96, 0x9a, 0x9f, 0xbe,
        !           918:                 0xbf, 0xcf, 0x9b, 0x8b, 0x88, 0};
        !           919:        static  unsigned char   upper_case[] = 
        !           920:                {0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0xae,
        !           921:                 0xaf, 0xce, 0xcd, 0xcc, 0xcb, 0};
        !           922: 
        !           923:        for (j=0 ; j<count ; j++) {
        !           924:                ch = str[j];
        !           925:                if (ch >= 'a' && ch <= 'z')
        !           926:                        str[j] = ch + 'A' - 'a';
        !           927:                else if (ch & 0x80)
        !           928:                        for (i=0; lower_case[i]; i++)
        !           929:                                if (ch == lower_case[i])
        !           930:                                        str[j] = upper_case[i];
        !           931:        }
        !           932: }
        !           933: 
        !           934: 
        !           935: static u_int   nbp_strhash (nvestr)
        !           936: register at_nvestr_t   *nvestr;
        !           937: {
        !           938:        /* upshift while hashing */
        !           939:        register u_int  hash = 0;
        !           940:        register int    i, len;
        !           941:        union {
        !           942:                u_char  h_4char[4];
        !           943:                int     h_int;
        !           944:        } un;
        !           945: 
        !           946:        for (i=0; (unsigned) i < nvestr->len; i+=sizeof(int)) {
        !           947:                len = MIN((nvestr->len-i), sizeof(int));
        !           948:                if (len == sizeof(int))
        !           949:                        bcopy(&(nvestr->str[i]), &un, sizeof(un));
        !           950:                else {
        !           951:                        un.h_int = -1;
        !           952:                        for ( ; (unsigned) i<nvestr->len; i++)
        !           953:                                un.h_4char[i % sizeof(int)] = nvestr->str[i];
        !           954:                }
        !           955:                nbp_upshift (un.h_4char, len);
        !           956:                hash ^= un.h_int;
        !           957:        }
        !           958:        
        !           959:        return (hash);
        !           960: }
        !           961: 
        !           962: 
        !           963: static nve_entry_t     *nbp_search_nve (nbp_req, ifID)
        !           964: register nbp_req_t     *nbp_req;
        !           965: register at_if_t       *ifID;          /* NULL ok */
        !           966: {
        !           967:        register nve_entry_t    *nve_entry;
        !           968: 
        !           969: #ifdef NBP_DEBUG
        !           970:        {
        !           971:                char zone[35],object[35],type[35];
        !           972:                strncpy(zone,nbp_req->nve.zone.str, nbp_req->nve.zone.len);
        !           973:                strncpy(object,nbp_req->nve.object.str, nbp_req->nve.object.len);
        !           974:                strncpy(type,nbp_req->nve.type.str, nbp_req->nve.type.len);
        !           975:                object[nbp_req->nve.object.len] = '\0';
        !           976:                zone[nbp_req->nve.zone.len] = '\0';
        !           977:                type[nbp_req->nve.type.len] = '\0';
        !           978:                dPrintf(D_M_NBP_LOW, D_L_USR4,
        !           979:                                ("nbp_search: looking for %s:%s@%s resp:0x%x\n",object,type,zone,
        !           980:                                (u_int) nbp_req->response));
        !           981:        }
        !           982: #endif /* NBP_DEBUG */
        !           983:        ATDISABLE(nve_lock_pri,NVE_LOCK);
        !           984:        for (nve_entry = name_registry.fwd; nve_entry != &name_registry ; 
        !           985:                nve_entry = nve_entry->fwd) {
        !           986: 
        !           987:                if ((nbp_req->nve.zone_hash) && 
        !           988:                        ((nbp_req->nve.zone_hash != 
        !           989:                          nve_entry->zone_hash) &&
        !           990:                         (nbp_req->nve.zone_hash != hzonehash)
        !           991:                    )
        !           992:                   ) {
        !           993:                        dPrintf(D_M_NBP_LOW,D_L_USR4,
        !           994:                                ("nbp_search: no match for zone, req hash:%x\n",
        !           995:                        nbp_req->nve.zone_hash));
        !           996:                        continue;
        !           997:                }
        !           998:                else {  /* for this entry's zone OR no zone in request or entry */
        !           999:                                /* only in singleport mode (!MULTIPORT_MODE) with empty PRAM
        !          1000:                    can an entry have '*' for it's zone
        !          1001:                  */
        !          1002:                        at_nvestr_t *ezone=&nve_entry->zone;
        !          1003:                        at_nvestr_t *rzone=&nbp_req->nve.zone;
        !          1004: /*                     if (!(rzone->len == 1 && rzone->str[0] == '*'))  { */
        !          1005:                        if (!DEFAULT_ZONE(rzone) && !DEFAULT_ZONE(ezone))  {
        !          1006:                                if (nbp_strcmp (rzone, ezone, 0) != 0)
        !          1007:                                        continue;
        !          1008:                        }
        !          1009:                        else {
        !          1010:                                if (MULTIHOME_MODE && ifID && 
        !          1011:                                        NET_NOTEQ(nve_entry->address.net, ifID->ifThisNode.atalk_net)) {
        !          1012:                                dPrintf(D_M_NBP, D_L_USR4, 
        !          1013:                                        ("nbp search ifID (%d) & req net (%d) not eq\n",
        !          1014:                                        NET_VALUE(nve_entry->address.net),
        !          1015:                                        NET_VALUE(ifID->ifThisNode.atalk_net)));
        !          1016:                                        continue;
        !          1017:                                }
        !          1018:                                dPrintf(D_M_NBP, D_L_USR4, 
        !          1019:                                        ("nbp search ifID (%d) & req net (%d)  equal\n",
        !          1020:                                        NET_VALUE(nve_entry->address.net),
        !          1021:                                        NET_VALUE(ifID->ifThisNode.atalk_net)));
        !          1022:                        }
        !          1023:                
        !          1024:                }
        !          1025:                if (!(nbp_req->flags & NBP_WILD_OBJECT)) {
        !          1026:                        if ((nbp_req->nve.object_hash) && 
        !          1027:                                (nbp_req->nve.object_hash != 
        !          1028:                                nve_entry->object_hash))
        !          1029:                                continue;
        !          1030:                        else {
        !          1031:                                if (nbp_strcmp (&nbp_req->nve.object, 
        !          1032:                                        &nve_entry->object, 
        !          1033:                                        NBP_SPL_WILDCARD) != 0)
        !          1034:                                        continue;
        !          1035:                        }
        !          1036:                }
        !          1037: 
        !          1038: 
        !          1039:                if (!(nbp_req->flags & NBP_WILD_TYPE)) {
        !          1040:                        if ((nbp_req->nve.type_hash) && 
        !          1041:                                (nbp_req->nve.type_hash !=nve_entry->type_hash))
        !          1042:                                continue;
        !          1043:                        else {
        !          1044:                                if (nbp_strcmp (&nbp_req->nve.type, 
        !          1045:                                        &nve_entry->type, 
        !          1046:                                        NBP_SPL_WILDCARD) != 0)
        !          1047:                                        continue;
        !          1048:                        }
        !          1049:                }
        !          1050: 
        !          1051:                /* Found a match! */
        !          1052: #ifdef NBP_DEBUG
        !          1053:        {
        !          1054:                char zone[35],object[35],type[35];
        !          1055:                int net;
        !          1056:                net = NET_VALUE(nve_entry->address.net);
        !          1057:                strncpy(zone,nbp_req->nve.zone.str, nbp_req->nve.zone.len);
        !          1058:                strncpy(object,nbp_req->nve.object.str, nbp_req->nve.object.len);
        !          1059:                strncpy(type,nbp_req->nve.type.str, nbp_req->nve.type.len);
        !          1060:                object[nbp_req->nve.object.len] = '\0';
        !          1061:                zone[nbp_req->nve.zone.len] = '\0';
        !          1062:                type[nbp_req->nve.type.len] = '\0';
        !          1063:                dPrintf(D_M_NBP_LOW, D_L_USR2,
        !          1064:                        ("nbp_search: found  %s:%s@%s  net:%d\n",
        !          1065:                        object, type, zone, net));
        !          1066:        }
        !          1067: #endif /* NBP_DEBUG */
        !          1068:                if (nbp_req->func != NULL) {
        !          1069:                        if ((*(nbp_req->func))(nbp_req, nve_entry) != 0) {
        !          1070:                                /* errno expected to be set by func */
        !          1071:                                ATENABLE(nve_lock_pri,NVE_LOCK);
        !          1072:                                return (NULL);
        !          1073:                        }
        !          1074:                } else {
        !          1075:                        ATENABLE(nve_lock_pri,NVE_LOCK);
        !          1076:                        return (nve_entry);
        !          1077:                }
        !          1078:        }
        !          1079:        ATENABLE(nve_lock_pri,NVE_LOCK);
        !          1080: 
        !          1081:        errno = 0;
        !          1082:        return (NULL);
        !          1083: }
        !          1084: 
        !          1085: 
        !          1086: static int     nbp_lkup_reply (nbp_req, nve_entry)
        !          1087: register nbp_req_t     *nbp_req;
        !          1088: register nve_entry_t   *nve_entry;
        !          1089: {
        !          1090:        register at_nbptuple_t  *tuple;
        !          1091:        register int    tuple_size, buf_len;
        !          1092:        register int    obj_len, type_len;
        !          1093: 
        !          1094:        /* size of the current tuple we want to write... */
        !          1095:        tuple_size = nve_entry->object.len + 1 +        /* object */
        !          1096:                        nve_entry->type.len + 1 +       /* type */
        !          1097:                        2 +                             /* zone */
        !          1098:                        sizeof (at_inet_t) + 1;         /* addr + enum */
        !          1099: 
        !          1100:        buf_len = ((nbp_req->flags & NBP_WILD_MASK) ? DDP_DATA_SIZE:tuple_size);
        !          1101:        if (nbp_req->response == NULL) {
        !          1102:                if (nbp_setup_resp (nbp_req, buf_len) != 0)
        !          1103:                        /* errno expected to be set by nbp_setup_resp() */
        !          1104:                        return (-1);
        !          1105:        }
        !          1106: 
        !          1107:        if ((nbp_req->space_unused < tuple_size) || 
        !          1108:                (DATA_NBP(nbp_req->response)->tuple_count == NBP_TUPLE_MAX)) {
        !          1109:                if (nbp_send_resp (nbp_req) != 0)
        !          1110:                        return (-1);
        !          1111:                if (nbp_setup_resp (nbp_req, buf_len) != 0)
        !          1112:                        return (-1);
        !          1113:        }
        !          1114: 
        !          1115:        /* At this point, we have a response buffer that can accommodate the
        !          1116:         * tuple we want to write. Write it!
        !          1117:         */
        !          1118:        tuple = (at_nbptuple_t *)gbuf_wptr(nbp_req->response);
        !          1119:        tuple->enu_addr = nve_entry->address;
        !          1120:        tuple->enu_enum = nve_entry->enumerator;
        !          1121:        obj_len = nve_entry->object.len + 1;
        !          1122:        bcopy(&nve_entry->object, &tuple->enu_name[0], obj_len);
        !          1123:        type_len = nve_entry->type.len + 1;
        !          1124:        bcopy(&nve_entry->type, &tuple->enu_name[obj_len], type_len);
        !          1125:        tuple->enu_name[obj_len + type_len] = 1;
        !          1126:        tuple->enu_name[obj_len + type_len + 1] = '*';
        !          1127: 
        !          1128:        nbp_req->space_unused -= tuple_size;
        !          1129:        gbuf_winc(nbp_req->response, tuple_size);
        !          1130: 
        !          1131:        /* increment the tuple count in header by 1 */
        !          1132:        DATA_NBP(nbp_req->response)->tuple_count++;
        !          1133: 
        !          1134:        return (0);
        !          1135: }
        !          1136: 
        !          1137: 
        !          1138: static int     nbp_strcmp (str1, str2, embedded_wildcard)
        !          1139: register at_nvestr_t   *str1, *str2;
        !          1140: register u_char        embedded_wildcard;      /* If str1 may contain a character
        !          1141:                                         * that's to be treated as an
        !          1142:                                         * embedded wildcard, this character
        !          1143:                                         * is it.  Making this special case
        !          1144:                                         * since for zone names, squiggly
        !          1145:                                         * equal is not to be treated as a 
        !          1146:                                         * wildcard.
        !          1147:                                         */
        !          1148: {
        !          1149:        u_char          ch1,ch2;
        !          1150:        register int    i1, i2;
        !          1151:        register int    reverse = 0;
        !          1152:        register int    left_index;
        !          1153: 
        !          1154:        /* Embedded wildcard, if any, could only be in the first string (str1).
        !          1155:         * returns 0 if two strings are equal (modulo case), -1 otherwise 
        !          1156:         */
        !          1157:        
        !          1158:        if (str1->len == 0 || str2->len == 0) {
        !          1159:                return (-1);
        !          1160:        }       
        !          1161:        
        !          1162:        /* Wildcards are not allowed in str2.
        !          1163:         *
        !          1164:         * If str1 could potentially contain an embedded wildcard, since the
        !          1165:         * embedded wildcard matches ZERO OR MORE characters, str1 can not be
        !          1166:         * more than 1 character longer than str2.
        !          1167:         *
        !          1168:         * If str1 is not supposed to have embedded wildcards, the two strs 
        !          1169:         * must be of equal length.
        !          1170:         */
        !          1171:        if ((embedded_wildcard && (str2->len < (unsigned) (str1->len-1))) ||
        !          1172:                (!embedded_wildcard && (str2->len !=  str1->len))) {
        !          1173:                return (-1);
        !          1174:        }
        !          1175: 
        !          1176:        for (i1 = i2 = left_index = 0; (unsigned) i1 < str1->len ;) {
        !          1177:                ch1 = str1->str[i1];
        !          1178:                ch2 = str2->str[i2];
        !          1179: 
        !          1180:                if (embedded_wildcard && (ch1==embedded_wildcard)) {
        !          1181:                        /* hit the embedded wild card... start comparing from 
        !          1182:                         * the other end of the string.
        !          1183:                         */
        !          1184:                        reverse++;
        !          1185:                        /* But, if embedded wildcard was the last character of 
        !          1186:                         * the string, the two strings match, so return okay.
        !          1187:                         */
        !          1188:                        if (i1 == str1->len-1) {
        !          1189:                                return (0);
        !          1190:                        }
        !          1191:                        
        !          1192:                        i1 = str1->len - 1;
        !          1193:                        i2 = str2->len - 1;
        !          1194:                        
        !          1195:                        continue;
        !          1196:                }
        !          1197:                
        !          1198:                nbp_upshift(&ch1, 1);
        !          1199:                nbp_upshift(&ch2, 1);
        !          1200: 
        !          1201:                if (ch1 != ch2) {
        !          1202:                        return (-1);
        !          1203:                }
        !          1204:                
        !          1205:                if (reverse) {
        !          1206:                        i1--; i2--;
        !          1207:                        if (i1 == left_index) {
        !          1208:                                return (0);
        !          1209:                        }
        !          1210:                } else {
        !          1211:                        i1++; i2++; left_index++;
        !          1212:                }
        !          1213:        }
        !          1214:        return (0);
        !          1215: }
        !          1216: 
        !          1217: 
        !          1218: static void    nbp_setup_hdr (nbp_req)
        !          1219: register nbp_req_t     *nbp_req;
        !          1220: {
        !          1221:        register at_ddp_t       *ddp;
        !          1222:        register at_nbp_t       *nbp;
        !          1223: 
        !          1224:        ddp = DATA_DDP(nbp_req->response);
        !          1225:        nbp = DATA_NBP(nbp_req->response);
        !          1226:        
        !          1227:        ddp->type = NBP_DDP_TYPE;
        !          1228:        UAS_ASSIGN(ddp->checksum, 0);
        !          1229:        ddp->unused = ddp->hopcount = 0;
        !          1230: 
        !          1231:        switch(DATA_NBP(nbp_req->request)->control) {
        !          1232:        case NBP_LKUP :
        !          1233:                ddp->dst_socket = nbp_req->nve.address.socket;
        !          1234:                ddp->dst_node = nbp_req->nve.address.node;
        !          1235:                NET_NET(ddp->dst_net, nbp_req->nve.address.net);
        !          1236:                nbp->control = NBP_LKUP_REPLY;
        !          1237:                break;
        !          1238:        case NBP_REGISTER :
        !          1239:        case NBP_DELETE :
        !          1240:                ddp->dst_socket = DATA_DDP(nbp_req->request)->src_socket;
        !          1241:                ddp->dst_node = DATA_DDP(nbp_req->request)->src_node;
        !          1242:                NET_NET(ddp->dst_net, DATA_DDP(nbp_req->request)->src_net);
        !          1243:                nbp->control = NBP_STATUS_REPLY;
        !          1244:                break;
        !          1245:        }
        !          1246:        nbp->at_nbp_id = DATA_NBP(nbp_req->request)->at_nbp_id;
        !          1247:        return;
        !          1248: }
        !          1249: 
        !          1250: 
        !          1251: static int     nbp_setup_resp (nbp_req, tuples_size)
        !          1252: register nbp_req_t     *nbp_req;
        !          1253: register int           tuples_size;
        !          1254: {
        !          1255:        int     buf_size = tuples_size + DDP_X_HDR_SIZE + NBP_HDR_SIZE;
        !          1256:        nbp_req->response = gbuf_alloc(AT_WR_OFFSET+buf_size, PRI_MED);
        !          1257:        if (nbp_req->response == NULL) {
        !          1258:                errno = ENOBUFS;
        !          1259:                return(-1);
        !          1260:        }
        !          1261:        gbuf_rinc(nbp_req->response, AT_WR_OFFSET);
        !          1262:        gbuf_wset(nbp_req->response, DDP_X_HDR_SIZE + NBP_HDR_SIZE);
        !          1263:        nbp_setup_hdr(nbp_req);
        !          1264: 
        !          1265:        DATA_NBP(nbp_req->response)->tuple_count = 0;
        !          1266:        nbp_req->space_unused = tuples_size;
        !          1267: 
        !          1268:        return (0);
        !          1269: } /* nbp_setup_resp */
        !          1270: 
        !          1271: 
        !          1272: static int     nbp_send_resp (nbp_req)
        !          1273: register nbp_req_t     *nbp_req;
        !          1274: {
        !          1275:        int             status;
        !          1276: 
        !          1277:        status = ddp_output(&nbp_req->response, (at_socket)NBP_SOCKET, NULL);
        !          1278: 
        !          1279:        if (status)
        !          1280:                gbuf_freem(nbp_req->response);
        !          1281:        nbp_req->response = NULL;
        !          1282:        errno = status;
        !          1283:        return(errno?-1:0);
        !          1284: }
        !          1285: 
        !          1286: static int     nbp_insert_entry (nve_entry)
        !          1287: nve_entry_t    *nve_entry;
        !          1288: {
        !          1289:        gbuf_t          *tag;
        !          1290:        nve_entry_t     *new_entry;
        !          1291:        int i;
        !          1292:        at_if_t *ifID;
        !          1293:        at_nvestr_t *zone;
        !          1294:        int             multiZone = 0;          /* true if we should do multiple registrations */
        !          1295:        int             defaultZone = 0;        /* true if zone is '*' */
        !          1296: 
        !          1297:        /* Got an nve entry on hand.... allocate a buffer, copy the entry
        !          1298:         * on to it and stick it in the registry.
        !          1299:         */
        !          1300:        if (nve_entry->zone.str[0] == '*')
        !          1301:                defaultZone=TRUE;
        !          1302:        if (defaultZone  && MULTIHOME_MODE) {
        !          1303:                        multiZone = TRUE;
        !          1304:        }
        !          1305:        for (ifID = ifID_table[0],i=0; ifID; ifID=ifID_table[++i]) {
        !          1306:                if (!defaultZone && MULTIPORT_MODE ) {
        !          1307:                                /* if registering for a specific zone and we have multiple
        !          1308:                                   I/F's running, find the first I/F containing the 
        !          1309:                                   requested zone 
        !          1310:                                 */
        !          1311:                        int zno;
        !          1312:                        char ifs_in_zone[IF_TOTAL_MAX];
        !          1313:                        if (!(zno = zt_find_zname(&nve_entry->zone))) {
        !          1314:                                errno = ENOENT;
        !          1315:                                return(-1);
        !          1316:                        }
        !          1317:                        getIfUsage(zno-1, ifs_in_zone);
        !          1318:                        for(; ifID; ifID=ifID_table[++i])
        !          1319:                                if (ifs_in_zone[i])
        !          1320:                                        break;
        !          1321:                        if (!ifID) {
        !          1322:                                errno = ENOENT;
        !          1323:                                return(-1);
        !          1324:                        }
        !          1325:                }
        !          1326: 
        !          1327:                if ((tag = gbuf_alloc(sizeof(nve_entry_t), PRI_HI)) == NULL){
        !          1328:                        errno = ENOBUFS;
        !          1329:                        return (-1);
        !          1330:                }
        !          1331:                gbuf_wset(tag, sizeof(nve_entry_t));
        !          1332:                new_entry = (nve_entry_t *)gbuf_rptr(tag);
        !          1333:                bcopy(nve_entry, new_entry, sizeof(nve_entry_t));
        !          1334:                NET_NET(new_entry->address.net, ifID->ifThisNode.atalk_net);
        !          1335:                new_entry->address.node = ifID->ifThisNode.atalk_node;
        !          1336:                if (multiZone ){
        !          1337:                        new_entry->zone = ZT_table[ifID->ifDefZone-1].Zone;
        !          1338:                        new_entry->zone_hash = nbp_strhash(&new_entry->zone);
        !          1339:                }
        !          1340:                
        !          1341:                if (defaultZone && !multiZone ) {
        !          1342:                                /* put actual zone name in entry instead of "*" */
        !          1343:                                /* if single port mode and no zone name, then a router
        !          1344:                    is down, so use pram zone name hint from elap cfg */
        !          1345:                        if (!MULTIPORT_MODE && ifID->ifZoneName.str[0] == '*') {
        !          1346:                                elap_specifics_t *elapp;
        !          1347:                                elapp = (elap_specifics_t*)(ifID_table[IFID_HOME]->ifLapp);
        !          1348:                                zone = &elapp->cfg.zonename;
        !          1349:                        }
        !          1350:                        else {
        !          1351:                                zone = &ifID_table[IFID_HOME]->ifZoneName; 
        !          1352:                        }
        !          1353:                        new_entry->zone = *zone;
        !          1354:                        if ( new_entry->zone.len == 0 ) {
        !          1355:                                new_entry->zone.str[0] = '*';
        !          1356:                                new_entry->zone.len = 1;
        !          1357:                        }
        !          1358:                        new_entry->zone_hash = nbp_strhash(&new_entry->zone);
        !          1359:                }
        !          1360:                new_entry->tag = tag;
        !          1361: #ifdef NEXT
        !          1362: /* Fixes PR 2243737: didn't deregister nbp entity properly */
        !          1363:                new_entry->pid =  current_proc()->p_pid;
        !          1364: #else
        !          1365:                new_entry->pid = getpid();
        !          1366: #endif
        !          1367: 
        !          1368:                ATDISABLE(nve_lock_pri,NVE_LOCK);
        !          1369:                ddp_insque(new_entry, name_registry.fwd);
        !          1370:                ATENABLE(nve_lock_pri,NVE_LOCK);
        !          1371:                at_statep->flags |= AT_ST_NBP_CHANGED;
        !          1372: #ifdef NBP_DEBUG
        !          1373:        {
        !          1374:                char zone[35],object[35],type[35];
        !          1375:                strncpy(zone,new_entry->zone.str, new_entry->zone.len);
        !          1376:                strncpy(object,new_entry->object.str, new_entry->object.len);
        !          1377:                strncpy(type,new_entry->type.str, new_entry->type.len);
        !          1378:                object[new_entry->object.len] = '\0';
        !          1379:                zone[new_entry->zone.len] = '\0';
        !          1380:                type[new_entry->type.len] = '\0';
        !          1381:                dPrintf(D_M_NBP_LOW, D_L_USR4,
        !          1382:                        ("nbp_insert:adding %s:%s@%s i/f:%s ",
        !          1383:                        object, type, zone, ifID->ifName));
        !          1384:                dPrintf(D_M_NBP_LOW, D_L_USR4,
        !          1385:                        ("addr:%d.%d\n",
        !          1386:                        NET_VALUE(new_entry->address.net),
        !          1387:                        new_entry->address.node));
        !          1388:        }
        !          1389: #endif /* NBP_DEBUG */
        !          1390:                nbp_add_multicast(&new_entry->zone, ifID);
        !          1391:                if (!multiZone)
        !          1392:                        break;
        !          1393:        }
        !          1394:        return (0);
        !          1395: }
        !          1396: 
        !          1397: nbp_add_multicast(zone, ifID)
        !          1398: at_nvestr_t *zone;
        !          1399: at_if_t *ifID;
        !          1400: {
        !          1401:        char data[ETHERNET_ADDR_LEN];
        !          1402:        int i;
        !          1403: 
        !          1404:        if (zone->str[0] == '*')
        !          1405:                return;
        !          1406:                {
        !          1407:                        char str[35];
        !          1408:                        strncpy(str,zone->str,zone->len);
        !          1409:                        str[zone->len] = '\0';
        !          1410:                        dPrintf(D_M_NBP_LOW, D_L_USR3,
        !          1411:                                ("nbp_add_multi getting mc for %s\n", str));
        !          1412:                }
        !          1413:                zt_get_zmcast(ifID, zone, data); 
        !          1414:                if ((ifID->ifType == IFTYPE_FDDITALK)
        !          1415:                        || (ifID->ifType == IFTYPE_TOKENTALK))
        !          1416:                        ddp_bit_reverse(data);
        !          1417:                dPrintf(D_M_NBP_LOW,D_L_USR3,
        !          1418:                        ("nbp_add_multi adding  0x%x%x port:%d ifID:0x%x if:%s\n",
        !          1419:                        *(unsigned*)data, (*(unsigned *)(data+2))&0x0000ffff,
        !          1420:                        i, (u_int) ifID, ifID->ifName));
        !          1421: 
        !          1422:                elap_control(ifID, ELAP_REG_ZONE_MCAST, data);
        !          1423: }
        !          1424: 
        !          1425: 
        !          1426: static void    nbp_delete_entry (nve_entry)
        !          1427: nve_entry_t    *nve_entry;
        !          1428: {
        !          1429:        ddp_remque(nve_entry);
        !          1430:        gbuf_freem(nve_entry->tag);
        !          1431:        at_statep->flags |= AT_ST_NBP_CHANGED;
        !          1432: }
        !          1433: 
        !          1434: 
        !          1435: static int     nbp_enum_gen (nve_entry)
        !          1436: register nve_entry_t   *nve_entry;
        !          1437: {
        !          1438:        register int            new_enum = 0;
        !          1439:        register nve_entry_t    *ne;
        !          1440: 
        !          1441:        ATDISABLE(nve_lock_pri,NVE_LOCK);
        !          1442: re_do:
        !          1443:        for (ne = name_registry.fwd; ne != &name_registry; ne = ne->fwd) {
        !          1444:                if ((*(int *)&ne->address == *(int *)&nve_entry->address) &&
        !          1445:                        (ne->enumerator == new_enum)) {
        !          1446:                        if (new_enum == 255) {
        !          1447:                                errno = EADDRNOTAVAIL;
        !          1448:                                ATENABLE(nve_lock_pri,NVE_LOCK);
        !          1449:                                return (-1);
        !          1450:                        } else {
        !          1451:                                new_enum++;
        !          1452:                                goto re_do;
        !          1453:                        }
        !          1454:                }
        !          1455:        }
        !          1456: 
        !          1457:        ATENABLE(nve_lock_pri,NVE_LOCK);
        !          1458:        nve_entry->enumerator = new_enum;
        !          1459:        return (0);
        !          1460: }
        !          1461: 
        !          1462: 
        !          1463: getNbpTableSize()
        !          1464: 
        !          1465: /* for SNMP, returns size in # of entries */
        !          1466: {
        !          1467:        register nve_entry_t *nve;
        !          1468:        register int i=0;
        !          1469: 
        !          1470:        ATDISABLE(nve_lock_pri,NVE_LOCK);
        !          1471:        for (nve = name_registry.fwd; nve != &name_registry; nve = nve->fwd, i++) 
        !          1472:                        ;
        !          1473:        ATENABLE(nve_lock_pri,NVE_LOCK);
        !          1474:        return(i);
        !          1475: }
        !          1476: 
        !          1477: getNbpTable(p,s,c)
        !          1478: snmpNbpEntry_t *p;
        !          1479: int            s;              /* starting entry */
        !          1480: int                    c;              /* # entries to copy */
        !          1481: 
        !          1482: /* for SNMP, returns section of nbp table */
        !          1483: 
        !          1484: {
        !          1485:        register nve_entry_t *nve;
        !          1486:        register int i=0;
        !          1487:        static   int nextNo=0;          /* entry that *next points to */
        !          1488:        static   nve_entry_t  *next = (nve_entry_t*)NULL;
        !          1489:        
        !          1490:        if (s && next && nextNo == s) {
        !          1491:                nve = next;
        !          1492:                i = nextNo;
        !          1493:        }
        !          1494:        else
        !          1495:                nve = name_registry.fwd;
        !          1496: 
        !          1497:        ATDISABLE(nve_lock_pri,NVE_LOCK);
        !          1498:        for ( ; nve != &name_registry && c ; nve = nve->fwd, p++,i++) {
        !          1499:                if (i>= s) {
        !          1500:                        p->nbpe_object = nve->object;
        !          1501:                        p->nbpe_type   = nve->type;
        !          1502:                        c--;
        !          1503:                }
        !          1504:        }
        !          1505:        ATENABLE(nve_lock_pri,NVE_LOCK);
        !          1506:        if (nve != &name_registry) {
        !          1507:                next = nve;
        !          1508:                nextNo = i;
        !          1509:        }else {
        !          1510:                next = (nve_entry_t*)NULL;
        !          1511:                nextNo = 0;
        !          1512:        }
        !          1513: }
        !          1514: 
        !          1515: 
        !          1516: #define ZONES_PER_BLK          31      /* 31 fits within a 1k blk) */
        !          1517: #define ZONE_BLK_SIZE          ZONES_PER_BLK * sizeof(at_nvestr_t)
        !          1518: 
        !          1519: setLocalZones(newzones, size)
        !          1520: at_nvestr_t *newzones;
        !          1521: int size;
        !          1522: /* updates list of zones which are local to all active ports
        !          1523:    missing zones are not deleted, only missing zones are added.
        !          1524: */
        !          1525: {
        !          1526:        int     bytesread=0;            /* #bytes read from tuple */
        !          1527:        int i=0, dupe;
        !          1528:        gbuf_t  *m;
        !          1529:        at_nvestr_t             *pnve, *pnew = newzones;
        !          1530: 
        !          1531:        if (!lzones) {
        !          1532:                if(!(lzones = gbuf_alloc(ZONE_BLK_SIZE, PRI_MED)))
        !          1533:                        return(ENOBUFS);
        !          1534:                gbuf_wset(lzones,0);
        !          1535:        }
        !          1536:        while (bytesread < size) {              /* for each new zone */
        !          1537:                {
        !          1538:                        char str[35];
        !          1539:                        strncpy(str,pnew->str,pnew->len);
        !          1540:                        str[pnew->len] = '\0';
        !          1541:                }
        !          1542:                m = lzones;                             
        !          1543:                pnve = (at_nvestr_t*)gbuf_rptr(m);
        !          1544:                dupe = 0;
        !          1545:                for (i=0; i<lzonecnt && !dupe; i++,pnve++)  {
        !          1546:                        if (i && !(i%ZONES_PER_BLK))
        !          1547:                                if (gbuf_cont(m)) {
        !          1548:                                        m = gbuf_cont(m);
        !          1549:                                        pnve = (at_nvestr_t*)gbuf_rptr(m);
        !          1550:                                }
        !          1551:                                else
        !          1552:                                        break;
        !          1553:                        if (pnew->len != pnve->len)
        !          1554:                                continue;
        !          1555:                        if ((pnew->len > 33) || (pnew->len <0) ) {
        !          1556:                                return(0);
        !          1557:                        }
        !          1558:                        if (!strncmp(pnew->str, pnve->str, pnew->len)) {
        !          1559:                                dupe=1;
        !          1560:                                continue;
        !          1561:                        }
        !          1562:                }
        !          1563:                if (!dupe) {
        !          1564:                        /* add new zone */
        !          1565:                        if (lzonecnt && !(lzonecnt%ZONES_PER_BLK)) {
        !          1566:                                if(!(gbuf_cont(m) = gbuf_alloc(ZONE_BLK_SIZE, PRI_MED)))
        !          1567:                                        return(ENOBUFS);
        !          1568:                                gbuf_wset(gbuf_cont(m),0);
        !          1569:                                pnve = (at_nvestr_t*)gbuf_rptr(gbuf_cont(m));
        !          1570:                        }
        !          1571:                        strncpy(pnve->str,pnew->str,pnew->len);
        !          1572:                        pnve->len = pnew->len;
        !          1573:                        lzonecnt++;
        !          1574:                }
        !          1575:                bytesread += (pnew->len+1);
        !          1576:                pnew = (at_nvestr_t*) (((char *)pnew) + pnew->len + 1);
        !          1577:        }
        !          1578:        /* showLocalZones1(); */
        !          1579:        return(0);
        !          1580: }
        !          1581: 
        !          1582: /**********
        !          1583: showLocalZones1()
        !          1584: {
        !          1585:        int i;
        !          1586:        at_nvestr_t *pnve;
        !          1587:        gbuf_t  *m;
        !          1588:        char str[35];
        !          1589:        
        !          1590:        for (i=0;  ; i++) {
        !          1591:                if (!(pnve = getLocalZone(i))) {
        !          1592:                        break;
        !          1593:                }
        !          1594:                strncpy(str,pnve->str,pnve->len);
        !          1595:                str[pnve->len] = '\0';
        !          1596:        }
        !          1597: }
        !          1598: 
        !          1599: *********/
        !          1600: 
        !          1601: isZoneLocal(zone)
        !          1602: at_nvestr_t *zone;
        !          1603: {
        !          1604:        at_nvestr_t *pnve;
        !          1605:        int i;
        !          1606:        if ((zone->len == 1 && zone->str[0] == '*') || zone->len == 0)
        !          1607:                return(1);
        !          1608:        for (i=0;  ; i++) {
        !          1609:                if (!(pnve = getLocalZone(i))) 
        !          1610:                        break;
        !          1611:                if (!nbp_strcmp(pnve,zone,0))
        !          1612:                        return(1);
        !          1613:        }
        !          1614:        return(0);
        !          1615: }
        !          1616:        
        !          1617: 
        !          1618: #define NULL_PNVESTR (at_nvestr_t *) 0
        !          1619: 
        !          1620: at_nvestr_t *getLocalZone(zno)
        !          1621:        int zno;                        /* zone number in virtual list to
        !          1622:                                                   return, 0 for first zone */
        !          1623: /* returns pointer to a new local zone number zno,
        !          1624:    returns null when no zones left.
        !          1625: */
        !          1626: {
        !          1627:        if_zone_t ifz;
        !          1628:        ifz.ifzn.zone = zno;
        !          1629:        if (ROUTING_MODE || MULTIHOME_MODE) 
        !          1630:                return(getRTRLocalZone(&ifz));
        !          1631:        else
        !          1632:                return(getSPLocalZone(zno));
        !          1633: }
        !          1634: 
        !          1635: 
        !          1636: at_nvestr_t *getSPLocalZone(zno)
        !          1637:        int zno;                        /* zone number in virtual list to
        !          1638:                                                   return, 0 for first zone */
        !          1639: /* single port mode version */
        !          1640: {
        !          1641:        int curz=0;             /* current zone */
        !          1642:        gbuf_t *m;
        !          1643:        at_nvestr_t *pnve;
        !          1644: 
        !          1645:        if (lzones) {
        !          1646:                m = lzones;
        !          1647:                pnve = (at_nvestr_t*)gbuf_rptr(m);
        !          1648:        }
        !          1649:        else
        !          1650:                return(NULL_PNVESTR);
        !          1651:        if ( zno>=lzonecnt )
        !          1652:                return(NULL_PNVESTR);
        !          1653:        for (curz=0; curz<zno; curz++,pnve++ ) {
        !          1654:                if ( curz<lzonecnt ) {
        !          1655:                        if (curz && !(curz%ZONES_PER_BLK) ) {
        !          1656:                                if (gbuf_cont(m)) {
        !          1657:                                        m = gbuf_cont(m);
        !          1658:                                        pnve = (at_nvestr_t*)gbuf_rptr(m);
        !          1659:                                }
        !          1660:                                else {
        !          1661:                                        return(NULL_PNVESTR);
        !          1662:                                }
        !          1663:                        }
        !          1664:                        if ((pnve->len > NBP_NVE_STR_SIZE) || (pnve->len <0) ) {
        !          1665:                                return(NULL_PNVESTR);
        !          1666:                        }
        !          1667:                }
        !          1668:                else
        !          1669:                        return(NULL_PNVESTR);
        !          1670:        }
        !          1671:        return(pnve);
        !          1672: }
        !          1673: 
        !          1674: 
        !          1675: 
        !          1676: 

unix.superglobalmegacorp.com

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