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