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