Annotation of Net2/netiso/clnp_subr.c, revision 1.1.1.3

1.1       root        1: /*-
                      2:  * Copyright (c) 1991 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
                     13:  * 3. All advertising materials mentioning features or use of this software
                     14:  *    must display the following acknowledgement:
                     15:  *     This product includes software developed by the University of
                     16:  *     California, Berkeley and its contributors.
                     17:  * 4. Neither the name of the University nor the names of its contributors
                     18:  *    may be used to endorse or promote products derived from this software
                     19:  *    without specific prior written permission.
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     31:  * SUCH DAMAGE.
                     32:  *
1.1.1.3 ! root       33:  *     from: @(#)clnp_subr.c   7.13 (Berkeley) 5/6/91
        !            34:  *     clnp_subr.c,v 1.2 1993/05/20 05:26:57 cgd Exp
1.1       root       35:  */
                     36: 
                     37: /***********************************************************
                     38:                Copyright IBM Corporation 1987
                     39: 
                     40:                       All Rights Reserved
                     41: 
                     42: Permission to use, copy, modify, and distribute this software and its 
                     43: documentation for any purpose and without fee is hereby granted, 
                     44: provided that the above copyright notice appear in all copies and that
                     45: both that copyright notice and this permission notice appear in 
                     46: supporting documentation, and that the name of IBM not be
                     47: used in advertising or publicity pertaining to distribution of the
                     48: software without specific, written prior permission.  
                     49: 
                     50: IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     51: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     52: IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     53: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     54: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     55: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     56: SOFTWARE.
                     57: 
                     58: ******************************************************************/
                     59: 
                     60: /*
                     61:  * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
                     62:  */
                     63: 
                     64: #ifdef ISO
                     65: 
                     66: #include "types.h"
                     67: #include "param.h"
                     68: #include "mbuf.h"
                     69: #include "domain.h"
                     70: #include "protosw.h"
                     71: #include "socket.h"
                     72: #include "socketvar.h"
                     73: #include "errno.h"
                     74: #include "time.h"
                     75: 
                     76: #include "../net/if.h"
                     77: #include "../net/route.h"
                     78: #include "../net/if_dl.h"
                     79: 
                     80: #include "iso.h"
                     81: #include "iso_var.h"
                     82: #include "iso_pcb.h"
                     83: #include "iso_snpac.h"
                     84: #include "clnp.h"
                     85: #include "clnp_stat.h"
                     86: #include "argo_debug.h"
                     87: 
                     88: /*
                     89:  * FUNCTION:           clnp_data_ck
                     90:  *
                     91:  * PURPOSE:                    Check that the amount of data in the mbuf chain is
                     92:  *                                     at least as much as the clnp header would have us
                     93:  *                                     expect. Trim mbufs if longer than expected, drop
                     94:  *                                     packet if shorter than expected.
                     95:  *
                     96:  * RETURNS:                    success - ptr to mbuf chain
                     97:  *                                     failure - 0
                     98:  *
                     99:  * SIDE EFFECTS:       
                    100:  *
                    101:  * NOTES:                      
                    102:  */
                    103: struct mbuf *
                    104: clnp_data_ck(m, length)
                    105: register struct mbuf   *m;             /* ptr to mbuf chain containing hdr & data */
                    106: int                                            length; /* length (in bytes) of packet */
                    107:  {
                    108:        register int                    len;            /* length of data */
                    109:        register struct mbuf    *mhead;         /* ptr to head of chain */
                    110: 
                    111:        len = -length;
                    112:        mhead = m;
                    113:        for (;;) {
                    114:                len += m->m_len;
                    115:                if (m->m_next == 0)
                    116:                        break;
                    117:                m = m->m_next;
                    118:        }
                    119:        if (len != 0) {
                    120:                if (len < 0) {
                    121:                        INCSTAT(cns_toosmall);
                    122:                        clnp_discard(mhead, GEN_INCOMPLETE);
                    123:                        return 0;
                    124:                }
                    125:                if (len <= m->m_len)
                    126:                        m->m_len -= len;
                    127:                else
                    128:                        m_adj(mhead, -len);
                    129:        }
                    130:        return mhead;
                    131: }
                    132: 
                    133: #ifdef notdef
                    134: /*
                    135:  * FUNCTION:           clnp_extract_addr
                    136:  *
                    137:  * PURPOSE:                    Extract the source and destination address from the
                    138:  *                                     supplied buffer. Place them in the supplied address buffers.
                    139:  *                                     If insufficient data is supplied, then fail.
                    140:  *
                    141:  * RETURNS:                    success - Address of first byte in the packet past 
                    142:  *                                             the address part.
                    143:  *                                     failure - 0
                    144:  *
                    145:  * SIDE EFFECTS:       
                    146:  *
                    147:  * NOTES:                      
                    148:  */
                    149: caddr_t
                    150: clnp_extract_addr(bufp, buflen, srcp, destp)
                    151: caddr_t                                        bufp;           /* ptr to buffer containing addresses */
                    152: int                                            buflen;         /* length of buffer */
                    153: register struct iso_addr       *srcp;          /* ptr to source address buffer */
                    154: register struct iso_addr       *destp;         /* ptr to destination address buffer */
                    155:  {
                    156:        int     len;            /* argument to bcopy */
                    157: 
                    158:        /* 
                    159:         *      check that we have enough data. Plus1 is for length octet
                    160:         */
                    161:        if ((u_char)*bufp + 1 > buflen) {
                    162:                return((caddr_t)0);
                    163:        }
                    164:        len = destp->isoa_len = (u_char)*bufp++;
                    165:        (void) bcopy(bufp, (caddr_t)destp, len);
                    166:        buflen -= len;
                    167:        bufp += len;
                    168: 
                    169:        /* 
                    170:         *      check that we have enough data. Plus1 is for length octet
                    171:         */
                    172:        if ((u_char)*bufp + 1 > buflen) {
                    173:                return((caddr_t)0);
                    174:        }
                    175:        len = srcp->isoa_len = (u_char)* bufp++;
                    176:        (void) bcopy(bufp, (caddr_t)srcp, len);
                    177:        bufp += len;
                    178: 
                    179:        /*
                    180:         *      Insure that the addresses make sense
                    181:         */
                    182:        if (iso_ck_addr(srcp) && iso_ck_addr(destp))
                    183:                return bufp;
                    184:        else
                    185:                return (caddr_t) 0;
                    186: }
                    187: #endif notdef
                    188: 
                    189: /*
                    190:  * FUNCTION:           clnp_ours
                    191:  *
                    192:  * PURPOSE:                    Decide whether the supplied packet is destined for
                    193:  *                                     us, or that it should be forwarded on.
                    194:  *
                    195:  * RETURNS:                    packet is for us - 1
                    196:  *                                     packet is not for us - 0
                    197:  *
                    198:  * SIDE EFFECTS:       
                    199:  *
                    200:  * NOTES:                      
                    201:  */
                    202: clnp_ours(dst)
                    203: register struct iso_addr *dst;         /* ptr to destination address */
                    204: {
                    205:        register struct iso_ifaddr *ia; /* scan through interface addresses */
                    206: 
                    207:        for (ia = iso_ifaddr; ia; ia = ia->ia_next) {
                    208:                IFDEBUG(D_ROUTE)
                    209:                        printf("clnp_ours: ia_sis x%x, dst x%x\n", &ia->ia_addr, 
                    210:                                dst);
                    211:                ENDDEBUG
                    212:                /*
                    213:                 * XXX Warning:
                    214:                 * We are overloading siso_tlen in the if's address, as an nsel length.
                    215:                 */
                    216:                if (dst->isoa_len == ia->ia_addr.siso_nlen &&
                    217:                        bcmp((caddr_t)ia->ia_addr.siso_addr.isoa_genaddr,
                    218:                                 (caddr_t)dst->isoa_genaddr,
                    219:                                 ia->ia_addr.siso_nlen - ia->ia_addr.siso_tlen) == 0)
                    220:                                        return 1;
                    221:        }
                    222:        return 0;
                    223: }
                    224: 
                    225: /* Dec bit set if ifp qlen is greater than congest_threshold */
                    226: int congest_threshold = 0;
                    227: 
                    228: /*
                    229:  * FUNCTION:           clnp_forward
                    230:  *
                    231:  * PURPOSE:                    Forward the datagram passed
                    232:  *                                     clnpintr guarantees that the header will be
                    233:  *                                     contigious (a cluster mbuf will be used if necessary).
                    234:  *
                    235:  *                                     If oidx is NULL, no options are present.
                    236:  *
                    237:  * RETURNS:                    nothing
                    238:  *
                    239:  * SIDE EFFECTS:       
                    240:  *
                    241:  * NOTES:                      
                    242:  */
                    243: clnp_forward(m, len, dst, oidx, seg_off, inbound_shp)
                    244: struct mbuf                    *m;             /* pkt to forward */
                    245: int                                    len;    /* length of pkt */
                    246: struct iso_addr                *dst;   /* destination address */
                    247: struct clnp_optidx     *oidx;  /* option index */
                    248: int                                    seg_off;/* offset of segmentation part */
                    249: struct snpa_hdr                *inbound_shp;   /* subnetwork header of inbound packet */
                    250: {
                    251:        struct clnp_fixed               *clnp;  /* ptr to fixed part of header */
                    252:        int                                             error;  /* return value of route function */
                    253:        struct sockaddr                 *next_hop;      /* next hop for dgram */
                    254:        struct ifnet                    *ifp;   /* ptr to outgoing interface */
                    255:        struct iso_ifaddr               *ia = 0;/* ptr to iso name for ifp */
                    256:        struct route_iso                route;  /* filled in by clnp_route */
                    257:        extern int                              iso_systype;
                    258: 
                    259:        clnp = mtod(m, struct clnp_fixed *);
                    260:        bzero((caddr_t)&route, sizeof(route)); /* MUST be done before "bad:" */
                    261: 
                    262:        /*
                    263:         *      Don't forward multicast or broadcast packets
                    264:         */
                    265:        if ((inbound_shp) && (IS_MULTICAST(inbound_shp->snh_dhost))) {
                    266:                IFDEBUG(D_FORWARD)
                    267:                        printf("clnp_forward: dropping multicast packet\n");
                    268:                ENDDEBUG
                    269:                clnp->cnf_type &= ~CNF_ERR_OK; /* so we don't generate an ER */
                    270:                clnp_discard(m, 0);
                    271:                INCSTAT(cns_cantforward);
                    272:                goto done;
                    273:        }
                    274: 
                    275:        IFDEBUG(D_FORWARD)
                    276:                printf("clnp_forward: %d bytes, to %s, options x%x\n", len,
                    277:                        clnp_iso_addrp(dst), oidx);
                    278:        ENDDEBUG
                    279: 
                    280:        /*
                    281:         *      Decrement ttl, and if zero drop datagram
                    282:         *      Can't compare ttl as less than zero 'cause its a unsigned
                    283:         */
                    284:        if ((clnp->cnf_ttl == 0) || (--clnp->cnf_ttl == 0)) {
                    285:                IFDEBUG(D_FORWARD)
                    286:                        printf("clnp_forward: discarding datagram because ttl is zero\n");
                    287:                ENDDEBUG
                    288:                INCSTAT(cns_ttlexpired);
                    289:                clnp_discard(m, TTL_EXPTRANSIT);
                    290:                goto done;
                    291:        }
                    292:        /*
                    293:         *      Route packet; special case for source rt
                    294:         */
                    295:        if CLNPSRCRT_VALID(oidx) {
                    296:                /*
                    297:                 *      Update src route first
                    298:                 */
                    299:                clnp_update_srcrt(m, oidx);
                    300:                error = clnp_srcroute(m, oidx, &route, &next_hop, &ia, dst);
                    301:        } else {
                    302:                error = clnp_route(dst, &route, 0, &next_hop, &ia);
                    303:        }
                    304:        if (error || ia == 0) {
                    305:                IFDEBUG(D_FORWARD)
                    306:                        printf("clnp_forward: can't route packet (errno %d)\n", error);
                    307:                ENDDEBUG
                    308:                clnp_discard(m, ADDR_DESTUNREACH);
                    309:                INCSTAT(cns_cantforward);
                    310:                goto done;
                    311:        }
                    312:        ifp = ia->ia_ifp;
                    313: 
                    314:        IFDEBUG(D_FORWARD)
                    315:                printf("clnp_forward: packet routed to %s\n", 
                    316:                        clnp_iso_addrp(&((struct sockaddr_iso *)next_hop)->siso_addr));
                    317:        ENDDEBUG
                    318: 
                    319:        INCSTAT(cns_forward);
                    320: 
                    321:        /*
                    322:         *      If we are an intermediate system and
                    323:         *      we are routing outbound on the same ifp that the packet
                    324:         *      arrived upon, and we know the next hop snpa, 
                    325:         *      then generate a redirect request
                    326:         */
                    327:        if ((iso_systype & SNPA_IS) && (inbound_shp) && 
                    328:                (ifp == inbound_shp->snh_ifp))
                    329:                    esis_rdoutput(inbound_shp, m, oidx, dst, route.ro_rt);
                    330:        /*
                    331:         *      If options are present, update them
                    332:         */
                    333:        if (oidx) {
                    334:                struct iso_addr *mysrc = &ia->ia_addr.siso_addr;
                    335:                if (mysrc == NULL) {
                    336:                        clnp_discard(m, ADDR_DESTUNREACH);
                    337:                        INCSTAT(cns_cantforward);
                    338:                        clnp_stat.cns_forward--;
                    339:                        goto done;
                    340:                } else {
                    341:                        (void) clnp_dooptions(m, oidx, ifp, mysrc);
                    342:                }
                    343:        }
                    344: 
                    345: #ifdef DECBIT
                    346:        if (ifp->if_snd.ifq_len > congest_threshold) {
                    347:                /*
                    348:                 *      Congestion! Set the Dec Bit and thank Dave Oran
                    349:                 */
                    350:                IFDEBUG(D_FORWARD)
                    351:                        printf("clnp_forward: congestion experienced\n");
                    352:                ENDDEBUG
                    353:                if ((oidx) && (oidx->cni_qos_formatp)) {
                    354:                        caddr_t qosp = CLNP_OFFTOOPT(m, oidx->cni_qos_formatp);
                    355:                        u_char  qos = *qosp;
                    356:                        IFDEBUG(D_FORWARD)
                    357:                                printf("clnp_forward: setting congestion bit (qos x%x)\n", qos);
                    358:                        ENDDEBUG
                    359:                        if ((qos & CLNPOVAL_GLOBAL) == CLNPOVAL_GLOBAL) {
                    360:                                qos |= CLNPOVAL_CONGESTED;
                    361:                                INCSTAT(cns_congest_set);
                    362:                                *qosp = qos;
                    363:                        }
                    364:                }
                    365:        }
                    366: #endif DECBIT
                    367:        
                    368:        /*
                    369:         *      Dispatch the datagram if it is small enough, otherwise fragment
                    370:         */
                    371:        if (len <= SN_MTU(ifp, route.ro_rt)) {
                    372:                iso_gen_csum(m, CLNP_CKSUM_OFF, (int)clnp->cnf_hdr_len);
                    373:                (void) (*ifp->if_output)(ifp, m, next_hop, route.ro_rt);
                    374:        } else {
                    375:                (void) clnp_fragment(ifp, m, next_hop, len, seg_off, /* flags */0, route.ro_rt);
                    376:        }
                    377:        
                    378: done:
                    379:        /*
                    380:         *      Free route
                    381:         */
                    382:        if (route.ro_rt != NULL) {
                    383:                RTFREE(route.ro_rt);
                    384:        }
                    385: }
                    386: 
                    387: #ifdef notdef
                    388: /*
                    389:  * FUNCTION:           clnp_insert_addr
                    390:  *
                    391:  * PURPOSE:                    Insert the address part into a clnp datagram.
                    392:  *
                    393:  * RETURNS:                    Address of first byte after address part in datagram.
                    394:  *
                    395:  * SIDE EFFECTS:       
                    396:  *
                    397:  * NOTES:                      Assume that there is enough space for the address part.
                    398:  */
                    399: caddr_t
                    400: clnp_insert_addr(bufp, srcp, dstp)
                    401: caddr_t                                                bufp;   /* address of where addr part goes */
                    402: register struct iso_addr       *srcp;  /* ptr to src addr */
                    403: register struct iso_addr       *dstp;  /* ptr to dst addr */
                    404: {
                    405:        *bufp++ = dstp->isoa_len;
                    406:        (void) bcopy((caddr_t)dstp, bufp, dstp->isoa_len);
                    407:        bufp += dstp->isoa_len;
                    408: 
                    409:        *bufp++ = srcp->isoa_len;
                    410:        (void) bcopy((caddr_t)srcp, bufp, srcp->isoa_len);
                    411:        bufp += srcp->isoa_len;
                    412: 
                    413:        return bufp;
                    414: }
                    415: 
                    416: #endif notdef
                    417: 
                    418: /*
                    419:  * FUNCTION:           clnp_route
                    420:  *
                    421:  * PURPOSE:                    Route a clnp datagram to the first hop toward its 
                    422:  *                                     destination. In many cases, the first hop will be
                    423:  *                                     the destination. The address of a route
                    424:  *                                     is specified. If a routing entry is present in
                    425:  *                                     that route, and it is still up to the same destination,
                    426:  *                                     then no further action is necessary. Otherwise, a
                    427:  *                                     new routing entry will be allocated.
                    428:  *
                    429:  * RETURNS:                    route found - 0
                    430:  *                                     unix error code
                    431:  *
                    432:  * SIDE EFFECTS:       
                    433:  *
                    434:  * NOTES:                      It is up to the caller to free the routing entry
                    435:  *                                     allocated in route.
                    436:  */
                    437: clnp_route(dst, ro, flags, first_hop, ifa)
                    438:        struct iso_addr *dst;                   /* ptr to datagram destination */
                    439:        register struct route_iso *ro;  /* existing route structure */
                    440:        int flags;                                              /* flags for routing */
                    441:        struct sockaddr **first_hop;    /* result: fill in with ptr to firsthop */
                    442:        struct iso_ifaddr **ifa;                /* result: fill in with ptr to interface */
                    443: {
                    444:        if (flags & SO_DONTROUTE) {
                    445:                struct iso_ifaddr *ia;
                    446: 
                    447:                if (ro->ro_rt) {
                    448:                        RTFREE(ro->ro_rt);
                    449:                        ro->ro_rt = 0;
                    450:                }
                    451:                bzero((caddr_t)&ro->ro_dst, sizeof(ro->ro_dst));
                    452:                bcopy((caddr_t)dst, (caddr_t)&ro->ro_dst.siso_addr,
                    453:                        1 + (unsigned)dst->isoa_len);
                    454:                ro->ro_dst.siso_family = AF_ISO;
                    455:                ro->ro_dst.siso_len = sizeof(ro->ro_dst);
                    456:                ia = iso_localifa(&ro->ro_dst);
                    457:                if (ia == 0)
                    458:                        return EADDRNOTAVAIL;
                    459:                if (ifa)
                    460:                        *ifa = ia;
                    461:                if (first_hop)
                    462:                        *first_hop = (struct sockaddr *)&ro->ro_dst;
                    463:                return 0;
                    464:        }
                    465:        /*
                    466:         *      If there is a cached route, check that it is still up and to
                    467:         *      the same destination. If not, free it and try again.
                    468:         */
                    469:        if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
                    470:                (Bcmp(ro->ro_dst.siso_data, dst->isoa_genaddr, dst->isoa_len)))) {
                    471:                IFDEBUG(D_ROUTE)
                    472:                        printf("clnp_route: freeing old route: ro->ro_rt 0x%x\n",
                    473:                                ro->ro_rt);
                    474:                        printf("clnp_route: old route refcnt: 0x%x\n",
                    475:                                ro->ro_rt->rt_refcnt);
                    476:                ENDDEBUG
                    477: 
                    478:                /* free old route entry */
                    479:                RTFREE(ro->ro_rt);
                    480:                ro->ro_rt = (struct rtentry *)0;
                    481:        } else {
                    482:                IFDEBUG(D_ROUTE)
                    483:                        printf("clnp_route: OK route exists\n");
                    484:                ENDDEBUG
                    485:        }
                    486: 
                    487:        if (ro->ro_rt == 0) {
                    488:                /* set up new route structure */
                    489:                bzero((caddr_t)&ro->ro_dst, sizeof(ro->ro_dst));
                    490:                ro->ro_dst.siso_len = sizeof(ro->ro_dst);
                    491:                ro->ro_dst.siso_family = AF_ISO;
                    492:                Bcopy(dst, &ro->ro_dst.siso_addr, 1 + dst->isoa_len);
                    493:                /* allocate new route */
                    494:                IFDEBUG(D_ROUTE)
                    495:                        printf("clnp_route: allocating new route to %s\n",
                    496:                                clnp_iso_addrp(dst));
                    497:                ENDDEBUG
                    498:                rtalloc((struct route *)ro);
                    499:        }
                    500:        if (ro->ro_rt == 0)
                    501:                return(ENETUNREACH);    /* rtalloc failed */
                    502:        ro->ro_rt->rt_use++;
                    503:        if (ifa)
                    504:                if ((*ifa = (struct iso_ifaddr *)ro->ro_rt->rt_ifa) == 0)
                    505:                        panic("clnp_route");
                    506:        if (first_hop) {
                    507:                if (ro->ro_rt->rt_flags & RTF_GATEWAY)
                    508:                        *first_hop = ro->ro_rt->rt_gateway;
                    509:                else
                    510:                        *first_hop = (struct sockaddr *)&ro->ro_dst;
                    511:        }
                    512:        return(0);
                    513: }
                    514: 
                    515: /*
                    516:  * FUNCTION:           clnp_srcroute
                    517:  *
                    518:  * PURPOSE:                    Source route the datagram. If complete source
                    519:  *                                     routing is specified but not possible, then
                    520:  *                                     return an error. If src routing is terminated, then
                    521:  *                                     try routing on destination.
                    522:  *                                     Usage of first_hop,
                    523:  *                                     ifp, and error return is identical to clnp_route.
                    524:  *
                    525:  * RETURNS:                    0 or unix error code
                    526:  *
                    527:  * SIDE EFFECTS:       
                    528:  *
                    529:  * NOTES:                      Remember that option index pointers are really
                    530:  *                                     offsets from the beginning of the mbuf.
                    531:  */
                    532: clnp_srcroute(options, oidx, ro, first_hop, ifa, final_dst)
                    533: struct mbuf                    *options;               /* ptr to options */
                    534: struct clnp_optidx     *oidx;                  /* index to options */
                    535: struct route_iso       *ro;                    /* route structure */
                    536: struct sockaddr                **first_hop;    /* RETURN: fill in with ptr to firsthop */
                    537: struct iso_ifaddr      **ifa;                  /* RETURN: fill in with ptr to interface */
                    538: struct iso_addr                *final_dst;             /* final destination */
                    539: {
                    540:        struct iso_addr dst;            /* first hop specified by src rt */
                    541:        int                             error = 0;      /* return code */
                    542: 
                    543:        /*
                    544:         *      Check if we have run out of routes 
                    545:         *      If so, then try to route on destination.
                    546:         */
                    547:        if CLNPSRCRT_TERM(oidx, options) {
                    548:                dst.isoa_len = final_dst->isoa_len;
                    549:                bcopy(final_dst->isoa_genaddr, dst.isoa_genaddr, dst.isoa_len);
                    550:        } else {
                    551:                /*
                    552:                 * setup dst based on src rt specified
                    553:                 */
                    554:                dst.isoa_len = CLNPSRCRT_CLEN(oidx, options);
                    555:                bcopy(CLNPSRCRT_CADDR(oidx, options), dst.isoa_genaddr, dst.isoa_len);
                    556:        }
                    557: 
                    558:        /*
                    559:         *      try to route it
                    560:         */
                    561:        error = clnp_route(&dst, ro, 0, first_hop, ifa);
                    562:        if (error != 0)
                    563:                return error;
                    564:        
                    565:        /*
                    566:         *      If complete src rt, first hop must be equal to dst
                    567:         */
                    568:        if ((CLNPSRCRT_TYPE(oidx, options) == CLNPOVAL_COMPRT) &&
                    569:         (!iso_addrmatch1(&(*(struct sockaddr_iso **)first_hop)->siso_addr,&dst))){
                    570:                IFDEBUG(D_OPTIONS)
                    571:                        printf("clnp_srcroute: complete src route failed\n");
                    572:                ENDDEBUG
                    573:                return EHOSTUNREACH; /* RAH? would like ESRCRTFAILED */
                    574:        }
                    575:        
                    576:        return error;
                    577: }
                    578: 
                    579: /*
                    580:  * FUNCTION:           clnp_badmtu
                    581:  *
                    582:  * PURPOSE:                    print notice of route with mtu not initialized.
                    583:  *
                    584:  * RETURNS:                    mtu of ifp.
                    585:  *
                    586:  * SIDE EFFECTS:       prints notice, slows down system.
                    587:  */
                    588: clnp_badmtu(ifp, rt, line, file)
                    589: struct ifnet *ifp;     /* outgoing interface */
                    590: struct rtentry *rt; /* dst route */
                    591: int line;                      /* where the dirty deed occured */
                    592: char *file;                    /* where the dirty deed occured */
                    593: {
                    594:        printf("sending on route %x with no mtu, line %s of file %s\n",
                    595:                rt, line, file);
                    596: #ifdef ARGO_DEBUG
                    597:        printf("route dst is");
                    598:        dump_isoaddr(rt_key(rt));
                    599: #endif
                    600:        return ifp->if_mtu;
                    601: }
                    602: 
                    603: /*
                    604:  * FUNCTION:           clnp_ypocb - backwards bcopy
                    605:  *
                    606:  * PURPOSE:                    bcopy starting at end of src rather than beginning.
                    607:  *
                    608:  * RETURNS:                    none
                    609:  *
                    610:  * SIDE EFFECTS:       
                    611:  *
                    612:  * NOTES:                      No attempt has been made to make this efficient
                    613:  */
                    614: clnp_ypocb(from, to, len)
                    615: caddr_t from;          /* src buffer */
                    616: caddr_t to;                    /* dst buffer */
                    617: u_int  len;            /* number of bytes */
                    618: {
                    619:        while (len--)
                    620:                *(to + len) = *(from + len);
                    621: }
                    622: #endif ISO

unix.superglobalmegacorp.com

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