|
|
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: tp_cons.c,v 5.6 88/11/18 17:27:13 nhall Exp $
30: * $Source: /usr/argo/sys/netiso/RCS/tp_cons.c,v $
31: * @(#)tp_cons.c 7.3 (Berkeley) 8/29/89 *
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: * tpcons_mtu: figure out what size tpdu to use
40: * tpcons_input: pullup and call tp_input w/ correct arguments
41: * tpcons_output_dg: package a pkt for cons given 2 addresses & some data
42: * tpcons_output: package a pkt for cons given an isopcb & some data
43: * cons_chan_to_tpcb: find a tpcb based on the channel #
44: */
45:
46: #ifndef lint
47: static char *rcsid = "$Header: tp_cons.c,v 5.6 88/11/18 17:27:13 nhall Exp $";
48: #endif lint
49:
50: #include "argoxtwentyfive.h"
51:
52: #ifdef ISO
53: #if NARGOXTWENTYFIVE > 0
54:
55: #include "param.h"
56: #include "socket.h"
57: #include "domain.h"
58: #include "mbuf.h"
59: #include "errno.h"
60: #include "time.h"
61: #include "../net/if.h"
62:
63: #include "tp_param.h"
64: #include "argo_debug.h"
65: #include "tp_stat.h"
66: #include "tp_pcb.h"
67: #include "tp_trace.h"
68: #include "tp_stat.h"
69: #include "tp_tpdu.h"
70: #include "../net/route.h"
71: #include "iso.h"
72: #include "iso_pcb.h"
73: #include "cons.h"
74: #include "tp_seq.h"
75:
76: int tpcons_output();
77:
78: /*
79: * CALLED FROM:
80: * tp_input() on incoming CR, CC, and pr_usrreq() for PRU_CONNECT
81: * FUNCTION, ARGUMENTS, SIDE EFFECTS and RETURN VALUE:
82: * version of the previous procedure for X.25
83: */
84:
85: void
86: tpcons_mtu(so, isop, size, negot)
87: struct socket *so;
88: struct isopcb *isop;
89: int *size;
90: u_char *negot;
91: {
92: register struct ifnet *ifp;
93: register int i=0;
94: int windowsize = so->so_rcv.sb_hiwat;
95: struct ifnet *iso_routeifp();
96:
97: IFTRACE(D_CONN)
98: tptrace(TPPTmisc, "ENTER GET MTU: size negot ",*size, *negot, 0, 0);
99: ENDTRACE
100:
101:
102: *size = 1 << *negot;
103: if ((ifp = iso_routeifp(&isop->isop_faddr)) == (struct ifnet *)0)
104: return;
105:
106: if( *size > windowsize ) {
107: *size = windowsize;
108: i++;
109: }
110:
111: if(*size > ifp->if_mtu) {
112: *size = ifp->if_mtu ;
113: i++;
114: }
115: if(i) {
116: /* size was changed by this routine - have to transform it to
117: * the log2 of size
118: */
119: for(i=TP_MIN_TPDUSIZE; (i<TP_MAX_TPDUSIZE && ((1<<i)<*size)) ; i++)
120: ;
121: /* are we on the same LAN? if so, negotiate one tpdu size larger,
122: * and actually send the real mtu size
123: */
124: /* PHASE2: replace with iso_on_localnet(&isop->isop_faddr);
125: */
126: if ( !iso_netmatch(&isop->isop_laddr, &isop->isop_faddr) ) {
127: i--;
128: *size = 1<<i;
129: }
130: *negot = i;
131: }
132:
133: IFDEBUG(D_CONN)
134: printf("GET MTU RETURNS: ifp %s size 0x%x negot 0x%x\n",
135: ifp->if_name, *size, *negot);
136: ENDDEBUG
137: IFTRACE(D_CONN)
138: tptrace(TPPTmisc, "EXIT GET MTU: tpcb size negot ",
139: *size, *negot, 0, 0);
140: ENDTRACE
141: }
142:
143: /*
144: * CALLED FROM:
145: * cons
146: * FUNCTION and ARGUMENTS:
147: * THIS MAYBE BELONGS IN SOME OTHER PLACE??? but i think not -
148: */
149: ProtoHook
150: tpcons_ctlinput(cmd, siso, isop)
151: int cmd;
152: struct sockaddr_iso *siso;
153: struct isopcb *isop;
154: {
155: switch (cmd) {
156:
157: case PRC_CONS_SEND_DONE:
158: if( isop->isop_socket ) { /* tp 0 only */
159: register struct tp_pcb *tpcb =
160: (struct tp_pcb *)isop->isop_socket->so_tpcb;
161: struct tp_event E;
162: int error = 0;
163:
164: if( tpcb->tp_class == TP_CLASS_0 ) {
165: /* only if class is exactly class zero, not
166: * still in class negotiation
167: */
168: /* fake an ack */
169: register SeqNum seq = SEQ_ADD(tpcb, tpcb->tp_snduna, 1);
170:
171: IFTRACE(D_DATA)
172: tptrace(TPPTmisc, "FAKE ACK seq cdt 1",
173: seq, 0,0,0);
174: ENDTRACE
175: IFDEBUG(D_DATA)
176: printf("FAKE ACK seq 0x%x cdt 1\n", seq );
177: ENDDEBUG
178: E.ATTR(AK_TPDU).e_cdt = 1;
179: E.ATTR(AK_TPDU).e_seq = seq;
180: E.ATTR(AK_TPDU).e_subseq = 0;
181: E.ATTR(AK_TPDU).e_fcc_present = 0;
182: error = DoEvent(AK_TPDU);
183: if( error ) {
184: tpcb->tp_sock->so_error = error;
185: }
186: } /* else ignore it */
187: }
188: break;
189: case PRC_ROUTEDEAD:
190: if( isop->isop_socket ) { /* tp 0 only */
191: tpiso_reset(isop);
192: break;
193: } /* else drop through */
194: default:
195: (void) tpclnp_ctlinput(cmd, siso);
196: break;
197: }
198: return 0;
199: }
200:
201: /*
202: * CALLED FROM:
203: * cons's intr routine
204: * FUNCTION and ARGUMENTS:
205: * Take a packet (m) from cons, pullup m as required by tp,
206: * ignore the socket argument, and call tp_input.
207: * No return value.
208: */
209: ProtoHook
210: tpcons_input(m, faddr, laddr, so, channel)
211: struct mbuf *m;
212: struct sockaddr_iso *faddr, *laddr;
213: struct socket *so; /* not used */
214: int channel;
215: {
216: if( m == MNULL)
217: return 0;
218:
219: m = (struct mbuf *)tp_inputprep(m);
220:
221: IFDEBUG(D_TPINPUT)
222: printf("tpcons_input before tp_input(m 0x%x)\n", m);
223: dump_buf( m, 12+ m->m_len);
224: ENDDEBUG
225: tp_input(m, faddr, laddr, channel, tpcons_output);
226: return 0;
227: }
228:
229:
230: /*
231: * CALLED FROM:
232: * tp_emit()
233: * FUNCTION and ARGUMENTS:
234: * Take a packet(m0) from tp and package it so that cons will accept it.
235: * This means filling in a few of the fields.
236: * inp is the isopcb structure; datalen is the length of the data in the
237: * mbuf string m0.
238: * RETURN VALUE:
239: * whatever (E*) is returned form the net layer output routine.
240: */
241:
242: int
243: tpcons_output(isop, m0, datalen, nochksum)
244: struct isopcb *isop;
245: struct mbuf *m0;
246: int datalen;
247: int nochksum;
248: {
249: struct tp_pcb *tpcb;
250: int error;
251:
252: IFDEBUG(D_EMIT)
253: printf(
254: "tpcons_output(isop 0x%x, m 0x%x, len 0x%x socket 0x%x\n",
255: isop, m0, datalen, isop->isop_socket);
256: ENDDEBUG
257: if(m0 == MNULL)
258: return 0;
259: ASSERT(m0->m_len > 0);
260: tpcb = (struct tp_pcb *)isop->isop_socket->so_tpcb;
261:
262: /* check is for class EQUAL to 4: if still in negotiation stage,
263: * cannot send as dgm
264: */
265: error = cons_output(isop, m0, datalen, (tpcb->tp_class == TP_CLASS_4));
266: IncStat(ts_tpdu_sent);
267:
268: IFTRACE(D_EMIT)
269: tptrace( TPPTmisc,
270: "tpcons_output( isop m isdgm cons_output returns",
271: isop, m0, (tpcb->tp_class == TP_CLASS_4), error );
272: ENDTRACE
273: return error;
274: }
275:
276: /*
277: * CALLED FROM:
278: * tp_error_emit()
279: * FUNCTION and ARGUMENTS:
280: * This is a copy of tpcons_output that takes the addresses
281: * instead of a pcb. It's used by the tp_error_emit, when we
282: * don't have an iso_pcb with which to call the normal output rtn.
283: * RETURN VALUE:
284: * ENOBUFS or
285: * whatever (E*) is returned form the net layer output routine.
286: */
287:
288: int
289: tpcons_output_dg(laddr, faddr, m0, datalen, ro, nochksum)
290: struct iso_addr *laddr, *faddr;
291: struct mbuf *m0;
292: int datalen;
293: struct route *ro;
294: int nochksum;
295: {
296: IFDEBUG(D_TPISO)
297: printf("PANIC: tpcons_output_dg datalen 0x%x m0 0x%x\n", datalen, m0);
298: ENDDEBUG
299:
300: return 0;
301: }
302:
303: struct tp_pcb *
304: cons_chan_to_tpcb(chan)
305: int chan;
306: {
307: extern struct isopcb *cons_chan_to_pcb ();
308: #ifdef ARGO_DEBUG
309: struct isopcb *isop = cons_chan_to_pcb (chan, -1);
310: #else ARGO_DEBUG
311: struct isopcb *isop = cons_chan_to_pcb (chan);
312: #endif ARGO_DEBUG
313:
314: IFTRACE(D_CONN)
315: tptrace(TPPTmisc, "vc->tpcb(chan) socket",
316: chan, isop->isop_socket, 0, 0);
317: ENDTRACE
318: IFDEBUG(D_CONN)
319: printf("vc->tpcb(0x%x) socket 0x%x, *ISOP dump:",
320: chan, isop->isop_socket);
321: dump_buf( isop, 32);
322: ENDDEBUG
323: if( isop->isop_socket == (struct socket *)0 )
324: return (struct tp_pcb *) 0;
325: else {
326: return (struct tp_pcb *)(isop->isop_socket->so_tpcb);
327: }
328: }
329: #endif NARGOXTWENTYFIVE
330: #endif ISO
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.