|
|
1.1 root 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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.