fixes for range locking
[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 $
194a383a 31 * @(#)tp_cons.c 7.4 (Berkeley) %G% *
47f37345 32 *
194a383a 33 * Here is where you find the iso- and cons-dependent code. We've tried
47f37345
KS
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
47f37345
KS
41 * tpcons_output: package a pkt for cons given an isopcb & some data
42 * cons_chan_to_tpcb: find a tpcb based on the channel #
43 */
44
45#ifndef lint
46static char *rcsid = "$Header: tp_cons.c,v 5.6 88/11/18 17:27:13 nhall Exp $";
47#endif lint
48
47f37345
KS
49
50#ifdef ISO
194a383a 51#ifdef TPCONS
47f37345 52
a50e2bc0 53#include "param.h"
47f37345
KS
54#include "socket.h"
55#include "domain.h"
56#include "mbuf.h"
57#include "errno.h"
58#include "time.h"
194a383a 59
47f37345 60#include "../net/if.h"
194a383a 61#include "../net/route.h"
47f37345 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"
a50e2bc0 70#include "iso.h"
194a383a 71#include "iso_errno.h"
a50e2bc0
KS
72#include "iso_pcb.h"
73#include "cons.h"
74#include "tp_seq.h"
47f37345 75
194a383a
KS
76#undef FALSE
77#undef TRUE
78#include "../netccitt/x25.h"
79#include "../netccitt/pk.h"
80#include "../netccitt/pk_var.h"
81
82#include "if_cons.c"
47f37345
KS
83int tpcons_output();
84
194a383a
KS
85/*
86 * CALLED FROM:
87 * tp_route_to() for PRU_CONNECT
88 * FUNCTION, ARGUMENTS, SIDE EFFECTS and RETURN VALUE:
89 * version of the previous procedure for X.25
90 */
91
92tpcons_pcbconnect(isop, nam)
93struct isopcb *isop;
94register struct mbuf *nam;
95{
96 int error;
97 if (error = iso_pcbconnect(isop, nam))
98 return error;
99 if ((isop->isop_chan = (caddr_t) pk_attach((struct socket *)0)) == 0) {
100 IFDEBUG(D_CCONS)
101 printf("tpcons_pcbconnect: no pklcd; returns 0x%x\n", error);
102 ENDDEBUG
103 return ENOBUFS;
104 }
105 if (error = cons_connect(isop)) { /* if it doesn't work */
106 /* oh, dear, throw packet away */
107 pk_disconnect((struct pklcd *)isop->isop_chan);
108 isop->isop_chan = 0;
109 return error;
110 }
111}
112
113
47f37345
KS
114/*
115 * CALLED FROM:
116 * tp_input() on incoming CR, CC, and pr_usrreq() for PRU_CONNECT
117 * FUNCTION, ARGUMENTS, SIDE EFFECTS and RETURN VALUE:
118 * version of the previous procedure for X.25
119 */
120
121void
122tpcons_mtu(so, isop, size, negot)
123 struct socket *so;
124 struct isopcb *isop;
125 int *size;
126 u_char *negot;
127{
128 register struct ifnet *ifp;
194a383a 129 register int i=0, isize;
47f37345 130 int windowsize = so->so_rcv.sb_hiwat;
47f37345
KS
131
132 IFTRACE(D_CONN)
133 tptrace(TPPTmisc, "ENTER GET MTU: size negot ",*size, *negot, 0, 0);
134 ENDTRACE
135
194a383a
KS
136 isize = *size = 1 << *negot;
137#ifdef ancient_history
47f37345
KS
138 if ((ifp = iso_routeifp(&isop->isop_faddr)) == (struct ifnet *)0)
139 return;
194a383a 140#endif
47f37345 141
194a383a
KS
142 if (isize > windowsize) {
143 isize = windowsize;
47f37345
KS
144 i++;
145 }
194a383a
KS
146 if (isize > ifp->if_mtu) {
147 isize = ifp->if_mtu;
47f37345
KS
148 i++;
149 }
194a383a 150 if (i) {
47f37345
KS
151 /* size was changed by this routine - have to transform it to
152 * the log2 of size
153 */
194a383a
KS
154 for (i = TP_MIN_TPDUSIZE; i < TP_MAX_TPDUSIZE; i++) {
155 if (isize < (1 << (1 + i)))
156 break;
47f37345
KS
157 }
158 *negot = i;
194a383a 159 *size = 1 << i;
47f37345
KS
160 }
161
162 IFDEBUG(D_CONN)
163 printf("GET MTU RETURNS: ifp %s size 0x%x negot 0x%x\n",
164 ifp->if_name, *size, *negot);
165 ENDDEBUG
166 IFTRACE(D_CONN)
167 tptrace(TPPTmisc, "EXIT GET MTU: tpcb size negot ",
168 *size, *negot, 0, 0);
169 ENDTRACE
170}
171
172/*
173 * CALLED FROM:
174 * cons
175 * FUNCTION and ARGUMENTS:
176 * THIS MAYBE BELONGS IN SOME OTHER PLACE??? but i think not -
177 */
178ProtoHook
179tpcons_ctlinput(cmd, siso, isop)
180 int cmd;
181 struct sockaddr_iso *siso;
182 struct isopcb *isop;
183{
184 switch (cmd) {
185
186 case PRC_CONS_SEND_DONE:
187 if( isop->isop_socket ) { /* tp 0 only */
188 register struct tp_pcb *tpcb =
189 (struct tp_pcb *)isop->isop_socket->so_tpcb;
190 struct tp_event E;
191 int error = 0;
192
193 if( tpcb->tp_class == TP_CLASS_0 ) {
194 /* only if class is exactly class zero, not
195 * still in class negotiation
196 */
197 /* fake an ack */
198 register SeqNum seq = SEQ_ADD(tpcb, tpcb->tp_snduna, 1);
199
200 IFTRACE(D_DATA)
201 tptrace(TPPTmisc, "FAKE ACK seq cdt 1",
202 seq, 0,0,0);
203 ENDTRACE
204 IFDEBUG(D_DATA)
205 printf("FAKE ACK seq 0x%x cdt 1\n", seq );
206 ENDDEBUG
207 E.ATTR(AK_TPDU).e_cdt = 1;
208 E.ATTR(AK_TPDU).e_seq = seq;
209 E.ATTR(AK_TPDU).e_subseq = 0;
210 E.ATTR(AK_TPDU).e_fcc_present = 0;
211 error = DoEvent(AK_TPDU);
212 if( error ) {
213 tpcb->tp_sock->so_error = error;
214 }
215 } /* else ignore it */
216 }
217 break;
218 case PRC_ROUTEDEAD:
219 if( isop->isop_socket ) { /* tp 0 only */
220 tpiso_reset(isop);
221 break;
222 } /* else drop through */
223 default:
224 (void) tpclnp_ctlinput(cmd, siso);
225 break;
226 }
227 return 0;
228}
229
230/*
231 * CALLED FROM:
232 * cons's intr routine
233 * FUNCTION and ARGUMENTS:
234 * Take a packet (m) from cons, pullup m as required by tp,
235 * ignore the socket argument, and call tp_input.
236 * No return value.
237 */
238ProtoHook
194a383a 239tpcons_input(m, faddr, laddr, channel)
47f37345
KS
240 struct mbuf *m;
241 struct sockaddr_iso *faddr, *laddr;
194a383a 242 caddr_t channel;
47f37345
KS
243{
244 if( m == MNULL)
245 return 0;
246
247 m = (struct mbuf *)tp_inputprep(m);
248
249 IFDEBUG(D_TPINPUT)
250 printf("tpcons_input before tp_input(m 0x%x)\n", m);
251 dump_buf( m, 12+ m->m_len);
252 ENDDEBUG
253 tp_input(m, faddr, laddr, channel, tpcons_output);
254 return 0;
255}
256
257
258/*
259 * CALLED FROM:
260 * tp_emit()
261 * FUNCTION and ARGUMENTS:
262 * Take a packet(m0) from tp and package it so that cons will accept it.
263 * This means filling in a few of the fields.
264 * inp is the isopcb structure; datalen is the length of the data in the
265 * mbuf string m0.
266 * RETURN VALUE:
267 * whatever (E*) is returned form the net layer output routine.
268 */
269
270int
271tpcons_output(isop, m0, datalen, nochksum)
272 struct isopcb *isop;
273 struct mbuf *m0;
274 int datalen;
275 int nochksum;
276{
194a383a 277 register struct mbuf *m = m0;
47f37345
KS
278 int error;
279
280 IFDEBUG(D_EMIT)
281 printf(
282 "tpcons_output(isop 0x%x, m 0x%x, len 0x%x socket 0x%x\n",
283 isop, m0, datalen, isop->isop_socket);
284 ENDDEBUG
194a383a 285 if (m == MNULL)
47f37345 286 return 0;
194a383a
KS
287 if (m->m_flags & M_PKTHDR == 0) {
288 MGETHDR(m, M_DONTWAIT, MT_DATA);
289 if (m == 0)
290 return ENOBUFS;
291 m->m_next = m0;
292 }
293 m->m_pkthdr.len = datalen;
294 error = pk_send(isop->isop_chan, m);
47f37345
KS
295 IncStat(ts_tpdu_sent);
296
47f37345
KS
297 return error;
298}
47f37345
KS
299/*
300 * CALLED FROM:
301 * tp_error_emit()
302 * FUNCTION and ARGUMENTS:
194a383a
KS
303 * Take a packet(m0) from tp and package it so that cons will accept it.
304 * chan is the cons channel to use; datalen is the length of the data in the
305 * mbuf string m0.
47f37345 306 * RETURN VALUE:
47f37345
KS
307 * whatever (E*) is returned form the net layer output routine.
308 */
309
310int
194a383a
KS
311tpcons_dg_output(chan, m0, datalen)
312 caddr_t chan;
47f37345
KS
313 struct mbuf *m0;
314 int datalen;
47f37345 315{
194a383a 316 return tpcons_output(((struct pklcd *)chan)->lcd_upnext, m0, datalen, 0);
47f37345 317}
194a383a 318#endif TPCONS
47f37345 319#endif ISO