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