ec_rxstart doesn't eists
[unix-history] / usr / src / sys / netiso / tp_iso.c
CommitLineData
7bcd1bb8
KB
1/*-
2 * Copyright (c) 1991 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 *
f501b4b9 7 * @(#)tp_iso.c 7.13 (Berkeley) %G%
7bcd1bb8
KB
8 */
9
238ab140
KS
10/***********************************************************
11 Copyright IBM Corporation 1987
12
13 All Rights Reserved
14
15Permission to use, copy, modify, and distribute this software and its
16documentation for any purpose and without fee is hereby granted,
17provided that the above copyright notice appear in all copies and that
18both that copyright notice and this permission notice appear in
19supporting documentation, and that the name of IBM not be
20used in advertising or publicity pertaining to distribution of the
21software without specific, written prior permission.
22
23IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
24ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
25IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
26ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
27WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
28ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
29SOFTWARE.
30
31******************************************************************/
32
33/*
34 * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
35 */
36/*
37 * ARGO TP
a50e2bc0
KS
38 * $Header: /var/src/sys/netiso/RCS/tp_iso.c,v 5.1 89/02/09 16:20:51 hagens Exp $
39 * $Source: /var/src/sys/netiso/RCS/tp_iso.c,v $
238ab140
KS
40 *
41 * Here is where you find the iso-dependent code. We've tried
42 * keep all net-level and (primarily) address-family-dependent stuff
43 * out of the tp source, and everthing here is reached indirectly
44 * through a switch table (struct nl_protosw *) tpcb->tp_nlproto
45 * (see tp_pcb.c).
46 * The routines here are:
47 * iso_getsufx: gets transport suffix out of an isopcb structure.
48 * iso_putsufx: put transport suffix into an isopcb structure.
49 * iso_putnetaddr: put a whole net addr into an isopcb.
50 * iso_getnetaddr: get a whole net addr from an isopcb.
63f88aec 51 * iso_cmpnetaddr: compare a whole net addr from an isopcb.
238ab140
KS
52 * iso_recycle_suffix: clear suffix for reuse in isopcb
53 * tpclnp_ctlinput: handle ER CNLPdu : icmp-like stuff
54 * tpclnp_mtu: figure out what size tpdu to use
55 * tpclnp_input: take a pkt from clnp, strip off its clnp header,
56 * give to tp
57 * tpclnp_output_dg: package a pkt for clnp given 2 addresses & some data
58 * tpclnp_output: package a pkt for clnp given an isopcb & some data
59 */
60
238ab140
KS
61#ifdef ISO
62
a50e2bc0
KS
63#include "param.h"
64#include "socket.h"
65#include "socketvar.h"
66#include "domain.h"
67#include "malloc.h"
68#include "mbuf.h"
69#include "errno.h"
70#include "time.h"
71#include "protosw.h"
72
238ab140
KS
73#include "../net/if.h"
74#include "../net/route.h"
238ab140 75
a50e2bc0
KS
76#include "argo_debug.h"
77#include "tp_param.h"
78#include "tp_stat.h"
79#include "tp_pcb.h"
80#include "tp_trace.h"
81#include "tp_stat.h"
82#include "tp_tpdu.h"
83#include "tp_clnp.h"
c0dbf2a0 84#include "cltp_var.h"
238ab140
KS
85
86/*
87 * CALLED FROM:
88 * pr_usrreq() on PRU_BIND, PRU_CONNECT, PRU_ACCEPT, and PRU_PEERADDR
a50e2bc0 89 * FUNCTION, ARGUMENTS:
238ab140
KS
90 * The argument (which) takes the value TP_LOCAL or TP_FOREIGN.
91 */
92
a50e2bc0 93iso_getsufx(isop, lenp, data_out, which)
238ab140 94 struct isopcb *isop;
a50e2bc0
KS
95 u_short *lenp;
96 caddr_t data_out;
238ab140
KS
97 int which;
98{
a50e2bc0
KS
99 register struct sockaddr_iso *addr = 0;
100
238ab140
KS
101 switch (which) {
102 case TP_LOCAL:
a50e2bc0
KS
103 addr = isop->isop_laddr;
104 break;
238ab140
KS
105
106 case TP_FOREIGN:
a50e2bc0 107 addr = isop->isop_faddr;
238ab140 108 }
a50e2bc0 109 if (addr)
44f52ea5 110 bcopy(TSEL(addr), data_out, (*lenp = addr->siso_tlen));
238ab140
KS
111}
112
113/* CALLED FROM:
114 * tp_newsocket(); i.e., when a connection is being established by an
115 * incoming CR_TPDU.
116 *
117 * FUNCTION, ARGUMENTS:
118 * Put a transport suffix (found in name) into an isopcb structure (isop).
119 * The argument (which) takes the value TP_LOCAL or TP_FOREIGN.
120 */
121void
a50e2bc0 122iso_putsufx(isop, sufxloc, sufxlen, which)
238ab140 123 struct isopcb *isop;
a50e2bc0
KS
124 caddr_t sufxloc;
125 int sufxlen, which;
238ab140 126{
a50e2bc0
KS
127 struct sockaddr_iso **dst, *backup;
128 register struct sockaddr_iso *addr;
129 struct mbuf *m;
130 int len;
131
238ab140 132 switch (which) {
a50e2bc0
KS
133 default:
134 return;
135
238ab140 136 case TP_LOCAL:
a50e2bc0
KS
137 dst = &isop->isop_laddr;
138 backup = &isop->isop_sladdr;
238ab140 139 break;
a50e2bc0 140
238ab140 141 case TP_FOREIGN:
a50e2bc0
KS
142 dst = &isop->isop_faddr;
143 backup = &isop->isop_sfaddr;
144 }
145 if ((addr = *dst) == 0) {
146 addr = *dst = backup;
147 addr->siso_nlen = 0;
44f52ea5
KS
148 addr->siso_slen = 0;
149 addr->siso_plen = 0;
a50e2bc0 150 printf("iso_putsufx on un-initialized isopcb\n");
238ab140 151 }
a50e2bc0 152 len = sufxlen + addr->siso_nlen +
44f52ea5 153 (sizeof(*addr) - sizeof(addr->siso_data));
a50e2bc0 154 if (addr == backup) {
44f52ea5 155 if (len > sizeof(*addr)) {
a50e2bc0
KS
156 m = m_getclr(M_DONTWAIT, MT_SONAME);
157 if (m == 0)
158 return;
159 addr = *dst = mtod(m, struct sockaddr_iso *);
160 *addr = *backup;
161 m->m_len = len;
162 }
44f52ea5 163 }
a50e2bc0 164 bcopy(sufxloc, TSEL(addr), sufxlen);
44f52ea5 165 addr->siso_tlen = sufxlen;
a50e2bc0 166 addr->siso_len = len;
238ab140
KS
167}
168
169/*
170 * CALLED FROM:
171 * tp.trans whenever we go into REFWAIT state.
172 * FUNCTION and ARGUMENT:
173 * Called when a ref is frozen, to allow the suffix to be reused.
174 * (isop) is the net level pcb. This really shouldn't have to be
175 * done in a NET level pcb but... for the internet world that just
176 * the way it is done in BSD...
177 * The alternative is to have the port unusable until the reference
178 * timer goes off.
179 */
180void
181iso_recycle_tsuffix(isop)
182 struct isopcb *isop;
183{
44f52ea5 184 isop->isop_laddr->siso_tlen = isop->isop_faddr->siso_tlen = 0;
238ab140
KS
185}
186
187/*
188 * CALLED FROM:
189 * tp_newsocket(); i.e., when a connection is being established by an
190 * incoming CR_TPDU.
191 *
192 * FUNCTION and ARGUMENTS:
193 * Copy a whole net addr from a struct sockaddr (name).
194 * into an isopcb (isop).
195 * The argument (which) takes values TP_LOCAL or TP_FOREIGN
196 */
197void
198iso_putnetaddr(isop, name, which)
199 register struct isopcb *isop;
200 struct sockaddr_iso *name;
201 int which;
202{
a50e2bc0
KS
203 struct sockaddr_iso **sisop, *backup;
204 register struct sockaddr_iso *siso;
205
238ab140 206 switch (which) {
63f88aec
KS
207 default:
208 printf("iso_putnetaddr: should panic\n");
209 return;
238ab140 210 case TP_LOCAL:
a50e2bc0
KS
211 sisop = &isop->isop_laddr;
212 backup = &isop->isop_sladdr;
238ab140
KS
213 break;
214 case TP_FOREIGN:
a50e2bc0
KS
215 sisop = &isop->isop_faddr;
216 backup = &isop->isop_sfaddr;
238ab140 217 }
a50e2bc0
KS
218 siso = ((*sisop == 0) ? (*sisop = backup) : *sisop);
219 IFDEBUG(D_TPISO)
220 printf("ISO_PUTNETADDR\n");
221 dump_isoaddr(isop->isop_faddr);
222 ENDDEBUG
223 siso->siso_addr = name->siso_addr;
238ab140
KS
224}
225
63f88aec
KS
226/*
227 * CALLED FROM:
228 * tp_input() when a connection is being established by an
229 * incoming CR_TPDU, and considered for interception.
230 *
231 * FUNCTION and ARGUMENTS:
232 * compare a whole net addr from a struct sockaddr (name),
233 * with that implicitly stored in an isopcb (isop).
234 * The argument (which) takes values TP_LOCAL or TP_FOREIGN.
235 */
236iso_cmpnetaddr(isop, name, which)
237 register struct isopcb *isop;
238 register struct sockaddr_iso *name;
239 int which;
240{
241 struct sockaddr_iso **sisop, *backup;
242 register struct sockaddr_iso *siso;
243
244 switch (which) {
245 default:
246 printf("iso_cmpnetaddr: should panic\n");
247 return 0;
248 case TP_LOCAL:
249 sisop = &isop->isop_laddr;
250 backup = &isop->isop_sladdr;
251 break;
252 case TP_FOREIGN:
253 sisop = &isop->isop_faddr;
254 backup = &isop->isop_sfaddr;
255 }
256 siso = ((*sisop == 0) ? (*sisop = backup) : *sisop);
257 IFDEBUG(D_TPISO)
258 printf("ISO_CMPNETADDR\n");
259 dump_isoaddr(siso);
260 ENDDEBUG
261 if (name->siso_tlen && bcmp(TSEL(name), TSEL(siso), name->siso_tlen))
262 return (0);
263 return (bcmp((caddr_t)name->siso_data,
264 (caddr_t)siso->siso_data, name->siso_nlen) == 0);
265}
266
238ab140
KS
267/*
268 * CALLED FROM:
269 * pr_usrreq() PRU_SOCKADDR, PRU_ACCEPT, PRU_PEERADDR
270 * FUNCTION and ARGUMENTS:
271 * Copy a whole net addr from an isopcb (isop) into
272 * a struct sockaddr (name).
273 * The argument (which) takes values TP_LOCAL or TP_FOREIGN.
274 */
275
276void
277iso_getnetaddr( isop, name, which)
278 struct isopcb *isop;
a50e2bc0 279 struct mbuf *name;
238ab140
KS
280 int which;
281{
a50e2bc0
KS
282 struct sockaddr_iso *siso =
283 (which == TP_LOCAL ? isop->isop_laddr : isop->isop_faddr);
284 if (siso)
285 bcopy((caddr_t)siso, mtod(name, caddr_t),
286 (unsigned)(name->m_len = siso->siso_len));
287 else
288 name->m_len = 0;
238ab140 289}
238ab140 290/*
f501b4b9
KS
291 * NAME: tpclnp_mtu()
292 *
238ab140 293 * CALLED FROM:
f501b4b9
KS
294 * tp_route_to() on incoming CR, CC, and pr_usrreq() for PRU_CONNECT
295 *
296 * FUNCTION, ARGUMENTS, and RETURN VALUE:
238ab140 297 *
f501b4b9
KS
298 * Perform subnetwork dependent part of determining MTU information.
299 * It appears that setting a double pointer to the rtentry associated with
300 * the destination, and returning the header size for the network protocol
301 * suffices.
238ab140 302 *
f501b4b9
KS
303 * SIDE EFFECTS:
304 * Sets tp_routep pointer in pcb.
305 *
306 * NOTES:
238ab140 307 */
f501b4b9
KS
308tpclnp_mtu(tpcb)
309register struct tp_pcb *tpcb;
238ab140 310{
f501b4b9 311 struct isopcb *isop = (struct isopcb *)tpcb->tp_npcb;
238ab140
KS
312
313 IFDEBUG(D_CONN)
f501b4b9 314 printf("tpclnp_mtu(tpcb)\n", tpcb);
238ab140 315 ENDDEBUG
f501b4b9
KS
316 tpcb->tp_routep = &(isop->isop_route.ro_rt);
317 if (tpcb->tp_netservice == ISO_CONS)
318 return 0;
319 else
320 return (sizeof(struct clnp_fixed) + sizeof(struct clnp_segment) +
321 2 * sizeof(struct iso_addr));
238ab140 322
238ab140
KS
323}
324
238ab140
KS
325/*
326 * CALLED FROM:
327 * tp_emit()
328 * FUNCTION and ARGUMENTS:
329 * Take a packet(m0) from tp and package it so that clnp will accept it.
330 * This means prepending space for the clnp header and filling in a few
331 * of the fields.
f501b4b9 332 * isop is the isopcb structure; datalen is the length of the data in the
238ab140
KS
333 * mbuf string m0.
334 * RETURN VALUE:
335 * whatever (E*) is returned form the net layer output routine.
336 */
337
338int
339tpclnp_output(isop, m0, datalen, nochksum)
340 struct isopcb *isop;
341 struct mbuf *m0;
342 int datalen;
343 int nochksum;
344{
a50e2bc0 345 register struct mbuf *m = m0;
238ab140
KS
346 IncStat(ts_tpdu_sent);
347
348 IFDEBUG(D_TPISO)
349 struct tpdu *hdr = mtod(m0, struct tpdu *);
350
351 printf(
352"abt to call clnp_output: datalen 0x%x, hdr.li 0x%x, hdr.dutype 0x%x nocsum x%x dst addr:\n",
353 datalen,
354 (int)hdr->tpdu_li, (int)hdr->tpdu_type, nochksum);
a50e2bc0 355 dump_isoaddr(isop->isop_faddr);
238ab140 356 printf("\nsrc addr:\n");
a50e2bc0 357 dump_isoaddr(isop->isop_laddr);
238ab140
KS
358 dump_mbuf(m0, "at tpclnp_output");
359 ENDDEBUG
360
361 return
44f52ea5 362 clnp_output(m0, isop, datalen, /* flags */nochksum ? CLNP_NO_CKSUM : 0);
238ab140
KS
363}
364
365/*
366 * CALLED FROM:
367 * tp_error_emit()
368 * FUNCTION and ARGUMENTS:
369 * This is a copy of tpclnp_output that takes the addresses
370 * instead of a pcb. It's used by the tp_error_emit, when we
371 * don't have an iso_pcb with which to call the normal output rtn.
372 * RETURN VALUE:
373 * ENOBUFS or
374 * whatever (E*) is returned form the net layer output routine.
375 */
376
377int
378tpclnp_output_dg(laddr, faddr, m0, datalen, ro, nochksum)
379 struct iso_addr *laddr, *faddr;
380 struct mbuf *m0;
381 int datalen;
382 struct route *ro;
383 int nochksum;
384{
385 struct isopcb tmppcb;
238ab140
KS
386 int err;
387 int flags;
a50e2bc0 388 register struct mbuf *m = m0;
238ab140
KS
389
390 IFDEBUG(D_TPISO)
391 printf("tpclnp_output_dg datalen 0x%x m0 0x%x\n", datalen, m0);
392 ENDDEBUG
393
394 /*
395 * Fill in minimal portion of isopcb so that clnp can send the
396 * packet.
397 */
398 bzero((caddr_t)&tmppcb, sizeof(tmppcb));
a50e2bc0
KS
399 tmppcb.isop_laddr = &tmppcb.isop_sladdr;
400 tmppcb.isop_laddr->siso_addr = *laddr;
401 tmppcb.isop_faddr = &tmppcb.isop_sfaddr;
402 tmppcb.isop_faddr->siso_addr = *faddr;
238ab140
KS
403
404 IFDEBUG(D_TPISO)
405 printf("tpclnp_output_dg faddr: \n");
a50e2bc0 406 dump_isoaddr(&tmppcb.isop_sfaddr);
238ab140 407 printf("\ntpclnp_output_dg laddr: \n");
a50e2bc0 408 dump_isoaddr(&tmppcb.isop_sladdr);
238ab140
KS
409 printf("\n");
410 ENDDEBUG
411
412 /*
413 * Do not use packet cache since this is a one shot error packet
414 */
415 flags = (CLNP_NOCACHE|(nochksum?CLNP_NO_CKSUM:0));
416
417 IncStat(ts_tpdu_sent);
418
44f52ea5 419 err = clnp_output(m0, &tmppcb, datalen, flags);
238ab140
KS
420
421 /*
422 * Free route allocated by clnp (if the route was indeed allocated)
423 */
424 if (tmppcb.isop_route.ro_rt)
425 RTFREE(tmppcb.isop_route.ro_rt);
426
427 return(err);
428}
238ab140
KS
429/*
430 * CALLED FROM:
431 * clnp's input routine, indirectly through the protosw.
432 * FUNCTION and ARGUMENTS:
433 * Take a packet (m) from clnp, strip off the clnp header and give it to tp
434 * No return value.
435 */
436ProtoHook
e02c2019 437tpclnp_input(m, src, dst, clnp_len, ce_bit)
c0dbf2a0
KS
438 register struct mbuf *m;
439 struct sockaddr_iso *src, *dst;
e02c2019 440 int clnp_len, ce_bit;
238ab140 441{
238ab140 442 int s = splnet();
a50e2bc0 443 struct mbuf *tp_inputprep();
c0dbf2a0 444 int tp_input(), cltp_input(), (*input)() = tp_input;
238ab140
KS
445
446 IncStat(ts_pkt_rcvd);
447
448 IFDEBUG(D_TPINPUT)
449 printf("tpclnp_input: m 0x%x clnp_len 0x%x\n", m, clnp_len);
450 dump_mbuf(m, "at tpclnp_input");
451 ENDDEBUG
452 /*
453 * CLNP gives us an mbuf chain WITH the clnp header pulled up,
454 * and the length of the clnp header.
455 * First, strip off the Clnp header. leave the mbuf there for the
456 * pullup that follows.
457 */
458
459 m->m_len -= clnp_len;
a50e2bc0 460 m->m_data += clnp_len;
238ab140 461
a50e2bc0 462 m = tp_inputprep(m);
c0dbf2a0
KS
463 if (m == 0)
464 return 0;
465 if (mtod(m, u_char *)[1] == UD_TPDU_type)
466 input = cltp_input;
238ab140
KS
467
468 IFDEBUG(D_TPINPUT)
469 dump_mbuf(m, "after tpclnp_input both pullups");
470 ENDDEBUG
471
238ab140 472 IFDEBUG(D_TPISO)
c0dbf2a0
KS
473 printf("calling %sinput : src 0x%x, dst 0x%x, src addr:\n",
474 (input == tp_input ? "tp_" : "clts_"), src, dst);
475 dump_isoaddr(src);
238ab140 476 printf(" dst addr:\n");
c0dbf2a0 477 dump_isoaddr(dst);
238ab140
KS
478 ENDDEBUG
479
c0dbf2a0 480 (void) (*input)(m, (struct sockaddr *)src, (struct sockaddr *)dst,
e02c2019 481 0, tpclnp_output_dg, ce_bit);
238ab140
KS
482
483 IFDEBUG(D_QUENCH)
484 {
485 if(time.tv_usec & 0x4 && time.tv_usec & 0x40) {
486 printf("tpclnp_input: FAKING %s\n",
487 tp_stat.ts_pkt_rcvd & 0x1?"QUENCH":"QUENCH2");
488 if(tp_stat.ts_pkt_rcvd & 0x1) {
489 tpclnp_ctlinput(PRC_QUENCH, &src);
490 } else {
491 tpclnp_ctlinput(PRC_QUENCH2, &src);
492 }
493 }
494 }
495 ENDDEBUG
496
497 splx(s);
498 return 0;
238ab140
KS
499}
500
501ProtoHook
502iso_rtchange()
503{
504 return 0;
505}
506
507/*
508 * CALLED FROM:
509 * tpclnp_ctlinput()
510 * FUNCTION and ARGUMENTS:
511 * find the tpcb pointer and pass it to tp_quench
512 */
513void
514tpiso_decbit(isop)
515 struct isopcb *isop;
516{
f15f73d2 517 tp_quench((struct tp_pcb *)isop->isop_socket->so_pcb, PRC_QUENCH2);
238ab140
KS
518}
519/*
520 * CALLED FROM:
521 * tpclnp_ctlinput()
522 * FUNCTION and ARGUMENTS:
523 * find the tpcb pointer and pass it to tp_quench
524 */
525void
526tpiso_quench(isop)
527 struct isopcb *isop;
528{
f15f73d2 529 tp_quench((struct tp_pcb *)isop->isop_socket->so_pcb, PRC_QUENCH);
238ab140
KS
530}
531
532/*
533 * CALLED FROM:
534 * The network layer through the protosw table.
535 * FUNCTION and ARGUMENTS:
536 * When clnp an ICMP-like msg this gets called.
537 * It either returns an error status to the user or
538 * it causes all connections on this address to be aborted
539 * by calling the appropriate xx_notify() routine.
540 * (cmd) is the type of ICMP error.
541 * (siso) is the address of the guy who sent the ER CLNPDU
542 */
543ProtoHook
544tpclnp_ctlinput(cmd, siso)
545 int cmd;
546 struct sockaddr_iso *siso;
547{
548 extern u_char inetctlerrmap[];
549 extern ProtoHook tpiso_abort();
550 extern ProtoHook iso_rtchange();
551 extern ProtoHook tpiso_reset();
a50e2bc0 552 void iso_pcbnotify();
238ab140
KS
553
554 IFDEBUG(D_TPINPUT)
c0dbf2a0
KS
555 printf("tpclnp_ctlinput1: cmd 0x%x addr: \n", cmd);
556 dump_isoaddr(siso);
238ab140
KS
557 ENDDEBUG
558
559 if (cmd < 0 || cmd > PRC_NCMDS)
560 return 0;
c0dbf2a0
KS
561 if (siso->siso_family != AF_ISO)
562 return 0;
238ab140
KS
563 switch (cmd) {
564
565 case PRC_QUENCH2:
c0dbf2a0 566 iso_pcbnotify(&tp_isopcb, siso, 0, (int (*)())tpiso_decbit);
238ab140
KS
567 break;
568
569 case PRC_QUENCH:
c0dbf2a0 570 iso_pcbnotify(&tp_isopcb, siso, 0, (int (*)())tpiso_quench);
238ab140
KS
571 break;
572
573 case PRC_TIMXCEED_REASS:
574 case PRC_ROUTEDEAD:
c0dbf2a0 575 iso_pcbnotify(&tp_isopcb, siso, 0, tpiso_reset);
238ab140
KS
576 break;
577
578 case PRC_HOSTUNREACH:
579 case PRC_UNREACH_NET:
580 case PRC_IFDOWN:
581 case PRC_HOSTDEAD:
c0dbf2a0 582 iso_pcbnotify(&tp_isopcb, siso,
238ab140
KS
583 (int)inetctlerrmap[cmd], iso_rtchange);
584 break;
585
586 default:
587 /*
588 case PRC_MSGSIZE:
589 case PRC_UNREACH_HOST:
590 case PRC_UNREACH_PROTOCOL:
591 case PRC_UNREACH_PORT:
592 case PRC_UNREACH_NEEDFRAG:
593 case PRC_UNREACH_SRCFAIL:
594 case PRC_REDIRECT_NET:
595 case PRC_REDIRECT_HOST:
596 case PRC_REDIRECT_TOSNET:
597 case PRC_REDIRECT_TOSHOST:
598 case PRC_TIMXCEED_INTRANS:
599 case PRC_PARAMPROB:
600 */
c0dbf2a0 601 iso_pcbnotify(&tp_isopcb, siso, (int)inetctlerrmap[cmd], tpiso_abort);
238ab140
KS
602 break;
603 }
604 return 0;
605}
c0dbf2a0
KS
606/*
607 * XXX - Variant which is called by clnp_er.c with an isoaddr rather
608 * than a sockaddr_iso.
609 */
610
611static struct sockaddr_iso siso = {sizeof(siso), AF_ISO};
612tpclnp_ctlinput1(cmd, isoa)
613 int cmd;
614 struct iso_addr *isoa;
615{
616 bzero((caddr_t)&siso.siso_addr, sizeof(siso.siso_addr));
617 bcopy((caddr_t)isoa, (caddr_t)&siso.siso_addr, isoa->isoa_len);
618 tpclnp_ctlinput(cmd, &siso);
619}
238ab140
KS
620
621/*
622 * These next 2 routines are
623 * CALLED FROM:
624 * xxx_notify() from tp_ctlinput() when
625 * net level gets some ICMP-equiv. type event.
626 * FUNCTION and ARGUMENTS:
627 * Cause the connection to be aborted with some sort of error
628 * reason indicating that the network layer caused the abort.
629 * Fakes an ER TPDU so we can go through the driver.
630 * abort always aborts the TP connection.
631 * reset may or may not, depending on the TP class that's in use.
632 */
633ProtoHook
634tpiso_abort(isop)
635 struct isopcb *isop;
636{
637 struct tp_event e;
638
639 IFDEBUG(D_CONN)
640 printf("tpiso_abort 0x%x\n", isop);
641 ENDDEBUG
642 e.ev_number = ER_TPDU;
643 e.ATTR(ER_TPDU).e_reason = ECONNABORTED;
f15f73d2 644 return tp_driver((struct tp_pcb *)isop->isop_socket->so_pcb, &e);
238ab140
KS
645}
646
647ProtoHook
648tpiso_reset(isop)
649 struct isopcb *isop;
650{
651 struct tp_event e;
652
653 e.ev_number = T_NETRESET;
f15f73d2 654 return tp_driver((struct tp_pcb *)isop->isop_socket->so_pcb, &e);
238ab140
KS
655
656}
657
658#endif ISO