summaryrefslogtreecommitdiffhomepage
path: root/pkg/abi/linux/netfilter.go
blob: 80dc09aa9d94db9dde485980c7b1665bc8d76feb (plain)
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
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
// 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.

package linux

// This file contains structures required to support netfilter, specifically
// the iptables tool.

// Hooks into the network stack. These correspond to values in
// include/uapi/linux/netfilter.h.
const (
	NF_INET_PRE_ROUTING  = 0
	NF_INET_LOCAL_IN     = 1
	NF_INET_FORWARD      = 2
	NF_INET_LOCAL_OUT    = 3
	NF_INET_POST_ROUTING = 4
	NF_INET_NUMHOOKS     = 5
)

// Verdicts that can be returned by targets. These correspond to values in
// include/uapi/linux/netfilter.h
const (
	NF_DROP        = 0
	NF_ACCEPT      = 1
	NF_STOLEN      = 2
	NF_QUEUE       = 3
	NF_REPEAT      = 4
	NF_STOP        = 5
	NF_MAX_VERDICT = NF_STOP
	// NF_RETURN is defined in include/uapi/linux/netfilter/x_tables.h.
	NF_RETURN = -NF_REPEAT - 1
)

// VerdictStrings maps int verdicts to the strings they represent. It is used
// for debugging.
var VerdictStrings = map[int32]string{
	-NF_DROP - 1:   "DROP",
	-NF_ACCEPT - 1: "ACCEPT",
	-NF_QUEUE - 1:  "QUEUE",
	NF_RETURN:      "RETURN",
}

// Socket options. These correspond to values in
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
const (
	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

	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
)

// Name lengths. These correspond to values in
// include/uapi/linux/netfilter/x_tables.h.
const (
	XT_FUNCTION_MAXNAMELEN  = 30
	XT_EXTENSION_MAXNAMELEN = 29
	XT_TABLE_MAXNAMELEN     = 32
)

// IPTEntry is an iptable rule. It corresponds to struct ipt_entry in
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
type IPTEntry struct {
	// IP is used to filter packets based on the IP header.
	IP IPTIP

	// NFCache relates to kernel-internal caching and isn't used by
	// userspace.
	NFCache uint32

	// TargetOffset is the byte offset from the beginning of this IPTEntry
	// to the start of the entry's target.
	TargetOffset uint16

	// NextOffset is the byte offset from the beginning of this IPTEntry to
	// the start of the next entry. It is thus also the size of the entry.
	NextOffset uint16

	// Comeback is a return pointer. It is not used by userspace.
	Comeback uint32

	// Counters holds the packet and byte counts for this rule.
	Counters XTCounters

	// Elems holds the data for all this rule's matches followed by the
	// target. It is variable length -- users have to iterate over any
	// matches and use TargetOffset and NextOffset to make sense of the
	// data.
	//
	// Elems is omitted here because it would cause IPTEntry to be an extra
	// byte larger (see http://www.catb.org/esr/structure-packing/).
	//
	// Elems [0]byte
}

// SizeOfIPTEntry is the size of an IPTEntry.
const SizeOfIPTEntry = 112

// KernelIPTEntry is identical to IPTEntry, but includes the Elems field. This
// struct marshaled via the binary package to write an IPTEntry to userspace.
type KernelIPTEntry struct {
	IPTEntry

	// Elems holds the data for all this rule's matches followed by the
	// target. It is variable length -- users have to iterate over any
	// matches and use TargetOffset and NextOffset to make sense of the
	// data.
	Elems []byte
}

// IPTIP contains information for matching a packet's IP header.
// It corresponds to struct ipt_ip in
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
type IPTIP struct {
	// Src is the source IP address.
	Src InetAddr

	// Dst is the destination IP address.
	Dst InetAddr

	// SrcMask is the source IP mask.
	SrcMask InetAddr

	// DstMask is the destination IP mask.
	DstMask InetAddr

	// InputInterface is the input network interface.
	InputInterface [IFNAMSIZ]byte

	// OutputInterface is the output network interface.
	OutputInterface [IFNAMSIZ]byte

	// InputInterfaceMask is the intput interface mask.
	InputInterfaceMask [IFNAMSIZ]byte

	// OuputInterfaceMask is the output interface mask.
	OutputInterfaceMask [IFNAMSIZ]byte

	// Protocol is the transport protocol.
	Protocol uint16

	// Flags define matching behavior for the IP header.
	Flags uint8

	// InverseFlags invert the meaning of fields in struct IPTIP. See the
	// IPT_INV_* flags.
	InverseFlags uint8
}

