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