1*56483Ssklower /* 2*56483Ssklower * Copyright (c) 1982, 1986, 1988, 1990 Regents of the University of California. 3*56483Ssklower * All rights reserved. 4*56483Ssklower * 5*56483Ssklower * %sccs.include.redist.c% 6*56483Ssklower * 7*56483Ssklower * @(#)tuba_subr.c 7.1 (Berkeley) 10/09/92 8*56483Ssklower */ 9*56483Ssklower 10*56483Ssklower #include "param.h" 11*56483Ssklower #include "proc.h" 12*56483Ssklower #include "systm.h" 13*56483Ssklower #include "malloc.h" 14*56483Ssklower #include "mbuf.h" 15*56483Ssklower #include "socket.h" 16*56483Ssklower #include "socketvar.h" 17*56483Ssklower #include "protosw.h" 18*56483Ssklower #include "errno.h" 19*56483Ssklower 20*56483Ssklower #include "../net/route.h" 21*56483Ssklower #include "../net/if.h" 22*56483Ssklower 23*56483Ssklower #include "in.h" 24*56483Ssklower #include "in_systm.h" 25*56483Ssklower #include "ip.h" 26*56483Ssklower #include "in_pcb.h" 27*56483Ssklower #include "ip_var.h" 28*56483Ssklower #include "ip_icmp.h" 29*56483Ssklower #include "tcp.h" 30*56483Ssklower #include "tcp_fsm.h" 31*56483Ssklower #include "tcp_seq.h" 32*56483Ssklower #include "tcp_timer.h" 33*56483Ssklower #include "tcp_var.h" 34*56483Ssklower #include "tcpip.h" 35*56483Ssklower 36*56483Ssklower #include "netiso/argo_debug.h" 37*56483Ssklower #include "netiso/iso.h" 38*56483Ssklower #include "netiso/clnp.h" 39*56483Ssklower #include "netiso/iso_pcb.h" 40*56483Ssklower #include "netiso/iso_var.h" 41*56483Ssklower 42*56483Ssklower #include "tuba_addr.h" 43*56483Ssklower /* 44*56483Ssklower * Tuba initialization 45*56483Ssklower */ 46*56483Ssklower tuba_init() 47*56483Ssklower { 48*56483Ssklower 49*56483Ssklower extern struct isopcb tuba_isopcb; 50*56483Ssklower 51*56483Ssklower tuba_isopcb.isop_next = tuba_isopcb.isop_prev = &tuba_isopcb; 52*56483Ssklower #define TUBAHDRSIZE (3 /*LLC*/ + 9 /*CLNP Fixed*/ + 42 /*Addresses*/ \ 53*56483Ssklower + 6 /*CLNP Segment*/ + 20 /*TCP*/) 54*56483Ssklower 55*56483Ssklower if (max_protohdr < TUBAHDRSIZE) 56*56483Ssklower max_protohdr = TUBAHDRSIZE; 57*56483Ssklower if (max_linkhdr + TUBAHDRSIZE > MHLEN) 58*56483Ssklower panic("tuba_init"); 59*56483Ssklower } 60*56483Ssklower 61*56483Ssklower tuba_output(tp, m) 62*56483Ssklower struct tcpcb *tp; 63*56483Ssklower register struct mbuf *m; 64*56483Ssklower { 65*56483Ssklower struct isopcb *isop = (struct isopcb *)tp->t_tuba_pcb; 66*56483Ssklower register struct tcpiphdr *n = tp->tp_template; 67*56483Ssklower 68*56483Ssklower if (n->ni_sum == 0) { 69*56483Ssklower register struct inpcb *inp = tp->tp_inpcb; 70*56483Ssklower register struct tuba_cache *tc; 71*56483Ssklower u_long cksum_fixup; 72*56483Ssklower 73*56483Ssklower if ((tc = tuba_table[inp->in_faddr.s_addr]) == 0) 74*56483Ssklower return (ENOBUFS); 75*56483Ssklower cksum_fixup = tc->tc_sum_out; /* includes -index */ 76*56483Ssklower if ((tc = tuba_table[inp->in_laddr.s_addr]) == 0) 77*56483Ssklower return (ENOBUFS); 78*56483Ssklower ICKSUM(cksum_fixup, cksum_fixup + tc->tc_sum_out); 79*56483Ssklower n->ti_sum = cksum_fixup; 80*56483Ssklower n = mtod(m, struct tcpiphdr *); 81*56483Ssklower ICKSUM(n->ti_sum, cksum_fixup + n->ti_sum); 82*56483Ssklower } 83*56483Ssklower m->m_len -= sizeof (struct ip); 84*56483Ssklower m->m_pkthdr.len -= sizeof (struct ip); 85*56483Ssklower m->m_data += sizeof (struct ip); 86*56483Ssklower return (clnp_output(m, isop, m->m_pkthdr.len, 0)); 87*56483Ssklower } 88*56483Ssklower 89*56483Ssklower tuba_refcnt(isop, delta) 90*56483Ssklower struct isopcb *isop; 91*56483Ssklower { 92*56483Ssklower register struct tuba_cache *tc; 93*56483Ssklower unsigned index; 94*56483Ssklower 95*56483Ssklower if (delta != 1) 96*56483Ssklower delta = -1; 97*56483Ssklower if (isop == 0 || isop->isop_faddr == 0 || isop->isop_laddr == 0 || 98*56483Ssklower (delta == -1 && isop->isop_tuba_cached == 0) || 99*56483Ssklower (delta == 1 && isop->isop_tuba_cached != 0)) 100*56483Ssklower return; 101*56483Ssklower isop->isop_tuba_cached = (delta == 1); 102*56483Ssklower if ((index = tuba_lookup(&isop->isop_faddr.siso_addr)) != 0 && 103*56483Ssklower (tc = tuba_cache[index]) != 0 && (delta == 1 || tc->tc_refcnt > 0)) 104*56483Ssklower tc->tc_refcnt += delta; 105*56483Ssklower if ((index = tuba_lookup(&isop->isop_laddr.siso_addr)) != 0 && 106*56483Ssklower (tc = tuba_cache[index]) != 0 && (delta == 1 || tc->tc_refcnt > 0)) 107*56483Ssklower tc->tc_refcnt += delta; 108*56483Ssklower } 109*56483Ssklower 110*56483Ssklower tuba_pcbdetach(isop) 111*56483Ssklower struct isopcb *isop; 112*56483Ssklower { 113*56483Ssklower if (isop == 0) 114*56483Ssklower return; 115*56483Ssklower tuba_refcnt(isop, -1); 116*56483Ssklower isop->isop_socket = 0; 117*56483Ssklower iso_pcbdetach(isop); 118*56483Ssklower } 119*56483Ssklower 120*56483Ssklower static struct sockaddr_iso null_siso = { sizeof(null_siso), AF_ISO, }; 121*56483Ssklower /* 122*56483Ssklower * Avoid in_pcbconnect in faked out tcp_input() 123*56483Ssklower */ 124*56483Ssklower tuba_pcbconnect(inp, nam) 125*56483Ssklower register struct inpcb *inp; 126*56483Ssklower struct mbuf *nam; 127*56483Ssklower { 128*56483Ssklower register struct sockaddr_iso *siso = mtod(m, struct sockaddr_iso *); 129*56483Ssklower struct sockaddr_in *sin = mtod(m, struct sockaddr_in *); 130*56483Ssklower struct tcpcb *tp = intotcpcb(inp); 131*56483Ssklower unsigned index = sin->sin_addr.s_addr; 132*56483Ssklower struct tuba_cache *tc = tuba_table[index]; 133*56483Ssklower struct isopcb *isop = (struct isopcb *)tp->tp_tuba_pcb; 134*56483Ssklower int error; 135*56483Ssklower 136*56483Ssklower inp->inp_faddr.s_addr = index; 137*56483Ssklower inp->inp_fport = sin->sin_port; 138*56483Ssklower *siso = null_siso; 139*56483Ssklower siso->siso_addr = tc->tc_addr; 140*56483Ssklower siso->siso_tlen = sizeof(inp->inp_fport); 141*56483Ssklower bcopy((caddr_t)&inp->inp_fport, TSEL(siso), sizeof(inp->inp_fport)); 142*56483Ssklower nam->m_len = sizeof(*siso); 143*56483Ssklower if ((error = iso_pcbconnect(isop, nam)) == 0) 144*56483Ssklower tuba_refcnt(isop, 1); 145*56483Ssklower return (error); 146*56483Ssklower } 147*56483Ssklower 148*56483Ssklower /* 149*56483Ssklower * CALLED FROM: 150*56483Ssklower * clnp's input routine, indirectly through the protosw. 151*56483Ssklower * FUNCTION and ARGUMENTS: 152*56483Ssklower * Take a packet (m) from clnp, strip off the clnp header and give it to tcp 153*56483Ssklower * or udp. 154*56483Ssklower * No return value. 155*56483Ssklower */ 156*56483Ssklower ProtoHook 157*56483Ssklower tpclnp_input(m, src, dst, clnp_len, ce_bit) 158*56483Ssklower register struct mbuf *m; 159*56483Ssklower struct sockaddr_iso *src, *dst; 160*56483Ssklower int clnp_len, ce_bit; 161*56483Ssklower { 162*56483Ssklower int s = splnet(); 163*56483Ssklower unsigned long fix_csum, lindex, findex; 164*56483Ssklower register struct tcpiphdr *ti; 165*56483Ssklower register struct inpcb *inp; 166*56483Ssklower struct mbuf *om = 0; 167*56483Ssklower int len, tlen, off; 168*56483Ssklower register struct tcpcb *tp = 0; 169*56483Ssklower int tiflags; 170*56483Ssklower struct socket *so; 171*56483Ssklower int todrop, acked, ourfinisacked, needoutput = 0; 172*56483Ssklower short ostate; 173*56483Ssklower struct in_addr laddr; 174*56483Ssklower int dropsocket = 0, iss = 0; 175*56483Ssklower 176*56483Ssklower if ((m->m_flags & M_PKTHDR) == 0) 177*56483Ssklower panic("tuba_input"); 178*56483Ssklower /* 179*56483Ssklower * Do some housekeeping looking up CLNP addresses. 180*56483Ssklower * If we are out of space might as well drop the packet now. 181*56483Ssklower */ 182*56483Ssklower tcpstat.tcps_rcvtotal++; 183*56483Ssklower if ((lindex = tuba_lookup(&dst->siso_addr) == 0 || 184*56483Ssklower (findex = tuba_lookup(&dst->siso_addr) == 0)) 185*56483Ssklower goto drop; 186*56483Ssklower /* 187*56483Ssklower * Get CLNP and TCP header together in first mbuf. 188*56483Ssklower * CLNP gave us an mbuf chain WITH the clnp header pulled up, 189*56483Ssklower * and the length of the clnp header. 190*56483Ssklower */ 191*56483Ssklower len = clnp_len + sizeof(struct tcphdr); 192*56483Ssklower if (m->m_len < len) { 193*56483Ssklower if ((m = m_pullup(m, len)) == 0) { 194*56483Ssklower tcpstat.tcps_rcvshort++; 195*56483Ssklower return; 196*56483Ssklower } 197*56483Ssklower } 198*56483Ssklower /* 199*56483Ssklower * Calculate checksum of extended TCP header and data, 200*56483Ssklower * by adjusting the checksum for missing parts of the header. 201*56483Ssklower */ 202*56483Ssklower m->m_data += clnp_len; 203*56483Ssklower m->m_len -= clnp_len; 204*56483Ssklower tlen = m->m_pkthdr.len -= clnp_len; 205*56483Ssklower ICKSUM(fix_cksum, tuba_table[findex]->tc_sum_in + htons((u_short)tlen) 206*56483Ssklower + tuba_table[lindex]->tc_sum_in + in_cksum(m, tlen)); 207*56483Ssklower if (fix_cksum != 0xffff) { 208*56483Ssklower tcpstat.tcps_rcvbadsum++; 209*56483Ssklower goto drop; 210*56483Ssklower } 211*56483Ssklower m->m_data -= sizeof(struct ip); 212*56483Ssklower m->m_len += sizeof(struct ip); 213*56483Ssklower m->m_pkthdr.len += sizeof(struct ip); 214*56483Ssklower /* 215*56483Ssklower * The reassembly code assumes it will be overwriting a useless 216*56483Ssklower * part of the packet, which is why we need to have ti point 217*56483Ssklower * into the packet itself. 218*56483Ssklower * 219*56483Ssklower * Check to see if the data is properly alligned 220*56483Ssklower * so that we can save copying the tcp header. 221*56483Ssklower * This code knows way too much about the structure of mbufs! 222*56483Ssklower */ 223*56483Ssklower off = ((sizeof (long) - 1) & ((m->m_flags & EXT) ? 224*56483Ssklower (m->m_data - m->m_ext.ext_buf) : (m->m_data - m_pktdat))); 225*56483Ssklower if (off) { 226*56483Ssklower struct mbuf *m0 = m_gethdr(M_DONTWAIT, MT_DATA) 227*56483Ssklower if (m0 == 0) { 228*56483Ssklower goto drop; 229*56483Ssklower } 230*56483Ssklower bcopy(mtod(m, caddr_t) + sizeof(struct ip), 231*56483Ssklower mtod(m0, caddr_t) + sizeof(struct ip), 232*56483Ssklower sizeof(struct tcphdr)); 233*56483Ssklower m->m_data += sizeof(struct tcpiphdr); 234*56483Ssklower m0->m_next = m; 235*56483Ssklower m0->m_pkthdr = m->m_pkthdr; 236*56483Ssklower m0->m_flags = m->m_pkthdr & M_COPYFLAGS; 237*56483Ssklower m0->m_len = sizeof(struct tcpiphdr); 238*56483Ssklower m = m0; 239*56483Ssklower } 240*56483Ssklower ti = mtod(m, struct tcpiphdr *); 241*56483Ssklower ti->ti_src.s_addr = findex; 242*56483Ssklower ti->ti_dst.s_addr = lindex; 243*56483Ssklower ti->ti_len = tlen; 244*56483Ssklower /* 245*56483Ssklower * Now include the rest of TCP input 246*56483Ssklower */ 247*56483Ssklower #define TUBA_INPUT 248*56483Ssklower #define in_pcbconnect tuba_pcbconnect 249*56483Ssklower 250*56483Ssklower #include "../netinet/tcp_input.c" 251*56483Ssklower } 252