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