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