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