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