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