|
|
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_inet.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 inet-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: * in_getsufx: gets transport suffix out of an inpcb structure. ! 93: * in_putsufx: put transport suffix into an inpcb structure. ! 94: * in_putnetaddr: put a whole net addr into an inpcb. ! 95: * in_getnetaddr: get a whole net addr from an inpcb. ! 96: * in_cmpnetaddr: compare a whole net addr from an isopcb. ! 97: * in_recycle_suffix: clear suffix for reuse in inpcb ! 98: * tpip_mtu: figure out what size tpdu to use ! 99: * tpip_input: take a pkt from ip, strip off its ip header, give to tp ! 100: * tpip_output_dg: package a pkt for ip given 2 addresses & some data ! 101: * tpip_output: package a pkt for ip given an inpcb & some data ! 102: */ ! 103: ! 104: #if INET ! 105: ! 106: #include <sys/param.h> ! 107: #include <sys/socket.h> ! 108: #include <sys/socketvar.h> ! 109: #include <sys/mbuf.h> ! 110: #include <sys/errno.h> ! 111: #include <sys/time.h> ! 112: ! 113: #include <net/if.h> ! 114: ! 115: #include <netiso/tp_param.h> ! 116: #include <netiso/argo_debug.h> ! 117: #include <netiso/tp_stat.h> ! 118: #include <netiso/tp_ip.h> ! 119: #include <netiso/tp_pcb.h> ! 120: #include <netiso/tp_trace.h> ! 121: #include <netiso/tp_stat.h> ! 122: #include <netiso/tp_tpdu.h> ! 123: #include <netinet/in_var.h> ! 124: ! 125: #ifndef ISO ! 126: #include <netiso/iso_chksum.c> ! 127: #endif ! 128: ! 129: /* ! 130: * NAME: in_getsufx() ! 131: ! 132: * CALLED FROM: pr_usrreq() on PRU_BIND, ! 133: * PRU_CONNECT, PRU_ACCEPT, and PRU_PEERADDR ! 134: * ! 135: * FUNCTION, ARGUMENTS, and RETURN VALUE: ! 136: * Get a transport suffix from an inpcb structure (inp). ! 137: * The argument (which) takes the value TP_LOCAL or TP_FOREIGN. ! 138: * ! 139: * RETURNS: internet port / transport suffix ! 140: * (CAST TO AN INT) ! 141: * ! 142: * SIDE EFFECTS: ! 143: * ! 144: * NOTES: ! 145: */ ! 146: in_getsufx(inp, lenp, data_out, which) ! 147: struct inpcb *inp; ! 148: u_short *lenp; ! 149: caddr_t data_out; ! 150: int which; ! 151: { ! 152: *lenp = sizeof(u_short); ! 153: switch (which) { ! 154: case TP_LOCAL: ! 155: *(u_short *)data_out = inp->inp_lport; ! 156: return; ! 157: ! 158: case TP_FOREIGN: ! 159: *(u_short *)data_out = inp->inp_fport; ! 160: } ! 161: ! 162: } ! 163: ! 164: /* ! 165: * NAME: in_putsufx() ! 166: * ! 167: * CALLED FROM: tp_newsocket(); i.e., when a connection ! 168: * is being established by an incoming CR_TPDU. ! 169: * ! 170: * FUNCTION, ARGUMENTS: ! 171: * Put a transport suffix (found in name) into an inpcb structure (inp). ! 172: * The argument (which) takes the value TP_LOCAL or TP_FOREIGN. ! 173: * ! 174: * RETURNS: Nada ! 175: * ! 176: * SIDE EFFECTS: ! 177: * ! 178: * NOTES: ! 179: */ ! 180: /*ARGSUSED*/ ! 181: void ! 182: in_putsufx(inp, sufxloc, sufxlen, which) ! 183: struct inpcb *inp; ! 184: caddr_t sufxloc; ! 185: int which; ! 186: { ! 187: if (which == TP_FOREIGN) { ! 188: bcopy(sufxloc, (caddr_t)&inp->inp_fport, sizeof(inp->inp_fport)); ! 189: } ! 190: } ! 191: ! 192: /* ! 193: * NAME: in_recycle_tsuffix() ! 194: * ! 195: * CALLED FROM: tp.trans whenever we go into REFWAIT state. ! 196: * ! 197: * FUNCTION and ARGUMENT: ! 198: * Called when a ref is frozen, to allow the suffix to be reused. ! 199: * (inp) is the net level pcb. ! 200: * ! 201: * RETURNS: Nada ! 202: * ! 203: * SIDE EFFECTS: ! 204: * ! 205: * NOTES: This really shouldn't have to be done in a NET level pcb ! 206: * but... for the internet world that just the way it is done in BSD... ! 207: * The alternative is to have the port unusable until the reference ! 208: * timer goes off. ! 209: */ ! 210: void ! 211: in_recycle_tsuffix(inp) ! 212: struct inpcb *inp; ! 213: { ! 214: inp->inp_fport = inp->inp_lport = 0; ! 215: } ! 216: ! 217: /* ! 218: * NAME: in_putnetaddr() ! 219: * ! 220: * CALLED FROM: ! 221: * tp_newsocket(); i.e., when a connection is being established by an ! 222: * incoming CR_TPDU. ! 223: * ! 224: * FUNCTION and ARGUMENTS: ! 225: * Copy a whole net addr from a struct sockaddr (name). ! 226: * into an inpcb (inp). ! 227: * The argument (which) takes values TP_LOCAL or TP_FOREIGN ! 228: * ! 229: * RETURNS: Nada ! 230: * ! 231: * SIDE EFFECTS: ! 232: * ! 233: * NOTES: ! 234: */ ! 235: void ! 236: in_putnetaddr(inp, name, which) ! 237: register struct inpcb *inp; ! 238: struct sockaddr_in *name; ! 239: int which; ! 240: { ! 241: switch (which) { ! 242: case TP_LOCAL: ! 243: bcopy((caddr_t)&name->sin_addr, ! 244: (caddr_t)&inp->inp_laddr, sizeof(struct in_addr)); ! 245: /* won't work if the dst address (name) is INADDR_ANY */ ! 246: ! 247: break; ! 248: case TP_FOREIGN: ! 249: if( name != (struct sockaddr_in *)0 ) { ! 250: bcopy((caddr_t)&name->sin_addr, ! 251: (caddr_t)&inp->inp_faddr, sizeof(struct in_addr)); ! 252: } ! 253: } ! 254: } ! 255: ! 256: /* ! 257: * NAME: in_putnetaddr() ! 258: * ! 259: * CALLED FROM: ! 260: * tp_input() when a connection is being established by an ! 261: * incoming CR_TPDU, and considered for interception. ! 262: * ! 263: * FUNCTION and ARGUMENTS: ! 264: * Compare a whole net addr from a struct sockaddr (name), ! 265: * with that implicitly stored in an inpcb (inp). ! 266: * The argument (which) takes values TP_LOCAL or TP_FOREIGN ! 267: * ! 268: * RETURNS: Nada ! 269: * ! 270: * SIDE EFFECTS: ! 271: * ! 272: * NOTES: ! 273: */ ! 274: in_cmpnetaddr(inp, name, which) ! 275: register struct inpcb *inp; ! 276: register struct sockaddr_in *name; ! 277: int which; ! 278: { ! 279: if (which == TP_LOCAL) { ! 280: if (name->sin_port && name->sin_port != inp->inp_lport) ! 281: return 0; ! 282: return (name->sin_addr.s_addr == inp->inp_laddr.s_addr); ! 283: } ! 284: if (name->sin_port && name->sin_port != inp->inp_fport) ! 285: return 0; ! 286: return (name->sin_addr.s_addr == inp->inp_faddr.s_addr); ! 287: } ! 288: ! 289: /* ! 290: * NAME: in_getnetaddr() ! 291: * ! 292: * CALLED FROM: ! 293: * pr_usrreq() PRU_SOCKADDR, PRU_ACCEPT, PRU_PEERADDR ! 294: * FUNCTION and ARGUMENTS: ! 295: * Copy a whole net addr from an inpcb (inp) into ! 296: * an mbuf (name); ! 297: * The argument (which) takes values TP_LOCAL or TP_FOREIGN. ! 298: * ! 299: * RETURNS: Nada ! 300: * ! 301: * SIDE EFFECTS: ! 302: * ! 303: * NOTES: ! 304: */ ! 305: ! 306: void ! 307: in_getnetaddr( inp, name, which) ! 308: register struct mbuf *name; ! 309: struct inpcb *inp; ! 310: int which; ! 311: { ! 312: register struct sockaddr_in *sin = mtod(name, struct sockaddr_in *); ! 313: bzero((caddr_t)sin, sizeof(*sin)); ! 314: switch (which) { ! 315: case TP_LOCAL: ! 316: sin->sin_addr = inp->inp_laddr; ! 317: sin->sin_port = inp->inp_lport; ! 318: break; ! 319: case TP_FOREIGN: ! 320: sin->sin_addr = inp->inp_faddr; ! 321: sin->sin_port = inp->inp_fport; ! 322: break; ! 323: default: ! 324: return; ! 325: } ! 326: name->m_len = sin->sin_len = sizeof (*sin); ! 327: sin->sin_family = AF_INET; ! 328: } ! 329: ! 330: /* ! 331: * NAME: tpip_mtu() ! 332: * ! 333: * CALLED FROM: ! 334: * tp_route_to() on incoming CR, CC, and pr_usrreq() for PRU_CONNECT ! 335: * ! 336: * FUNCTION, ARGUMENTS, and RETURN VALUE: ! 337: * ! 338: * Perform subnetwork dependent part of determining MTU information. ! 339: * It appears that setting a double pointer to the rtentry associated with ! 340: * the destination, and returning the header size for the network protocol ! 341: * suffices. ! 342: * ! 343: * SIDE EFFECTS: ! 344: * Sets tp_routep pointer in pcb. ! 345: * ! 346: * NOTES: ! 347: */ ! 348: ! 349: tpip_mtu(tpcb) ! 350: register struct tp_pcb *tpcb; ! 351: { ! 352: struct inpcb *inp = (struct inpcb *)tpcb->tp_npcb; ! 353: ! 354: IFDEBUG(D_CONN) ! 355: printf("tpip_mtu(tpcb)\n", tpcb); ! 356: printf("tpip_mtu routing to addr 0x%x\n", inp->inp_faddr.s_addr); ! 357: ENDDEBUG ! 358: tpcb->tp_routep = &(inp->inp_route.ro_rt); ! 359: return (sizeof (struct ip)); ! 360: ! 361: } ! 362: ! 363: /* ! 364: * NAME: tpip_output() ! 365: * ! 366: * CALLED FROM: tp_emit() ! 367: * ! 368: * FUNCTION and ARGUMENTS: ! 369: * Take a packet(m0) from tp and package it so that ip will accept it. ! 370: * This means prepending space for the ip header and filling in a few ! 371: * of the fields. ! 372: * inp is the inpcb structure; datalen is the length of the data in the ! 373: * mbuf string m0. ! 374: * RETURNS: ! 375: * whatever (E*) is returned form the net layer output routine. ! 376: * ! 377: * SIDE EFFECTS: ! 378: * ! 379: * NOTES: ! 380: */ ! 381: ! 382: int ! 383: tpip_output(inp, m0, datalen, nochksum) ! 384: struct inpcb *inp; ! 385: struct mbuf *m0; ! 386: int datalen; ! 387: int nochksum; ! 388: { ! 389: return tpip_output_dg( &inp->inp_laddr, &inp->inp_faddr, m0, datalen, ! 390: &inp->inp_route, nochksum); ! 391: } ! 392: ! 393: /* ! 394: * NAME: tpip_output_dg() ! 395: * ! 396: * CALLED FROM: tp_error_emit() ! 397: * ! 398: * FUNCTION and ARGUMENTS: ! 399: * This is a copy of tpip_output that takes the addresses ! 400: * instead of a pcb. It's used by the tp_error_emit, when we ! 401: * don't have an in_pcb with which to call the normal output rtn. ! 402: * ! 403: * RETURNS: ENOBUFS or whatever (E*) is ! 404: * returned form the net layer output routine. ! 405: * ! 406: * SIDE EFFECTS: ! 407: * ! 408: * NOTES: ! 409: */ ! 410: ! 411: /*ARGSUSED*/ ! 412: int ! 413: tpip_output_dg(laddr, faddr, m0, datalen, ro, nochksum) ! 414: struct in_addr *laddr, *faddr; ! 415: struct mbuf *m0; ! 416: int datalen; ! 417: struct route *ro; ! 418: int nochksum; ! 419: { ! 420: register struct mbuf *m; ! 421: register struct ip *ip; ! 422: int error; ! 423: ! 424: IFDEBUG(D_EMIT) ! 425: printf("tpip_output_dg datalen 0x%x m0 0x%x\n", datalen, m0); ! 426: ENDDEBUG ! 427: ! 428: ! 429: MGETHDR(m, M_DONTWAIT, TPMT_IPHDR); ! 430: if (m == 0) { ! 431: error = ENOBUFS; ! 432: goto bad; ! 433: } ! 434: m->m_next = m0; ! 435: MH_ALIGN(m, sizeof(struct ip)); ! 436: m->m_len = sizeof(struct ip); ! 437: ! 438: ip = mtod(m, struct ip *); ! 439: bzero((caddr_t)ip, sizeof *ip); ! 440: ! 441: ip->ip_p = IPPROTO_TP; ! 442: m->m_pkthdr.len = ip->ip_len = sizeof(struct ip) + datalen; ! 443: ip->ip_ttl = MAXTTL; ! 444: /* don't know why you need to set ttl; ! 445: * overlay doesn't even make this available ! 446: */ ! 447: ! 448: ip->ip_src = *laddr; ! 449: ip->ip_dst = *faddr; ! 450: ! 451: IncStat(ts_tpdu_sent); ! 452: IFDEBUG(D_EMIT) ! 453: dump_mbuf(m, "tpip_output_dg before ip_output\n"); ! 454: ENDDEBUG ! 455: ! 456: error = ip_output(m, (struct mbuf *)0, ro, IP_ALLOWBROADCAST, NULL); ! 457: ! 458: IFDEBUG(D_EMIT) ! 459: printf("tpip_output_dg after ip_output\n"); ! 460: ENDDEBUG ! 461: ! 462: return error; ! 463: ! 464: bad: ! 465: m_freem(m); ! 466: IncStat(ts_send_drop); ! 467: return error; ! 468: } ! 469: ! 470: /* ! 471: * NAME: tpip_input() ! 472: * ! 473: * CALLED FROM: ! 474: * ip's input routine, indirectly through the protosw. ! 475: * ! 476: * FUNCTION and ARGUMENTS: ! 477: * Take a packet (m) from ip, strip off the ip header and give it to tp ! 478: * ! 479: * RETURNS: No return value. ! 480: * ! 481: * SIDE EFFECTS: ! 482: * ! 483: * NOTES: ! 484: */ ! 485: ProtoHook ! 486: tpip_input(m, iplen) ! 487: struct mbuf *m; ! 488: int iplen; ! 489: { ! 490: struct sockaddr_in src, dst; ! 491: register struct ip *ip; ! 492: int s = splnet(), hdrlen; ! 493: ! 494: IncStat(ts_pkt_rcvd); ! 495: ! 496: /* ! 497: * IP layer has already pulled up the IP header, ! 498: * but the first byte after the IP header may not be there, ! 499: * e.g. if you came in via loopback, so you have to do an ! 500: * m_pullup to before you can even look to see how much you ! 501: * really need. The good news is that m_pullup will round ! 502: * up to almost the next mbuf's worth. ! 503: */ ! 504: ! 505: ! 506: if((m = m_pullup(m, iplen + 1)) == MNULL) ! 507: goto discard; ! 508: CHANGE_MTYPE(m, TPMT_DATA); ! 509: ! 510: /* ! 511: * Now pull up the whole tp header: ! 512: * Unfortunately, there may be IP options to skip past so we ! 513: * just fetch it as an unsigned char. ! 514: */ ! 515: hdrlen = iplen + 1 + mtod(m, u_char *)[iplen]; ! 516: ! 517: if( m->m_len < hdrlen ) { ! 518: if((m = m_pullup(m, hdrlen)) == MNULL){ ! 519: IFDEBUG(D_TPINPUT) ! 520: printf("tp_input, pullup 2!\n"); ! 521: ENDDEBUG ! 522: goto discard; ! 523: } ! 524: } ! 525: /* ! 526: * cannot use tp_inputprep() here 'cause you don't ! 527: * have quite the same situation ! 528: */ ! 529: ! 530: IFDEBUG(D_TPINPUT) ! 531: dump_mbuf(m, "after tpip_input both pullups"); ! 532: ENDDEBUG ! 533: /* ! 534: * m_pullup may have returned a different mbuf ! 535: */ ! 536: ip = mtod(m, struct ip *); ! 537: ! 538: /* ! 539: * drop the ip header from the front of the mbuf ! 540: * this is necessary for the tp checksum ! 541: */ ! 542: m->m_len -= iplen; ! 543: m->m_data += iplen; ! 544: ! 545: src.sin_addr = *(struct in_addr *)&(ip->ip_src); ! 546: src.sin_family = AF_INET; ! 547: src.sin_len = sizeof(src); ! 548: dst.sin_addr = *(struct in_addr *)&(ip->ip_dst); ! 549: dst.sin_family = AF_INET; ! 550: dst.sin_len = sizeof(dst); ! 551: ! 552: (void) tp_input(m, (struct sockaddr *)&src, (struct sockaddr *)&dst, ! 553: 0, tpip_output_dg, 0); ! 554: return 0; ! 555: ! 556: discard: ! 557: IFDEBUG(D_TPINPUT) ! 558: printf("tpip_input DISCARD\n"); ! 559: ENDDEBUG ! 560: IFTRACE(D_TPINPUT) ! 561: tptrace(TPPTmisc, "tpip_input DISCARD m", m,0,0,0); ! 562: ENDTRACE ! 563: m_freem(m); ! 564: IncStat(ts_recv_drop); ! 565: splx(s); ! 566: return 0; ! 567: } ! 568: ! 569: ! 570: #include <sys/protosw.h> ! 571: #include <netinet/ip_icmp.h> ! 572: ! 573: extern void tp_quench(); ! 574: /* ! 575: * NAME: tpin_quench() ! 576: * ! 577: * CALLED FROM: tpip_ctlinput() ! 578: * ! 579: * FUNCTION and ARGUMENTS: find the tpcb pointer and pass it to tp_quench ! 580: * ! 581: * RETURNS: Nada ! 582: * ! 583: * SIDE EFFECTS: ! 584: * ! 585: * NOTES: ! 586: */ ! 587: ! 588: void ! 589: tpin_quench(inp) ! 590: struct inpcb *inp; ! 591: { ! 592: tp_quench((struct tp_pcb *)inp->inp_socket->so_pcb, PRC_QUENCH); ! 593: } ! 594: ! 595: /* ! 596: * NAME: tpip_ctlinput() ! 597: * ! 598: * CALLED FROM: ! 599: * The network layer through the protosw table. ! 600: * ! 601: * FUNCTION and ARGUMENTS: ! 602: * When clnp gets an ICMP msg this gets called. ! 603: * It either returns an error status to the user or ! 604: * causes all connections on this address to be aborted ! 605: * by calling the appropriate xx_notify() routine. ! 606: * (cmd) is the type of ICMP error. ! 607: * (sa) the address of the sender ! 608: * ! 609: * RETURNS: Nothing ! 610: * ! 611: * SIDE EFFECTS: ! 612: * ! 613: * NOTES: ! 614: */ ! 615: ProtoHook ! 616: tpip_ctlinput(cmd, sin) ! 617: int cmd; ! 618: struct sockaddr_in *sin; ! 619: { ! 620: extern u_char inetctlerrmap[]; ! 621: extern struct in_addr zeroin_addr; ! 622: void tp_quench __P((struct inpcb *,int)); ! 623: void tpin_abort __P((struct inpcb *,int)); ! 624: ! 625: if (sin->sin_family != AF_INET && sin->sin_family != AF_IMPLINK) ! 626: return 0; ! 627: if (sin->sin_addr.s_addr == INADDR_ANY) ! 628: return 0; ! 629: if (cmd < 0 || cmd > PRC_NCMDS) ! 630: return 0; ! 631: switch (cmd) { ! 632: ! 633: case PRC_QUENCH: ! 634: in_pcbnotify(&tp_inpcb, (struct sockaddr *)sin, 0, ! 635: zeroin_addr, 0, cmd, tp_quench); ! 636: break; ! 637: ! 638: case PRC_ROUTEDEAD: ! 639: case PRC_HOSTUNREACH: ! 640: case PRC_UNREACH_NET: ! 641: case PRC_IFDOWN: ! 642: case PRC_HOSTDEAD: ! 643: in_pcbnotify(&tp_inpcb, (struct sockaddr *)sin, 0, ! 644: zeroin_addr, 0, cmd, in_rtchange); ! 645: break; ! 646: ! 647: default: ! 648: /* ! 649: case PRC_MSGSIZE: ! 650: case PRC_UNREACH_HOST: ! 651: case PRC_UNREACH_PROTOCOL: ! 652: case PRC_UNREACH_PORT: ! 653: case PRC_UNREACH_NEEDFRAG: ! 654: case PRC_UNREACH_SRCFAIL: ! 655: case PRC_REDIRECT_NET: ! 656: case PRC_REDIRECT_HOST: ! 657: case PRC_REDIRECT_TOSNET: ! 658: case PRC_REDIRECT_TOSHOST: ! 659: case PRC_TIMXCEED_INTRANS: ! 660: case PRC_TIMXCEED_REASS: ! 661: case PRC_PARAMPROB: ! 662: */ ! 663: in_pcbnotify(&tp_inpcb, (struct sockaddr *)sin, 0, ! 664: zeroin_addr, 0, cmd, tpin_abort); ! 665: } ! 666: return 0; ! 667: } ! 668: ! 669: /* ! 670: * NAME: tpin_abort() ! 671: * ! 672: * CALLED FROM: ! 673: * xxx_notify() from tp_ctlinput() when ! 674: * net level gets some ICMP-equiv. type event. ! 675: * ! 676: * FUNCTION and ARGUMENTS: ! 677: * Cause the connection to be aborted with some sort of error ! 678: * reason indicating that the network layer caused the abort. ! 679: * Fakes an ER TPDU so we can go through the driver. ! 680: * ! 681: * RETURNS: Nothing ! 682: * ! 683: * SIDE EFFECTS: ! 684: * ! 685: * NOTES: ! 686: */ ! 687: ! 688: ProtoHook ! 689: tpin_abort(inp) ! 690: struct inpcb *inp; ! 691: { ! 692: struct tp_event e; ! 693: ! 694: e.ev_number = ER_TPDU; ! 695: e.ATTR(ER_TPDU).e_reason = ENETRESET; ! 696: (void) tp_driver((struct tp_pcb *)inp->inp_ppcb, &e); ! 697: return 0; ! 698: } ! 699: ! 700: #ifdef ARGO_DEBUG ! 701: dump_inaddr(addr) ! 702: register struct sockaddr_in *addr; ! 703: { ! 704: printf("INET: port 0x%x; addr 0x%x\n", addr->sin_port, addr->sin_addr); ! 705: } ! 706: #endif /* ARGO_DEBUG */ ! 707: #endif /* INET */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.