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