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