compaq changes
[unix-history] / usr / src / sys / netiso / tp_cons.c
CommitLineData
47f37345
KS
1/***********************************************************
2 Copyright IBM Corporation 1987
3
4 All Rights Reserved
5
6Permission to use, copy, modify, and distribute this software and its
7documentation for any purpose and without fee is hereby granted,
8provided that the above copyright notice appear in all copies and that
9both that copyright notice and this permission notice appear in
10supporting documentation, and that the name of IBM not be
11used in advertising or publicity pertaining to distribution of the
12software without specific, written prior permission.
13
14IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20SOFTWARE.
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 $
44f52ea5 31 * @(#)tp_cons.c 7.3 (Berkeley) %G% *
47f37345
KS
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
47static 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
a50e2bc0 55#include "param.h"
47f37345
KS
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
a50e2bc0
KS
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"
47f37345 70#include "../net/route.h"
a50e2bc0
KS
71#include "iso.h"
72#include "iso_pcb.h"
73#include "cons.h"
74#include "tp_seq.h"
47f37345
KS
75
76int 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
85void
86tpcons_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 */
149ProtoHook
150tpcons_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 */
209ProtoHook
210tpcons_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
242int
243tpcons_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
288int
289tpcons_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
303struct tp_pcb *
304cons_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