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