// Flags in IPTIP.InverseFlags. Corresponding constants are in
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
const (
	// Invert the meaning of InputInterface.
	IPT_INV_VIA_IN = 0x01
	// Invert the meaning of OutputInterface.
	IPT_INV_VIA_OUT = 0x02
	// Unclear what this is, as no references to it exist in the kernel.
	IPT_INV_TOS = 0x04
	// Invert the meaning of Src.
	IPT_INV_SRCIP = 0x08
	// Invert the meaning of Dst.
	IPT_INV_DSTIP = 0x10
	// Invert the meaning of the IPT_F_FRAG flag.
	IPT_INV_FRAG = 0x20
	// Invert the meaning of the Protocol field.
	IPT_INV_PROTO = 0x40
	// Enable all flags.
	IPT_INV_MASK = 0x7F
)

// SizeOfIPTIP is the size of an IPTIP.
const SizeOfIPTIP = 84

// XTCounters holds packet and byte counts for a rule. It corresponds to struct
// xt_counters in include/uapi/linux/netfilter/x_tables.h.
type XTCounters struct {
	// Pcnt is the packet count.
	Pcnt uint64

	// Bcnt is the byte count.
	Bcnt uint64
}

// SizeOfXTCounters is the size of an XTCounters.
const SizeOfXTCounters = 16

// XTEntryMatch holds a match for a rule. For example, a user using the
// addrtype iptables match extension would put the data for that match into an
// XTEntryMatch. iptables-extensions(8) has a list of possible matches.
//
// XTEntryMatch corresponds to struct xt_entry_match in
// include/uapi/linux/netfilter/x_tables.h. That struct contains a union
// exposing different data to the user and kernel, but this struct holds only
// the user data.
type XTEntryMatch struct {
	MatchSize uint16
	Name      ExtensionName
	Revision  uint8
	// Data is omitted here because it would cause XTEntryMatch to be an
	// extra byte larger (see http://www.catb.org/esr/structure-packing/).
	// Data [0]byte
}

// SizeOfXTEntryMatch is the size of an XTEntryMatch.
const SizeOfXTEntryMatch = 32

// KernelXTEntryMatch is identical to XTEntryMatch, but contains
// variable-length Data field.
type KernelXTEntryMatch struct {
	XTEntryMatch
	Data []byte
}

// XTEntryTarget holds a target for a rule. For example, it can specify that
// packets matching the rule should DROP, ACCEPT, or use an extension target.
// iptables-extension(8) has a list of possible targets.
//
// XTEntryTarget corresponds to struct xt_entry_target in
// include/uapi/linux/netfilter/x_tables.h. That struct contains a union
// exposing different data to the user and kernel, but this struct holds only
// the user data.
type XTEntryTarget struct {
	TargetSize uint16
	Name       ExtensionName
	Revision   uint8
	// Data is omitted here because it would cause XTEntryTarget to be an
	// extra byte larger (see http://www.catb.org/esr/structure-packing/).
	// Data [0]byte
}

// SizeOfXTEntryTarget is the size of an XTEntryTarget.
const SizeOfXTEntryTarget = 32

// XTStandardTarget is a built-in target, one of ACCEPT, DROP, JUMP, QUEUE,
// RETURN, or jump. It corresponds to struct xt_standard_target in
// include/uapi/linux/netfilter/x_tables.h.
type XTStandardTarget struct {
	Target XTEntryTarget
	// A positive verdict indicates a jump, and is the offset from the
	// start of the table to jump to. A negative value means one of the
	// other built-in targets.
	Verdict int32
	_       [4]byte
}

// SizeOfXTStandardTarget is the size of an XTStandardTarget.
const SizeOfXTStandardTarget = 40

// XTErrorTarget triggers an error when reached. It is also used to mark the
// beginning of user-defined chains by putting the name of the chain in
// ErrorName. It corresponds to struct xt_error_target in
// include/uapi/linux/netfilter/x_tables.h.
type XTErrorTarget struct {
	Target XTEntryTarget
	Name   ErrorName
	_      [2]byte
}

// SizeOfXTErrorTarget is the size of an XTErrorTarget.
const SizeOfXTErrorTarget = 64

