Annotation of XNU/bsd/netat/aurp_zi.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) 1996 Apple Computer, Inc. 
        !            24:  *
        !            25:  *             Created April 8, 1996 by Tuyen Nguyen
        !            26:  *   Modified, March 17, 1997 by Tuyen Nguyen for MacOSX.
        !            27:  *
        !            28:  *     File: zi.c
        !            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/socket.h>
        !            41: #include <sys/socketvar.h>
        !            42: #include <net/if.h>
        !            43: #include <kern/assert.h>
        !            44: 
        !            45: #include <netat/sysglue.h>
        !            46: #include <netat/appletalk.h>
        !            47: #include <netat/at_var.h>
        !            48: #include <netat/routing_tables.h>
        !            49: #include <netat/at_pcb.h>
        !            50: #include <netat/aurp.h>
        !            51: #include <netat/debug.h>
        !            52: 
        !            53: static int AURPgetzi(int, unsigned char *, short *, gbuf_t *, int);
        !            54: static void AURPsetzi(unsigned char, gbuf_t *, short, short);
        !            55: 
        !            56: /* */
        !            57: void AURPsndZReq(state)
        !            58:        aurp_state_t *state;
        !            59: {
        !            60:        gbuf_t *m;
        !            61:        int msize;
        !            62:        aurp_hdr_t *hdrp;
        !            63:        short *net, nets_cnt, net_sent=0, entry_num=0;
        !            64:        RT_entry *entry = RT_table;
        !            65: 
        !            66:        if (!state->get_zi || (state->rcv_state == AURPSTATE_Unconnected))
        !            67:                return;
        !            68: 
        !            69: l_more:
        !            70:        msize = sizeof(aurp_hdr_t);
        !            71:        if ((m = (gbuf_t *)gbuf_alloc(msize+AURP_MaxPktSize, PRI_MED)) == 0) {
        !            72:                dPrintf(D_M_AURP, D_L_WARNING, ("AURPsndZReq: node=%d, out of mblk\n",
        !            73:                        state->rem_node));
        !            74:                return;
        !            75:        }
        !            76:        gbuf_wset(m,msize);
        !            77: 
        !            78:        /* construct the ZI request packet */
        !            79:        hdrp = (aurp_hdr_t *)gbuf_rptr(m);
        !            80:        hdrp->connection_id = state->rcv_connection_id;
        !            81:        hdrp->sequence_number = 0;
        !            82:        hdrp->command_code = AURPCMD_ZReq;
        !            83:        hdrp->flags = 0;
        !            84:        *(short *)(hdrp+1) = AURPSUBCODE_ZoneInfo1;
        !            85:        gbuf_winc(m,sizeof(short));
        !            86: 
        !            87:        net = (short *)gbuf_wptr(m);
        !            88:        nets_cnt = 0;
        !            89: 
        !            90:        while (entry_num < RT_maxentry) {
        !            91:                /*
        !            92:                 * scan the router table, and build the ZI request packet
        !            93:                 * with the right entries, i.e.,
        !            94:                 *  - entry in use and not of the net_port
        !            95:                 *  - with no zones and in an active state
        !            96:                 *  - talking to the right router
        !            97:                 */
        !            98:                if ( (entry->NetPort == net_port) && entry->NetStop &&
        !            99:                        ((entry->EntryState & 0x0F) >= RTE_STATE_SUSPECT) &&
        !           100:                                (!RT_ALL_ZONES_KNOWN(entry)) ) {
        !           101:                        *net++ = (entry->NetStart) ? entry->NetStart : entry->NetStop;
        !           102:                        nets_cnt++;
        !           103:                }
        !           104: 
        !           105:                if (nets_cnt >= 640) {
        !           106:                        /* query only 640 networks per packet */
        !           107:                        dPrintf(D_M_AURP, D_L_INFO, ("AURPsndZReq: node=%d\n",
        !           108:                                state->rem_node));
        !           109:                        gbuf_winc(m,(nets_cnt * sizeof(short)));
        !           110:                        AURPsend(m, AUD_AURP, state->rem_node);
        !           111:                        net_sent = 1;
        !           112:                        goto l_more;
        !           113:                }
        !           114: 
        !           115:                entry_num++;
        !           116:                entry++;
        !           117:        }
        !           118: 
        !           119:        if (nets_cnt) {
        !           120:                dPrintf(D_M_AURP, D_L_INFO, ("AURPsndZReq: node=%d\n",
        !           121:                        state->rem_node));
        !           122:                gbuf_winc(m,(nets_cnt * sizeof(short)));
        !           123:                AURPsend(m, AUD_AURP, state->rem_node);
        !           124:                net_sent = 1;
        !           125:        } else
        !           126:                gbuf_freeb(m);
        !           127: 
        !           128:        if (!net_sent)
        !           129:                state->get_zi = 0;
        !           130: }
        !           131: 
        !           132: /* */
        !           133: void AURPsndZRsp(state, dat_m, flag)
        !           134:        aurp_state_t *state;
        !           135:        gbuf_t *dat_m;
        !           136:        int flag;
        !           137: {
        !           138:        short len;
        !           139:        int msize, next_entry = 0;
        !           140:        gbuf_t *m;
        !           141:        aurp_hdr_t *hdrp;
        !           142: 
        !           143:        if ((state->snd_state == AURPSTATE_Unconnected) || (dat_m == 0))
        !           144:                return;
        !           145:        msize = sizeof(aurp_hdr_t);
        !           146: 
        !           147:   do {
        !           148:        if ((m = (gbuf_t *)gbuf_alloc(msize+AURP_MaxPktSize, PRI_MED)) == 0) {
        !           149:                dPrintf(D_M_AURP, D_L_WARNING, ("AURPsndZRsp: node=%d, out of mblk\n",
        !           150:                        state->rem_node));
        !           151:                return;
        !           152:        }
        !           153:        gbuf_wset(m,msize);
        !           154: 
        !           155:        /* construct the ZI response packet */
        !           156:        hdrp = (aurp_hdr_t *)gbuf_rptr(m);
        !           157:        hdrp->connection_id = state->snd_connection_id;
        !           158:        hdrp->sequence_number = 0;
        !           159:        hdrp->command_code = AURPCMD_ZRsp;
        !           160:        hdrp->flags = 0;
        !           161: 
        !           162:        /* get zone info of the local networks */
        !           163:        next_entry = AURPgetzi(next_entry, gbuf_wptr(m), &len, dat_m, flag);
        !           164:        gbuf_winc(m,len);
        !           165: 
        !           166:        /* send the packet */
        !           167:        dPrintf(D_M_AURP, D_L_INFO, ("AURPsndZRsp: len=%d\n", len));
        !           168:        AURPsend(m, AUD_AURP, state->rem_node);
        !           169: 
        !           170:   } while (next_entry);
        !           171: 
        !           172:        gbuf_freem(dat_m);
        !           173: }
        !           174: 
        !           175: /* */
        !           176: void AURPsndGZN(state, dat_m)
        !           177:        aurp_state_t *state;
        !           178:        gbuf_t *dat_m;
        !           179: {
        !           180:        short zname_len;
        !           181:        int msize;
        !           182:        gbuf_t *m;
        !           183:        aurp_hdr_t *hdrp;
        !           184: 
        !           185:        if (state->snd_state == AURPSTATE_Unconnected)
        !           186:                return;
        !           187: 
        !           188:        msize = sizeof(aurp_hdr_t);
        !           189:        if ((m = (gbuf_t *)gbuf_alloc(msize+AURP_MaxPktSize, PRI_MED)) == 0) {
        !           190:                dPrintf(D_M_AURP, D_L_WARNING, ("AURPsndGZN: node=%d, out of mblk\n",
        !           191:                        state->rem_node));
        !           192:                return;
        !           193:        }
        !           194:        gbuf_wset(m,msize);
        !           195: 
        !           196:        /* construct the GZN response packet */
        !           197:        hdrp = (aurp_hdr_t *)gbuf_rptr(m);
        !           198:        hdrp->connection_id = state->snd_connection_id;
        !           199:        hdrp->sequence_number = 0;
        !           200:        hdrp->command_code = AURPCMD_ZRsp;
        !           201:        hdrp->flags = 0;
        !           202:        *(short *)(gbuf_wptr(m)) = AURPSUBCODE_GetZoneNets;
        !           203:        gbuf_winc(m,sizeof(short));
        !           204:        zname_len = gbuf_len(dat_m);
        !           205:        bcopy(gbuf_rptr(dat_m), gbuf_wptr(m), zname_len);
        !           206:        gbuf_winc(m,zname_len);
        !           207:        *(short *)(gbuf_wptr(m)) = -1; /* number of tuples - proto not supported */
        !           208:        gbuf_winc(m,sizeof(short));
        !           209: 
        !           210:        /* send the packet */
        !           211:        dPrintf(D_M_AURP, D_L_INFO, ("AURPsndGZN: count=%d\n", -1));
        !           212:        AURPsend(m, AUD_AURP, state->rem_node);
        !           213: }
        !           214: 
        !           215: /* */
        !           216: void AURPsndGDZL(state, dat_m)
        !           217:        aurp_state_t *state;
        !           218:        gbuf_t *dat_m;
        !           219: {
        !           220:        int msize;
        !           221:        gbuf_t *m;
        !           222:        aurp_hdr_t *hdrp;
        !           223: 
        !           224:        if (state->snd_state == AURPSTATE_Unconnected)
        !           225:                return;
        !           226: 
        !           227:        msize = sizeof(aurp_hdr_t);
        !           228:        if ((m = (gbuf_t *)gbuf_alloc(msize+AURP_MaxPktSize, PRI_MED)) == 0) {
        !           229:                dPrintf(D_M_AURP, D_L_WARNING, ("AURPsndGDZL: node=%d, out of mblk\n",
        !           230:                        state->rem_node));
        !           231:                return;
        !           232:        }
        !           233:        gbuf_wset(m,msize);
        !           234: 
        !           235:        /* construct the GDZL response packet */
        !           236:        hdrp = (aurp_hdr_t *)gbuf_rptr(m);
        !           237:        hdrp->connection_id = state->snd_connection_id;
        !           238:        hdrp->sequence_number = 0;
        !           239:        hdrp->command_code = AURPCMD_ZRsp;
        !           240:        hdrp->flags = 0;
        !           241:        *(short *)(gbuf_wptr(m)) = AURPSUBCODE_GetDomainZoneList;
        !           242:        gbuf_winc(m,sizeof(short));
        !           243:        *(short *)(gbuf_wptr(m)) = -1; /* start index - proto not supported */
        !           244:        gbuf_winc(m,sizeof(short));
        !           245: 
        !           246:        /* send the packet */
        !           247:        dPrintf(D_M_AURP, D_L_INFO, ("AURPsndGDZL: index=%d\n", -1));
        !           248:        AURPsend(m, AUD_AURP, state->rem_node);
        !           249: }
        !           250: 
        !           251: /* */
        !           252: void AURPrcvZReq(state, m)
        !           253:        aurp_state_t *state;
        !           254:        gbuf_t *m;
        !           255: {
        !           256:        short sub_code;
        !           257:        aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m);
        !           258: 
        !           259:        /* make sure we're in a valid state to accept it */
        !           260:        if (state->snd_state == AURPSTATE_Unconnected) {
        !           261:                dPrintf(D_M_AURP, D_L_WARNING, ("AURPrcvZReq: unexpected response\n"));
        !           262:                gbuf_freem(m);
        !           263:                return;
        !           264:        }
        !           265: 
        !           266:        /* check for the correct connection id */
        !           267:        if (hdrp->connection_id != state->snd_connection_id) {
        !           268:                dPrintf(D_M_AURP, D_L_WARNING,
        !           269:                        ("AURPrcvZReq: invalid connection id, r=%d, m=%d\n",
        !           270:                        hdrp->connection_id, state->snd_connection_id));
        !           271:                gbuf_freem(m);
        !           272:                return;
        !           273:        }
        !           274: 
        !           275:        gbuf_rinc(m,sizeof(*hdrp));
        !           276:        sub_code = *(short *)gbuf_rptr(m);
        !           277:        gbuf_rinc(m,sizeof(short));
        !           278: 
        !           279:        dPrintf(D_M_AURP, D_L_INFO, ("AURPrcvZReq: len=%ld\n", gbuf_len(m)));
        !           280: 
        !           281:        switch (sub_code) {
        !           282:        case AURPSUBCODE_ZoneInfo1:
        !           283:                AURPsndZRsp(state, m, 0);
        !           284:                return;
        !           285: 
        !           286:        case AURPSUBCODE_GetZoneNets:
        !           287:                AURPsndGZN(state, m);
        !           288:                break;
        !           289: 
        !           290:        case AURPSUBCODE_GetDomainZoneList:
        !           291:                AURPsndGDZL(state, m);
        !           292:                break;
        !           293:        }
        !           294: 
        !           295:        gbuf_freem(m);
        !           296: }
        !           297: 
        !           298: /* */
        !           299: void AURPrcvZRsp(state, m)
        !           300:        aurp_state_t *state;
        !           301:        gbuf_t *m;
        !           302: {
        !           303:        short sub_code, tuples_cnt;
        !           304:        aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m);
        !           305: 
        !           306:        /* make sure we're in a valid state to accept it */
        !           307:        if (state->rcv_state == AURPSTATE_Unconnected) {
        !           308:                dPrintf(D_M_AURP, D_L_WARNING, ("AURPrcvZRsp: unexpected response\n"));
        !           309:                gbuf_freem(m);
        !           310:                return;
        !           311:        }
        !           312: 
        !           313:        /* check for the correct connection id */
        !           314:        if (hdrp->connection_id != state->rcv_connection_id) {
        !           315:                dPrintf(D_M_AURP, D_L_WARNING,
        !           316:                        ("AURPrcvZRsp: invalid connection id, r=%d, m=%d\n",
        !           317:                        hdrp->connection_id, state->rcv_connection_id));
        !           318:                gbuf_freem(m);
        !           319:                return;
        !           320:        }
        !           321: 
        !           322:        gbuf_rinc(m,sizeof(*hdrp));
        !           323:        sub_code = *(short *)gbuf_rptr(m);
        !           324:        gbuf_rinc(m,sizeof(short));
        !           325: 
        !           326:        dPrintf(D_M_AURP, D_L_INFO, ("AURPrcvZRsp: len=%ld\n", gbuf_len(m)));
        !           327: 
        !           328:        switch (sub_code) {
        !           329:        case AURPSUBCODE_ZoneInfo1:
        !           330:        case AURPSUBCODE_ZoneInfo2:
        !           331:                tuples_cnt = *(short *)gbuf_rptr(m);
        !           332:                gbuf_rinc(m,sizeof(short));
        !           333:                AURPsetzi(state->rem_node, m, sub_code, tuples_cnt);
        !           334:                break;
        !           335: 
        !           336:        case AURPSUBCODE_GetZoneNets:
        !           337:                break;
        !           338: 
        !           339:        case AURPSUBCODE_GetDomainZoneList:
        !           340:                break;
        !           341:        }
        !           342: 
        !           343:        gbuf_freem(m);
        !           344: }
        !           345: 
        !           346: /* */
        !           347: static int
        !           348: AURPgetzi(next_entry, buf, len, dat_m, flag)
        !           349:        int next_entry;
        !           350:        unsigned char *buf;
        !           351:        short *len;
        !           352:        gbuf_t *dat_m;
        !           353:        int flag;
        !           354: {
        !           355:        static int i_sav=ZT_BYTES-1, j_sav=0, idx_sav=-1;
        !           356:        unsigned char ev, zname_len, *zmap, *zname_base, *zname_sav, *tuples_ptr;
        !           357:        unsigned short net_num, *net, zname_offset;
        !           358:        short *sub_codep, *tuples_cntp, tuples_cnt, dat_len;
        !           359:        int i, j, idx, nets_cnt;
        !           360:        RT_entry *entry;
        !           361: 
        !           362:        /*
        !           363:         * XXX CHS June-98: The compiler complains that some of these
        !           364:         * XXX variables may be used before they're set. I don't think
        !           365:         * XXX that's actually the case, but to check, I'll assign them
        !           366:         * XXX with some test value, and add asserts to check them at
        !           367:         * XXX run-time. The asserts won't be compiled in for production.
        !           368:         */
        !           369:        zname_sav = tuples_ptr = (unsigned char *) 0xdeadbeef;  /* XXX */
        !           370:        net = (unsigned short *) 0xdeadbeef;                    /* XXX */
        !           371:        net_num = 0xdead;                                       /* XXX */
        !           372:        nets_cnt = 0xfeedface;                                  /* XXX */
        !           373: 
        !           374:        sub_codep = (short *)buf;
        !           375:        buf += sizeof(short);
        !           376:        tuples_cntp = (short *)buf;
        !           377:        buf += sizeof(short);
        !           378:        *len = sizeof(short) + sizeof(short);
        !           379:        zname_base = buf + sizeof(short);
        !           380:        dat_len = 0;
        !           381: 
        !           382:        /* set the subcode in the ZI response packet */
        !           383:        *sub_codep = next_entry ? AURPSUBCODE_ZoneInfo2 : AURPSUBCODE_ZoneInfo1;
        !           384: 
        !           385:        switch (flag) {
        !           386:        case 0: /* zone info in response to ZI request */
        !           387:                net = (unsigned short *)gbuf_rptr(dat_m);
        !           388:                nets_cnt = (gbuf_len(dat_m))/2;
        !           389:                break;
        !           390:        case 1: /* zone info in response to Ack of RI response */
        !           391:                tuples_ptr = gbuf_rptr(dat_m);
        !           392:                nets_cnt = (gbuf_len(dat_m))/3;
        !           393:                next_entry = 0;
        !           394:                break;
        !           395:        case 2: /* zone info in response to Ack of RI update */
        !           396:                tuples_ptr = gbuf_rptr(dat_m);
        !           397:                nets_cnt = (gbuf_len(dat_m))/4;
        !           398:                next_entry = 0;
        !           399:                break;
        !           400:        }
        !           401: 
        !           402:        /*
        !           403:         * for each network, find all the zones that it belongs to
        !           404:         */
        !           405:        assert(nets_cnt != 0xfeedface);                         /* XXX */
        !           406:        for (tuples_cnt=0; next_entry < nets_cnt; next_entry++) {
        !           407:                switch(flag) {
        !           408:                case 0:
        !           409:                        assert(net != 0xdeadbeef);              /* XXX */
        !           410:                        net_num = net[next_entry];
        !           411:                        break;
        !           412:                case 1:
        !           413:                        assert(tuples_ptr != 0xdeadbeef);       /* XXX */
        !           414:                        net_num = *(unsigned short *)tuples_ptr; 
        !           415:                        tuples_ptr += 3;
        !           416:                        gbuf_rinc(dat_m,3);
        !           417:                        if (tuples_ptr[-1] & 0x80) {
        !           418:                                tuples_ptr += 3;
        !           419:                                gbuf_rinc(dat_m,3);
        !           420:                                next_entry++;
        !           421:                        }
        !           422:                        break;
        !           423:                case 2:
        !           424:                        if (gbuf_len(dat_m) <= 0) {
        !           425:                                next_entry = nets_cnt;
        !           426:                                goto l_done;
        !           427:                        }
        !           428:                        assert(tuples_ptr != 0xdeadbeef);       /* XXX */
        !           429:                        ev = *tuples_ptr++;
        !           430:                        net_num = *(unsigned short *)tuples_ptr; 
        !           431:                        tuples_ptr += 3;
        !           432:                        gbuf_rinc(dat_m,4);
        !           433:                        if (tuples_ptr[-1] & 0x80) {
        !           434:                                tuples_ptr += 2;
        !           435:                                gbuf_rinc(dat_m,2);
        !           436:                        }
        !           437:                        if (ev != AURPEV_NetAdded)
        !           438:                                continue;
        !           439:                        break;
        !           440:                }
        !           441: 
        !           442:                /*
        !           443:                 * find the RT entry associated with the network
        !           444:                 */
        !           445:                assert(net_num != 0xdead);                      /* XXX */
        !           446:                if ((entry = rt_blookup(net_num)) == 0) {
        !           447:                        dPrintf(D_M_AURP, D_L_WARNING, ("AURPgetzi: invalid net, %d\n",
        !           448:                                net_num));
        !           449:                        continue;
        !           450:                }
        !           451:                if ( ((entry->EntryState & 0x0F) < RTE_STATE_SUSPECT) ||
        !           452:                                !RT_ALL_ZONES_KNOWN(entry) ||
        !           453:                                (entry->AURPFlag & AURP_NetHiden) ) {
        !           454:                        dPrintf(D_M_AURP_LOW, D_L_INFO, ("AURPgetzi: zombie net, net=%d\n",
        !           455:                                net_num));
        !           456:                        continue;
        !           457:                }
        !           458: 
        !           459:          if (entry->NetStart == 0) {
        !           460:                if ((idx = zt_ent_zindex(entry->ZoneBitMap)) == 0)
        !           461:                        continue;
        !           462:                idx--; /* index in the zone table */
        !           463:                zname_len = ZT_table[idx].Zone.len;
        !           464:                if (zname_len) {
        !           465:                        assert(net_num != 0xdead);              /* XXX */
        !           466:                        *(unsigned short *)buf = net_num;
        !           467:                        buf += sizeof(short);
        !           468:                  if (idx == idx_sav) {
        !           469:                        /* use the optimized format */
        !           470:                        assert(zname_sav != 0xdeadbeef);        /* XXX */
        !           471:                        zname_offset = zname_sav - zname_base;
        !           472:                        *(unsigned short *)buf = (0x8000 | zname_offset);
        !           473:                        buf += sizeof(short);
        !           474:                        dat_len += 4;
        !           475:                  } else {
        !           476:                        /* use the long format */
        !           477:                        zname_sav = buf; 
        !           478:                        *buf++ = zname_len;
        !           479:                        bcopy(ZT_table[idx].Zone.str, buf, zname_len);
        !           480:                        buf += zname_len;
        !           481:                        dat_len += (3 + zname_len);
        !           482:                  }
        !           483:                        tuples_cnt++;
        !           484:                        idx_sav = idx;
        !           485:                }
        !           486: 
        !           487:          } else {
        !           488:                zmap = entry->ZoneBitMap;
        !           489:                for (i=i_sav; i >=0; i--) {
        !           490:                        if (!zmap[i])
        !           491:                                continue;
        !           492: 
        !           493:                        for (j=j_sav; j < 8; j++) {
        !           494:                                if (!((zmap[i] << j) & 0x80))
        !           495:                                        continue;
        !           496: 
        !           497:                                idx = i*8 + j; /* index in the zone table */
        !           498:                                zname_len = ZT_table[idx].Zone.len;
        !           499:                                if (zname_len) {
        !           500:                                        if ((dat_len+3+zname_len) > AURP_MaxPktSize) {
        !           501:                                                i_sav = i;
        !           502:                                                j_sav = j;
        !           503:                                                goto l_done;
        !           504:                                        }
        !           505: 
        !           506:                                        assert(net_num != 0xdead); /* XXX */
        !           507:                                        *(unsigned short *)buf = net_num;
        !           508:                                        buf += sizeof(short);
        !           509:                                  if (idx == idx_sav) {
        !           510:                                        /* use the optimized format */
        !           511:                                        assert(zname_sav != 0xdeadbeef);/*XXX*/
        !           512:                                        zname_offset = zname_sav - zname_base;
        !           513:                                        *(unsigned short *)buf = (0x8000 | zname_offset);
        !           514:                                        buf += sizeof(short);
        !           515:                                        dat_len += 4;
        !           516:                                  } else {
        !           517:                                        /* use the long format */
        !           518:                                        zname_sav = buf; 
        !           519:                                        *buf++ = zname_len;
        !           520:                                        bcopy(ZT_table[idx].Zone.str, buf, zname_len);
        !           521:                                        buf += zname_len;
        !           522:                                        dat_len += (3 + zname_len);
        !           523:                                  }
        !           524:                                        tuples_cnt++;
        !           525:                                        idx_sav = idx;
        !           526:                                }
        !           527:                        }
        !           528:                }
        !           529:          }
        !           530:                if ((dat_len+3+32) > AURP_MaxPktSize) {
        !           531:                        next_entry++;
        !           532:                        break;
        !           533:                }
        !           534:        }
        !           535:        i_sav = ZT_BYTES-1;
        !           536:        j_sav = 0;
        !           537: 
        !           538: l_done:
        !           539:        *len += dat_len;
        !           540:        if (next_entry == nets_cnt)
        !           541:                next_entry = 0;
        !           542: 
        !           543:        /* set the subcode in the ZI response packet */
        !           544:        if (next_entry)
        !           545:                *sub_codep = AURPSUBCODE_ZoneInfo2;
        !           546: 
        !           547:        /* set the tuples count in the ZI response packet */
        !           548:        *tuples_cntp = tuples_cnt;
        !           549: 
        !           550:        idx_sav = -1;
        !           551:        return next_entry;
        !           552: }
        !           553: 
        !           554: /* */
        !           555: static void
        !           556: AURPsetzi(node, m, sub_code, tuples_cnt)
        !           557:        unsigned char node;
        !           558:        gbuf_t *m;
        !           559:        short sub_code;
        !           560:        short tuples_cnt;
        !           561: {
        !           562:        int rc, tuple_fmt;
        !           563:        unsigned short net_num, zname_offset;
        !           564:        unsigned char *buf = gbuf_rptr(m), *zname_base;
        !           565:        RT_entry *entry;
        !           566:        at_nvestr_t *zname;
        !           567: 
        !           568:        /* compute the base of the zone names of the optimized tuples */
        !           569:        zname_base = buf + sizeof(short);
        !           570: 
        !           571:        /* process all tuples */
        !           572:        while (tuples_cnt-- > 0) {
        !           573:                net_num = *(unsigned short *)buf;
        !           574:                buf += sizeof(short);
        !           575:                if (*buf & 0x80) {
        !           576:                        /* optimized-format tuple */
        !           577:                        zname_offset = (*(unsigned short *)buf) & 0x7fff;
        !           578:                        buf += sizeof(short);
        !           579:                        zname = (at_nvestr_t *)(zname_base + zname_offset);
        !           580:                        tuple_fmt = 0;
        !           581:                        dPrintf(D_M_AURP_LOW, D_L_INFO,
        !           582:                                ("AURPsetzi: optimized fmt, net=%d. zlen=%d, zoffset=%d\n ",
        !           583:                                        net_num, zname->len, zname_offset));
        !           584:                } else {
        !           585:                        /* long-format tuple */
        !           586:                        zname = (at_nvestr_t *)buf;
        !           587:                        tuple_fmt = 1;
        !           588:                        dPrintf(D_M_AURP_LOW, D_L_INFO,
        !           589:                                ("AURPsetzi: long fmt, net=%d, zlen=%d\n ",
        !           590:                                        net_num, zname->len));
        !           591:                }
        !           592: 
        !           593:                /*
        !           594:                 * find the RT entry associated with the specified network
        !           595:                 */
        !           596:                if ((entry = rt_blookup(net_num)) == 0) {
        !           597:                        dPrintf(D_M_AURP, D_L_WARNING,
        !           598:                                ("AURPsetzi: invalid net, net=%d\n", net_num));
        !           599:                } else { /* entry found */
        !           600:                        if (entry->EntryState >= RTE_STATE_SUSPECT)  {
        !           601:                                if ((rc = zt_add_zonename(zname)) == ZT_MAXEDOUT) {
        !           602:                                        dPrintf(D_M_AURP, D_L_WARNING,
        !           603:                                                ("AURPsetzi: ZT_table full\n"));
        !           604:                                } else {
        !           605:                                        zt_set_zmap(rc, entry->ZoneBitMap);
        !           606:                                        RT_SET_ZONE_KNOWN(entry);
        !           607:                                }
        !           608:                        }
        !           609:                }
        !           610:                if (tuple_fmt)
        !           611:                        buf += zname->len+1;
        !           612:        }
        !           613: }

unix.superglobalmegacorp.com

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