1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * TCP Support with SACK for file transfer.
4  *
5  * Copyright 2017 Duncan Hare, All rights reserved.
6  */
7 
8 #define TCP_ACTIVITY 127		/* Number of packets received   */
9 					/* before console progress mark */
10 /**
11  * struct ip_tcp_hdr - IP and TCP header
12  * @ip_hl_v: header length and version
13  * @ip_tos: type of service
14  * @ip_len: total length
15  * @ip_id: identification
16  * @ip_off: fragment offset field
17  * @ip_ttl: time to live
18  * @ip_p: protocol
19  * @ip_sum: checksum
20  * @ip_src: Source IP address
21  * @ip_dst: Destination IP address
22  * @tcp_src: TCP source port
23  * @tcp_dst: TCP destination port
24  * @tcp_seq: TCP sequence number
25  * @tcp_ack: TCP Acknowledgment number
26  * @tcp_hlen: 4 bits TCP header Length/4, 4 bits reserved, 2 more bits reserved
27  * @tcp_flag: flags of TCP
28  * @tcp_win: TCP windows size
29  * @tcp_xsum: Checksum
30  * @tcp_ugr: Pointer to urgent data
31  */
32 struct ip_tcp_hdr {
33 	u8		ip_hl_v;
34 	u8		ip_tos;
35 	u16		ip_len;
36 	u16		ip_id;
37 	u16		ip_off;
38 	u8		ip_ttl;
39 	u8		ip_p;
40 	u16		ip_sum;
41 	struct in_addr	ip_src;
42 	struct in_addr	ip_dst;
43 	u16		tcp_src;
44 	u16		tcp_dst;
45 	u32		tcp_seq;
46 	u32		tcp_ack;
47 	u8		tcp_hlen;
48 	u8		tcp_flags;
49 	u16		tcp_win;
50 	u16		tcp_xsum;
51 	u16		tcp_ugr;
52 } __packed;
53 
54 #define IP_TCP_HDR_SIZE		(sizeof(struct ip_tcp_hdr))
55 #define TCP_HDR_SIZE		(IP_TCP_HDR_SIZE  - IP_HDR_SIZE)
56 
57 #define TCP_DATA	0x00	/* Data Packet - internal use only	*/
58 #define TCP_FIN		0x01	/* Finish flag				*/
59 #define TCP_SYN		0x02	/* Synch (start) flag			*/
60 #define TCP_RST		0x04	/* reset flag				*/
61 #define TCP_PUSH	0x08	/* Push - Notify app			*/
62 #define TCP_ACK		0x10	/* Acknowledgment of data received	*/
63 #define TCP_URG		0x20	/* Urgent				*/
64 #define TCP_ECE		0x40	/* Congestion control			*/
65 #define TCP_CWR		0x80	/* Congestion Control			*/
66 
67 /*
68  * TCP header options, Seq, MSS, and SACK
69  */
70 
71 #define TCP_SACK 32			/* Number of packets analyzed   */
72 					/* on leading edge of stream    */
73 
74 #define TCP_O_END	0x00		/* End of option list		*/
75 #define TCP_1_NOP	0x01		/* Single padding NOP		*/
76 #define TCP_O_NOP	0x01010101	/* NOPs pad to 32 bit boundary	*/
77 #define TCP_O_MSS	0x02		/* MSS Size option		*/
78 #define TCP_O_SCL	0x03		/* Window Scale option		*/
79 #define TCP_P_SACK	0x04		/* SACK permitted		*/
80 #define TCP_V_SACK	0x05		/* SACK values			*/
81 #define TCP_O_TS	0x08		/* Timestamp option		*/
82 #define TCP_OPT_LEN_2	0x02
83 #define TCP_OPT_LEN_3	0x03
84 #define TCP_OPT_LEN_4	0x04
85 #define TCP_OPT_LEN_6	0x06
86 #define TCP_OPT_LEN_8	0x08
87 #define TCP_OPT_LEN_A	0x0a		/* Timestamp Length		*/
88 #define TCP_MSS		1460		/* Max segment size		*/
89 #define TCP_SCALE	0x01		/* Scale			*/
90 
91 /**
92  * struct tcp_mss - TCP option structure for MSS (Max segment size)
93  * @kind: Field ID
94  * @len: Field length
95  * @mss: Segment size value
96  */
97 struct tcp_mss {
98 	u8	kind;
99 	u8	len;
100 	u16	mss;
101 } __packed;
102 
103 /**
104  * struct tcp_scale - TCP option structure for Windows scale
105  * @kind: Field ID
106  * @len: Field length
107  * @scale: windows shift value used for networks with many hops.
108  *         Typically 4 or more hops
109  */
110 struct tcp_scale {
111 	u8	kind;
112 	u8	len;
113 	u8	scale;
114 } __packed;
115 
116 /**
117  * struct tcp_sack_p - TCP option structure for SACK permitted
118  * @kind: Field ID
119  * @len: Field length
120  */
121 struct tcp_sack_p {
122 	u8	kind;
123 	u8	len;
124 } __packed;
125 
126 /**
127  * struct sack_edges - structure for SACK edges
128  * @l: Left edge of stream
129  * @r: right edge of stream
130  */
131 struct sack_edges {
132 	u32	l;
133 	u32	r;
134 } __packed;
135 
136 #define TCP_SACK_SIZE (sizeof(struct sack_edges))
137 
138 /*
139  * A TCP stream has holes when packets are missing or disordered.
140  * A hill is the inverse of a hole, and is data received.
141  * TCP received hills (a sequence of data), and inferrs Holes
142  * from the "hills" or packets received.
143  */
144 
145 #define TCP_SACK_HILLS	4
146 
147 /**
148  * struct tcp_sack_v - TCP option structure for SACK
149  * @kind: Field ID
150  * @len: Field length
151  * @hill: L & R window edges
152  */
153 struct tcp_sack_v {
154 	u8	kind;
155 	u8	len;
156 	struct	sack_edges hill[TCP_SACK_HILLS];
157 } __packed;
158 
159 /**
160  * struct tcp_t_opt - TCP option structure for time stamps
161  * @kind: Field ID
162  * @len: Field length
163  * @t_snd: Sender timestamp
164  * @t_rcv: Receiver timestamp
165  */
166 struct tcp_t_opt {
167 	u8	kind;
168 	u8	len;
169 	u32	t_snd;
170 	u32	t_rcv;
171 } __packed;
172 
173 #define TCP_TSOPT_SIZE (sizeof(struct tcp_t_opt))
174 
175 /*
176  * ip tcp  structure with options
177  */
178 
179 /**
180  * struct ip_tcp_hdr_o - IP + TCP header + TCP options
181  * @hdr: IP + TCP header
182  * @mss: TCP MSS Option
183  * @scale: TCP Windows Scale Option
184  * @sack_p: TCP Sack-Permitted Option
185  * @t_opt: TCP Timestamp Option
186  * @end: end of options
187  */
188 struct ip_tcp_hdr_o {
189 	struct	ip_tcp_hdr hdr;
190 	struct	tcp_mss	   mss;
191 	struct	tcp_scale  scale;
192 	struct	tcp_sack_p sack_p;
193 	struct	tcp_t_opt  t_opt;
194 	u8	end;
195 } __packed;
196 
197 #define IP_TCP_O_SIZE (sizeof(struct ip_tcp_hdr_o))
198 
199 /**
200  * struct ip_tcp_hdr_s - IP + TCP header + TCP options
201  * @hdr: IP + TCP header
202  * @t_opt: TCP Timestamp Option
203  * @sack_v: TCP SACK Option
204  * @end: end of options
205  */
206 struct ip_tcp_hdr_s {
207 	struct	ip_tcp_hdr	hdr;
208 	struct	tcp_t_opt	t_opt;
209 	struct	tcp_sack_v	sack_v;
210 	u8	end;
211 } __packed;
212 
213 #define IP_TCP_SACK_SIZE (sizeof(struct ip_tcp_hdr_s))
214 
215 /*
216  * TCP pseudo header definitions
217  */
218 #define PSEUDO_PAD_SIZE	8
219 
220 /**
221  * struct pseudo_hdr - Pseudo Header
222  * @padding: pseudo hdr size = ip_tcp hdr size
223  * @p_src: Source IP address
224  * @p_dst: Destination IP address
225  * @rsvd: reserved
226  * @p: protocol
227  * @len: length of header
228  */
229 struct pseudo_hdr {
230 	u8 padding[PSEUDO_PAD_SIZE];
231 	struct in_addr p_src;
232 	struct in_addr p_dst;
233 	u8      rsvd;
234 	u8      p;
235 	u16     len;
236 } __packed;
237 
238 #define PSEUDO_HDR_SIZE	(sizeof(struct pseudo_hdr)) - PSEUDO_PAD_SIZE
239 
240 /**
241  * union tcp_build_pkt - union for building TCP/IP packet.
242  * @ph: pseudo header
243  * @ip: IP and TCP header plus TCP options
244  * @sack: IP and TCP header plus SACK options
245  * @raw: buffer
246  *
247  * Build Pseudo header in packed buffer
248  * first, calculate TCP checksum, then build IP header in packed buffer.
249  *
250  */
251 union tcp_build_pkt {
252 	struct pseudo_hdr ph;
253 	struct ip_tcp_hdr_o ip;
254 	struct ip_tcp_hdr_s sack;
255 	uchar  raw[1600];
256 } __packed;
257 
258 /**
259  * enum tcp_state - TCP State machine states for connection
260  * @TCP_CLOSED: Need to send SYN to connect
261  * @TCP_SYN_SENT: Trying to connect, waiting for SYN ACK
262  * @TCP_SYN_RECEIVED: Initial SYN received, waiting for ACK
263  * @TCP_ESTABLISHED: both server & client have a connection
264  * @TCP_CLOSE_WAIT: Rec FIN, passed to app for FIN, ACK rsp
265  * @TCP_CLOSING: Rec FIN, sent FIN, ACK waiting for ACK
266  * @TCP_FIN_WAIT_1: Sent FIN waiting for response
267  * @TCP_FIN_WAIT_2: Rec ACK from FIN sent, waiting for FIN
268  */
269 enum tcp_state {
270 	TCP_CLOSED,
271 	TCP_SYN_SENT,
272 	TCP_SYN_RECEIVED,
273 	TCP_ESTABLISHED,
274 	TCP_CLOSE_WAIT,
275 	TCP_CLOSING,
276 	TCP_FIN_WAIT_1,
277 	TCP_FIN_WAIT_2
278 };
279 
280 enum tcp_state tcp_get_tcp_state(void);
281 void tcp_set_tcp_state(enum tcp_state new_state);
282 int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len,
283 		       u8 action, u32 tcp_seq_num, u32 tcp_ack_num);
284 
285 /**
286  * rxhand_tcp() - An incoming packet handler.
287  * @pkt: pointer to the application packet
288  * @dport: destination TCP port
289  * @sip: source IP address
290  * @sport: source TCP port
291  * @tcp_seq_num: TCP sequential number
292  * @tcp_ack_num: TCP acknowledgment number
293  * @action: TCP action (SYN, ACK, FIN, etc)
294  * @len: packet length
295  */
296 typedef void rxhand_tcp(uchar *pkt, u16 dport,
297 			struct in_addr sip, u16 sport,
298 			u32 tcp_seq_num, u32 tcp_ack_num,
299 			u8 action, unsigned int len);
300 void tcp_set_tcp_handler(rxhand_tcp *f);
301 
302 void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int len);
303 
304 u16 tcp_set_pseudo_header(uchar *pkt, struct in_addr src, struct in_addr dest,
305 			  int tcp_len, int pkt_len);
306