Annotation of 43BSDReno/sys/netiso/clnp_subr.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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