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

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

unix.superglobalmegacorp.com

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