No empty .Rs/.Re
[netbsd-mini2440.git] / sys / netiso / tp_iso.c
blob6d0823a86d8b4a65944230023c06831f475a146b
1 /* $NetBSD: tp_iso.c,v 1.33 2009/03/18 15:14:32 cegger Exp $ */
3 /*-
4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
31 * @(#)tp_iso.c 8.2 (Berkeley) 9/22/94
34 /***********************************************************
35 Copyright IBM Corporation 1987
37 All Rights Reserved
39 Permission to use, copy, modify, and distribute this software and its
40 documentation for any purpose and without fee is hereby granted,
41 provided that the above copyright notice appear in all copies and that
42 both that copyright notice and this permission notice appear in
43 supporting documentation, and that the name of IBM not be
44 used in advertising or publicity pertaining to distribution of the
45 software without specific, written prior permission.
47 IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
48 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
49 IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
50 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
51 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
52 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 SOFTWARE.
55 ******************************************************************/
58 * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
61 * Here is where you find the iso-dependent code. We've tried keep all
62 * net-level and (primarily) address-family-dependent stuff out of the tp
63 * source, and everthing here is reached indirectly through a switch table
64 * (struct nl_protosw *) tpcb->tp_nlproto (see tp_pcb.c). The routines here
65 * are: iso_getsufx: gets transport suffix out of an isopcb structure.
66 * iso_putsufx: put transport suffix into an isopcb structure.
67 * iso_putnetaddr: put a whole net addr into an isopcb. iso_getnetaddr: get a
68 * whole net addr from an isopcb. iso_cmpnetaddr: compare a whole net addr
69 * from an isopcb. iso_recycle_suffix: clear suffix for reuse in isopcb
70 * tpclnp_ctlinput: handle ER CNLPdu : icmp-like stuff tpclnp_mtu: figure out
71 * what size tpdu to use tpclnp_input: take a pkt from clnp, strip off its
72 * clnp header, give to tp tpclnp_output_dg: package a pkt for clnp given 2
73 * addresses & some data tpclnp_output: package a pkt for clnp given an
74 * isopcb & some data
77 #include <sys/cdefs.h>
78 __KERNEL_RCSID(0, "$NetBSD: tp_iso.c,v 1.33 2009/03/18 15:14:32 cegger Exp $");
80 #include "opt_iso.h"
81 #ifdef ISO
83 #include <sys/param.h>
84 #include <sys/socket.h>
85 #include <sys/socketvar.h>
86 #include <sys/domain.h>
87 #include <sys/malloc.h>
88 #include <sys/mbuf.h>
89 #include <sys/errno.h>
90 #include <sys/time.h>
91 #include <sys/protosw.h>
92 #include <sys/systm.h>
93 #include <sys/kernel.h>
95 #include <net/if.h>
96 #include <net/route.h>
98 #include <netiso/argo_debug.h>
99 #include <netiso/tp_param.h>
100 #include <netiso/tp_stat.h>
101 #include <netiso/tp_pcb.h>
102 #include <netiso/tp_trace.h>
103 #include <netiso/tp_tpdu.h>
104 #include <netiso/tp_clnp.h>
105 #include <netiso/tp_var.h>
106 #include <netiso/cltp_var.h>
107 #include <netiso/idrp_var.h>
109 #include <machine/stdarg.h>
112 * CALLED FROM:
113 * pr_usrreq() on PRU_BIND, PRU_CONNECT, PRU_ACCEPT, and PRU_PEERADDR
114 * FUNCTION, ARGUMENTS:
115 * The argument (which) takes the value TP_LOCAL or TP_FOREIGN.
118 void
119 iso_getsufx(void *v, u_short *lenp, void *data_out, int which)
121 struct isopcb *isop = v;
122 struct sockaddr_iso *addr = 0;
124 switch (which) {
125 case TP_LOCAL:
126 addr = isop->isop_laddr;
127 break;
129 case TP_FOREIGN:
130 addr = isop->isop_faddr;
132 if (addr)
133 bcopy(TSEL(addr), data_out, (*lenp = addr->siso_tlen));
137 * CALLED FROM: tp_newsocket(); i.e., when a connection is being established
138 * by an incoming CR_TPDU.
140 * FUNCTION, ARGUMENTS: Put a transport suffix (found in name) into an isopcb
141 * structure (isop). The argument (which) takes the value TP_LOCAL or
142 * TP_FOREIGN.
144 void
145 iso_putsufx(void *v, void *sufxloc, int sufxlen, int which)
147 struct isopcb *isop = v;
148 struct sockaddr_iso **dst, *backup;
149 struct sockaddr_iso *addr;
150 struct mbuf *m;
151 int len;
153 switch (which) {
154 default:
155 return;
157 case TP_LOCAL:
158 dst = &isop->isop_laddr;
159 backup = &isop->isop_sladdr;
160 break;
162 case TP_FOREIGN:
163 dst = &isop->isop_faddr;
164 backup = &isop->isop_sfaddr;
166 if ((addr = *dst) == 0) {
167 addr = *dst = backup;
168 addr->siso_nlen = 0;
169 addr->siso_slen = 0;
170 addr->siso_plen = 0;
171 printf("iso_putsufx on un-initialized isopcb\n");
173 len = sufxlen + addr->siso_nlen +
174 (sizeof(*addr) - sizeof(addr->siso_data));
175 if (addr == backup) {
176 if (len > sizeof(*addr)) {
177 m = m_getclr(M_DONTWAIT, MT_SONAME);
178 if (m == 0)
179 return;
180 addr = *dst = mtod(m, struct sockaddr_iso *);
181 *addr = *backup;
182 m->m_len = len;
185 memcpy(WRITABLE_TSEL(addr), sufxloc, sufxlen);
186 addr->siso_tlen = sufxlen;
187 addr->siso_len = len;
191 * CALLED FROM:
192 * tp.trans whenever we go into REFWAIT state.
193 * FUNCTION and ARGUMENT:
194 * Called when a ref is frozen, to allow the suffix to be reused.
195 * (isop) is the net level pcb. This really shouldn't have to be
196 * done in a NET level pcb but... for the internet world that just
197 * the way it is done in BSD...
198 * The alternative is to have the port unusable until the reference
199 * timer goes off.
201 void
202 iso_recycle_tsuffix(void *v)
204 struct isopcb *isop = v;
205 isop->isop_laddr->siso_tlen = isop->isop_faddr->siso_tlen = 0;
209 * CALLED FROM:
210 * tp_newsocket(); i.e., when a connection is being established by an
211 * incoming CR_TPDU.
213 * FUNCTION and ARGUMENTS:
214 * Copy a whole net addr from a struct sockaddr (name).
215 * into an isopcb (isop).
216 * The argument (which) takes values TP_LOCAL or TP_FOREIGN
218 void
219 iso_putnetaddr(void *v, struct sockaddr *nm, int which)
221 struct isopcb *isop = v;
222 struct sockaddr_iso *name = (struct sockaddr_iso *) nm;
223 struct sockaddr_iso **sisop, *backup;
224 struct sockaddr_iso *siso;
226 switch (which) {
227 default:
228 printf("iso_putnetaddr: should panic\n");
229 return;
230 case TP_LOCAL:
231 sisop = &isop->isop_laddr;
232 backup = &isop->isop_sladdr;
233 break;
234 case TP_FOREIGN:
235 sisop = &isop->isop_faddr;
236 backup = &isop->isop_sfaddr;
238 siso = ((*sisop == 0) ? (*sisop = backup) : *sisop);
239 #ifdef ARGO_DEBUG
240 if (argo_debug[D_TPISO]) {
241 printf("ISO_PUTNETADDR\n");
242 dump_isoaddr(isop->isop_faddr);
244 #endif
245 siso->siso_addr = name->siso_addr;
249 * CALLED FROM:
250 * tp_input() when a connection is being established by an
251 * incoming CR_TPDU, and considered for interception.
253 * FUNCTION and ARGUMENTS:
254 * compare a whole net addr from a struct sockaddr (name),
255 * with that implicitly stored in an isopcb (isop).
256 * The argument (which) takes values TP_LOCAL or TP_FOREIGN.
259 iso_cmpnetaddr(void *v, struct sockaddr *nm, int which)
261 struct isopcb *isop = v;
262 struct sockaddr_iso *name = (struct sockaddr_iso *) nm;
263 struct sockaddr_iso **sisop, *backup;
264 struct sockaddr_iso *siso;
266 switch (which) {
267 default:
268 printf("iso_cmpnetaddr: should panic\n");
269 return 0;
270 case TP_LOCAL:
271 sisop = &isop->isop_laddr;
272 backup = &isop->isop_sladdr;
273 break;
274 case TP_FOREIGN:
275 sisop = &isop->isop_faddr;
276 backup = &isop->isop_sfaddr;
278 siso = ((*sisop == 0) ? (*sisop = backup) : *sisop);
279 #ifdef ARGO_DEBUG
280 if (argo_debug[D_TPISO]) {
281 printf("ISO_CMPNETADDR\n");
282 dump_isoaddr(siso);
284 #endif
285 if (name->siso_tlen && memcmp(TSEL(name), TSEL(siso), name->siso_tlen))
286 return (0);
287 return (memcmp((void *) name->siso_data,
288 (void *) siso->siso_data, name->siso_nlen) == 0);
292 * CALLED FROM:
293 * pr_usrreq() PRU_SOCKADDR, PRU_ACCEPT, PRU_PEERADDR
294 * FUNCTION and ARGUMENTS:
295 * Copy a whole net addr from an isopcb (isop) into
296 * a struct sockaddr (name).
297 * The argument (which) takes values TP_LOCAL or TP_FOREIGN.
300 void
301 iso_getnetaddr(void *v, struct mbuf *name, int which)
303 struct inpcb *inp = v;
304 struct isopcb *isop = (struct isopcb *) inp;
305 struct sockaddr_iso *siso =
306 (which == TP_LOCAL ? isop->isop_laddr : isop->isop_faddr);
307 if (siso)
308 bcopy((void *) siso, mtod(name, void *),
309 (unsigned) (name->m_len = siso->siso_len));
310 else
311 name->m_len = 0;
314 * NAME: tpclnp_mtu()
316 * CALLED FROM:
317 * tp_route_to() on incoming CR, CC, and pr_usrreq() for PRU_CONNECT
319 * FUNCTION, ARGUMENTS, and RETURN VALUE:
321 * Perform subnetwork dependent part of determining MTU information.
322 * It appears that setting a double pointer to the rtentry associated with
323 * the destination, and returning the header size for the network protocol
324 * suffices.
326 * SIDE EFFECTS:
327 * Sets tp_routep pointer in pcb.
329 * NOTES:
332 tpclnp_mtu(void *v)
334 struct tp_pcb *tpcb = v;
335 struct isopcb *isop = (struct isopcb *) tpcb->tp_npcb;
337 #ifdef ARGO_DEBUG
338 if (argo_debug[D_CONN]) {
339 printf("tpclnp_mtu(tpcb %p)\n", tpcb);
341 #endif
342 tpcb->tp_routep = &isop->isop_route;
343 if (tpcb->tp_netservice == ISO_CONS)
344 return 0;
345 return (sizeof(struct clnp_fixed) + sizeof(struct clnp_segment) +
346 2 * sizeof(struct iso_addr));
350 * CALLED FROM:
351 * tp_emit()
352 * FUNCTION and ARGUMENTS:
353 * Take a packet(m0) from tp and package it so that clnp will accept it.
354 * This means prepending space for the clnp header and filling in a few
355 * of the fields.
356 * isop is the isopcb structure; datalen is the length of the data in the
357 * mbuf string m0.
358 * RETURN VALUE:
359 * whatever (E*) is returned form the net layer output routine.
363 tpclnp_output(struct mbuf *m0, ...)
365 int datalen;
366 struct isopcb *isop;
367 int nochksum;
368 va_list ap;
370 va_start(ap, m0);
371 datalen = va_arg(ap, int);
372 isop = va_arg(ap, struct isopcb *);
373 nochksum = va_arg(ap, int);
374 va_end(ap);
376 IncStat(ts_tpdu_sent);
378 #ifdef ARGO_DEBUG
379 if (argo_debug[D_TPISO]) {
380 struct tpdu *hdr = mtod(m0, struct tpdu *);
382 printf(
383 "abt to call clnp_output: datalen 0x%x, hdr.li 0x%x, hdr.dutype 0x%x nocsum x%x dst addr:\n",
384 datalen,
385 (int) hdr->tpdu_li, (int) hdr->tpdu_type, nochksum);
386 dump_isoaddr(isop->isop_faddr);
387 printf("\nsrc addr:\n");
388 dump_isoaddr(isop->isop_laddr);
389 dump_mbuf(m0, "at tpclnp_output");
391 #endif
393 return
394 clnp_output(m0, isop, datalen, /* flags */ nochksum ? CLNP_NO_CKSUM : 0);
398 * CALLED FROM:
399 * tp_error_emit()
400 * FUNCTION and ARGUMENTS:
401 * This is a copy of tpclnp_output that takes the addresses
402 * instead of a pcb. It's used by the tp_error_emit, when we
403 * don't have an iso_pcb with which to call the normal output rtn.
404 * RETURN VALUE:
405 * ENOBUFS or
406 * whatever (E*) is returned form the net layer output routine.
410 tpclnp_output_dg(struct mbuf *m0, ...)
412 struct isopcb tmppcb;
413 int err;
414 int flags;
415 int datalen;
416 struct iso_addr *laddr, *faddr;
417 struct route *ro;
418 int nochksum;
419 va_list ap;
421 va_start(ap, m0);
422 datalen = va_arg(ap, int);
423 laddr = va_arg(ap, struct iso_addr *);
424 faddr = va_arg(ap, struct iso_addr *);
425 ro = va_arg(ap, struct route *);
426 nochksum = va_arg(ap, int);
427 va_end(ap);
429 #ifdef ARGO_DEBUG
430 if (argo_debug[D_TPISO]) {
431 printf("tpclnp_output_dg datalen 0x%x m0 %p\n", datalen, m0);
433 #endif
436 * Fill in minimal portion of isopcb so that clnp can send the
437 * packet.
439 memset((void *) & tmppcb, 0, sizeof(tmppcb));
440 tmppcb.isop_laddr = &tmppcb.isop_sladdr;
441 tmppcb.isop_laddr->siso_addr = *laddr;
442 tmppcb.isop_faddr = &tmppcb.isop_sfaddr;
443 tmppcb.isop_faddr->siso_addr = *faddr;
445 #ifdef ARGO_DEBUG
446 if (argo_debug[D_TPISO]) {
447 printf("tpclnp_output_dg faddr: \n");
448 dump_isoaddr(&tmppcb.isop_sfaddr);
449 printf("\ntpclnp_output_dg laddr: \n");
450 dump_isoaddr(&tmppcb.isop_sladdr);
451 printf("\n");
453 #endif
456 * Do not use packet cache since this is a one shot error packet
458 flags = (CLNP_NOCACHE | (nochksum ? CLNP_NO_CKSUM : 0));
460 IncStat(ts_tpdu_sent);
462 err = clnp_output(m0, &tmppcb, datalen, flags);
465 * Free route allocated by clnp (if the route was indeed allocated)
467 rtcache_free(&tmppcb.isop_route);
469 return (err);
472 * CALLED FROM:
473 * clnp's input routine, indirectly through the protosw.
474 * FUNCTION and ARGUMENTS:
475 * Take a packet (m) from clnp, strip off the clnp header and give it to tp
476 * No return value.
478 void
479 tpclnp_input(struct mbuf *m, ...)
481 struct sockaddr_iso *src, *dst;
482 int clnp_len, ce_bit;
483 void (*input) (struct mbuf *, ...) = tp_input;
484 va_list ap;
486 va_start(ap, m);
487 src = va_arg(ap, struct sockaddr_iso *);
488 dst = va_arg(ap, struct sockaddr_iso *);
489 clnp_len = va_arg(ap, int);
490 ce_bit = va_arg(ap, int);
491 va_end(ap);
493 IncStat(ts_pkt_rcvd);
495 #ifdef ARGO_DEBUG
496 if (argo_debug[D_TPINPUT]) {
497 printf("tpclnp_input: m %p clnp_len 0x%x\n", m, clnp_len);
498 dump_mbuf(m, "at tpclnp_input");
500 #endif
502 * CLNP gives us an mbuf chain WITH the clnp header pulled up,
503 * and the length of the clnp header.
504 * First, strip off the Clnp header. leave the mbuf there for the
505 * pullup that follows.
507 m->m_len -= clnp_len;
508 m->m_data += clnp_len;
509 m->m_pkthdr.len -= clnp_len;
510 /* XXXX: should probably be in clnp_input */
511 switch (dst->siso_data[dst->siso_nlen - 1]) {
512 case 0:
513 if (m->m_len == 0 && (m = m_pullup(m, 1)) == 0)
514 return;
515 if (*(mtod(m, u_char *)) == ISO10747_IDRP) {
516 idrp_input(m, src, dst);
517 return;
520 m = tp_inputprep(m);
521 if (m == 0)
522 return;
523 if (mtod(m, u_char *)[1] == UD_TPDU_type)
524 input = cltp_input;
526 #ifdef ARGO_DEBUG
527 if (argo_debug[D_TPINPUT]) {
528 dump_mbuf(m, "after tpclnp_input both pullups");
530 #endif
532 #ifdef ARGO_DEBUG
533 if (argo_debug[D_TPISO]) {
534 printf("calling %sinput : src %p, dst %p, src addr:\n",
535 (input == tp_input ? "tp_" : "clts_"), src, dst);
536 dump_isoaddr(src);
537 printf(" dst addr:\n");
538 dump_isoaddr(dst);
540 #endif
542 (*input) (m, (struct sockaddr *) src, (struct sockaddr *) dst, 0,
543 tpclnp_output_dg, ce_bit);
545 #ifdef ARGO_DEBUG
546 if (argo_debug[D_QUENCH]) {{
547 struct timeval now;
549 getmicrotime(&now);
550 if (now.tv_usec & 0x4 && now.tv_usec & 0x40) {
551 printf("tpclnp_input: FAKING %s\n",
552 tp_stat.ts_pkt_rcvd & 0x1 ? "QUENCH" : "QUENCH2");
553 if (tp_stat.ts_pkt_rcvd & 0x1)
554 tpclnp_ctlinput(PRC_QUENCH,
555 (struct sockaddr *)
556 &src, NULL);
557 else
558 tpclnp_ctlinput(PRC_QUENCH2,
559 (struct sockaddr *)
560 &src, NULL);
564 #endif
567 /*ARGSUSED*/
568 void
569 iso_rtchange(struct isopcb *pcb)
575 * CALLED FROM:
576 * tpclnp_ctlinput()
577 * FUNCTION and ARGUMENTS:
578 * find the tpcb pointer and pass it to tp_quench
580 void
581 tpiso_decbit(struct isopcb *isop)
583 tp_quench((struct inpcb *) isop->isop_socket->so_pcb, PRC_QUENCH2);
586 * CALLED FROM:
587 * tpclnp_ctlinput()
588 * FUNCTION and ARGUMENTS:
589 * find the tpcb pointer and pass it to tp_quench
591 void
592 tpiso_quench(struct isopcb *isop)
594 tp_quench((struct inpcb *) isop->isop_socket->so_pcb, PRC_QUENCH);
598 * CALLED FROM:
599 * The network layer through the protosw table.
600 * FUNCTION and ARGUMENTS:
601 * When clnp an ICMP-like msg this gets called.
602 * It either returns an error status to the user or
603 * it causes all connections on this address to be aborted
604 * by calling the appropriate xx_notify() routine.
605 * (cmd) is the type of ICMP error.
606 * (siso) is the address of the guy who sent the ER CLNPDU
608 void *
609 tpclnp_ctlinput(int cmd, const struct sockaddr *sa, void *dummy)
611 const struct sockaddr_iso *siso = (const struct sockaddr_iso *)sa;
613 #ifdef ARGO_DEBUG
614 if (argo_debug[D_TPINPUT]) {
615 printf("tpclnp_ctlinput1: cmd 0x%x addr: \n", cmd);
616 dump_isoaddr(siso);
618 #endif
620 if ((unsigned)cmd >= PRC_NCMDS)
621 return NULL;
622 if (siso->siso_family != AF_ISO)
623 return NULL;
624 switch (cmd) {
626 case PRC_QUENCH2:
627 iso_pcbnotify(&tp_isopcb, siso, 0, tpiso_decbit);
628 break;
630 case PRC_QUENCH:
631 iso_pcbnotify(&tp_isopcb, siso, 0, tpiso_quench);
632 break;
634 case PRC_TIMXCEED_REASS:
635 case PRC_ROUTEDEAD:
636 iso_pcbnotify(&tp_isopcb, siso, 0, tpiso_reset);
637 break;
639 case PRC_HOSTUNREACH:
640 case PRC_UNREACH_NET:
641 case PRC_IFDOWN:
642 case PRC_HOSTDEAD:
643 iso_pcbnotify(&tp_isopcb, siso,
644 (int) isoctlerrmap[cmd], iso_rtchange);
645 break;
647 default:
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_PARAMPROB:
662 iso_pcbnotify(&tp_isopcb, siso, (int) isoctlerrmap[cmd], tpiso_abort);
663 break;
665 return NULL;
668 * XXX - Variant which is called by clnp_er.c with an isoaddr rather
669 * than a sockaddr_iso.
672 static struct sockaddr_iso siso = {
673 .siso_len = sizeof(siso),
674 .siso_family = AF_ISO,
676 void
677 tpclnp_ctlinput1(int cmd, struct iso_addr *isoa)
679 memset((void *) & siso.siso_addr, 0, sizeof(siso.siso_addr));
680 bcopy((void *) isoa, (void *) & siso.siso_addr, isoa->isoa_len);
681 tpclnp_ctlinput(cmd, (struct sockaddr *) &siso, NULL);
685 * These next 2 routines are
686 * CALLED FROM:
687 * xxx_notify() from tp_ctlinput() when
688 * net level gets some ICMP-equiv. type event.
689 * FUNCTION and ARGUMENTS:
690 * Cause the connection to be aborted with some sort of error
691 * reason indicating that the network layer caused the abort.
692 * Fakes an ER TPDU so we can go through the driver.
693 * abort always aborts the TP connection.
694 * reset may or may not, depending on the TP class that's in use.
696 void
697 tpiso_abort(struct isopcb *isop)
699 struct tp_event e;
701 #ifdef ARGO_DEBUG
702 if (argo_debug[D_CONN]) {
703 printf("tpiso_abort %p\n", isop);
705 #endif
706 e.ev_number = ER_TPDU;
707 e.TPDU_ATTR(ER).e_reason = ECONNABORTED;
708 tp_driver((struct tp_pcb *) isop->isop_socket->so_pcb, &e);
711 void
712 tpiso_reset(struct isopcb *isop)
714 struct tp_event e;
716 e.ev_number = T_NETRESET;
717 tp_driver((struct tp_pcb *) isop->isop_socket->so_pcb, &e);
721 #endif /* ISO */