|
|
1.1 ! root 1: /* tcp_subr.c 6.1 83/07/29 */ ! 2: #include "tcp.h" ! 3: #if NTCP > 0 ! 4: ! 5: #include "../h/param.h" ! 6: #include "../h/systm.h" ! 7: #include "../h/stream.h" ! 8: #include "../h/inet/mbuf.h" ! 9: #include "../h/inet/in.h" ! 10: #include "../h/inet/ip.h" ! 11: #include "../h/inet/ip_var.h" ! 12: #include "../h/inet/tcp.h" ! 13: #include "../h/inet/tcp_fsm.h" ! 14: #include "../h/inet/tcp_seq.h" ! 15: #include "../h/inet/tcp_timer.h" ! 16: #include "../h/inet/tcp_var.h" ! 17: #include "../h/inet/tcpip.h" ! 18: #include "../h/inet/socket.h" ! 19: #include "../h/inet/tcpdebug.h" ! 20: ! 21: extern int tcp_maxseg; ! 22: ! 23: /* ! 24: * Create template to be used to send tcp packets on a connection. ! 25: * Call after host entry created, allocates an mbuf and fills ! 26: * in a skeletal tcp/ip header, minimizing the amount of work ! 27: * necessary when the connection is used. ! 28: */ ! 29: struct tcpiphdr * ! 30: tcp_template(tp) ! 31: struct tcpcb *tp; ! 32: { ! 33: register struct socket *so = tp->t_socket; ! 34: register struct mbuf *m; ! 35: register struct tcpiphdr *n; ! 36: ! 37: m = m_get(M_WAIT, MT_HEADER); ! 38: if (m == NULL) ! 39: return (0); ! 40: m->next = 0; ! 41: m->wptr += sizeof (struct tcpiphdr); ! 42: n = mtod(m, struct tcpiphdr *); ! 43: n->ti_next = n->ti_prev = 0; ! 44: n->ti_x1 = 0; ! 45: n->ti_pr = 6; /* tcp protocol number */ ! 46: n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip)); ! 47: n->ti_src = so->so_laddr; ! 48: n->ti_dst = so->so_faddr; ! 49: n->ti_sport = so->so_lport; ! 50: n->ti_dport = so->so_fport; ! 51: n->ti_seq = 0; ! 52: n->ti_ack = 0; ! 53: n->ti_x2 = 0; ! 54: n->ti_off = 5; ! 55: n->ti_flags = 0; ! 56: n->ti_win = 0; ! 57: n->ti_sum = 0; ! 58: n->ti_urp = 0; ! 59: return (n); ! 60: } ! 61: ! 62: /* ! 63: * Send a single message to the TCP at address specified by ! 64: * the given TCP/IP header. If flags==0, then we make a copy ! 65: * of the tcpiphdr at ti and send directly to the addressed host. ! 66: * This is used to force keep alive messages out using the TCP ! 67: * template for a connection tp->t_template. If flags are given ! 68: * then we send a message back to the TCP which originated the ! 69: * segment ti, and discard the mbuf containing it and any other ! 70: * attached mbufs. ! 71: * ! 72: * In any case the ack and sequence number of the transmitted ! 73: * segment are as specified by the parameters. ! 74: */ ! 75: tcp_respond(tp, ti, ack, seq, flags) ! 76: struct tcpcb *tp; ! 77: register struct tcpiphdr *ti; ! 78: tcp_seq ack, seq; ! 79: int flags; ! 80: { ! 81: struct mbuf *m; ! 82: int win = 0, tlen; ! 83: ! 84: if (tp) { ! 85: win = sbrcvspace(tp->t_socket); ! 86: } ! 87: if (flags == 0) { ! 88: m = m_get(M_DONTWAIT, MT_HEADER); ! 89: if (m == NULL) ! 90: return; ! 91: m->next = 0; ! 92: m->wptr += sizeof (struct tcpiphdr) + 1; ! 93: *mtod(m, struct tcpiphdr *) = *ti; ! 94: ti = mtod(m, struct tcpiphdr *); ! 95: flags = TH_ACK; ! 96: tlen = 1; ! 97: } else { ! 98: in_addr taddr; ! 99: tcp_port tport; ! 100: ! 101: m = dtom(ti); ! 102: MCHECK(m); ! 103: m_freem(m->m_next); ! 104: m->m_next = 0; ! 105: m->rptr = (u_char *)ti; ! 106: m->wptr = m->rptr + sizeof (struct tcpiphdr); ! 107: taddr = ti->ti_src; ! 108: ti->ti_src = ti->ti_dst; ! 109: ti->ti_dst = taddr; ! 110: tport = ti->ti_sport; ! 111: ti->ti_sport = ti->ti_dport; ! 112: ti->ti_dport = tport; ! 113: tlen = 0; ! 114: } ! 115: ti->ti_next = ti->ti_prev = 0; ! 116: ti->ti_x1 = 0; ! 117: ti->ti_pr = 6; /* tcp protocol number */ ! 118: ti->ti_len = (u_short)(sizeof (struct tcphdr) + tlen); ! 119: ti->ti_len = htons(ti->ti_len); ! 120: ti->ti_seq = htonl(seq); ! 121: ti->ti_ack = htonl(ack); ! 122: ti->ti_x2 = 0; ! 123: ti->ti_off = sizeof (struct tcphdr) >> 2; ! 124: ti->ti_flags = flags; ! 125: ti->ti_win = htons((u_short)win); ! 126: ti->ti_urp = 0; ! 127: ti->ti_src = htonl(ti->ti_src); ! 128: ti->ti_dst = htonl(ti->ti_dst); ! 129: ti->ti_sport = htons(ti->ti_sport); ! 130: ti->ti_dport = htons(ti->ti_dport); ! 131: ti->ti_sum = 0; ! 132: ti->ti_sum = in_cksum(m, sizeof(struct tcpiphdr) + tlen); ! 133: tcp_debug(ti, 1); ! 134: ((struct ip *)ti)->ip_len = sizeof (struct tcpiphdr) + tlen; ! 135: ((struct ip *)ti)->ip_ttl = TCP_TTL; ! 136: ti->ti_dst = ntohl(ti->ti_dst); ! 137: ti->ti_src = ntohl(ti->ti_src); ! 138: tcp_ldout(m); ! 139: } ! 140: ! 141: /* ! 142: * Create a new TCP control block, making an ! 143: * empty reassembly queue and hooking it to the argument ! 144: * protocol control block. ! 145: */ ! 146: struct tcpcb * ! 147: tcp_newtcpcb(so) ! 148: struct socket *so; ! 149: { ! 150: register struct tcpcb *tp; ! 151: extern struct tcpcb tcpcb[]; ! 152: ! 153: tp = &tcpcb[so->so_dev]; ! 154: if(tp->t_template) ! 155: (void) m_free(dtom(tp->t_template)); ! 156: bzero(tp, sizeof(struct tcpcb)); ! 157: tp->seg_next = tp->seg_prev = (struct tcpiphdr *)tp; ! 158: tp->t_maxseg = tcp_maxseg; /* satisfy the rest of the world */ ! 159: tp->t_flags = 0; /* sends options! */ ! 160: tp->t_socket = so; ! 161: so->so_tcpcb = tp; ! 162: return (tp); ! 163: } ! 164: ! 165: /* ! 166: * Drop a TCP connection. ! 167: * If connection is synchronized, ! 168: * then send a RST to peer. ! 169: */ ! 170: struct tcpcb * ! 171: tcp_drop(tp) ! 172: register struct tcpcb *tp; ! 173: { ! 174: ! 175: if (TCPS_HAVERCVDSYN(tp->t_state)) { ! 176: tp->t_state = TCPS_CLOSED; ! 177: (void) tcp_output(tp); ! 178: } ! 179: return (tcp_close(tp)); ! 180: } ! 181: ! 182: /* ! 183: * Close a TCP control block: ! 184: * discard all space held by the tcp ! 185: * discard internet protocol block ! 186: * wake up any sleepers ! 187: */ ! 188: struct tcpcb * ! 189: tcp_close(tp) ! 190: register struct tcpcb *tp; ! 191: { ! 192: register struct tcpiphdr *t; ! 193: struct socket *so = tp->t_socket; ! 194: register struct mbuf *m; ! 195: ! 196: if(!tp) ! 197: panic("tcp_close"); ! 198: t = tp->seg_next; ! 199: while (t != (struct tcpiphdr *)tp) { ! 200: t = (struct tcpiphdr *)t->ti_next; ! 201: m = dtom(t->ti_prev); ! 202: remque(t->ti_prev); ! 203: m_freem(m); ! 204: } ! 205: if (tp->t_template) ! 206: (void) m_free(dtom(tp->t_template)); ! 207: tp->t_template = 0; ! 208: if (tp->t_tcpopt) ! 209: (void) m_free(dtom(tp->t_tcpopt)); ! 210: tp->t_tcpopt = 0; ! 211: if (tp->t_ipopt) ! 212: (void) m_free(dtom(tp->t_ipopt)); ! 213: tp->t_ipopt = 0; ! 214: so->so_tcpcb = 0; ! 215: soisdisconnected(so); ! 216: return ((struct tcpcb *)0); ! 217: } ! 218: ! 219: /* ! 220: * For debugging save time event occurred, the direction of the message, ! 221: * and the tcp header. Then increment the pointer to the tcp ! 222: * debug queue. ! 223: */ ! 224: int Nbugarr=SIZDEBUG; ! 225: struct tcpdebug bugarr[SIZDEBUG]; /* buffer to store the debug info in */ ! 226: int tcpdbg_ind=0; /* index into bugarr at last entry */ ! 227: ! 228: tcp_debug(ti, code) ! 229: struct tcpiphdr *ti; ! 230: { ! 231: bugarr[tcpdbg_ind].stamp = time; ! 232: bugarr[tcpdbg_ind].inout = code; ! 233: bugarr[tcpdbg_ind].hdr = *ti; ! 234: tcpdbg_ind = (tcpdbg_ind + 1) % SIZDEBUG; ! 235: } ! 236: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.