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