xref: /csrg-svn/sys/netiso/tp_cons.c (revision 49268)
1*49268Sbostic /*-
2*49268Sbostic  * Copyright (c) 1991 The Regents of the University of California.
3*49268Sbostic  * All rights reserved.
4*49268Sbostic  *
5*49268Sbostic  * %sccs.include.redist.c%
6*49268Sbostic  *
7*49268Sbostic  *	@(#)tp_cons.c	7.7 (Berkeley) 05/06/91
8*49268Sbostic  */
9*49268Sbostic 
1036398Ssklower /***********************************************************
1136398Ssklower 		Copyright IBM Corporation 1987
1236398Ssklower 
1336398Ssklower                       All Rights Reserved
1436398Ssklower 
1536398Ssklower Permission to use, copy, modify, and distribute this software and its
1636398Ssklower documentation for any purpose and without fee is hereby granted,
1736398Ssklower provided that the above copyright notice appear in all copies and that
1836398Ssklower both that copyright notice and this permission notice appear in
1936398Ssklower supporting documentation, and that the name of IBM not be
2036398Ssklower used in advertising or publicity pertaining to distribution of the
2136398Ssklower software without specific, written prior permission.
2236398Ssklower 
2336398Ssklower IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
2436398Ssklower ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
2536398Ssklower IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
2636398Ssklower ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
2736398Ssklower WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
2836398Ssklower ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
2936398Ssklower SOFTWARE.
3036398Ssklower 
3136398Ssklower ******************************************************************/
3236398Ssklower 
3336398Ssklower /*
3436398Ssklower  * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
3536398Ssklower  */
3636398Ssklower /*
3736398Ssklower  * ARGO TP
3836398Ssklower  * $Header: tp_cons.c,v 5.6 88/11/18 17:27:13 nhall Exp $
3936398Ssklower  * $Source: /usr/argo/sys/netiso/RCS/tp_cons.c,v $
4036398Ssklower  *
4145900Ssklower  * Here is where you find the iso- and cons-dependent code.  We've tried
4236398Ssklower  * keep all net-level and (primarily) address-family-dependent stuff
4336398Ssklower  * out of the tp source, and everthing here is reached indirectly
4436398Ssklower  * through a switch table (struct nl_protosw *) tpcb->tp_nlproto
4536398Ssklower  * (see tp_pcb.c).
4636398Ssklower  * The routines here are:
47*49268Sbostic  *	tpcons_input: pullup and call tp_input w/ correct arguments
48*49268Sbostic  *	tpcons_output: package a pkt for cons given an isopcb & some data
49*49268Sbostic  *	cons_chan_to_tpcb: find a tpcb based on the channel #
5036398Ssklower  */
5136398Ssklower 
5236398Ssklower #ifdef ISO
5345900Ssklower #ifdef TPCONS
5436398Ssklower 
5537469Ssklower #include "param.h"
5636398Ssklower #include "socket.h"
5736398Ssklower #include "domain.h"
5836398Ssklower #include "mbuf.h"
5936398Ssklower #include "errno.h"
6036398Ssklower #include "time.h"
6145900Ssklower 
6236398Ssklower #include "../net/if.h"
6345900Ssklower #include "../net/route.h"
6436398Ssklower 
6537469Ssklower #include "tp_param.h"
6637469Ssklower #include "argo_debug.h"
6737469Ssklower #include "tp_stat.h"
6837469Ssklower #include "tp_pcb.h"
6937469Ssklower #include "tp_trace.h"
7037469Ssklower #include "tp_stat.h"
7137469Ssklower #include "tp_tpdu.h"
7237469Ssklower #include "iso.h"
7345900Ssklower #include "iso_errno.h"
7437469Ssklower #include "iso_pcb.h"
7537469Ssklower #include "cons.h"
7637469Ssklower #include "tp_seq.h"
7736398Ssklower 
7845900Ssklower #undef FALSE
7945900Ssklower #undef TRUE
8045900Ssklower #include "../netccitt/x25.h"
8145900Ssklower #include "../netccitt/pk.h"
8245900Ssklower #include "../netccitt/pk_var.h"
8345900Ssklower 
8445900Ssklower #include "if_cons.c"
8536398Ssklower int tpcons_output();
8636398Ssklower 
8736398Ssklower /*
8836398Ssklower  * CALLED FROM:
8945900Ssklower  *  tp_route_to() for PRU_CONNECT
9045900Ssklower  * FUNCTION, ARGUMENTS, SIDE EFFECTS and RETURN VALUE:
9145900Ssklower  *  version of the previous procedure for X.25
9245900Ssklower  */
9345900Ssklower 
9445900Ssklower tpcons_pcbconnect(isop, nam)
9545900Ssklower struct isopcb *isop;
9645900Ssklower register struct mbuf *nam;
9745900Ssklower {
9845900Ssklower 	int error;
9945900Ssklower 	if (error = iso_pcbconnect(isop, nam))
10045900Ssklower 		return error;
10145900Ssklower 	if ((isop->isop_chan = (caddr_t) pk_attach((struct socket *)0)) == 0) {
10245900Ssklower 		IFDEBUG(D_CCONS)
10345900Ssklower 			printf("tpcons_pcbconnect: no pklcd; returns 0x%x\n", error);
10445900Ssklower 		ENDDEBUG
10545900Ssklower 		return ENOBUFS;
10645900Ssklower 	}
10745900Ssklower 	if (error = cons_connect(isop)) { /* if it doesn't work */
10845900Ssklower 		/* oh, dear, throw packet away */
10945900Ssklower 		pk_disconnect((struct pklcd *)isop->isop_chan);
11045900Ssklower 		isop->isop_chan = 0;
11149257Ssklower 	} else
11249257Ssklower 		isop->isop_refcnt = 1;
11349257Ssklower 	return error;
11445900Ssklower }
11545900Ssklower 
11645900Ssklower 
11745900Ssklower /*
11845900Ssklower  * CALLED FROM:
11936398Ssklower  * 	cons
12036398Ssklower  * FUNCTION and ARGUMENTS:
12136398Ssklower  * THIS MAYBE BELONGS IN SOME OTHER PLACE??? but i think not -
12236398Ssklower  */
12336398Ssklower ProtoHook
12436398Ssklower tpcons_ctlinput(cmd, siso, isop)
12536398Ssklower 	int cmd;
12636398Ssklower 	struct sockaddr_iso *siso;
12736398Ssklower 	struct isopcb *isop;
12836398Ssklower {
12936398Ssklower 	switch (cmd) {
13036398Ssklower 
13136398Ssklower 	case PRC_CONS_SEND_DONE:
13236398Ssklower 		if( isop->isop_socket ) { /* tp 0 only */
13336398Ssklower 			register struct tp_pcb *tpcb =
13436398Ssklower 				(struct tp_pcb *)isop->isop_socket->so_tpcb;
13536398Ssklower 			struct 	tp_event 		E;
13636398Ssklower 			int 					error = 0;
13736398Ssklower 
13836398Ssklower 			if( tpcb->tp_class == TP_CLASS_0 ) {
13936398Ssklower 				/* only if class is exactly class zero, not
14036398Ssklower 				 * still in class negotiation
14136398Ssklower 				 */
14236398Ssklower 				/* fake an ack */
14336398Ssklower 				register SeqNum	seq =  SEQ_ADD(tpcb, tpcb->tp_snduna, 1);
14436398Ssklower 
14536398Ssklower 				IFTRACE(D_DATA)
14636398Ssklower 					tptrace(TPPTmisc, "FAKE ACK seq cdt 1",
14736398Ssklower 						seq, 0,0,0);
14836398Ssklower 				ENDTRACE
14936398Ssklower 				IFDEBUG(D_DATA)
15036398Ssklower 					printf("FAKE ACK seq 0x%x cdt 1\n", seq );
15136398Ssklower 				ENDDEBUG
15236398Ssklower 				E.ATTR(AK_TPDU).e_cdt = 1;
15336398Ssklower 				E.ATTR(AK_TPDU).e_seq = seq;
15436398Ssklower 				E.ATTR(AK_TPDU).e_subseq = 0;
15536398Ssklower 				E.ATTR(AK_TPDU).e_fcc_present = 0;
15636398Ssklower 				error =  DoEvent(AK_TPDU);
15736398Ssklower 				if( error ) {
15836398Ssklower 					tpcb->tp_sock->so_error = error;
15936398Ssklower 				}
16036398Ssklower 			} /* else ignore it */
16136398Ssklower 		}
16236398Ssklower 		break;
16336398Ssklower 	case PRC_ROUTEDEAD:
16436398Ssklower 		if( isop->isop_socket ) { /* tp 0 only */
16536398Ssklower 			tpiso_reset(isop);
16636398Ssklower 			break;
16736398Ssklower 		} /* else drop through */
16836398Ssklower 	default:
16936398Ssklower 		(void) tpclnp_ctlinput(cmd, siso);
17036398Ssklower 		break;
17136398Ssklower 	}
17236398Ssklower 	return 0;
17336398Ssklower }
17436398Ssklower 
17536398Ssklower /*
17636398Ssklower  * CALLED FROM:
17736398Ssklower  * 	cons's intr routine
17836398Ssklower  * FUNCTION and ARGUMENTS:
17936398Ssklower  * Take a packet (m) from cons, pullup m as required by tp,
18036398Ssklower  *  ignore the socket argument, and call tp_input.
18136398Ssklower  * No return value.
18236398Ssklower  */
18336398Ssklower ProtoHook
18445900Ssklower tpcons_input(m, faddr, laddr, channel)
18536398Ssklower 	struct mbuf 		*m;
18636398Ssklower 	struct sockaddr_iso	*faddr, *laddr;
18745900Ssklower 	caddr_t				channel;
18836398Ssklower {
18936398Ssklower 	if( m == MNULL)
19036398Ssklower 		return 0;
19136398Ssklower 
19236398Ssklower 	m = (struct mbuf *)tp_inputprep(m);
19336398Ssklower 
19436398Ssklower 	IFDEBUG(D_TPINPUT)
19536398Ssklower 		printf("tpcons_input before tp_input(m 0x%x)\n", m);
19636398Ssklower 		dump_buf( m, 12+ m->m_len);
19736398Ssklower 	ENDDEBUG
19848743Ssklower 	tp_input(m, faddr, laddr, channel, tpcons_output, 0);
19936398Ssklower 	return 0;
20036398Ssklower }
20136398Ssklower 
20236398Ssklower 
20336398Ssklower /*
20436398Ssklower  * CALLED FROM:
20536398Ssklower  *  tp_emit()
20636398Ssklower  * FUNCTION and ARGUMENTS:
20736398Ssklower  *  Take a packet(m0) from tp and package it so that cons will accept it.
20836398Ssklower  *  This means filling in a few of the fields.
20936398Ssklower  *  inp is the isopcb structure; datalen is the length of the data in the
21036398Ssklower  *  mbuf string m0.
21136398Ssklower  * RETURN VALUE:
21236398Ssklower  *  whatever (E*) is returned form the net layer output routine.
21336398Ssklower  */
21436398Ssklower 
21536398Ssklower int
21636398Ssklower tpcons_output(isop, m0, datalen, nochksum)
21736398Ssklower 	struct isopcb		*isop;
21836398Ssklower 	struct mbuf 		*m0;
21936398Ssklower 	int 				datalen;
22036398Ssklower 	int					nochksum;
22136398Ssklower {
22245900Ssklower 	register	struct mbuf *m = m0;
22336398Ssklower 	int					error;
22436398Ssklower 
22536398Ssklower 	IFDEBUG(D_EMIT)
22636398Ssklower 		printf(
22736398Ssklower 		"tpcons_output(isop 0x%x, m 0x%x, len 0x%x socket 0x%x\n",
22836398Ssklower 			isop, m0, datalen, isop->isop_socket);
22936398Ssklower 	ENDDEBUG
23045900Ssklower 	if (m == MNULL)
23136398Ssklower 		return 0;
23245900Ssklower 	if (m->m_flags & M_PKTHDR == 0) {
23345900Ssklower 		MGETHDR(m, M_DONTWAIT, MT_DATA);
23445900Ssklower 		if (m == 0)
23545900Ssklower 			return ENOBUFS;
23645900Ssklower 		m->m_next = m0;
23745900Ssklower 	}
23845900Ssklower 	m->m_pkthdr.len = datalen;
23945900Ssklower 	error = pk_send(isop->isop_chan, m);
24036398Ssklower 	IncStat(ts_tpdu_sent);
24136398Ssklower 
24236398Ssklower 	return error;
24336398Ssklower }
24436398Ssklower /*
24536398Ssklower  * CALLED FROM:
24636398Ssklower  *  tp_error_emit()
24736398Ssklower  * FUNCTION and ARGUMENTS:
24845900Ssklower  *  Take a packet(m0) from tp and package it so that cons will accept it.
24945900Ssklower  *  chan is the cons channel to use; datalen is the length of the data in the
25045900Ssklower  *  mbuf string m0.
25136398Ssklower  * RETURN VALUE:
25236398Ssklower  *  whatever (E*) is returned form the net layer output routine.
25336398Ssklower  */
25436398Ssklower 
25536398Ssklower int
25645900Ssklower tpcons_dg_output(chan, m0, datalen)
25745900Ssklower 	caddr_t				chan;
25836398Ssklower 	struct mbuf 		*m0;
25936398Ssklower 	int 				datalen;
26036398Ssklower {
26145900Ssklower 	return tpcons_output(((struct pklcd *)chan)->lcd_upnext, m0, datalen, 0);
26236398Ssklower }
26345900Ssklower #endif TPCONS
26436398Ssklower #endif ISO
265