FreeBSD/Linux Kernel Cross Reference
sys/netiso/tp_cons.c
1 /* $NetBSD: tp_cons.c,v 1.19 2005/02/26 22:39:49 perry 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.19 2005/02/26 22:39:49 perry 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 /*
115 * CALLED FROM:
116 * tp_route_to() for PRU_CONNECT
117 * FUNCTION, ARGUMENTS, SIDE EFFECTS and RETURN VALUE:
118 * version of the previous procedure for X.25
119 */
120
121 int
122 tpcons_pcbconnect(void *v, struct mbuf *nam)
123 {
124 struct isopcb *isop = v;
125 int error;
126 if ((error = iso_pcbconnect(isop, nam)) != 0)
127 return error;
128 if ((isop->isop_chan = (caddr_t) pk_attach((struct socket *) 0)) == 0) {
129 #ifdef ARGO_DEBUG
130 if (argo_debug[D_CCONS]) {
131 printf("tpcons_pcbconnect: no pklcd; returns 0x%x\n", error);
132 }
133 #endif
134 return ENOBUFS;
135 }
136 if ((error = cons_connect(isop)) != 0) { /* if it doesn't work */
137 /* oh, dear, throw packet away */
138 pk_disconnect((struct pklcd *) isop->isop_chan);
139 isop->isop_chan = 0;
140 } else
141 isop->isop_refcnt = 1;
142 return error;
143 }
144
145
146 /*
147 * CALLED FROM:
148 * cons
149 * FUNCTION and ARGUMENTS:
150 * THIS MAYBE BELONGS IN SOME OTHER PLACE??? but i think not -
151 */
152 void *
153 tpcons_ctlinput(int cmd, struct sockaddr *siso, void *v)
154 {
155 struct isopcb *isop = v;
156 struct tp_pcb *tpcb = 0;
157
158 /*XXX correct? */
159 if (siso->sa_family != AF_ISO)
160 return NULL;
161
162 if (isop->isop_socket)
163 tpcb = (struct tp_pcb *) isop->isop_socket->so_pcb;
164 switch (cmd) {
165
166 case PRC_CONS_SEND_DONE:
167 if (tpcb) {
168 struct tp_event E;
169 int error = 0;
170
171 if (tpcb->tp_class == TP_CLASS_0) {
172 /*
173 * only if class is exactly class zero, not
174 * still in class negotiation
175 */
176 /* fake an ack */
177 SeqNum seq = SEQ_ADD(tpcb, tpcb->tp_snduna, 1);
178
179 #ifdef TPPT
180 if(tp_traceflags[D_DATA])
181 tptrace(TPPTmisc, "FAKE ACK seq cdt 1",
182 seq, 0, 0, 0);
183 #endif
184 #ifdef ARGO_DEBUG
185 if (argo_debug[D_DATA]) {
186 printf("FAKE ACK seq 0x%x cdt 1\n", seq);
187 }
188 #endif
189 E.ev_union.EV_AK_TPDU.e_cdt = 1;
190 E.ev_union.EV_AK_TPDU.e_seq = seq;
191 E.ev_union.EV_AK_TPDU.e_subseq = 0;
192 E.ev_union.EV_AK_TPDU.e_fcc_present = 0;
193 error = DoEvent(AK_TPDU);
194 if (error) {
195 tpcb->tp_sock->so_error = error;
196 }
197 } /* else ignore it */
198 }
199 break;
200 case PRC_ROUTEDEAD:
201 if (tpcb && tpcb->tp_class == TP_CLASS_0) {
202 tpiso_reset(isop);
203 break;
204 } /* else drop through */
205 default:
206 tpclnp_ctlinput(cmd, siso, NULL);
207 break;
208 }
209 return NULL;
210 }
211
212 /*
213 * CALLED FROM:
214 * cons's intr routine
215 * FUNCTION and ARGUMENTS:
216 * Take a packet (m) from cons, pullup m as required by tp,
217 * ignore the socket argument, and call tp_input.
218 * No return value.
219 */
220 void
221 tpcons_input(struct mbuf *m, ...)
222 {
223 struct sockaddr *faddr, *laddr;
224 caddr_t channel;
225 va_list ap;
226 if (m == NULL)
227 return;
228 va_start(ap, m);
229 faddr = va_arg(ap, struct sockaddr *);
230 laddr = va_arg(ap, struct sockaddr *);
231 channel = va_arg(ap, caddr_t);
232 va_end(ap);
233
234 m = (struct mbuf *) tp_inputprep(m);
235
236 #ifdef ARGO_DEBUG
237 if (argo_debug[D_TPINPUT]) {
238 printf("tpcons_input before tp_input(m %p)\n", m);
239 dump_buf(m, 12 + m->m_len);
240 }
241 #endif
242 tp_input(m, faddr, laddr, channel, tpcons_output, 0);
243 }
244
245
246 /*
247 * CALLED FROM:
248 * tp_emit()
249 * FUNCTION and ARGUMENTS:
250 * Take a packet(m0) from tp and package it so that cons will accept it.
251 * This means filling in a few of the fields.
252 * inp is the isopcb structure; datalen is the length of the data in the
253 * mbuf string m0.
254 * RETURN VALUE:
255 * whatever (E*) is returned form the net layer output routine.
256 */
257
258 int
259 tpcons_output(struct mbuf *m0, ...)
260 {
261 struct isopcb *isop;
262 int datalen;
263 int nochksum;
264 struct mbuf *m = m0;
265 int error;
266 va_list ap;
267
268 va_start(ap, m0);
269 datalen = va_arg(ap, int);
270 isop = va_arg(ap, struct isopcb *);
271 nochksum = va_arg(ap, int);
272 va_end(ap);
273
274 #ifdef ARGO_DEBUG
275 if (argo_debug[D_EMIT]) {
276 printf(
277 "tpcons_output(isop=%p, m=%p, len=%#x socket=%p\n",
278 isop, m0, datalen, isop->isop_socket);
279 }
280 #endif
281 if (m == NULL)
282 return 0;
283 if ((m->m_flags & M_PKTHDR) == 0) {
284 MGETHDR(m, M_DONTWAIT, MT_DATA);
285 if (m == 0)
286 return ENOBUFS;
287 m->m_next = m0;
288 }
289 m->m_pkthdr.len = datalen;
290 if (isop->isop_chan == 0) {
291 /* got a restart maybe? */
292 if ((isop->isop_chan = (caddr_t) pk_attach((struct socket *) 0)) == 0) {
293 #ifdef ARGO_DEBUG
294 if (argo_debug[D_CCONS]) {
295 printf("tpcons_output: no pklcd\n");
296 }
297 #endif
298 error = ENOBUFS;
299 }
300 if ((error = cons_connect(isop)) != 0) {
301 pk_disconnect((struct pklcd *) isop->isop_chan);
302 isop->isop_chan = 0;
303 #ifdef ARGO_DEBUG
304 if (argo_debug[D_CCONS]) {
305 printf("tpcons_output: can't reconnect\n");
306 }
307 #endif
308 }
309 } else {
310 error = pk_send(m, isop->isop_chan);
311 IncStat(ts_tpdu_sent);
312 }
313 return error;
314 }
315 /*
316 * CALLED FROM:
317 * tp_error_emit()
318 * FUNCTION and ARGUMENTS:
319 * Take a packet(m0) from tp and package it so that cons will accept it.
320 * chan is the cons channel to use; datalen is the length of the data in the
321 * mbuf string m0.
322 * RETURN VALUE:
323 * whatever (E*) is returned form the net layer output routine.
324 */
325
326 int
327 tpcons_output_dg(struct mbuf *m0, ...)
328 {
329 int datalen;
330 caddr_t chan;
331 va_list ap;
332
333 va_start(ap, m0);
334 datalen = va_arg(ap, int);
335 chan = va_arg(ap, caddr_t);
336 va_end(ap);
337
338 return tpcons_output(m0, datalen,
339 ((struct pklcd *) chan)->lcd_upnext,
340 0);
341 }
342 #else
343
344 #include <sys/param.h>
345
346 struct mbuf;
347
348 int tpcons_output (struct mbuf *m0, ...);
349
350 int
351 tpcons_output(struct mbuf *m0, ...)
352 {
353 return 0;
354 }
355 #endif /* TPCONS */
356 #endif /* ISO */
Cache object: c3deb47882d52f330d65ea39cf72e233
|