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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
|
// Copyright 2019 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// There are a number of structs and values that we can't #include because of a
// difference between C and C++ (C++ won't let you implicitly cast from void* to
// struct something*). We re-define them here.
#ifndef GVISOR_TEST_SYSCALLS_IPTABLES_TYPES_H_
#define GVISOR_TEST_SYSCALLS_IPTABLES_TYPES_H_
// Netfilter headers require some headers to preceed them.
// clang-format off
#include <netinet/in.h>
#include <stddef.h>
// clang-format on
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_ipv6.h>
#include <net/if.h>
#include <netinet/ip.h>
#include <stdint.h>
//
// IPv4 ABI.
//
#define ipt_standard_target xt_standard_target
#define ipt_entry_target xt_entry_target
#define ipt_error_target xt_error_target
enum SockOpts {
// For setsockopt.
IPT_BASE_CTL = 64,
IPT_SO_SET_REPLACE = IPT_BASE_CTL,
IPT_SO_SET_ADD_COUNTERS = IPT_BASE_CTL + 1,
IPT_SO_SET_MAX = IPT_SO_SET_ADD_COUNTERS,
// For getsockopt.
IPT_SO_GET_INFO = IPT_BASE_CTL,
IPT_SO_GET_ENTRIES = IPT_BASE_CTL + 1,
IPT_SO_GET_REVISION_MATCH = IPT_BASE_CTL + 2,
IPT_SO_GET_REVISION_TARGET = IPT_BASE_CTL + 3,
IPT_SO_GET_MAX = IPT_SO_GET_REVISION_TARGET
};
// ipt_ip specifies basic matching criteria that can be applied by examining
// only the IP header of a packet.
struct ipt_ip {
// Source IP address.
struct in_addr src;
// Destination IP address.
struct in_addr dst;
// Source IP address mask.
struct in_addr smsk;
// Destination IP address mask.
struct in_addr dmsk;
// Input interface.
char iniface[IFNAMSIZ];
// Output interface.
char outiface[IFNAMSIZ];
// Input interface mask.
unsigned char iniface_mask[IFNAMSIZ];
// Output interface mask.
unsigned char outiface_mask[IFNAMSIZ];
// Transport protocol.
uint16_t proto;
// Flags.
uint8_t flags;
// Inverse flags.
uint8_t invflags;
};
// ipt_entry is an iptables rule. It contains information about what packets the
// rule matches and what action (target) to perform for matching packets.
struct ipt_entry {
// Basic matching information used to match a packet's IP header.
struct ipt_ip ip;
// A caching field that isn't used by userspace.
unsigned int nfcache;
// The number of bytes between the start of this ipt_entry struct and the
// rule's target.
uint16_t target_offset;
// The total size of this rule, from the beginning of the entry to the end of
// the target.
uint16_t next_offset;
// A return pointer not used by userspace.
unsigned int comefrom;
// Counters for packets and bytes, which we don't yet implement.
struct xt_counters counters;
// The data for all this rules matches followed by the target. This runs
// beyond the value of sizeof(struct ipt_entry).
unsigned char elems[0];
};
// Passed to getsockopt(IPT_SO_GET_INFO).
struct ipt_getinfo {
// The name of the table. The user only fills this in, the rest is filled in
// when returning from getsockopt. Currently "nat" and "mangle" are supported.
char name[XT_TABLE_MAXNAMELEN];
// A bitmap of which hooks apply to the table. For example, a table with hooks
// PREROUTING and FORWARD has the value
// (1 << NF_IP_PRE_REOUTING) | (1 << NF_IP_FORWARD).
unsigned int valid_hooks;
// The offset into the entry table for each valid hook. The entry table is
// returned by getsockopt(IPT_SO_GET_ENTRIES).
unsigned int hook_entry[NF_IP_NUMHOOKS];
// For each valid hook, the underflow is the offset into the entry table to
// jump to in case traversing the table yields no verdict (although I have no
// clue how that could happen - builtin chains always end with a policy, and
// user-defined chains always end with a RETURN.
//
// The entry referred to must be an "unconditional" entry, meaning it has no
// matches, specifies no IP criteria, and either DROPs or ACCEPTs packets. It
// basically has to be capable of making a definitive decision no matter what
// it's passed.
unsigned int underflow[NF_IP_NUMHOOKS];
// The number of entries in the entry table returned by
// getsockopt(IPT_SO_GET_ENTRIES).
unsigned int num_entries;
// The size of the entry table returned by getsockopt(IPT_SO_GET_ENTRIES).
unsigned int size;
};
// Passed to getsockopt(IPT_SO_GET_ENTRIES).
struct ipt_get_entries {
// The name of the table. The user fills this in. Currently "nat" and "mangle"
// are supported.
char name[XT_TABLE_MAXNAMELEN];
// The size of the entry table in bytes. The user fills this in with the value
// from struct ipt_getinfo.size.
unsigned int size;
// The entries for the given table. This will run past the size defined by
// sizeof(struct ipt_get_entries).
struct ipt_entry entrytable[0];
};
// Passed to setsockopt(SO_SET_REPLACE).
struct ipt_replace {
// The name of the table.
char name[XT_TABLE_MAXNAMELEN];
// The same as struct ipt_getinfo.valid_hooks. Users don't change this.
unsigned int valid_hooks;
// The same as struct ipt_getinfo.num_entries.
unsigned int num_entries;
// The same as struct ipt_getinfo.size.
unsigned int size;
// The same as struct ipt_getinfo.hook_entry.
unsigned int hook_entry[NF_IP_NUMHOOKS];
// The same as struct ipt_getinfo.underflow.
unsigned int underflow[NF_IP_NUMHOOKS];
// The number of counters, which should equal the number of entries.
unsigned int num_counters;
// The unchanged values from each ipt_entry's counters.
struct xt_counters* counters;
// The entries to write to the table. This will run past the size defined by
// sizeof(srtuct ipt_replace);
struct ipt_entry entries[0];
};
//
// IPv6 ABI.
//
enum SockOpts6 {
// For setsockopt.
IP6T_BASE_CTL = 64,
IP6T_SO_SET_REPLACE = IP6T_BASE_CTL,
IP6T_SO_SET_ADD_COUNTERS = IP6T_BASE_CTL + 1,
IP6T_SO_SET_MAX = IP6T_SO_SET_ADD_COUNTERS,
// For getsockopt.
IP6T_SO_GET_INFO = IP6T_BASE_CTL,
IP6T_SO_GET_ENTRIES = IP6T_BASE_CTL + 1,
IP6T_SO_GET_REVISION_MATCH = IP6T_BASE_CTL + 4,
IP6T_SO_GET_REVISION_TARGET = IP6T_BASE_CTL + 5,
IP6T_SO_GET_MAX = IP6T_SO_GET_REVISION_TARGET
};
// ip6t_ip6 specifies basic matching criteria that can be applied by examining
// only the IP header of a packet.
struct ip6t_ip6 {
// Source IP address.
struct in6_addr src;
// Destination IP address.
struct in6_addr dst;
// Source IP address mask.
struct in6_addr smsk;
// Destination IP address mask.
struct in6_addr dmsk;
// Input interface.
char iniface[IFNAMSIZ];
// Output interface.
char outiface[IFNAMSIZ];
// Input interface mask.
unsigned char iniface_mask[IFNAMSIZ];
// Output interface mask.
unsigned char outiface_mask[IFNAMSIZ];
// Transport protocol.
uint16_t proto;
// TOS.
uint8_t tos;
// Flags.
uint8_t flags;
// Inverse flags.
uint8_t invflags;
};
// ip6t_entry is an ip6tables rule.
struct ip6t_entry {
// Basic matching information used to match a packet's IP header.
struct ip6t_ip6 ipv6;
// A caching field that isn't used by userspace.
unsigned int nfcache;
// The number of bytes between the start of this entry and the rule's target.
uint16_t target_offset;
// The total size of this rule, from the beginning of the entry to the end of
// the target.
uint16_t next_offset;
// A return pointer not used by userspace.
unsigned int comefrom;
// Counters for packets and bytes, which we don't yet implement.
struct xt_counters counters;
// The data for all this rules matches followed by the target. This runs
// beyond the value of sizeof(struct ip6t_entry).
unsigned char elems[0];
};
// Passed to getsockopt(IP6T_SO_GET_ENTRIES).
struct ip6t_get_entries {
// The name of the table.
char name[XT_TABLE_MAXNAMELEN];
// The size of the entry table in bytes. The user fills this in with the value
// from struct ipt_getinfo.size.
unsigned int size;
// The entries for the given table. This will run past the size defined by
// sizeof(struct ip6t_get_entries).
struct ip6t_entry entrytable[0];
};
#endif // GVISOR_TEST_SYSCALLS_IPTABLES_TYPES_H_
|