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