|
|
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: * @(#)tp_iso.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: * ARGO TP ! 85: * ! 86: * Here is where you find the iso-dependent code. We've tried ! 87: * keep all net-level and (primarily) address-family-dependent stuff ! 88: * out of the tp source, and everthing here is reached indirectly ! 89: * through a switch table (struct nl_protosw *) tpcb->tp_nlproto ! 90: * (see tp_pcb.c). ! 91: * The routines here are: ! 92: * iso_getsufx: gets transport suffix out of an isopcb structure. ! 93: * iso_putsufx: put transport suffix into an isopcb structure. ! 94: * iso_putnetaddr: put a whole net addr into an isopcb. ! 95: * iso_getnetaddr: get a whole net addr from an isopcb. ! 96: * iso_cmpnetaddr: compare a whole net addr from an isopcb. ! 97: * iso_recycle_suffix: clear suffix for reuse in isopcb ! 98: * tpclnp_ctlinput: handle ER CNLPdu : icmp-like stuff ! 99: * tpclnp_mtu: figure out what size tpdu to use ! 100: * tpclnp_input: take a pkt from clnp, strip off its clnp header, ! 101: * give to tp ! 102: * tpclnp_output_dg: package a pkt for clnp given 2 addresses & some data ! 103: * tpclnp_output: package a pkt for clnp given an isopcb & some data ! 104: */ ! 105: ! 106: #if ISO ! 107: ! 108: #include <sys/param.h> ! 109: #include <sys/socket.h> ! 110: #include <sys/socketvar.h> ! 111: #include <sys/domain.h> ! 112: #include <sys/malloc.h> ! 113: #include <sys/mbuf.h> ! 114: #include <sys/errno.h> ! 115: #include <sys/time.h> ! 116: #include <sys/protosw.h> ! 117: ! 118: #include <net/if.h> ! 119: #include <net/route.h> ! 120: ! 121: #include <netiso/argo_debug.h> ! 122: #include <netiso/tp_param.h> ! 123: #include <netiso/tp_stat.h> ! 124: #include <netiso/tp_pcb.h> ! 125: #include <netiso/tp_trace.h> ! 126: #include <netiso/tp_stat.h> ! 127: #include <netiso/tp_tpdu.h> ! 128: #include <netiso/tp_clnp.h> ! 129: #include <netiso/cltp_var.h> ! 130: ! 131: /* ! 132: * CALLED FROM: ! 133: * pr_usrreq() on PRU_BIND, PRU_CONNECT, PRU_ACCEPT, and PRU_PEERADDR ! 134: * FUNCTION, ARGUMENTS: ! 135: * The argument (which) takes the value TP_LOCAL or TP_FOREIGN. ! 136: */ ! 137: ! 138: iso_getsufx(isop, lenp, data_out, which) ! 139: struct isopcb *isop; ! 140: u_short *lenp; ! 141: caddr_t data_out; ! 142: int which; ! 143: { ! 144: register struct sockaddr_iso *addr = 0; ! 145: ! 146: switch (which) { ! 147: case TP_LOCAL: ! 148: addr = isop->isop_laddr; ! 149: break; ! 150: ! 151: case TP_FOREIGN: ! 152: addr = isop->isop_faddr; ! 153: } ! 154: if (addr) ! 155: bcopy(TSEL(addr), data_out, (*lenp = addr->siso_tlen)); ! 156: } ! 157: ! 158: /* CALLED FROM: ! 159: * tp_newsocket(); i.e., when a connection is being established by an ! 160: * incoming CR_TPDU. ! 161: * ! 162: * FUNCTION, ARGUMENTS: ! 163: * Put a transport suffix (found in name) into an isopcb structure (isop). ! 164: * The argument (which) takes the value TP_LOCAL or TP_FOREIGN. ! 165: */ ! 166: void ! 167: iso_putsufx(isop, sufxloc, sufxlen, which) ! 168: struct isopcb *isop; ! 169: caddr_t sufxloc; ! 170: int sufxlen, which; ! 171: { ! 172: struct sockaddr_iso **dst, *backup; ! 173: register struct sockaddr_iso *addr; ! 174: struct mbuf *m; ! 175: int len; ! 176: ! 177: switch (which) { ! 178: default: ! 179: return; ! 180: ! 181: case TP_LOCAL: ! 182: dst = &isop->isop_laddr; ! 183: backup = &isop->isop_sladdr; ! 184: break; ! 185: ! 186: case TP_FOREIGN: ! 187: dst = &isop->isop_faddr; ! 188: backup = &isop->isop_sfaddr; ! 189: } ! 190: if ((addr = *dst) == 0) { ! 191: addr = *dst = backup; ! 192: addr->siso_nlen = 0; ! 193: addr->siso_slen = 0; ! 194: addr->siso_plen = 0; ! 195: printf("iso_putsufx on un-initialized isopcb\n"); ! 196: } ! 197: len = sufxlen + addr->siso_nlen + ! 198: (sizeof(*addr) - sizeof(addr->siso_data)); ! 199: if (addr == backup) { ! 200: if (len > sizeof(*addr)) { ! 201: m = m_getclr(M_DONTWAIT, MT_SONAME); ! 202: if (m == 0) ! 203: return; ! 204: addr = *dst = mtod(m, struct sockaddr_iso *); ! 205: *addr = *backup; ! 206: m->m_len = len; ! 207: } ! 208: } ! 209: bcopy(sufxloc, TSEL(addr), sufxlen); ! 210: addr->siso_tlen = sufxlen; ! 211: addr->siso_len = len; ! 212: } ! 213: ! 214: /* ! 215: * CALLED FROM: ! 216: * tp.trans whenever we go into REFWAIT state. ! 217: * FUNCTION and ARGUMENT: ! 218: * Called when a ref is frozen, to allow the suffix to be reused. ! 219: * (isop) is the net level pcb. This really shouldn't have to be ! 220: * done in a NET level pcb but... for the internet world that just ! 221: * the way it is done in BSD... ! 222: * The alternative is to have the port unusable until the reference ! 223: * timer goes off. ! 224: */ ! 225: void ! 226: iso_recycle_tsuffix(isop) ! 227: struct isopcb *isop; ! 228: { ! 229: isop->isop_laddr->siso_tlen = isop->isop_faddr->siso_tlen = 0; ! 230: } ! 231: ! 232: /* ! 233: * CALLED FROM: ! 234: * tp_newsocket(); i.e., when a connection is being established by an ! 235: * incoming CR_TPDU. ! 236: * ! 237: * FUNCTION and ARGUMENTS: ! 238: * Copy a whole net addr from a struct sockaddr (name). ! 239: * into an isopcb (isop). ! 240: * The argument (which) takes values TP_LOCAL or TP_FOREIGN ! 241: */ ! 242: void ! 243: iso_putnetaddr(isop, name, which) ! 244: register struct isopcb *isop; ! 245: struct sockaddr_iso *name; ! 246: int which; ! 247: { ! 248: struct sockaddr_iso **sisop, *backup; ! 249: register struct sockaddr_iso *siso; ! 250: ! 251: switch (which) { ! 252: default: ! 253: printf("iso_putnetaddr: should panic\n"); ! 254: return; ! 255: case TP_LOCAL: ! 256: sisop = &isop->isop_laddr; ! 257: backup = &isop->isop_sladdr; ! 258: break; ! 259: case TP_FOREIGN: ! 260: sisop = &isop->isop_faddr; ! 261: backup = &isop->isop_sfaddr; ! 262: } ! 263: siso = ((*sisop == 0) ? (*sisop = backup) : *sisop); ! 264: IFDEBUG(D_TPISO) ! 265: printf("ISO_PUTNETADDR\n"); ! 266: dump_isoaddr(isop->isop_faddr); ! 267: ENDDEBUG ! 268: siso->siso_addr = name->siso_addr; ! 269: } ! 270: ! 271: /* ! 272: * CALLED FROM: ! 273: * tp_input() when a connection is being established by an ! 274: * incoming CR_TPDU, and considered for interception. ! 275: * ! 276: * FUNCTION and ARGUMENTS: ! 277: * compare a whole net addr from a struct sockaddr (name), ! 278: * with that implicitly stored in an isopcb (isop). ! 279: * The argument (which) takes values TP_LOCAL or TP_FOREIGN. ! 280: */ ! 281: iso_cmpnetaddr(isop, name, which) ! 282: register struct isopcb *isop; ! 283: register struct sockaddr_iso *name; ! 284: int which; ! 285: { ! 286: struct sockaddr_iso **sisop, *backup; ! 287: register struct sockaddr_iso *siso; ! 288: ! 289: switch (which) { ! 290: default: ! 291: printf("iso_cmpnetaddr: should panic\n"); ! 292: return 0; ! 293: case TP_LOCAL: ! 294: sisop = &isop->isop_laddr; ! 295: backup = &isop->isop_sladdr; ! 296: break; ! 297: case TP_FOREIGN: ! 298: sisop = &isop->isop_faddr; ! 299: backup = &isop->isop_sfaddr; ! 300: } ! 301: siso = ((*sisop == 0) ? (*sisop = backup) : *sisop); ! 302: IFDEBUG(D_TPISO) ! 303: printf("ISO_CMPNETADDR\n"); ! 304: dump_isoaddr(siso); ! 305: ENDDEBUG ! 306: if (name->siso_tlen && bcmp(TSEL(name), TSEL(siso), name->siso_tlen)) ! 307: return (0); ! 308: return (bcmp((caddr_t)name->siso_data, ! 309: (caddr_t)siso->siso_data, name->siso_nlen) == 0); ! 310: } ! 311: ! 312: /* ! 313: * CALLED FROM: ! 314: * pr_usrreq() PRU_SOCKADDR, PRU_ACCEPT, PRU_PEERADDR ! 315: * FUNCTION and ARGUMENTS: ! 316: * Copy a whole net addr from an isopcb (isop) into ! 317: * a struct sockaddr (name). ! 318: * The argument (which) takes values TP_LOCAL or TP_FOREIGN. ! 319: */ ! 320: ! 321: void ! 322: iso_getnetaddr( isop, name, which) ! 323: struct isopcb *isop; ! 324: struct mbuf *name; ! 325: int which; ! 326: { ! 327: struct sockaddr_iso *siso = ! 328: (which == TP_LOCAL ? isop->isop_laddr : isop->isop_faddr); ! 329: if (siso) ! 330: bcopy((caddr_t)siso, mtod(name, caddr_t), ! 331: (unsigned)(name->m_len = siso->siso_len)); ! 332: else ! 333: name->m_len = 0; ! 334: } ! 335: /* ! 336: * NAME: tpclnp_mtu() ! 337: * ! 338: * CALLED FROM: ! 339: * tp_route_to() on incoming CR, CC, and pr_usrreq() for PRU_CONNECT ! 340: * ! 341: * FUNCTION, ARGUMENTS, and RETURN VALUE: ! 342: * ! 343: * Perform subnetwork dependent part of determining MTU information. ! 344: * It appears that setting a double pointer to the rtentry associated with ! 345: * the destination, and returning the header size for the network protocol ! 346: * suffices. ! 347: * ! 348: * SIDE EFFECTS: ! 349: * Sets tp_routep pointer in pcb. ! 350: * ! 351: * NOTES: ! 352: */ ! 353: tpclnp_mtu(tpcb) ! 354: register struct tp_pcb *tpcb; ! 355: { ! 356: struct isopcb *isop = (struct isopcb *)tpcb->tp_npcb; ! 357: ! 358: IFDEBUG(D_CONN) ! 359: printf("tpclnp_mtu(tpcb)\n", tpcb); ! 360: ENDDEBUG ! 361: tpcb->tp_routep = &(isop->isop_route.ro_rt); ! 362: if (tpcb->tp_netservice == ISO_CONS) ! 363: return 0; ! 364: else ! 365: return (sizeof(struct clnp_fixed) + sizeof(struct clnp_segment) + ! 366: 2 * sizeof(struct iso_addr)); ! 367: ! 368: } ! 369: ! 370: /* ! 371: * CALLED FROM: ! 372: * tp_emit() ! 373: * FUNCTION and ARGUMENTS: ! 374: * Take a packet(m0) from tp and package it so that clnp will accept it. ! 375: * This means prepending space for the clnp header and filling in a few ! 376: * of the fields. ! 377: * isop is the isopcb structure; datalen is the length of the data in the ! 378: * mbuf string m0. ! 379: * RETURN VALUE: ! 380: * whatever (E*) is returned form the net layer output routine. ! 381: */ ! 382: ! 383: int ! 384: tpclnp_output(isop, m0, datalen, nochksum) ! 385: struct isopcb *isop; ! 386: struct mbuf *m0; ! 387: int datalen; ! 388: int nochksum; ! 389: { ! 390: register struct mbuf *m = m0; ! 391: IncStat(ts_tpdu_sent); ! 392: ! 393: IFDEBUG(D_TPISO) ! 394: struct tpdu *hdr = mtod(m0, struct tpdu *); ! 395: ! 396: printf( ! 397: "abt to call clnp_output: datalen 0x%x, hdr.li 0x%x, hdr.dutype 0x%x nocsum x%x dst addr:\n", ! 398: datalen, ! 399: (int)hdr->tpdu_li, (int)hdr->tpdu_type, nochksum); ! 400: dump_isoaddr(isop->isop_faddr); ! 401: printf("\nsrc addr:\n"); ! 402: dump_isoaddr(isop->isop_laddr); ! 403: dump_mbuf(m0, "at tpclnp_output"); ! 404: ENDDEBUG ! 405: ! 406: return ! 407: clnp_output(m0, isop, datalen, /* flags */nochksum ? CLNP_NO_CKSUM : 0); ! 408: } ! 409: ! 410: /* ! 411: * CALLED FROM: ! 412: * tp_error_emit() ! 413: * FUNCTION and ARGUMENTS: ! 414: * This is a copy of tpclnp_output that takes the addresses ! 415: * instead of a pcb. It's used by the tp_error_emit, when we ! 416: * don't have an iso_pcb with which to call the normal output rtn. ! 417: * RETURN VALUE: ! 418: * ENOBUFS or ! 419: * whatever (E*) is returned form the net layer output routine. ! 420: */ ! 421: ! 422: int ! 423: tpclnp_output_dg(laddr, faddr, m0, datalen, ro, nochksum) ! 424: struct iso_addr *laddr, *faddr; ! 425: struct mbuf *m0; ! 426: int datalen; ! 427: struct route *ro; ! 428: int nochksum; ! 429: { ! 430: struct isopcb tmppcb; ! 431: int err; ! 432: int flags; ! 433: register struct mbuf *m = m0; ! 434: ! 435: IFDEBUG(D_TPISO) ! 436: printf("tpclnp_output_dg datalen 0x%x m0 0x%x\n", datalen, m0); ! 437: ENDDEBUG ! 438: ! 439: /* ! 440: * Fill in minimal portion of isopcb so that clnp can send the ! 441: * packet. ! 442: */ ! 443: bzero((caddr_t)&tmppcb, sizeof(tmppcb)); ! 444: tmppcb.isop_laddr = &tmppcb.isop_sladdr; ! 445: tmppcb.isop_laddr->siso_addr = *laddr; ! 446: tmppcb.isop_faddr = &tmppcb.isop_sfaddr; ! 447: tmppcb.isop_faddr->siso_addr = *faddr; ! 448: ! 449: IFDEBUG(D_TPISO) ! 450: printf("tpclnp_output_dg faddr: \n"); ! 451: dump_isoaddr(&tmppcb.isop_sfaddr); ! 452: printf("\ntpclnp_output_dg laddr: \n"); ! 453: dump_isoaddr(&tmppcb.isop_sladdr); ! 454: printf("\n"); ! 455: ENDDEBUG ! 456: ! 457: /* ! 458: * Do not use packet cache since this is a one shot error packet ! 459: */ ! 460: flags = (CLNP_NOCACHE|(nochksum?CLNP_NO_CKSUM:0)); ! 461: ! 462: IncStat(ts_tpdu_sent); ! 463: ! 464: err = clnp_output(m0, &tmppcb, datalen, flags); ! 465: ! 466: /* ! 467: * Free route allocated by clnp (if the route was indeed allocated) ! 468: */ ! 469: if (tmppcb.isop_route.ro_rt) ! 470: RTFREE(tmppcb.isop_route.ro_rt); ! 471: ! 472: return(err); ! 473: } ! 474: /* ! 475: * CALLED FROM: ! 476: * clnp's input routine, indirectly through the protosw. ! 477: * FUNCTION and ARGUMENTS: ! 478: * Take a packet (m) from clnp, strip off the clnp header and give it to tp ! 479: * No return value. ! 480: */ ! 481: ProtoHook ! 482: tpclnp_input(m, src, dst, clnp_len, ce_bit) ! 483: register struct mbuf *m; ! 484: struct sockaddr_iso *src, *dst; ! 485: int clnp_len, ce_bit; ! 486: { ! 487: struct mbuf *tp_inputprep(); ! 488: int tp_input(), cltp_input(), (*input)() = tp_input; ! 489: ! 490: IncStat(ts_pkt_rcvd); ! 491: ! 492: IFDEBUG(D_TPINPUT) ! 493: printf("tpclnp_input: m 0x%x clnp_len 0x%x\n", m, clnp_len); ! 494: dump_mbuf(m, "at tpclnp_input"); ! 495: ENDDEBUG ! 496: /* ! 497: * CLNP gives us an mbuf chain WITH the clnp header pulled up, ! 498: * and the length of the clnp header. ! 499: * First, strip off the Clnp header. leave the mbuf there for the ! 500: * pullup that follows. ! 501: */ ! 502: m->m_len -= clnp_len; ! 503: m->m_data += clnp_len; ! 504: m->m_pkthdr.len -= clnp_len; ! 505: /* XXXX: should probably be in clnp_input */ ! 506: switch (dst->siso_data[dst->siso_nlen - 1]) { ! 507: #if TUBA ! 508: case ISOPROTO_TCP: ! 509: return (tuba_tcpinput(m, src, dst)); ! 510: #endif ! 511: case 0: ! 512: if (m->m_len == 0 && (m = m_pullup(m, 1)) == 0) ! 513: return 0; ! 514: if (*(mtod(m, u_char *)) == ISO10747_IDRP) ! 515: return (idrp_input(m, src, dst)); ! 516: } ! 517: m = tp_inputprep(m); ! 518: if (m == 0) ! 519: return 0; ! 520: if (mtod(m, u_char *)[1] == UD_TPDU_type) ! 521: input = cltp_input; ! 522: ! 523: IFDEBUG(D_TPINPUT) ! 524: dump_mbuf(m, "after tpclnp_input both pullups"); ! 525: ENDDEBUG ! 526: ! 527: IFDEBUG(D_TPISO) ! 528: printf("calling %sinput : src 0x%x, dst 0x%x, src addr:\n", ! 529: (input == tp_input ? "tp_" : "clts_"), src, dst); ! 530: dump_isoaddr(src); ! 531: printf(" dst addr:\n"); ! 532: dump_isoaddr(dst); ! 533: ENDDEBUG ! 534: ! 535: (void) (*input)(m, (struct sockaddr *)src, (struct sockaddr *)dst, ! 536: 0, tpclnp_output_dg, ce_bit); ! 537: ! 538: IFDEBUG(D_QUENCH) ! 539: { ! 540: if(time.tv_usec & 0x4 && time.tv_usec & 0x40) { ! 541: printf("tpclnp_input: FAKING %s\n", ! 542: tp_stat.ts_pkt_rcvd & 0x1?"QUENCH":"QUENCH2"); ! 543: if(tp_stat.ts_pkt_rcvd & 0x1) { ! 544: tpclnp_ctlinput(PRC_QUENCH, &src); ! 545: } else { ! 546: tpclnp_ctlinput(PRC_QUENCH2, &src); ! 547: } ! 548: } ! 549: } ! 550: ENDDEBUG ! 551: ! 552: return 0; ! 553: } ! 554: ! 555: ProtoHook ! 556: iso_rtchange() ! 557: { ! 558: return 0; ! 559: } ! 560: ! 561: /* ! 562: * CALLED FROM: ! 563: * tpclnp_ctlinput() ! 564: * FUNCTION and ARGUMENTS: ! 565: * find the tpcb pointer and pass it to tp_quench ! 566: */ ! 567: void ! 568: tpiso_decbit(isop) ! 569: struct isopcb *isop; ! 570: { ! 571: tp_quench((struct tp_pcb *)isop->isop_socket->so_pcb, PRC_QUENCH2); ! 572: } ! 573: /* ! 574: * CALLED FROM: ! 575: * tpclnp_ctlinput() ! 576: * FUNCTION and ARGUMENTS: ! 577: * find the tpcb pointer and pass it to tp_quench ! 578: */ ! 579: void ! 580: tpiso_quench(isop) ! 581: struct isopcb *isop; ! 582: { ! 583: tp_quench((struct tp_pcb *)isop->isop_socket->so_pcb, PRC_QUENCH); ! 584: } ! 585: ! 586: /* ! 587: * CALLED FROM: ! 588: * The network layer through the protosw table. ! 589: * FUNCTION and ARGUMENTS: ! 590: * When clnp an ICMP-like msg this gets called. ! 591: * It either returns an error status to the user or ! 592: * it causes all connections on this address to be aborted ! 593: * by calling the appropriate xx_notify() routine. ! 594: * (cmd) is the type of ICMP error. ! 595: * (siso) is the address of the guy who sent the ER CLNPDU ! 596: */ ! 597: ProtoHook ! 598: tpclnp_ctlinput(cmd, siso) ! 599: int cmd; ! 600: struct sockaddr_iso *siso; ! 601: { ! 602: extern u_char inetctlerrmap[]; ! 603: extern ProtoHook tpiso_abort(); ! 604: extern ProtoHook iso_rtchange(); ! 605: extern ProtoHook tpiso_reset(); ! 606: void iso_pcbnotify(); ! 607: ! 608: IFDEBUG(D_TPINPUT) ! 609: printf("tpclnp_ctlinput1: cmd 0x%x addr: \n", cmd); ! 610: dump_isoaddr(siso); ! 611: ENDDEBUG ! 612: ! 613: if (cmd < 0 || cmd > PRC_NCMDS) ! 614: return 0; ! 615: if (siso->siso_family != AF_ISO) ! 616: return 0; ! 617: switch (cmd) { ! 618: ! 619: case PRC_QUENCH2: ! 620: iso_pcbnotify(&tp_isopcb, siso, 0, (int (*)())tpiso_decbit); ! 621: break; ! 622: ! 623: case PRC_QUENCH: ! 624: iso_pcbnotify(&tp_isopcb, siso, 0, (int (*)())tpiso_quench); ! 625: break; ! 626: ! 627: case PRC_TIMXCEED_REASS: ! 628: case PRC_ROUTEDEAD: ! 629: iso_pcbnotify(&tp_isopcb, siso, 0, tpiso_reset); ! 630: break; ! 631: ! 632: case PRC_HOSTUNREACH: ! 633: case PRC_UNREACH_NET: ! 634: case PRC_IFDOWN: ! 635: case PRC_HOSTDEAD: ! 636: iso_pcbnotify(&tp_isopcb, siso, ! 637: (int)inetctlerrmap[cmd], iso_rtchange); ! 638: break; ! 639: ! 640: default: ! 641: /* ! 642: case PRC_MSGSIZE: ! 643: case PRC_UNREACH_HOST: ! 644: case PRC_UNREACH_PROTOCOL: ! 645: case PRC_UNREACH_PORT: ! 646: case PRC_UNREACH_NEEDFRAG: ! 647: case PRC_UNREACH_SRCFAIL: ! 648: case PRC_REDIRECT_NET: ! 649: case PRC_REDIRECT_HOST: ! 650: case PRC_REDIRECT_TOSNET: ! 651: case PRC_REDIRECT_TOSHOST: ! 652: case PRC_TIMXCEED_INTRANS: ! 653: case PRC_PARAMPROB: ! 654: */ ! 655: iso_pcbnotify(&tp_isopcb, siso, (int)inetctlerrmap[cmd], tpiso_abort); ! 656: break; ! 657: } ! 658: return 0; ! 659: } ! 660: /* ! 661: * XXX - Variant which is called by clnp_er.c with an isoaddr rather ! 662: * than a sockaddr_iso. ! 663: */ ! 664: ! 665: static struct sockaddr_iso siso = {sizeof(siso), AF_ISO}; ! 666: tpclnp_ctlinput1(cmd, isoa) ! 667: int cmd; ! 668: struct iso_addr *isoa; ! 669: { ! 670: bzero((caddr_t)&siso.siso_addr, sizeof(siso.siso_addr)); ! 671: bcopy((caddr_t)isoa, (caddr_t)&siso.siso_addr, isoa->isoa_len); ! 672: tpclnp_ctlinput(cmd, &siso); ! 673: } ! 674: ! 675: /* ! 676: * These next 2 routines are ! 677: * CALLED FROM: ! 678: * xxx_notify() from tp_ctlinput() when ! 679: * net level gets some ICMP-equiv. type event. ! 680: * FUNCTION and ARGUMENTS: ! 681: * Cause the connection to be aborted with some sort of error ! 682: * reason indicating that the network layer caused the abort. ! 683: * Fakes an ER TPDU so we can go through the driver. ! 684: * abort always aborts the TP connection. ! 685: * reset may or may not, depending on the TP class that's in use. ! 686: */ ! 687: ProtoHook ! 688: tpiso_abort(isop) ! 689: struct isopcb *isop; ! 690: { ! 691: struct tp_event e; ! 692: ! 693: IFDEBUG(D_CONN) ! 694: printf("tpiso_abort 0x%x\n", isop); ! 695: ENDDEBUG ! 696: e.ev_number = ER_TPDU; ! 697: e.ATTR(ER_TPDU).e_reason = ECONNABORTED; ! 698: return tp_driver((struct tp_pcb *)isop->isop_socket->so_pcb, &e); ! 699: } ! 700: ! 701: ProtoHook ! 702: tpiso_reset(isop) ! 703: struct isopcb *isop; ! 704: { ! 705: struct tp_event e; ! 706: ! 707: e.ev_number = T_NETRESET; ! 708: return tp_driver((struct tp_pcb *)isop->isop_socket->so_pcb, &e); ! 709: ! 710: } ! 711: ! 712: #endif /* ISO */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.