Commit | Line | Data |
---|---|---|
f1b2fa5b | 1 | /* tcp_subr.c 4.4 81/11/29 */ |
ecaa4e6f BJ |
2 | |
3 | #include "../h/param.h" | |
4 | #include "../h/systm.h" | |
5 | #include "../h/mbuf.h" | |
6 | #include "../h/socket.h" | |
7 | #include "../h/socketvar.h" | |
8 | #include "../h/protosw.h" | |
0974b45c BJ |
9 | #include "../net/in.h" |
10 | #include "../net/in_pcb.h" | |
11 | #include "../net/in_systm.h" | |
ecaa4e6f | 12 | #include "../net/if.h" |
ecaa4e6f BJ |
13 | #include "../net/ip.h" |
14 | #include "../net/ip_var.h" | |
15 | #include "../net/tcp.h" | |
16 | #define TCPFSTAB | |
17 | #include "../net/tcp_fsm.h" | |
0974b45c BJ |
18 | #include "../net/tcp_seq.h" |
19 | #include "../net/tcp_timer.h" | |
ecaa4e6f | 20 | #include "../net/tcp_var.h" |
0974b45c | 21 | #include "../net/tcpip.h" |
f1b2fa5b | 22 | #include "../errno.h" |
ecaa4e6f BJ |
23 | |
24 | /* | |
25 | * Tcp initialization | |
26 | */ | |
27 | tcp_init() | |
28 | { | |
29 | ||
0974b45c | 30 | COUNT(TCP_INIT); |
ecaa4e6f BJ |
31 | tcp_iss = 1; /* wrong */ |
32 | tcb.inp_next = tcb.inp_prev = &tcb; | |
33 | } | |
34 | ||
35 | /* | |
36 | * Create template to be used to send tcp packets on a connection. | |
37 | * Call after host entry created, allocates an mbuf and fills | |
38 | * in a skeletal tcp/ip header, minimizing the amount of work | |
39 | * necessary when the connection is used. | |
40 | */ | |
41 | struct tcpiphdr * | |
42 | tcp_template(tp) | |
43 | struct tcpcb *tp; | |
44 | { | |
45 | register struct inpcb *inp = tp->t_inpcb; | |
46 | register struct mbuf *m; | |
47 | register struct tcpiphdr *n; | |
48 | ||
49 | COUNT(TCP_TEMPLATE); | |
50 | m = m_get(1); | |
51 | if (m == 0) | |
52 | return (0); | |
53 | m->m_off = MMAXOFF - sizeof (struct tcpiphdr); | |
54 | m->m_len = sizeof (struct tcpiphdr); | |
55 | n = mtod(m, struct tcpiphdr *); | |
56 | n->ti_next = n->ti_prev = 0; | |
57 | n->ti_x1 = 0; | |
58 | n->ti_pr = IPPROTO_TCP; | |
59 | n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip)); | |
60 | n->ti_src = inp->inp_laddr; | |
61 | n->ti_dst = inp->inp_faddr; | |
62 | n->ti_sport = inp->inp_lport; | |
63 | n->ti_dport = inp->inp_fport; | |
64 | n->ti_seq = 0; | |
0974b45c | 65 | n->ti_ack = 0; |
ecaa4e6f BJ |
66 | n->ti_x2 = 0; |
67 | n->ti_off = 5; | |
68 | n->ti_flags = 0; | |
69 | n->ti_win = 0; | |
70 | n->ti_sum = 0; | |
71 | n->ti_urp = 0; | |
72 | return (n); | |
73 | } | |
74 | ||
75 | /* | |
0974b45c | 76 | * Send a reset message back to send of TCP segment ti, |
ecaa4e6f BJ |
77 | * with ack, seq and flags fields as specified by parameters. |
78 | */ | |
0974b45c | 79 | tcp_respond(ti, ack, seq, flags) |
ecaa4e6f | 80 | register struct tcpiphdr *ti; |
0974b45c | 81 | tcp_seq ack, seq; |
ecaa4e6f BJ |
82 | int flags; |
83 | { | |
0974b45c | 84 | struct mbuf *m = dtom(ti); |
ecaa4e6f | 85 | |
0974b45c | 86 | COUNT(TCP_RESPOND); |
ecaa4e6f BJ |
87 | m_freem(m->m_next); |
88 | m->m_next = 0; | |
89 | m->m_len = sizeof(struct tcpiphdr); | |
0974b45c BJ |
90 | #define xchg(a,b,type) { type t; t=a; a=b; b=t; } |
91 | xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr, u_long); | |
92 | xchg(ti->ti_dport, ti->ti_sport, u_short); | |
ecaa4e6f | 93 | #undef xchg |
0974b45c BJ |
94 | ti->ti_next = ti->ti_prev = 0; |
95 | ti->ti_x1 = 0; | |
96 | ti->ti_len = htons(sizeof (struct tcphdr)); | |
ecaa4e6f | 97 | ti->ti_seq = htonl(seq); |
0974b45c BJ |
98 | ti->ti_ack = htonl(ack); |
99 | ti->ti_x2 = 0; | |
100 | ti->ti_off = sizeof (struct tcphdr) >> 2; | |
ecaa4e6f | 101 | ti->ti_flags = flags; |
0974b45c BJ |
102 | ti->ti_win = ti->ti_urp = 0; |
103 | ti->ti_sum = in_cksum(m, sizeof(struct tcpiphdr)); | |
ecaa4e6f | 104 | ((struct ip *)ti)->ip_len = sizeof(struct tcpiphdr); |
0974b45c | 105 | ((struct ip *)ti)->ip_ttl = TCP_TTL; |
f1b2fa5b | 106 | (void) ip_output(m, (struct mbuf *)0); |
ecaa4e6f | 107 | } |
a6503abf | 108 | |
0974b45c BJ |
109 | /* |
110 | * Create a new TCP control block, making an | |
111 | * empty reassembly queue and hooking it to the argument | |
112 | * protocol control block. | |
113 | */ | |
a6503abf BJ |
114 | struct tcpcb * |
115 | tcp_newtcpcb(inp) | |
116 | struct inpcb *inp; | |
117 | { | |
118 | struct mbuf *m = m_getclr(0); | |
119 | register struct tcpcb *tp; | |
120 | COUNT(TCP_NEWTCPCB); | |
121 | ||
122 | if (m == 0) | |
123 | return (0); | |
124 | tp = mtod(m, struct tcpcb *); | |
a6503abf | 125 | tp->seg_next = tp->seg_prev = (struct tcpiphdr *)tp; |
0974b45c | 126 | tp->t_maxseg = 1024; |
a6503abf BJ |
127 | tp->t_inpcb = inp; |
128 | inp->inp_ppcb = (caddr_t)tp; | |
129 | return (tp); | |
130 | } | |
131 | ||
0974b45c BJ |
132 | /* |
133 | * Drop a TCP connection, reporting | |
134 | * the specified error. If connection is synchronized, | |
135 | * then send a RST to peer. | |
136 | */ | |
a6503abf BJ |
137 | tcp_drop(tp, errno) |
138 | struct tcpcb *tp; | |
139 | int errno; | |
140 | { | |
141 | struct socket *so = tp->t_inpcb->inp_socket; | |
142 | ||
143 | COUNT(TCP_DROP); | |
144 | if (TCPS_HAVERCVDSYN(tp->t_state) && | |
0974b45c | 145 | TCPS_OURFINNOTACKED(tp->t_state)) { |
a6503abf BJ |
146 | tp->t_state = TCPS_CLOSED; |
147 | tcp_output(tp); | |
148 | } | |
149 | so->so_error = errno; | |
a6503abf BJ |
150 | tcp_close(tp); |
151 | } | |
152 | ||
0974b45c BJ |
153 | /* |
154 | * Close a TCP control block: | |
155 | * discard all space held by the tcp | |
156 | * discard internet protocol block | |
157 | * wake up any sleepers | |
158 | */ | |
a6503abf BJ |
159 | tcp_close(tp) |
160 | register struct tcpcb *tp; | |
161 | { | |
162 | register struct tcpiphdr *t; | |
0974b45c | 163 | struct socket *so = tp->t_inpcb->inp_socket; |
a6503abf BJ |
164 | |
165 | COUNT(TCP_CLOSE); | |
a6503abf BJ |
166 | t = tp->seg_next; |
167 | for (; t != (struct tcpiphdr *)tp; t = (struct tcpiphdr *)t->ti_next) | |
168 | m_freem(dtom(t)); | |
0974b45c | 169 | if (tp->t_template) |
a6503abf | 170 | (void) m_free(dtom(tp->t_template)); |
0974b45c BJ |
171 | if (tp->t_tcpopt) |
172 | (void) m_free(dtom(tp->t_tcpopt)); | |
173 | if (tp->t_ipopt) | |
174 | (void) m_free(dtom(tp->t_ipopt)); | |
a6503abf BJ |
175 | in_pcbfree(tp->t_inpcb); |
176 | (void) m_free(dtom(tp)); | |
0974b45c BJ |
177 | socantrcvmore(so); |
178 | socantsendmore(so); | |
a6503abf BJ |
179 | } |
180 | ||
a6503abf BJ |
181 | tcp_drain() |
182 | { | |
a6503abf BJ |
183 | |
184 | COUNT(TCP_DRAIN); | |
185 | } | |
186 | ||
187 | tcp_ctlinput(m) | |
188 | struct mbuf *m; | |
189 | { | |
190 | ||
191 | COUNT(TCP_CTLINPUT); | |
192 | m_freem(m); | |
193 | } |