|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.