Annotation of XNU/bsd/netat/aurp_ri.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: ri.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: 
        !            44: #include <netat/sysglue.h>
        !            45: #include <netat/appletalk.h>
        !            46: #include <netat/at_var.h>
        !            47: #include <netat/rtmp.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: /* */
        !            54: void AURPsndRIAck(state, m, flags)
        !            55:        aurp_state_t *state;
        !            56:        gbuf_t *m;
        !            57:        unsigned short flags;
        !            58: {
        !            59:        unsigned short sequence_number;
        !            60:        aurp_hdr_t *hdrp;
        !            61:        int msize = sizeof(aurp_hdr_t);
        !            62: 
        !            63:        if (m) {
        !            64:                sequence_number = ((aurp_hdr_t *)gbuf_rptr(m))->sequence_number;
        !            65:                gbuf_wset(m,sizeof(aurp_hdr_t));
        !            66:        } else {
        !            67:                sequence_number = state->rcv_sequence_number;
        !            68:                if ((m = (gbuf_t *)gbuf_alloc(msize, PRI_MED)) == 0)
        !            69:                        return;
        !            70:                gbuf_wset(m,msize);
        !            71:        }
        !            72: 
        !            73:        /* construct the RI Ack packet */
        !            74:        hdrp = (aurp_hdr_t *)gbuf_rptr(m);
        !            75:        hdrp->connection_id = state->rcv_connection_id;
        !            76:        hdrp->sequence_number = sequence_number;
        !            77:        hdrp->command_code = AURPCMD_RIAck;
        !            78:        hdrp->flags = flags;
        !            79: 
        !            80:        /* send the packet */
        !            81:        dPrintf(D_M_AURP, D_L_INFO, ("AURPsndRIAck: node=%d\n",
        !            82:                state->rem_node));
        !            83:        AURPsend(m, AUD_AURP, state->rem_node);
        !            84: }
        !            85: 
        !            86: /* */
        !            87: void AURPsndRIReq(state)
        !            88:        aurp_state_t *state;
        !            89: {
        !            90:        int msize;
        !            91:        gbuf_t *m;
        !            92:        aurp_hdr_t *hdrp;
        !            93: 
        !            94:        if (state->rcv_state == AURPSTATE_Unconnected)
        !            95:                return;
        !            96:        if (state->rcv_tmo && (state->rcv_state != AURPSTATE_WaitingForRIRsp))
        !            97:                return;
        !            98: 
        !            99:        msize = sizeof(aurp_hdr_t);
        !           100:        if ((m = (gbuf_t *)gbuf_alloc(msize, PRI_MED)) != 0) {
        !           101:                gbuf_wset(m,msize);
        !           102: 
        !           103:                /* construct the RI request packet */
        !           104:                hdrp = (aurp_hdr_t *)gbuf_rptr(m);
        !           105:                hdrp->connection_id = state->rcv_connection_id;
        !           106:                hdrp->sequence_number = 0;
        !           107:                hdrp->command_code = AURPCMD_RIReq;
        !           108:                hdrp->flags = 0;
        !           109: 
        !           110:                /* update state info */
        !           111:                state->rcv_state = AURPSTATE_WaitingForRIRsp;
        !           112: 
        !           113:                /* send the packet */
        !           114:                dPrintf(D_M_AURP, D_L_INFO, ("AURPsndRIReq: node=%d\n",
        !           115:                        state->rem_node));
        !           116:                AURPsend(m, AUD_AURP, state->rem_node);
        !           117:        }
        !           118: 
        !           119:        /* start the retry timer */
        !           120:        timeout(AURPsndRIReq, state, AURP_RetryInterval*HZ);
        !           121:        state->rcv_tmo = 1;
        !           122: }
        !           123: 
        !           124: /* */
        !           125: void AURPsndRIRsp(state)
        !           126:        aurp_state_t *state;
        !           127: {
        !           128:        gbuf_t *m;
        !           129:        aurp_hdr_t *hdrp;
        !           130:        short len = 0;
        !           131:        int s, msize = 0;
        !           132: 
        !           133:        ATDISABLE(s, aurpgen_lock);
        !           134: 
        !           135:        /* make sure we're in a valid state to send RI response */
        !           136:        if ((state->snd_state == AURPSTATE_Unconnected) ||
        !           137:                (state->snd_state == AURPSTATE_WaitingForRIAck2)) {
        !           138:                ATENABLE(s, aurpgen_lock);
        !           139:                return;
        !           140:        }
        !           141: 
        !           142:        /* update state info */
        !           143:        state->snd_state = AURPSTATE_WaitingForRIAck1;
        !           144: 
        !           145:        if (state->rsp_m == 0) {
        !           146:                ATENABLE(s, aurpgen_lock);
        !           147:                msize = sizeof(aurp_hdr_t);
        !           148:                if ((m = (gbuf_t *)gbuf_alloc(msize+AURP_MaxPktSize, PRI_MED)) == 0) {
        !           149:                        timeout(AURPsndRIRsp, state, AURP_RetryInterval*HZ);
        !           150:                        state->snd_tmo = 1;
        !           151:                        return;
        !           152:                }
        !           153:                gbuf_wset(m,msize);
        !           154:                state->rsp_m = m;
        !           155: 
        !           156:                /* construct the RI response packet */
        !           157:                hdrp = (aurp_hdr_t *)gbuf_rptr(m);
        !           158:                hdrp->connection_id = state->snd_connection_id;
        !           159:                hdrp->sequence_number = state->snd_sequence_number;
        !           160:                hdrp->command_code = AURPCMD_RIRsp;
        !           161:                hdrp->flags = 0;
        !           162: 
        !           163:                /* get routing info of the local networks */
        !           164:                state->snd_next_entry = AURPgetri(
        !           165:                        state->snd_next_entry, gbuf_wptr(m), &len);
        !           166:                gbuf_winc(m,len);
        !           167: 
        !           168:                /* set the last flag if this is the last response packet */
        !           169:                if (!state->snd_next_entry)
        !           170:                        hdrp->flags = AURPFLG_LAST;
        !           171:        }
        !           172: 
        !           173:        /* keep a copy of the packet for retry */
        !           174:        m = (gbuf_t *)gbuf_dupb(state->rsp_m);
        !           175: 
        !           176:        /* start the retry timer */
        !           177:        timeout(AURPsndRIRsp, state, AURP_RetryInterval*HZ);
        !           178:        state->snd_tmo = 1;
        !           179: 
        !           180:        if (msize == 0)
        !           181:                ATENABLE(s, aurpgen_lock);
        !           182: 
        !           183:        /* send the packet */
        !           184:        if (m) {
        !           185:                dPrintf(D_M_AURP, D_L_INFO, ("AURPsndRIRsp: len=%d\n", len));
        !           186:                AURPsend(m, AUD_AURP, state->rem_node);
        !           187:        }
        !           188: }
        !           189: 
        !           190: /* */
        !           191: void AURPsndRIUpd(state)
        !           192:        aurp_state_t *state;
        !           193: {
        !           194:        gbuf_t *m;
        !           195:        aurp_hdr_t *hdrp;
        !           196:        short len = 0;
        !           197:        int s, msize = 0;
        !           198: 
        !           199:        ATDISABLE(s, aurpgen_lock);
        !           200: 
        !           201:        /* make sure we're in a valid state to send update */
        !           202:        if (state->snd_next_entry || (state->upd_m == 0) ||
        !           203:                (state->snd_state == AURPSTATE_Unconnected) ||
        !           204:                        (state->snd_state == AURPSTATE_WaitingForRIAck1)) {
        !           205:                ATENABLE(s, aurpgen_lock);
        !           206:                return;
        !           207:        }
        !           208: 
        !           209:        /* update state info */
        !           210:        state->snd_state = AURPSTATE_WaitingForRIAck2;
        !           211: 
        !           212:        if (state->snd_tmo == 0) {
        !           213:                ATENABLE(s, aurpgen_lock);
        !           214:                msize = sizeof(aurp_hdr_t);
        !           215:                m = state->upd_m;
        !           216:                len = gbuf_len(m);
        !           217:                gbuf_rdec(m,msize);
        !           218: 
        !           219:                /* construct the RI update packet */
        !           220:                hdrp = (aurp_hdr_t *)gbuf_rptr(m);
        !           221:                hdrp->connection_id = state->snd_connection_id;
        !           222:                hdrp->sequence_number = state->snd_sequence_number;
        !           223:                hdrp->command_code = AURPCMD_RIUpd;
        !           224:                hdrp->flags = 0;
        !           225:        }
        !           226: 
        !           227:        /* keep a copy of the packet for retry */
        !           228:        m = (gbuf_t *)gbuf_dupb(state->upd_m);
        !           229: 
        !           230:        /* start the retry timer */
        !           231:        timeout(AURPsndRIUpd, state, AURP_RetryInterval*HZ);
        !           232:        state->snd_tmo = 1;
        !           233: 
        !           234:        if (msize == 0)
        !           235:                ATENABLE(s, aurpgen_lock);
        !           236: 
        !           237:        /* send the packet */
        !           238:        if (m) {
        !           239:                dPrintf(D_M_AURP, D_L_INFO, ("AURPsndRIUpd: len=%d\n", len));
        !           240:                AURPsend(m, AUD_AURP, state->rem_node);
        !           241:        }
        !           242: }
        !           243: 
        !           244: /* */
        !           245: void AURPrcvRIReq(state, m)
        !           246:        aurp_state_t *state;
        !           247:        gbuf_t *m;
        !           248: {
        !           249:        aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m);
        !           250:        int s;
        !           251: 
        !           252:        ATDISABLE(s, aurpgen_lock);
        !           253: 
        !           254:        /* make sure we're in a valid state to accept it */
        !           255:        if ((state->snd_state == AURPSTATE_Unconnected) ||
        !           256:                        (state->snd_state == AURPSTATE_WaitingForRIAck2)) {
        !           257:                ATENABLE(s, aurpgen_lock);
        !           258:                dPrintf(D_M_AURP, D_L_WARNING, ("AURPrcvRIReq: unexpected request\n"));
        !           259:                gbuf_freem(m);
        !           260:                return;
        !           261:        }
        !           262: 
        !           263:        /* check for the correct connection id */
        !           264:        if (hdrp->connection_id != state->snd_connection_id) {
        !           265:                ATENABLE(s, aurpgen_lock);
        !           266:                dPrintf(D_M_AURP, D_L_WARNING,
        !           267:                        ("AURPrcvRIReq: invalid connection id, r=%d, m=%d\n",
        !           268:                        hdrp->connection_id, state->snd_connection_id));
        !           269:                gbuf_freem(m);
        !           270:                return;
        !           271:        }
        !           272: 
        !           273:        if (state->snd_state != AURPSTATE_WaitingForRIAck1) {
        !           274:                state->snd_next_entry = 0;
        !           275:                if (state->rsp_m) {
        !           276:                        gbuf_freem(state->rsp_m);
        !           277:                        state->rsp_m = 0;
        !           278:                }
        !           279:                ATENABLE(s, aurpgen_lock);
        !           280:                AURPsndRIRsp(state);
        !           281:        } else
        !           282:                ATENABLE(s, aurpgen_lock);
        !           283: 
        !           284:        gbuf_freem(m);
        !           285: }
        !           286: 
        !           287: /* */
        !           288: void AURPrcvRIRsp(state, m)
        !           289:        aurp_state_t *state;
        !           290:        gbuf_t *m;
        !           291: {
        !           292:        aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m);
        !           293:        int s;
        !           294: 
        !           295:        ATDISABLE(s, aurpgen_lock);
        !           296: 
        !           297:        /* make sure we're in a valid state to accept it */
        !           298:        if (state->rcv_state != AURPSTATE_WaitingForRIRsp) {
        !           299:                ATENABLE(s, aurpgen_lock);
        !           300:                dPrintf(D_M_AURP, D_L_WARNING, ("AURPrcvRIRsp: unexpected response\n"));
        !           301:                gbuf_freem(m);
        !           302:                return;
        !           303:        }
        !           304: 
        !           305:        /* check for the correct connection id */
        !           306:        if (hdrp->connection_id != state->rcv_connection_id) {
        !           307:                ATENABLE(s, aurpgen_lock);
        !           308:                dPrintf(D_M_AURP, D_L_WARNING,
        !           309:                        ("AURPrcvRIRsp: invalid connection id, r=%d, m=%d\n",
        !           310:                        hdrp->connection_id, state->rcv_connection_id));
        !           311:                gbuf_freem(m);
        !           312:                return;
        !           313:        }
        !           314: 
        !           315:        /* check for the correct sequence number */
        !           316:        if (hdrp->sequence_number != state->rcv_sequence_number) {
        !           317:                ATENABLE(s, aurpgen_lock);
        !           318:                if ( ((state->rcv_sequence_number == AURP_FirstSeqNum) &&
        !           319:                        (hdrp->sequence_number == AURP_LastSeqNum)) ||
        !           320:                (hdrp->sequence_number == (state->rcv_sequence_number-1)) ) {
        !           321:                        AURPsndRIAck(state, m, AURPFLG_SZI);
        !           322:                } else {
        !           323:                        dPrintf(D_M_AURP, D_L_WARNING,
        !           324:                                ("AURPrcvRIRsp: invalid sequence number, r=%d, m=%d\n",
        !           325:                                hdrp->sequence_number, state->rcv_sequence_number));
        !           326:                        gbuf_freem(m);
        !           327:                }
        !           328:                return;
        !           329:        }
        !           330:        gbuf_rinc(m,sizeof(*hdrp));
        !           331:        if (hdrp->flags & AURPFLG_LAST)
        !           332:                state->rcv_state = AURPSTATE_Connected;
        !           333:        ATENABLE(s, aurpgen_lock);
        !           334: 
        !           335:        dPrintf(D_M_AURP, D_L_INFO, ("AURPrcvRIRsp: len=%ld\n", gbuf_len(m)));
        !           336: 
        !           337:        /* cancel the retry timer */
        !           338:        untimeout(AURPsndRIReq, state);
        !           339:        state->rcv_tmo = 0;
        !           340: 
        !           341:        /* send RI ack */
        !           342:        AURPsndRIAck(state, 0, AURPFLG_SZI);
        !           343: 
        !           344:        /* update state info */
        !           345:        if (++state->rcv_sequence_number == 0)
        !           346:                state->rcv_sequence_number = AURP_FirstSeqNum;
        !           347: 
        !           348:        /* process routing info of the tunnel peer */
        !           349:        if (AURPsetri(state->rem_node, m)) {
        !           350:                dPrintf(D_M_AURP, D_L_ERROR, ("AURPrcvRIRsp: AURPsetri() error\n"));
        !           351:        }
        !           352:        gbuf_freem(m);
        !           353: 
        !           354:        /* set the get zone flag to get zone info later if required */ 
        !           355:        if (state->rcv_state == AURPSTATE_Connected)
        !           356:                state->get_zi = 1;
        !           357: }
        !           358: 
        !           359: /* */
        !           360: void AURPrcvRIUpd(state, m)
        !           361:        aurp_state_t *state;
        !           362:        gbuf_t *m;
        !           363: {
        !           364:        aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m);
        !           365: 
        !           366:        /* make sure we're in a valid state to accept it */
        !           367:        if (state->rcv_state == AURPSTATE_Unconnected) {
        !           368:                dPrintf(D_M_AURP, D_L_WARNING, ("AURPrcvRIUpd: unexpected response\n"));
        !           369:                gbuf_freem(m);
        !           370:                return;
        !           371:        }
        !           372: 
        !           373:        /* check for the correct connection id */
        !           374:        if (hdrp->connection_id != state->rcv_connection_id) {
        !           375:                dPrintf(D_M_AURP, D_L_WARNING,
        !           376:                        ("AURPrcvRIUpd: invalid connection id, r=%d, m=%d\n",
        !           377:                        hdrp->connection_id, state->rcv_connection_id));
        !           378:                gbuf_freem(m);
        !           379:                return;
        !           380:        }
        !           381: 
        !           382:        /* check for the correct sequence number */
        !           383:        if (hdrp->sequence_number != state->rcv_sequence_number) {
        !           384:                if ( ((state->rcv_sequence_number == AURP_FirstSeqNum) &&
        !           385:                        (hdrp->sequence_number == AURP_LastSeqNum)) ||
        !           386:                (hdrp->sequence_number == (state->rcv_sequence_number-1)) ) {
        !           387:                        AURPsndRIAck(state, m, AURPFLG_SZI);
        !           388:                } else {
        !           389:                        dPrintf(D_M_AURP, D_L_WARNING,
        !           390:                                ("AURPrcvRIUpd: invalid sequence number, r=%d, m=%d\n",
        !           391:                                hdrp->sequence_number, state->rcv_sequence_number));
        !           392:                        gbuf_freem(m);
        !           393:                }
        !           394:                return;
        !           395:        }
        !           396:        gbuf_rinc(m,sizeof(*hdrp));
        !           397: 
        !           398:        dPrintf(D_M_AURP, D_L_INFO, ("AURPrcvRIUpd: len=%ld\n", gbuf_len(m)));
        !           399: 
        !           400:        /* send RI ack */
        !           401:        AURPsndRIAck(state, 0, AURPFLG_SZI);
        !           402: 
        !           403:        /* update state info */
        !           404:        if (++state->rcv_sequence_number == 0)
        !           405:                state->rcv_sequence_number = AURP_FirstSeqNum;
        !           406: 
        !           407:        /* process update routing info of the tunnel peer */
        !           408:        if (AURPupdateri(state->rem_node, m)) {
        !           409:                dPrintf(D_M_AURP, D_L_ERROR, ("AURPrcvRIUpd: AURPupdateri() error\n"));
        !           410:        }
        !           411: 
        !           412:        /* set the get zone flag to get zone info later if required */ 
        !           413:        state->get_zi = 1;
        !           414: 
        !           415:        gbuf_freem(m);
        !           416: }
        !           417: 
        !           418: /* */
        !           419: void AURPrcvRIAck(state, m)
        !           420:        aurp_state_t *state;
        !           421:        gbuf_t *m;
        !           422: {
        !           423:        gbuf_t *dat_m;
        !           424:        aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m);
        !           425:        unsigned char snd_state;
        !           426:        int s;
        !           427:        int flag;
        !           428: 
        !           429:        dPrintf(D_M_AURP, D_L_INFO, ("AURPrcvRIAck: state=%d\n",
        !           430:                state->snd_state));
        !           431:        ATDISABLE(s, aurpgen_lock);
        !           432: 
        !           433:        /* make sure we're in a valid state to accept it */
        !           434:        snd_state = state->snd_state;
        !           435:        if (((snd_state == AURPSTATE_WaitingForRIAck1) ||
        !           436:                (snd_state == AURPSTATE_WaitingForRIAck2)) &&
        !           437:                        (hdrp->sequence_number == state->snd_sequence_number)) {
        !           438: 
        !           439:                if (snd_state == AURPSTATE_WaitingForRIAck1) {
        !           440:                        /* ack from the tunnel peer to our RI response */
        !           441:                        untimeout(AURPsndRIRsp, state);
        !           442:                        dat_m = state->rsp_m;
        !           443:                        state->rsp_m = 0;
        !           444:                        flag = 1;
        !           445:                } else {
        !           446:                        /* ack from the tunnel peer to our RI update */
        !           447:                        untimeout(AURPsndRIUpd, state);
        !           448:                        dat_m = state->upd_m;
        !           449:                        state->upd_m = 0;
        !           450:                        flag = 2;
        !           451:                }
        !           452:                state->snd_tmo = 0;
        !           453:                gbuf_rinc(dat_m,sizeof(aurp_hdr_t));
        !           454: 
        !           455:                /* increment the sequence number */
        !           456:                if (++state->snd_sequence_number == 0)
        !           457:                        state->snd_sequence_number = AURP_FirstSeqNum;
        !           458: 
        !           459:                /* update state info */
        !           460:                state->snd_state = AURPSTATE_Connected;
        !           461:                ATENABLE(s, aurpgen_lock);
        !           462: 
        !           463:                if (state->snd_next_entry) /* more RI responses to send? */
        !           464:                        AURPsndRIRsp(state);
        !           465: 
        !           466:                /* check to see if we need to send ZI responses */
        !           467:                if (hdrp->flags & AURPFLG_SZI)
        !           468:                        AURPsndZRsp(state, dat_m, flag);
        !           469:                else if (dat_m)
        !           470:                        gbuf_freem(dat_m);
        !           471:        } else
        !           472:                ATENABLE(s, aurpgen_lock);
        !           473: 
        !           474:        gbuf_freem(m);
        !           475: }
        !           476: 
        !           477: /* */
        !           478: int AURPgetri(next_entry, buf, len)
        !           479:        short next_entry;
        !           480:        unsigned char *buf;
        !           481:        short *len;
        !           482: {
        !           483:        short entry_num = next_entry;
        !           484:        RT_entry *entry = (RT_entry *)&RT_table[next_entry];
        !           485: 
        !           486:        for (*len=0; entry_num < RT_maxentry; entry_num++,entry++) {
        !           487:                if ((net_port != entry->NetPort) &&
        !           488:                                !(entry->AURPFlag & AURP_NetHiden)) {
        !           489:                        if ((entry->EntryState & 0x0F) >= RTE_STATE_SUSPECT) {
        !           490:                          if (entry->NetStart) {
        !           491:                                /* route info for extended network */
        !           492:                                *(short *)buf = entry->NetStart;
        !           493:                                buf += sizeof(short);
        !           494:                                *buf++ = 0x80 | (entry->NetDist & 0x1F);
        !           495:                                *(short *)buf = entry->NetStop;
        !           496:                                buf += sizeof(short);
        !           497:                                *buf++ = 0;
        !           498:                                *len += 6;
        !           499:                          } else {
        !           500:                                /* route info for non-extended network */
        !           501:                                *(short *)buf = entry->NetStop;
        !           502:                                buf += sizeof(short);
        !           503:                                *buf++ = (entry->NetDist & 0x1F);
        !           504:                                *len += 3;
        !           505:                          }
        !           506:                        }
        !           507:                }
        !           508:                if (*len > AURP_MaxPktSize)
        !           509:                        break;
        !           510:        }
        !           511: 
        !           512:        return (entry_num == RT_maxentry) ? 0 : entry_num;
        !           513: }
        !           514: 
        !           515: /* */
        !           516: int AURPsetri(node, m)
        !           517:        unsigned char node;
        !           518:        gbuf_t *m;
        !           519: {
        !           520:        int tuples_cnt;
        !           521:        unsigned char *tuples_ptr;
        !           522:        RT_entry new_rt, *curr_rt;
        !           523: 
        !           524:        new_rt.NextIRNet  = 0;
        !           525:        new_rt.NextIRNode = node;
        !           526:        new_rt.NetPort    = net_port;
        !           527: 
        !           528:        /*
        !           529:         * Process all the tuples against our routing table
        !           530:         */
        !           531:        tuples_ptr = (char *)gbuf_rptr(m);
        !           532:        tuples_cnt = (gbuf_len(m))/3;
        !           533: 
        !           534:        while (tuples_cnt--) {
        !           535:                new_rt.NetDist = TUPLEDIST(tuples_ptr) + 1;
        !           536:                new_rt.EntryState = RTE_STATE_GOOD;
        !           537:                new_rt.NetStart = TUPLENET(tuples_ptr);
        !           538:                tuples_ptr += 3;
        !           539:                if (tuples_ptr[-1] & 0x80) {
        !           540:                        new_rt.NetStop  = TUPLENET((tuples_ptr));
        !           541:                        tuples_ptr += 3;
        !           542:                        tuples_cnt--;
        !           543:                } else {
        !           544:                        new_rt.NetStop = new_rt.NetStart;
        !           545:                        new_rt.NetStart = 0;
        !           546:                }
        !           547:                if ((new_rt.NetStop == 0) || (new_rt.NetStop < new_rt.NetStart)) {
        !           548:                        dPrintf(D_M_AURP, D_L_WARNING,
        !           549:                        ("AURPsetri: %d, invalid tuple received [%d-%d]\n",
        !           550:                                net_port, new_rt.NetStart, new_rt.NetStop));
        !           551:                        continue;
        !           552:                }
        !           553:        
        !           554:                if ((curr_rt = rt_blookup(new_rt.NetStop)) != 0) { /* found? */
        !           555:                        /* ignore loop if present */
        !           556:                        if (curr_rt->NetPort != net_port)
        !           557:                                continue;
        !           558: 
        !           559:                        if (new_rt.NetDist < 16) {
        !           560:                                /*
        !           561:                                 * check if the definition of the route has changed
        !           562:                                 */
        !           563:                                if ((new_rt.NetStop != curr_rt->NetStop) ||
        !           564:                                                (new_rt.NetStart != curr_rt->NetStart)) {
        !           565:                                        if ((new_rt.NetStop == curr_rt->NetStop) &&
        !           566:                                                (new_rt.NetStop == curr_rt->NetStart) &&
        !           567:                                                        (new_rt.NetStart == 0)) {
        !           568:                                                new_rt.NetStart = new_rt.NetStop;
        !           569:                                        } else if ((new_rt.NetStop == curr_rt->NetStop) &&
        !           570:                                                (new_rt.NetStart == new_rt.NetStop) &&
        !           571:                                                        (curr_rt->NetStart == 0)) {
        !           572:                                                dPrintf(D_M_AURP, D_L_WARNING,
        !           573:                                        ("AURPsetri: [%d-%d] has changed to [%d-%d], Dist=%d\n",
        !           574:                                                curr_rt->NetStart, curr_rt->NetStop,
        !           575:                                        new_rt.NetStart, new_rt.NetStop, new_rt.NetDist));
        !           576:                                                new_rt.NetStart = 0;
        !           577:                                        } else {
        !           578:                                                dPrintf(D_M_AURP, D_L_WARNING,
        !           579:                                        ("AURPsetri: Net Conflict, Curr=[%d-%d], New=[%d-%d]\n",
        !           580:                                                        curr_rt->NetStart,curr_rt->NetStop,
        !           581:                                                        new_rt.NetStart,new_rt.NetStop));
        !           582:                                                zt_remove_zones(curr_rt->ZoneBitMap);
        !           583:                                                rt_delete(curr_rt->NetStop, curr_rt->NetStart);
        !           584:                                                continue;
        !           585:                                        }
        !           586:                                }
        !           587:                        }
        !           588: 
        !           589:                        if ((new_rt.NetDist <= curr_rt->NetDist) &&
        !           590:                                        (new_rt.NetDist < 16)) { 
        !           591:                                /*
        !           592:                                 * found a shorter or more recent route,
        !           593:                                 * replace with the new entry
        !           594:                                 */
        !           595:                                curr_rt->NetDist    = new_rt.NetDist;
        !           596:                                curr_rt->NextIRNode = new_rt.NextIRNode;
        !           597:                                dPrintf(D_M_AURP_LOW,D_L_INFO,
        !           598:                                        ("AURPsetri: shorter route found [%d-%d], update\n",
        !           599:                                        new_rt.NetStart,new_rt.NetStop));
        !           600:                        }
        !           601: 
        !           602:                } else { /* no entry found */
        !           603:                        if (new_rt.NetDist < 16) {
        !           604:                                new_rt.EntryState = RTE_STATE_GOOD;
        !           605:                                dPrintf(D_M_AURP, D_L_INFO,
        !           606:                                ("AURPsetri: new_rt [%d-%d], tuple #%d\n",
        !           607:                                        new_rt.NetStart, new_rt.NetStop, tuples_cnt));
        !           608:                                if (rt_insert(new_rt.NetStop, new_rt.NetStart,
        !           609:                                        new_rt.NextIRNet, new_rt.NextIRNode,
        !           610:                                        new_rt.NetDist, new_rt.NetPort,
        !           611:                                                new_rt.EntryState) == (RT_entry *)0) {
        !           612:                                dPrintf(D_M_AURP,D_L_ERROR,
        !           613:                                        ("AURPsetri: RTMP table full [%d-%d]\n",
        !           614:                                        new_rt.NetStart,new_rt.NetStop));
        !           615:                                        return -1;
        !           616:                                }
        !           617:                        }
        !           618:                }
        !           619:        } /* end of main while */                       
        !           620: 
        !           621:        return 0;
        !           622: }
        !           623: 
        !           624: /* */
        !           625: int AURPupdateri(node, m)
        !           626:        unsigned char node;
        !           627:        gbuf_t *m;
        !           628: {
        !           629:        char ev, ev_len;
        !           630:        RT_entry new_rt, *old_rt;
        !           631: 
        !           632:        while (gbuf_len(m) > 0) {
        !           633:                ev = *gbuf_rptr(m); /* event code */
        !           634:                gbuf_rinc(m,1);
        !           635:                if (gbuf_rptr(m)[2] & 0x80) {
        !           636:                        /* event tuple for extended network */
        !           637:                        new_rt.NetStart = *(unsigned short *)gbuf_rptr(m);
        !           638:                        new_rt.NetStop  = *(unsigned short *)&gbuf_rptr(m)[3];
        !           639:                        new_rt.NetDist  = gbuf_rptr(m)[2] & 0x7f;
        !           640:                        ev_len = 5;
        !           641:                } else {
        !           642:                        /* event tuple for non-extended network */
        !           643:                        new_rt.NetStart = 0;
        !           644:                        new_rt.NetStop  = *(unsigned short *)gbuf_rptr(m);
        !           645:                        new_rt.NetDist  = gbuf_rptr(m)[2];
        !           646:                        ev_len = 3;
        !           647:                }
        !           648: 
        !           649:          switch (ev) {
        !           650:          case AURPEV_Null:
        !           651:                break;
        !           652: 
        !           653:          case AURPEV_NetAdded:
        !           654:                gbuf_rinc(m,ev_len);
        !           655:                new_rt.NextIRNet  = 0;
        !           656:                new_rt.NextIRNode = node;
        !           657:                new_rt.NetPort    = net_port;
        !           658:                if ((new_rt.NetDist == 0) || (new_rt.NetStop == 0) ||
        !           659:                                (new_rt.NetStop < new_rt.NetStart)) {
        !           660:                        dPrintf(D_M_AURP,D_L_WARNING,
        !           661:                        ("AURPupdateri: %d, invalid NetAdded received [%d-%d]\n",
        !           662:                                net_port, new_rt.NetStart, new_rt.NetStop));
        !           663:                        break;
        !           664:                }
        !           665:        
        !           666:                if ((old_rt = rt_blookup(new_rt.NetStop)) != 0) { /* found? */
        !           667:                        if (old_rt->NetPort == net_port) {
        !           668:                                /*
        !           669:                                 * process this event as if it was an NDC event;
        !           670:                                 * update the route's distance
        !           671:                                 */
        !           672:                                old_rt->NetDist = new_rt.NetDist;
        !           673:                        }
        !           674:                } else {
        !           675: l_add:         if ((new_rt.NetDist < 16) && (new_rt.NetDist != NOTIFY_N_DIST)) {
        !           676:                                new_rt.EntryState = RTE_STATE_GOOD;
        !           677:                                dPrintf(D_M_AURP, D_L_INFO,
        !           678:                                ("AURPupdateri: NetAdded [%d-%d]\n",
        !           679:                                        new_rt.NetStart, new_rt.NetStop));
        !           680:                                if (rt_insert(new_rt.NetStop, new_rt.NetStart,
        !           681:                                        new_rt.NextIRNet, new_rt.NextIRNode,
        !           682:                                        new_rt.NetDist, new_rt.NetPort,
        !           683:                                                new_rt.EntryState) == (RT_entry *)0) {
        !           684:                                dPrintf(D_M_AURP, D_L_WARNING,
        !           685:                                        ("AURPupdateri: RTMP table full [%d-%d]\n",
        !           686:                                        new_rt.NetStart,new_rt.NetStop));
        !           687:                                        return 0;
        !           688:                                }
        !           689:                        }
        !           690:                }
        !           691:                break;
        !           692: 
        !           693:          case AURPEV_NetDeleted:
        !           694:          case AURPEV_NetRouteChange:
        !           695:                gbuf_rinc(m,ev_len);
        !           696: l_delete:      if ((old_rt = rt_blookup(new_rt.NetStop)) != 0) { /* found? */
        !           697:                        if (old_rt->NetPort == net_port) {
        !           698:                                zt_remove_zones(old_rt->ZoneBitMap);
        !           699:                                rt_delete(old_rt->NetStop, old_rt->NetStart);
        !           700:                        }
        !           701:                }
        !           702:                break;
        !           703: 
        !           704:          case AURPEV_NetDistChange:
        !           705:                gbuf_rinc(m,ev_len);
        !           706:                if (new_rt.NetDist == 15)
        !           707:                        goto l_delete; /* process this event as if was an ND event */
        !           708:                if ((old_rt = rt_blookup(new_rt.NetStop)) != 0) { /* found? */
        !           709:                        if (old_rt->NetPort == net_port) {
        !           710:                                /*
        !           711:                                 * update the route's distance
        !           712:                                 */
        !           713:                                old_rt->NetDist = new_rt.NetDist;
        !           714:                        }
        !           715:                } else
        !           716:                        goto l_add; /* process this event as if was an NA event */
        !           717:                break;
        !           718: 
        !           719:          case AURPEV_NetZoneChange:
        !           720:                break;
        !           721:          }
        !           722:        }
        !           723: 
        !           724:        return 0;
        !           725: }
        !           726: 
        !           727: /* */
        !           728: void AURPpurgeri(node)
        !           729:        unsigned char node;
        !           730: {
        !           731:        short entry_num;
        !           732:        RT_entry *entry = (RT_entry *)RT_table;
        !           733: 
        !           734:        /*
        !           735:         * purge all routes associated with the tunnel peer
        !           736:         */
        !           737:        for (entry_num=0; entry_num < RT_maxentry; entry_num++,entry++) {
        !           738:                if ((net_port == entry->NetPort) && (node == entry->NextIRNode)) {
        !           739:                        zt_remove_zones(entry->ZoneBitMap);
        !           740:                        rt_delete(entry->NetStop, entry->NetStart);
        !           741:                }
        !           742:        }
        !           743: }
        !           744: 
        !           745: /* */
        !           746: void AURPrtupdate(entry, ev)
        !           747:        RT_entry *entry;
        !           748:        unsigned char ev;
        !           749: {
        !           750:        unsigned char i, node, ev_len, ev_tuple[6];
        !           751:        gbuf_t *m;
        !           752:        aurp_state_t *state = (aurp_state_t *)&aurp_state[1];
        !           753:        int s, msize = sizeof(aurp_hdr_t);
        !           754: 
        !           755:        dPrintf(D_M_AURP, D_L_TRACE, ("AURPrtupdate: event=%d, net=[%d-%d]\n",
        !           756:                ev, entry->NetStart, entry->NetStop));
        !           757: 
        !           758:        /*
        !           759:         * check that the network can be exported; if not,
        !           760:         * we must not make it visible beyond the local networks
        !           761:         */
        !           762:        if (net_export) {
        !           763:                for (i=0; i < net_access_cnt; i++) {
        !           764:                        if ((net_access[i] == entry->NetStart) ||
        !           765:                                        (net_access[i] == entry->NetStop))
        !           766:                                break;
        !           767:                }
        !           768:                if (i == net_access_cnt)
        !           769:                        return;
        !           770:        } else {
        !           771:                for (i=0; i < net_access_cnt; i++) {
        !           772:                        if ((net_access[i] == entry->NetStart) ||
        !           773:                                        (net_access[i] == entry->NetStop))
        !           774:                                return;
        !           775:                }
        !           776:        }
        !           777: 
        !           778:        /*
        !           779:         * create the update event tuple
        !           780:         */
        !           781:        ev_tuple[0] = ev; /* event code */
        !           782:        if (entry->NetStart) {
        !           783:                *(unsigned short *)&ev_tuple[1] = entry->NetStart;
        !           784:                ev_tuple[3] = 0x80 | (entry->NetDist & 0x1F);
        !           785:                *(unsigned short *)&ev_tuple[4] = entry->NetStop;
        !           786:                ev_len = 6;
        !           787:        } else {
        !           788:                *(unsigned short *)&ev_tuple[1] = entry->NetStop;
        !           789:                ev_tuple[3] = (entry->NetDist & 0x1F);
        !           790:                ev_len = 4;
        !           791:        }
        !           792: 
        !           793:        for (node=1; node <= dst_addr_cnt; node++, state++) {
        !           794:                if ((ev == AURPEV_NetAdded) &&
        !           795:                                (!(state->snd_sui & AURPFLG_NA))) continue;
        !           796:                if ((ev == AURPEV_NetDeleted) &&
        !           797:                                (!(state->snd_sui & AURPFLG_ND))) continue;
        !           798:                if ((ev == AURPEV_NetDistChange) &&
        !           799:                                (!(state->snd_sui & AURPFLG_NDC))) continue;
        !           800:                ATDISABLE(s, aurpgen_lock);
        !           801:          if ((state->snd_state != AURPSTATE_Unconnected) &&
        !           802:                        (state->snd_state != AURPSTATE_WaitingForRIAck2)) {
        !           803:                if ((m = state->upd_m) == 0) {
        !           804:                        /*
        !           805:                         * we don't have the RI update buffer yet, allocate one
        !           806:                         */
        !           807:                        ATENABLE(s, aurpgen_lock);
        !           808:                        if ((m = (gbuf_t *)gbuf_alloc(msize+AURP_MaxPktSize, PRI_HI)) == 0)
        !           809:                                continue;
        !           810:                        ATDISABLE(s, aurpgen_lock);
        !           811:                        state->upd_m = m;
        !           812:                        gbuf_rinc(m,msize);
        !           813:                        gbuf_wset(m,0);
        !           814:                }
        !           815: 
        !           816:                /*
        !           817:                 * add the update event tuple to the RI update buffer;
        !           818:                 * the RI update buffer will be sent when the periodic update
        !           819:                 * timer expires
        !           820:                 */
        !           821:                bcopy(ev_tuple, gbuf_wptr(m), ev_len);
        !           822:                gbuf_winc(m,ev_len);
        !           823: 
        !           824:                /*
        !           825:                 * if the RI update buffer is full, send the RI update now
        !           826:                 */
        !           827:                if (gbuf_len(m) > (AURP_MaxPktSize-6)) {
        !           828:                        ATENABLE(s, aurpgen_lock);
        !           829:                        AURPsndRIUpd(state);
        !           830:                        continue;
        !           831:                }
        !           832:          }
        !           833:                ATENABLE(s, aurpgen_lock);
        !           834:        }
        !           835: }

unix.superglobalmegacorp.com

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