156483Ssklower /* 2*56484Ssklower * Copyright (c) 1992 Regents of the University of California. 356483Ssklower * All rights reserved. 456483Ssklower * 556483Ssklower * %sccs.include.redist.c% 656483Ssklower * 7*56484Ssklower * @(#)tuba_subr.c 7.2 (Berkeley) 10/09/92 856483Ssklower */ 956483Ssklower 1056483Ssklower #include "param.h" 1156483Ssklower #include "proc.h" 1256483Ssklower #include "systm.h" 1356483Ssklower #include "malloc.h" 1456483Ssklower #include "mbuf.h" 1556483Ssklower #include "socket.h" 1656483Ssklower #include "socketvar.h" 1756483Ssklower #include "protosw.h" 1856483Ssklower #include "errno.h" 1956483Ssklower 2056483Ssklower #include "../net/route.h" 2156483Ssklower #include "../net/if.h" 2256483Ssklower 2356483Ssklower #include "in.h" 2456483Ssklower #include "in_systm.h" 2556483Ssklower #include "ip.h" 2656483Ssklower #include "in_pcb.h" 2756483Ssklower #include "ip_var.h" 2856483Ssklower #include "ip_icmp.h" 2956483Ssklower #include "tcp.h" 3056483Ssklower #include "tcp_fsm.h" 3156483Ssklower #include "tcp_seq.h" 3256483Ssklower #include "tcp_timer.h" 3356483Ssklower #include "tcp_var.h" 3456483Ssklower #include "tcpip.h" 3556483Ssklower 3656483Ssklower #include "netiso/argo_debug.h" 3756483Ssklower #include "netiso/iso.h" 3856483Ssklower #include "netiso/clnp.h" 3956483Ssklower #include "netiso/iso_pcb.h" 4056483Ssklower #include "netiso/iso_var.h" 4156483Ssklower 4256483Ssklower #include "tuba_addr.h" 4356483Ssklower /* 4456483Ssklower * Tuba initialization 4556483Ssklower */ 4656483Ssklower tuba_init() 4756483Ssklower { 48*56484Ssklower #define TUBAHDRSIZE (3 /*LLC*/ + 9 /*CLNP Fixed*/ + 42 /*Addresses*/ \ 49*56484Ssklower + 6 /*CLNP Segment*/ + 20 /*TCP*/) 5056483Ssklower extern struct isopcb tuba_isopcb; 5156483Ssklower 5256483Ssklower tuba_isopcb.isop_next = tuba_isopcb.isop_prev = &tuba_isopcb; 5356483Ssklower if (max_protohdr < TUBAHDRSIZE) 5456483Ssklower max_protohdr = TUBAHDRSIZE; 5556483Ssklower if (max_linkhdr + TUBAHDRSIZE > MHLEN) 5656483Ssklower panic("tuba_init"); 57*56484Ssklower tuba_timer_init(); 5856483Ssklower } 5956483Ssklower 6056483Ssklower tuba_output(tp, m) 6156483Ssklower struct tcpcb *tp; 6256483Ssklower register struct mbuf *m; 6356483Ssklower { 6456483Ssklower struct isopcb *isop = (struct isopcb *)tp->t_tuba_pcb; 6556483Ssklower register struct tcpiphdr *n = tp->tp_template; 6656483Ssklower 6756483Ssklower if (n->ni_sum == 0) { 6856483Ssklower register struct inpcb *inp = tp->tp_inpcb; 6956483Ssklower register struct tuba_cache *tc; 7056483Ssklower u_long cksum_fixup; 7156483Ssklower 7256483Ssklower if ((tc = tuba_table[inp->in_faddr.s_addr]) == 0) 7356483Ssklower return (ENOBUFS); 7456483Ssklower cksum_fixup = tc->tc_sum_out; /* includes -index */ 7556483Ssklower if ((tc = tuba_table[inp->in_laddr.s_addr]) == 0) 7656483Ssklower return (ENOBUFS); 7756483Ssklower ICKSUM(cksum_fixup, cksum_fixup + tc->tc_sum_out); 7856483Ssklower n->ti_sum = cksum_fixup; 7956483Ssklower n = mtod(m, struct tcpiphdr *); 8056483Ssklower ICKSUM(n->ti_sum, cksum_fixup + n->ti_sum); 8156483Ssklower } 8256483Ssklower m->m_len -= sizeof (struct ip); 8356483Ssklower m->m_pkthdr.len -= sizeof (struct ip); 8456483Ssklower m->m_data += sizeof (struct ip); 8556483Ssklower return (clnp_output(m, isop, m->m_pkthdr.len, 0)); 8656483Ssklower } 8756483Ssklower 8856483Ssklower tuba_refcnt(isop, delta) 8956483Ssklower struct isopcb *isop; 9056483Ssklower { 9156483Ssklower register struct tuba_cache *tc; 9256483Ssklower unsigned index; 9356483Ssklower 9456483Ssklower if (delta != 1) 9556483Ssklower delta = -1; 9656483Ssklower if (isop == 0 || isop->isop_faddr == 0 || isop->isop_laddr == 0 || 9756483Ssklower (delta == -1 && isop->isop_tuba_cached == 0) || 9856483Ssklower (delta == 1 && isop->isop_tuba_cached != 0)) 9956483Ssklower return; 10056483Ssklower isop->isop_tuba_cached = (delta == 1); 10156483Ssklower if ((index = tuba_lookup(&isop->isop_faddr.siso_addr)) != 0 && 10256483Ssklower (tc = tuba_cache[index]) != 0 && (delta == 1 || tc->tc_refcnt > 0)) 10356483Ssklower tc->tc_refcnt += delta; 10456483Ssklower if ((index = tuba_lookup(&isop->isop_laddr.siso_addr)) != 0 && 10556483Ssklower (tc = tuba_cache[index]) != 0 && (delta == 1 || tc->tc_refcnt > 0)) 10656483Ssklower tc->tc_refcnt += delta; 10756483Ssklower } 10856483Ssklower 10956483Ssklower tuba_pcbdetach(isop) 11056483Ssklower struct isopcb *isop; 11156483Ssklower { 11256483Ssklower if (isop == 0) 11356483Ssklower return; 11456483Ssklower tuba_refcnt(isop, -1); 11556483Ssklower isop->isop_socket = 0; 11656483Ssklower iso_pcbdetach(isop); 11756483Ssklower } 11856483Ssklower 11956483Ssklower static struct sockaddr_iso null_siso = { sizeof(null_siso), AF_ISO, }; 12056483Ssklower /* 12156483Ssklower * Avoid in_pcbconnect in faked out tcp_input() 12256483Ssklower */ 12356483Ssklower tuba_pcbconnect(inp, nam) 12456483Ssklower register struct inpcb *inp; 12556483Ssklower struct mbuf *nam; 12656483Ssklower { 12756483Ssklower register struct sockaddr_iso *siso = mtod(m, struct sockaddr_iso *); 12856483Ssklower struct sockaddr_in *sin = mtod(m, struct sockaddr_in *); 12956483Ssklower struct tcpcb *tp = intotcpcb(inp); 13056483Ssklower unsigned index = sin->sin_addr.s_addr; 13156483Ssklower struct tuba_cache *tc = tuba_table[index]; 13256483Ssklower struct isopcb *isop = (struct isopcb *)tp->tp_tuba_pcb; 13356483Ssklower int error; 13456483Ssklower 13556483Ssklower inp->inp_faddr.s_addr = index; 13656483Ssklower inp->inp_fport = sin->sin_port; 13756483Ssklower *siso = null_siso; 13856483Ssklower siso->siso_addr = tc->tc_addr; 13956483Ssklower siso->siso_tlen = sizeof(inp->inp_fport); 14056483Ssklower bcopy((caddr_t)&inp->inp_fport, TSEL(siso), sizeof(inp->inp_fport)); 14156483Ssklower nam->m_len = sizeof(*siso); 14256483Ssklower if ((error = iso_pcbconnect(isop, nam)) == 0) 14356483Ssklower tuba_refcnt(isop, 1); 14456483Ssklower return (error); 14556483Ssklower } 14656483Ssklower 14756483Ssklower /* 14856483Ssklower * CALLED FROM: 14956483Ssklower * clnp's input routine, indirectly through the protosw. 15056483Ssklower * FUNCTION and ARGUMENTS: 15156483Ssklower * Take a packet (m) from clnp, strip off the clnp header and give it to tcp 15256483Ssklower * or udp. 15356483Ssklower * No return value. 15456483Ssklower */ 15556483Ssklower ProtoHook 15656483Ssklower tpclnp_input(m, src, dst, clnp_len, ce_bit) 15756483Ssklower register struct mbuf *m; 15856483Ssklower struct sockaddr_iso *src, *dst; 15956483Ssklower int clnp_len, ce_bit; 16056483Ssklower { 16156483Ssklower int s = splnet(); 16256483Ssklower unsigned long fix_csum, lindex, findex; 16356483Ssklower register struct tcpiphdr *ti; 16456483Ssklower register struct inpcb *inp; 16556483Ssklower struct mbuf *om = 0; 16656483Ssklower int len, tlen, off; 16756483Ssklower register struct tcpcb *tp = 0; 16856483Ssklower int tiflags; 16956483Ssklower struct socket *so; 17056483Ssklower int todrop, acked, ourfinisacked, needoutput = 0; 17156483Ssklower short ostate; 17256483Ssklower struct in_addr laddr; 17356483Ssklower int dropsocket = 0, iss = 0; 17456483Ssklower 17556483Ssklower if ((m->m_flags & M_PKTHDR) == 0) 17656483Ssklower panic("tuba_input"); 17756483Ssklower /* 17856483Ssklower * Do some housekeeping looking up CLNP addresses. 17956483Ssklower * If we are out of space might as well drop the packet now. 18056483Ssklower */ 18156483Ssklower tcpstat.tcps_rcvtotal++; 18256483Ssklower if ((lindex = tuba_lookup(&dst->siso_addr) == 0 || 18356483Ssklower (findex = tuba_lookup(&dst->siso_addr) == 0)) 18456483Ssklower goto drop; 18556483Ssklower /* 18656483Ssklower * Get CLNP and TCP header together in first mbuf. 18756483Ssklower * CLNP gave us an mbuf chain WITH the clnp header pulled up, 18856483Ssklower * and the length of the clnp header. 18956483Ssklower */ 19056483Ssklower len = clnp_len + sizeof(struct tcphdr); 19156483Ssklower if (m->m_len < len) { 19256483Ssklower if ((m = m_pullup(m, len)) == 0) { 19356483Ssklower tcpstat.tcps_rcvshort++; 19456483Ssklower return; 19556483Ssklower } 19656483Ssklower } 19756483Ssklower /* 19856483Ssklower * Calculate checksum of extended TCP header and data, 19956483Ssklower * by adjusting the checksum for missing parts of the header. 20056483Ssklower */ 20156483Ssklower m->m_data += clnp_len; 20256483Ssklower m->m_len -= clnp_len; 20356483Ssklower tlen = m->m_pkthdr.len -= clnp_len; 20456483Ssklower ICKSUM(fix_cksum, tuba_table[findex]->tc_sum_in + htons((u_short)tlen) 20556483Ssklower + tuba_table[lindex]->tc_sum_in + in_cksum(m, tlen)); 20656483Ssklower if (fix_cksum != 0xffff) { 20756483Ssklower tcpstat.tcps_rcvbadsum++; 20856483Ssklower goto drop; 20956483Ssklower } 21056483Ssklower m->m_data -= sizeof(struct ip); 21156483Ssklower m->m_len += sizeof(struct ip); 21256483Ssklower m->m_pkthdr.len += sizeof(struct ip); 21356483Ssklower /* 21456483Ssklower * The reassembly code assumes it will be overwriting a useless 21556483Ssklower * part of the packet, which is why we need to have ti point 21656483Ssklower * into the packet itself. 21756483Ssklower * 21856483Ssklower * Check to see if the data is properly alligned 21956483Ssklower * so that we can save copying the tcp header. 22056483Ssklower * This code knows way too much about the structure of mbufs! 22156483Ssklower */ 22256483Ssklower off = ((sizeof (long) - 1) & ((m->m_flags & EXT) ? 22356483Ssklower (m->m_data - m->m_ext.ext_buf) : (m->m_data - m_pktdat))); 22456483Ssklower if (off) { 22556483Ssklower struct mbuf *m0 = m_gethdr(M_DONTWAIT, MT_DATA) 22656483Ssklower if (m0 == 0) { 22756483Ssklower goto drop; 22856483Ssklower } 22956483Ssklower bcopy(mtod(m, caddr_t) + sizeof(struct ip), 23056483Ssklower mtod(m0, caddr_t) + sizeof(struct ip), 23156483Ssklower sizeof(struct tcphdr)); 23256483Ssklower m->m_data += sizeof(struct tcpiphdr); 23356483Ssklower m0->m_next = m; 23456483Ssklower m0->m_pkthdr = m->m_pkthdr; 23556483Ssklower m0->m_flags = m->m_pkthdr & M_COPYFLAGS; 23656483Ssklower m0->m_len = sizeof(struct tcpiphdr); 23756483Ssklower m = m0; 23856483Ssklower } 23956483Ssklower ti = mtod(m, struct tcpiphdr *); 24056483Ssklower ti->ti_src.s_addr = findex; 24156483Ssklower ti->ti_dst.s_addr = lindex; 24256483Ssklower ti->ti_len = tlen; 24356483Ssklower /* 24456483Ssklower * Now include the rest of TCP input 24556483Ssklower */ 24656483Ssklower #define TUBA_INPUT 24756483Ssklower #define in_pcbconnect tuba_pcbconnect 24856483Ssklower 24956483Ssklower #include "../netinet/tcp_input.c" 25056483Ssklower } 251