// Flag values for NfNATIPV4Range. The values indicate whether to map
// protocol specific part(ports) or IPs. It corresponds to values in
// include/uapi/linux/netfilter/nf_nat.h.
const (
	NF_NAT_RANGE_MAP_IPS            = 1 << 0
	NF_NAT_RANGE_PROTO_SPECIFIED    = 1 << 1
	NF_NAT_RANGE_PROTO_RANDOM       = 1 << 2
	NF_NAT_RANGE_PERSISTENT         = 1 << 3
	NF_NAT_RANGE_PROTO_RANDOM_FULLY = 1 << 4
	NF_NAT_RANGE_PROTO_RANDOM_ALL   = (NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PROTO_RANDOM_FULLY)
	NF_NAT_RANGE_MASK               = (NF_NAT_RANGE_MAP_IPS |
		NF_NAT_RANGE_PROTO_SPECIFIED | NF_NAT_RANGE_PROTO_RANDOM |
		NF_NAT_RANGE_PERSISTENT | NF_NAT_RANGE_PROTO_RANDOM_FULLY)
)

// NfNATIPV4Range corresponds to struct nf_nat_ipv4_range
// in include/uapi/linux/netfilter/nf_nat.h. The fields are in
// network byte order.
type NfNATIPV4Range struct {
	Flags   uint32
	MinIP   [4]byte
	MaxIP   [4]byte
	MinPort uint16
	MaxPort uint16
}

// NfNATIPV4MultiRangeCompat corresponds to struct
// nf_nat_ipv4_multi_range_compat in include/uapi/linux/netfilter/nf_nat.h.
type NfNATIPV4MultiRangeCompat struct {
	RangeSize uint32
	RangeIPV4 NfNATIPV4Range
}

// XTRedirectTarget triggers a redirect when reached.
// Adding 4 bytes of padding to make the struct 8 byte aligned.
type XTRedirectTarget struct {
	Target  XTEntryTarget
	NfRange NfNATIPV4MultiRangeCompat
	_       [4]byte
}

// SizeOfXTRedirectTarget is the size of an XTRedirectTarget.
const SizeOfXTRedirectTarget = 56

// IPTGetinfo is the argument for the IPT_SO_GET_INFO sockopt. It corresponds
// to struct ipt_getinfo in include/uapi/linux/netfilter_ipv4/ip_tables.h.
type IPTGetinfo struct {
	Name       TableName
	ValidHooks uint32
	HookEntry  [NF_INET_NUMHOOKS]uint32
	Underflow  [NF_INET_NUMHOOKS]uint32
	NumEntries uint32
	Size       uint32
}

// SizeOfIPTGetinfo is the size of an IPTGetinfo.
const SizeOfIPTGetinfo = 84

// IPTGetEntries is the argument for the IPT_SO_GET_ENTRIES sockopt. It
// corresponds to struct ipt_get_entries in
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
type IPTGetEntries struct {
	Name TableName
	Size uint32
	_    [4]byte
	// Entrytable is omitted here because it would cause IPTGetEntries to
	// be an extra byte longer (see
	// http://www.catb.org/esr/structure-packing/).
	// Entrytable [0]IPTEntry
}

// SizeOfIPTGetEntries is the size of an IPTGetEntries.
const SizeOfIPTGetEntries = 40

// KernelIPTGetEntries is identical to IPTGetEntries, but includes the
// Entrytable field. This struct marshaled via the binary package to write an
// KernelIPTGetEntries to userspace.
type KernelIPTGetEntries struct {
	IPTGetEntries
	Entrytable []KernelIPTEntry
}

// IPTReplace is the argument for the IPT_SO_SET_REPLACE sockopt. It
// corresponds to struct ipt_replace in
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
type IPTReplace struct {
	Name        TableName
	ValidHooks  uint32
	NumEntries  uint32
	Size        uint32
	HookEntry   [NF_INET_NUMHOOKS]uint32
	Underflow   [NF_INET_NUMHOOKS]uint32
	NumCounters uint32
	Counters    uint64 // This is really a *XTCounters.
	// Entries is omitted here because it would cause IPTReplace to be an
	// extra byte longer (see http://www.catb.org/esr/structure-packing/).
	// Entries [0]IPTEntry
}

