FreeBSD/Linux Kernel Cross Reference
sys/netiso/tp_cons.c
1 /* $NetBSD: tp_cons.c,v 1.16 2003/08/07 16:33:38 agc Exp $ */
2
3 /*-
4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * @(#)tp_cons.c 8.1 (Berkeley) 6/10/93
32 */
33
34 /***********************************************************
35 Copyright IBM Corporation 1987
36
37 All Rights Reserved
38
39 Permission to use, copy, modify, and distribute this software and its
40 documentation for any purpose and without fee is hereby granted,
41 provided that the above copyright notice appear in all copies and that
42 both that copyright notice and this permission notice appear in
43 supporting documentation, and that the name of IBM not be
44 used in advertising or publicity pertaining to distribution of the
45 software without specific, written prior permission.
46
47 IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
48 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
49 IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
50 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
51 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
52 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 SOFTWARE.
54
55 ******************************************************************/
56
57 /*
58 * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
59 */
60 /*
61 * Here is where you find the iso- and cons-dependent code. We've tried keep
62 * all net-level and (primarily) address-family-dependent stuff out of the tp
63 * source, and everthing here is reached indirectly through a switch table
64 * (struct nl_protosw *) tpcb->tp_nlproto (see tp_pcb.c). The routines here
65 * are: tpcons_input: pullup and call tp_input w/ correct arguments
66 * tpcons_output: package a pkt for cons given an isopcb & some data
67 * cons_chan_to_tpcb: find a tpcb based on the channel #
68 */
69
70 #include <sys/cdefs.h>
71 __KERNEL_RCSID(0, "$NetBSD: tp_cons.c,v 1.16 2003/08/07 16:33:38 agc Exp $");
72
73 #include "opt_iso.h"
74
75 #ifdef ISO
76 #ifdef TPCONS
77
78 #include <sys/param.h>
79 #include <sys/systm.h>
80 #include <sys/socket.h>
81 #include <sys/domain.h>
82 #include <sys/mbuf.h>
83 #include <sys/errno.h>
84 #include <sys/time.h>
85
86 #include <net/if.h>
87 #include <net/route.h>
88
89 #include <netiso/tp_param.h>
90 #include <netiso/argo_debug.h>
91 #include <netiso/tp_stat.h>
92 #include <netiso/tp_pcb.h>
93 #include <netiso/tp_trace.h>
94 #include <netiso/tp_stat.h>
95 #include <netiso/tp_tpdu.h>
96 #include <netiso/iso.h>
97 #include <netiso/iso_errno.h>
98 #include <netiso/iso_pcb.h>
99 #include <netiso/iso_var.h>
100 #include <netiso/cons.h>
101 #include <netiso/tp_seq.h>
102 #include <netiso/tp_var.h>
103 #include <netiso/clnp.h>
104
105 #undef FALSE
106 #undef TRUE
107 #include <netccitt/x25.h>
108 #include <netccitt/pk.h>
109 #include <netccitt/pk_var.h>
110 #include <netccitt/pk_extern.h>
111
112 #include <machine/stdarg.h>
113
114 #include <netiso/if_cons.c>
115
116
117 /*
118 * CALLED FROM:
119 * tp_route_to() for PRU_CONNECT
120 * FUNCTION, ARGUMENTS, SIDE EFFECTS and RETURN VALUE:
121 * version of the previous procedure for X.25
122 */
123
124 int
125 tpcons_pcbconnect(v, nam)
126 void *v;
127 struct mbuf *nam;
128 {
129 struct isopcb *isop = v;
130 int error;
131 if ((error = iso_pcbconnect(isop, nam)) != 0)
132 return error;
133 if ((isop->isop_chan = (caddr_t) pk_attach((struct socket *) 0)) == 0) {
134 #ifdef ARGO_DEBUG
135 if (argo_debug[D_CCONS]) {
136 printf("tpcons_pcbconnect: no pklcd; returns 0x%x\n", error);
137 }
138 #endif
139 return ENOBUFS;
140 }
141 if ((error = cons_connect(isop)) != 0) { /* if it doesn't work */
142 /* oh, dear, throw packet away */
143 pk_disconnect((struct pklcd *) isop->isop_chan);
144 isop->isop_chan = 0;
145 } else
146 isop->isop_refcnt = 1;
147 return error;
148 }
149
150
151 /*
152 * CALLED FROM:
153 * cons
154 * FUNCTION and ARGUMENTS:
155 * THIS MAYBE BELONGS IN SOME OTHER PLACE??? but i think not -
156 */
157 void *
158 tpcons_ctlinput(cmd, siso, v)
159 int cmd;
160 struct sockaddr *siso;
161 void *v;
162 {
163 struct isopcb *isop = v;
164 struct tp_pcb *tpcb = 0;
165
166 /*XXX correct? */
167 if (siso->sa_family != AF_ISO)
168 return NULL;
169
170 if (isop->isop_socket)
171 tpcb = (struct tp_pcb *) isop->isop_socket->so_pcb;
172 switch (cmd) {
173
174 case PRC_CONS_SEND_DONE:
175 if (tpcb) {
176 struct tp_event E;
177 int error = 0;
178
179 if (tpcb->tp_class == TP_CLASS_0) {
180 /*
181 * only if class is exactly class zero, not
182 * still in class negotiation
183 */
184 /* fake an ack */
185 SeqNum seq = SEQ_ADD(tpcb, tpcb->tp_snduna, 1);
186
187 #ifdef TPPT
188 if(tp_traceflags[D_DATA])
189 tptrace(TPPTmisc, "FAKE ACK seq cdt 1",
190 seq, 0, 0, 0);
191 #endif
192 #ifdef ARGO_DEBUG
193 if (argo_debug[D_DATA]) {
194 printf("FAKE ACK seq 0x%x cdt 1\n", seq);
195 }
196 #endif
197 E.TP_ATTR(AK_TPDU).e_cdt = 1;
198 E.TP_ATTR(AK_TPDU).e_seq = seq;
199 E.TP_ATTR(AK_TPDU).e_subseq = 0;
200 E.TP_ATTR(AK_TPDU).e_fcc_present = 0;
201 error = DoEvent(AK_TPDU);
202 if (error) {
203 tpcb->tp_sock->so_error = error;
204 }
205 } /* else ignore it */
206 }
207 break;
208 case PRC_ROUTEDEAD:
209 if (tpcb && tpcb->tp_class == TP_CLASS_0) {
210 tpiso_reset(isop);
211 break;
212 } /* else drop through */
213 default:
214 tpclnp_ctlinput(cmd, siso, NULL);
215 break;
216 }
217 return NULL;
218 }
219
220 /*
221 * CALLED FROM:
222 * cons's intr routine
223 * FUNCTION and ARGUMENTS:
224 * Take a packet (m) from cons, pullup m as required by tp,
225 * ignore the socket argument, and call tp_input.
226 * No return value.
227 */
228 void
229 #if __STDC__
230 tpcons_input(struct mbuf *m, ...)
231 #else
232 tpcons_input(m, va_alist)
233 struct mbuf *m;
234 va_dcl
235 #endif
236 {
237 struct sockaddr *faddr, *laddr;
238 caddr_t channel;
239 va_list ap;
240 if (m == NULL)
241 return;
242 va_start(ap, m);
243 faddr = va_arg(ap, struct sockaddr *);
244 laddr = va_arg(ap, struct sockaddr *);
245 channel = va_arg(ap, caddr_t);
246 va_end(ap);
247
248 m = (struct mbuf *) tp_inputprep(m);
249
250 #ifdef ARGO_DEBUG
251 if (argo_debug[D_TPINPUT]) {
252 printf("tpcons_input before tp_input(m 0x%x)\n", m);
253 dump_buf(m, 12 + m->m_len);
254 }
255 #endif
256 tp_input(m, faddr, laddr, channel, tpcons_output, 0);
257 }
258
259
260 /*
261 * CALLED FROM:
262 * tp_emit()
263 * FUNCTION and ARGUMENTS:
264 * Take a packet(m0) from tp and package it so that cons will accept it.
265 * This means filling in a few of the fields.
266 * inp is the isopcb structure; datalen is the length of the data in the
267 * mbuf string m0.
268 * RETURN VALUE:
269 * whatever (E*) is returned form the net layer output routine.
270 */
271
272 int
273 #if __STDC__
274 tpcons_output(struct mbuf *m0, ...)
275 #else
276 tpcons_output(m0, va_alist)
277 struct mbuf *m0;
278 va_dcl
279 #endif
280 {
281 struct isopcb *isop;
282 int datalen;
283 int nochksum;
284 struct mbuf *m = m0;
285 int error;
286 va_list ap;
287
288 va_start(ap, m0);
289 datalen = va_arg(ap, int);
290 isop = va_arg(ap, struct isopcb *);
291 nochksum = va_arg(ap, int);
292 va_end(ap);
293
294 #ifdef ARGO_DEBUG
295 if (argo_debug[D_EMIT]) {
296 printf(
297 "tpcons_output(isop 0x%x, m 0x%x, len 0x%x socket 0x%x\n",
298 isop, m0, datalen, isop->isop_socket);
299 }
300 #endif
301 if (m == NULL)
302 return 0;
303 if ((m->m_flags & M_PKTHDR) == 0) {
304 MGETHDR(m, M_DONTWAIT, MT_DATA);
305 if (m == 0)
306 return ENOBUFS;
307 m->m_next = m0;
308 }
309 m->m_pkthdr.len = datalen;
310 if (isop->isop_chan == 0) {
311 /* got a restart maybe? */
312 if ((isop->isop_chan = (caddr_t) pk_attach((struct socket *) 0)) == 0) {
313 #ifdef ARGO_DEBUG
314 if (argo_debug[D_CCONS]) {
315 printf("tpcons_output: no pklcd\n");
316 }
317 #endif
318 error = ENOBUFS;
319 }
320 if ((error = cons_connect(isop)) != 0) {
321 pk_disconnect((struct pklcd *) isop->isop_chan);
322 isop->isop_chan = 0;
323 #ifdef ARGO_DEBUG
324 if (argo_debug[D_CCONS]) {
325 printf("tpcons_output: can't reconnect\n");
326 }
327 #endif
328 }
329 } else {
330 error = pk_send(m, isop->isop_chan);
331 IncStat(ts_tpdu_sent);
332 }
333 return error;
334 }
335 /*
336 * CALLED FROM:
337 * tp_error_emit()
338 * FUNCTION and ARGUMENTS:
339 * Take a packet(m0) from tp and package it so that cons will accept it.
340 * chan is the cons channel to use; datalen is the length of the data in the
341 * mbuf string m0.
342 * RETURN VALUE:
343 * whatever (E*) is returned form the net layer output routine.
344 */
345
346 int
347 #if __STDC__
348 tpcons_output_dg(struct mbuf *m0, ...)
349 #else
350 tpcons_output_dg(m0, va_alist)
351 struct mbuf *m0;
352 va_dcl
353 #endif
354 {
355 int datalen;
356 caddr_t chan;
357 va_list ap;
358
359 va_start(ap, m0);
360 datalen = va_arg(ap, int);
361 chan = va_arg(ap, caddr_t);
362 va_end(ap);
363
364 return tpcons_output(m0, datalen,
365 ((struct pklcd *) chan)->lcd_upnext,
366 0);
367 }
368 #else
369
370 #include <sys/param.h>
371
372 struct mbuf;
373
374 int tpcons_output __P((struct mbuf *m0, ...));
375
376 int
377 #if __STDC__
378 tpcons_output(struct mbuf *m0, ...)
379 #else
380 tpcons_output(m0, va_alist)
381 struct mbuf *m0;
382 va_dcl
383 #endif
384 {
385 return 0;
386 }
387 #endif /* TPCONS */
388 #endif /* ISO */
Cache object: 858bb96f4a5d36cca4ea23de709336d4
|