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