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