|
|
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.