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