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

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: /*
                     26:  *     Copyright (c) 1988, 1989, 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.