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

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

unix.superglobalmegacorp.com

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