Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*
* Copyright 2013 Google Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/*
* Author: ncardwell@google.com (Neal Cardwell)
*
* Interfaces for reading and writing TCP options in their wire format.
*/
#ifndef __TCP_OPTIONS_H__
#define __TCP_OPTIONS_H__
#include "types.h"
#include "packet.h"
#define MAX_TCP_OPTION_BYTES (MAX_TCP_HEADER_BYTES - (int)sizeof(struct tcp))
/* TCP Fast Open uses the following magic number to be after the
* option value for sharing TCP experimental options.
*
* For a description of experimental options, see:
* https://tools.ietf.org/html/rfc6994
* https://tools.ietf.org/html/rfc7413
*/
#define TCPOPT_FASTOPEN_MAGIC 0xF989
/* TFO option must have: 1-byte kind, 1-byte length, and 2-byte magic: */
#define TCPOLEN_EXP_FASTOPEN_BASE 4 /* smallest legal TFO option size */
/* The TFO option base prefix leaves this amount of space: */
#define MAX_TCP_EXP_FAST_OPEN_COOKIE_BYTES \
(MAX_TCP_OPTION_BYTES - TCPOLEN_EXP_FASTOPEN_BASE)
/* TFO option must have: 1-byte kind, 1-byte length */
#define TCPOLEN_FASTOPEN_BASE 2 /* smallest legal TFO option size */
/* The TFO option base prefix leaves this amount of space: */
#define MAX_TCP_FAST_OPEN_COOKIE_BYTES \
(MAX_TCP_OPTION_BYTES - TCPOLEN_FASTOPEN_BASE)
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/* Represents a list of TCP options in their wire format. */
struct tcp_options {
u8 data[MAX_TCP_OPTION_BYTES]; /* The options data, in wire format */
u8 length; /* The length, in bytes, of the data */
};
/* Specification of a TCP SACK block (RFC 2018) */
struct sack_block {
u32 left; /* left edge: 1st sequence number in block */
u32 right; /* right edge: 1st sequence number just past block */
};
/* Represents a single TCP option in its wire format. Note that for
* EOL and NOP options the length and data field are not included in
* the on-the-wire data. For other options, the length field describes
* the number of bytes of the struct that go on the wire. */
struct tcp_option {
u8 kind;
u8 length; /* bytes on the wire; includes kind and length byte */
union {
struct {
u16 bytes; /* in network order */
} mss;
struct {
u32 val; /* in network order */
u32 ecr; /* in network order */
} time_stamp;
struct {
u8 shift_count;
} window_scale;
struct {
/* actual number of blocks will be 1..4 */
struct sack_block block[4];
} sack;
struct {
u16 magic; /* must be TCPOPT_FASTOPEN_MAGIC */
/* The fast open chookie should be 4-16 bytes
* of cookie, multiple of 2 bytes, but we
* allow for larger sizes, so we can test what
* stacks do with illegal options.
*/
u8 cookie[MAX_TCP_EXP_FAST_OPEN_COOKIE_BYTES];
} exp_fast_open;
struct {
/* The fast open chookie should be 4-16 bytes
* of cookie, multiple of 2 bytes, but we
* allow for larger sizes, so we can test what
* stacks do with illegal options.
*/
u8 cookie[MAX_TCP_FAST_OPEN_COOKIE_BYTES];
} fast_open;
} data;
/* Allocate a new options list. */
extern struct tcp_options *tcp_options_new(void);
/* Allocate a new option and initialize its kind and length fields. */
extern struct tcp_option *tcp_option_new(u8 kind, u8 length);
/* Appends the given option to the given list of options. Returns
* STATUS_OK on success; on failure returns STATUS_ERR and sets
* error message.
*/
extern int tcp_options_append(struct tcp_options *options,
struct tcp_option *option);
/* Calculate the number of SACK blocks in a SACK option of the given
* length and store it in *num_blocks. Returns STATUS_OK on success;
* on failure returns STATUS_ERR and sets error message.
*/
extern int num_sack_blocks(u8 opt_len, int *num_blocks, char **error);
#endif /* __TCP_OPTIONS_H__ */