xref: /csrg-svn/sys/netiso/tp_cons.c (revision 49257)
136398Ssklower /***********************************************************
236398Ssklower 		Copyright IBM Corporation 1987
336398Ssklower 
436398Ssklower                       All Rights Reserved
536398Ssklower 
636398Ssklower Permission to use, copy, modify, and distribute this software and its
736398Ssklower documentation for any purpose and without fee is hereby granted,
836398Ssklower provided that the above copyright notice appear in all copies and that
936398Ssklower both that copyright notice and this permission notice appear in
1036398Ssklower supporting documentation, and that the name of IBM not be
1136398Ssklower used in advertising or publicity pertaining to distribution of the
1236398Ssklower software without specific, written prior permission.
1336398Ssklower 
1436398Ssklower IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
1536398Ssklower ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
1636398Ssklower IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
1736398Ssklower ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
1836398Ssklower WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
1936398Ssklower ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
2036398Ssklower SOFTWARE.
2136398Ssklower 
2236398Ssklower ******************************************************************/
2336398Ssklower 
2436398Ssklower /*
2536398Ssklower  * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
2636398Ssklower  */
2736398Ssklower /*
2836398Ssklower  * ARGO TP
2936398Ssklower  * $Header: tp_cons.c,v 5.6 88/11/18 17:27:13 nhall Exp $
3036398Ssklower  * $Source: /usr/argo/sys/netiso/RCS/tp_cons.c,v $
31*49257Ssklower  *	@(#)tp_cons.c	7.6 (Berkeley) 05/06/91 *
3236398Ssklower  *
3345900Ssklower  * Here is where you find the iso- and cons-dependent code.  We've tried
3436398Ssklower  * keep all net-level and (primarily) address-family-dependent stuff
3536398Ssklower  * out of the tp source, and everthing here is reached indirectly
3636398Ssklower  * through a switch table (struct nl_protosw *) tpcb->tp_nlproto
3736398Ssklower  * (see tp_pcb.c).
3836398Ssklower  * The routines here are:
3936398Ssklower  *		tpcons_input: pullup and call tp_input w/ correct arguments
4036398Ssklower  *		tpcons_output: package a pkt for cons given an isopcb & some data
4136398Ssklower  *		cons_chan_to_tpcb: find a tpcb based on the channel #
4236398Ssklower  */
4336398Ssklower 
4436398Ssklower #ifndef lint
4536398Ssklower static char *rcsid = "$Header: tp_cons.c,v 5.6 88/11/18 17:27:13 nhall Exp $";
4636398Ssklower #endif lint
4736398Ssklower 
4836398Ssklower 
4936398Ssklower #ifdef ISO
5045900Ssklower #ifdef TPCONS
5136398Ssklower 
5237469Ssklower #include "param.h"
5336398Ssklower #include "socket.h"
5436398Ssklower #include "domain.h"
5536398Ssklower #include "mbuf.h"
5636398Ssklower #include "errno.h"
5736398Ssklower #include "time.h"
5845900Ssklower 
5936398Ssklower #include "../net/if.h"
6045900Ssklower #include "../net/route.h"
6136398Ssklower 
6237469Ssklower #include "tp_param.h"
6337469Ssklower #include "argo_debug.h"
6437469Ssklower #include "tp_stat.h"
6537469Ssklower #include "tp_pcb.h"
6637469Ssklower #include "tp_trace.h"
6737469Ssklower #include "tp_stat.h"
6837469Ssklower #include "tp_tpdu.h"
6937469Ssklower #include "iso.h"
7045900Ssklower #include "iso_errno.h"
7137469Ssklower #include "iso_pcb.h"
7237469Ssklower #include "cons.h"
7337469Ssklower #include "tp_seq.h"
7436398Ssklower 
7545900Ssklower #undef FALSE
7645900Ssklower #undef TRUE
7745900Ssklower #include "../netccitt/x25.h"
7845900Ssklower #include "../netccitt/pk.h"
7945900Ssklower #include "../netccitt/pk_var.h"
8045900Ssklower 
8145900Ssklower #include "if_cons.c"
8236398Ssklower int tpcons_output();
8336398Ssklower 
8436398Ssklower /*
8536398Ssklower  * CALLED FROM:
8645900Ssklower  *  tp_route_to() for PRU_CONNECT
8745900Ssklower  * FUNCTION, ARGUMENTS, SIDE EFFECTS and RETURN VALUE:
8845900Ssklower  *  version of the previous procedure for X.25
8945900Ssklower  */
9045900Ssklower 
9145900Ssklower tpcons_pcbconnect(isop, nam)
9245900Ssklower struct isopcb *isop;
9345900Ssklower register struct mbuf *nam;
9445900Ssklower {
9545900Ssklower 	int error;
9645900Ssklower 	if (error = iso_pcbconnect(isop, nam))
9745900Ssklower 		return error;
9845900Ssklower 	if ((isop->isop_chan = (caddr_t) pk_attach((struct socket *)0)) == 0) {
9945900Ssklower 		IFDEBUG(D_CCONS)
10045900Ssklower 			printf("tpcons_pcbconnect: no pklcd; returns 0x%x\n", error);
10145900Ssklower 		ENDDEBUG
10245900Ssklower 		return ENOBUFS;
10345900Ssklower 	}
10445900Ssklower 	if (error = cons_connect(isop)) { /* if it doesn't work */
10545900Ssklower 		/* oh, dear, throw packet away */
10645900Ssklower 		pk_disconnect((struct pklcd *)isop->isop_chan);
10745900Ssklower 		isop->isop_chan = 0;
108*49257Ssklower 	} else
109*49257Ssklower 		isop->isop_refcnt = 1;
110*49257Ssklower 	return error;
11145900Ssklower }
11245900Ssklower 
11345900Ssklower 
11445900Ssklower /*
11545900Ssklower  * CALLED FROM:
11636398Ssklower  * 	cons
11736398Ssklower  * FUNCTION and ARGUMENTS:
11836398Ssklower  * THIS MAYBE BELONGS IN SOME OTHER PLACE??? but i think not -
11936398Ssklower  */
12036398Ssklower ProtoHook
12136398Ssklower tpcons_ctlinput(cmd, siso, isop)
12236398Ssklower 	int cmd;
12336398Ssklower 	struct sockaddr_iso *siso;
12436398Ssklower 	struct isopcb *isop;
12536398Ssklower {
12636398Ssklower 	switch (cmd) {
12736398Ssklower 
12836398Ssklower 	case PRC_CONS_SEND_DONE:
12936398Ssklower 		if( isop->isop_socket ) { /* tp 0 only */
13036398Ssklower 			register struct tp_pcb *tpcb =
13136398Ssklower 				(struct tp_pcb *)isop->isop_socket->so_tpcb;
13236398Ssklower 			struct 	tp_event 		E;
13336398Ssklower 			int 					error = 0;
13436398Ssklower 
13536398Ssklower 			if( tpcb->tp_class == TP_CLASS_0 ) {
13636398Ssklower 				/* only if class is exactly class zero, not
13736398Ssklower 				 * still in class negotiation
13836398Ssklower 				 */
13936398Ssklower 				/* fake an ack */
14036398Ssklower 				register SeqNum	seq =  SEQ_ADD(tpcb, tpcb->tp_snduna, 1);
14136398Ssklower 
14236398Ssklower 				IFTRACE(D_DATA)
14336398Ssklower 					tptrace(TPPTmisc, "FAKE ACK seq cdt 1",
14436398Ssklower 						seq, 0,0,0);
14536398Ssklower 				ENDTRACE
14636398Ssklower 				IFDEBUG(D_DATA)
14736398Ssklower 					printf("FAKE ACK seq 0x%x cdt 1\n", seq );
14836398Ssklower 				ENDDEBUG
14936398Ssklower 				E.ATTR(AK_TPDU).e_cdt = 1;
15036398Ssklower 				E.ATTR(AK_TPDU).e_seq = seq;
15136398Ssklower 				E.ATTR(AK_TPDU).e_subseq = 0;
15236398Ssklower 				E.ATTR(AK_TPDU).e_fcc_present = 0;
15336398Ssklower 				error =  DoEvent(AK_TPDU);
15436398Ssklower 				if( error ) {
15536398Ssklower 					tpcb->tp_sock->so_error = error;
15636398Ssklower 				}
15736398Ssklower 			} /* else ignore it */
15836398Ssklower 		}
15936398Ssklower 		break;
16036398Ssklower 	case PRC_ROUTEDEAD:
16136398Ssklower 		if( isop->isop_socket ) { /* tp 0 only */
16236398Ssklower 			tpiso_reset(isop);
16336398Ssklower 			break;
16436398Ssklower 		} /* else drop through */
16536398Ssklower 	default:
16636398Ssklower 		(void) tpclnp_ctlinput(cmd, siso);
16736398Ssklower 		break;
16836398Ssklower 	}
16936398Ssklower 	return 0;
17036398Ssklower }
17136398Ssklower 
17236398Ssklower /*
17336398Ssklower  * CALLED FROM:
17436398Ssklower  * 	cons's intr routine
17536398Ssklower  * FUNCTION and ARGUMENTS:
17636398Ssklower  * Take a packet (m) from cons, pullup m as required by tp,
17736398Ssklower  *  ignore the socket argument, and call tp_input.
17836398Ssklower  * No return value.
17936398Ssklower  */
18036398Ssklower ProtoHook
18145900Ssklower tpcons_input(m, faddr, laddr, channel)
18236398Ssklower 	struct mbuf 		*m;
18336398Ssklower 	struct sockaddr_iso	*faddr, *laddr;
18445900Ssklower 	caddr_t				channel;
18536398Ssklower {
18636398Ssklower 	if( m == MNULL)
18736398Ssklower 		return 0;
18836398Ssklower 
18936398Ssklower 	m = (struct mbuf *)tp_inputprep(m);
19036398Ssklower 
19136398Ssklower 	IFDEBUG(D_TPINPUT)
19236398Ssklower 		printf("tpcons_input before tp_input(m 0x%x)\n", m);
19336398Ssklower 		dump_buf( m, 12+ m->m_len);
19436398Ssklower 	ENDDEBUG
19548743Ssklower 	tp_input(m, faddr, laddr, channel, tpcons_output, 0);
19636398Ssklower 	return 0;
19736398Ssklower }
19836398Ssklower 
19936398Ssklower 
20036398Ssklower /*
20136398Ssklower  * CALLED FROM:
20236398Ssklower  *  tp_emit()
20336398Ssklower  * FUNCTION and ARGUMENTS:
20436398Ssklower  *  Take a packet(m0) from tp and package it so that cons will accept it.
20536398Ssklower  *  This means filling in a few of the fields.
20636398Ssklower  *  inp is the isopcb structure; datalen is the length of the data in the
20736398Ssklower  *  mbuf string m0.
20836398Ssklower  * RETURN VALUE:
20936398Ssklower  *  whatever (E*) is returned form the net layer output routine.
21036398Ssklower  */
21136398Ssklower 
21236398Ssklower int
21336398Ssklower tpcons_output(isop, m0, datalen, nochksum)
21436398Ssklower 	struct isopcb		*isop;
21536398Ssklower 	struct mbuf 		*m0;
21636398Ssklower 	int 				datalen;
21736398Ssklower 	int					nochksum;
21836398Ssklower {
21945900Ssklower 	register	struct mbuf *m = m0;
22036398Ssklower 	int					error;
22136398Ssklower 
22236398Ssklower 	IFDEBUG(D_EMIT)
22336398Ssklower 		printf(
22436398Ssklower 		"tpcons_output(isop 0x%x, m 0x%x, len 0x%x socket 0x%x\n",
22536398Ssklower 			isop, m0, datalen, isop->isop_socket);
22636398Ssklower 	ENDDEBUG
22745900Ssklower 	if (m == MNULL)
22836398Ssklower 		return 0;
22945900Ssklower 	if (m->m_flags & M_PKTHDR == 0) {
23045900Ssklower 		MGETHDR(m, M_DONTWAIT, MT_DATA);
23145900Ssklower 		if (m == 0)
23245900Ssklower 			return ENOBUFS;
23345900Ssklower 		m->m_next = m0;
23445900Ssklower 	}
23545900Ssklower 	m->m_pkthdr.len = datalen;
23645900Ssklower 	error = pk_send(isop->isop_chan, m);
23736398Ssklower 	IncStat(ts_tpdu_sent);
23836398Ssklower 
23936398Ssklower 	return error;
24036398Ssklower }
24136398Ssklower /*
24236398Ssklower  * CALLED FROM:
24336398Ssklower  *  tp_error_emit()
24436398Ssklower  * FUNCTION and ARGUMENTS:
24545900Ssklower  *  Take a packet(m0) from tp and package it so that cons will accept it.
24645900Ssklower  *  chan is the cons channel to use; datalen is the length of the data in the
24745900Ssklower  *  mbuf string m0.
24836398Ssklower  * RETURN VALUE:
24936398Ssklower  *  whatever (E*) is returned form the net layer output routine.
25036398Ssklower  */
25136398Ssklower 
25236398Ssklower int
25345900Ssklower tpcons_dg_output(chan, m0, datalen)
25445900Ssklower 	caddr_t				chan;
25536398Ssklower 	struct mbuf 		*m0;
25636398Ssklower 	int 				datalen;
25736398Ssklower {
25845900Ssklower 	return tpcons_output(((struct pklcd *)chan)->lcd_upnext, m0, datalen, 0);
25936398Ssklower }
26045900Ssklower #endif TPCONS
26136398Ssklower #endif ISO
262