Annotation of kernel/bsd/netiso/clnp_subr.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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