// KernelIPTReplace is identical to IPTReplace, but includes the Entries field.
type KernelIPTReplace struct {
	IPTReplace
	Entries [0]IPTEntry
}

// SizeOfIPTReplace is the size of an IPTReplace.
const SizeOfIPTReplace = 96

// ExtensionName holds the name of a netfilter extension.
type ExtensionName [XT_EXTENSION_MAXNAMELEN]byte

// String implements fmt.Stringer.
func (en ExtensionName) String() string {
	return goString(en[:])
}

// TableName holds the name of a netfilter table.
type TableName [XT_TABLE_MAXNAMELEN]byte

// String implements fmt.Stringer.
func (tn TableName) String() string {
	return goString(tn[:])
}

// ErrorName holds the name of a netfilter error. These can also hold
// user-defined chains.
type ErrorName [XT_FUNCTION_MAXNAMELEN]byte

// String implements fmt.Stringer.
func (en ErrorName) String() string {
	return goString(en[:])
}

func goString(cstring []byte) string {
	for i, c := range cstring {
		if c == 0 {
			return string(cstring[:i])
		}
	}
	return string(cstring)
}

// XTTCP holds data for matching TCP packets. It corresponds to struct xt_tcp
// in include/uapi/linux/netfilter/xt_tcpudp.h.
type XTTCP struct {
	// SourcePortStart specifies the inclusive start of the range of source
	// ports to which the matcher applies.
	SourcePortStart uint16

	// SourcePortEnd specifies the inclusive end of the range of source ports
	// to which the matcher applies.
	SourcePortEnd uint16

	// DestinationPortStart specifies the start of the destination port
	// range to which the matcher applies.
	DestinationPortStart uint16

	// DestinationPortEnd specifies the end of the destination port
	// range to which the matcher applies.
	DestinationPortEnd uint16

	// Option specifies that a particular TCP option must be set.
	Option uint8

	// FlagMask masks TCP flags when comparing to the FlagCompare byte. It allows
	// for specification of which flags are important to the matcher.
	FlagMask uint8

	// FlagCompare, in combination with FlagMask, is used to match only packets
	// that have certain flags set.
	FlagCompare uint8

	// InverseFlags flips the meaning of certain fields. See the
	// TX_TCP_INV_* flags.
	InverseFlags uint8
}

// SizeOfXTTCP is the size of an XTTCP.
const SizeOfXTTCP = 12

// Flags in XTTCP.InverseFlags. Corresponding constants are in
// include/uapi/linux/netfilter/xt_tcpudp.h.
const (
	// Invert the meaning of SourcePortStart/End.
	XT_TCP_INV_SRCPT = 0x01
	// Invert the meaning of DestinationPortStart/End.
	XT_TCP_INV_DSTPT = 0x02
	// Invert the meaning of FlagCompare.
	XT_TCP_INV_FLAGS = 0x04
	// Invert the meaning of Option.
	XT_TCP_INV_OPTION = 0x08
	// Enable all flags.
	XT_TCP_INV_MASK = 0x0F
)

// XTUDP holds data for matching UDP packets. It corresponds to struct xt_udp
// in include/uapi/linux/netfilter/xt_tcpudp.h.
type XTUDP struct {
	// SourcePortStart is the inclusive start of the range of source ports
	// to which the matcher applies.
	SourcePortStart uint16

	// SourcePortEnd is the inclusive end of the range of source ports to
	// which the matcher applies.
	SourcePortEnd uint16

	// DestinationPortStart is the inclusive start of the destination port
	// range to which the matcher applies.
	DestinationPortStart uint16

	// DestinationPortEnd is the inclusive end of the destination port
	// range to which the matcher applies.
	DestinationPortEnd uint16

	// InverseFlags flips the meaning of certain fields. See the
	// TX_UDP_INV_* flags.
	InverseFlags uint8

	_ uint8
}

// SizeOfXTUDP is the size of an XTUDP.
const SizeOfXTUDP = 10

// Flags in XTUDP.InverseFlags. Corresponding constants are in
// include/uapi/linux/netfilter/xt_tcpudp.h.
const (
	// Invert the meaning of SourcePortStart/End.
	XT_UDP_INV_SRCPT = 0x01
	// Invert the meaning of DestinationPortStart/End.
	XT_UDP_INV_DSTPT = 0x02
	// Enable all flags.
	XT_UDP_INV_MASK = 0x03
)