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
|
# Copyright 2018 syzkaller project authors. All rights reserved.
# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
include <linux/socket.h>
include <uapi/linux/netfilter/x_tables.h>
include <uapi/linux/netfilter_bridge.h>
include <uapi/linux/netfilter_bridge/ebtables.h>
include <uapi/linux/netfilter_bridge/ebt_802_3.h>
include <uapi/linux/netfilter_bridge/ebt_among.h>
include <uapi/linux/netfilter_bridge/ebt_arp.h>
include <uapi/linux/netfilter_bridge/ebt_ip.h>
include <uapi/linux/netfilter_bridge/ebt_ip6.h>
include <uapi/linux/netfilter_bridge/ebt_limit.h>
include <uapi/linux/netfilter_bridge/ebt_mark_m.h>
include <uapi/linux/netfilter_bridge/ebt_pkttype.h>
include <uapi/linux/netfilter_bridge/ebt_stp.h>
include <uapi/linux/netfilter_bridge/ebt_vlan.h>
include <uapi/linux/netfilter_bridge/ebt_arpreply.h>
include <uapi/linux/netfilter_bridge/ebt_nat.h>
include <uapi/linux/netfilter_bridge/ebt_log.h>
include <uapi/linux/netfilter_bridge/ebt_mark_t.h>
include <uapi/linux/netfilter_bridge/ebt_nflog.h>
include <uapi/linux/netfilter_bridge/ebt_redirect.h>
setsockopt$EBT_SO_SET_ENTRIES(fd sock_in, level const[SOL_IP], opt const[EBT_SO_SET_ENTRIES], val ptr[in, ebt_replace], len const[0])
setsockopt$EBT_SO_SET_COUNTERS(fd sock_in, level const[SOL_IP], opt const[EBT_SO_SET_COUNTERS], val ptr[in, ebt_counters_info], len len[val])
getsockopt$EBT_SO_GET_INFO(fd sock_in, level const[SOL_IP], opt const[EBT_SO_GET_INFO], val ptr[in, ebt_getinfo], len ptr[in, len[val, int32]])
getsockopt$EBT_SO_GET_INIT_INFO(fd sock_in, level const[SOL_IP], opt const[EBT_SO_GET_INIT_INFO], val ptr[in, ebt_getinfo], len ptr[in, len[val, int32]])
getsockopt$EBT_SO_GET_ENTRIES(fd sock_in, level const[SOL_IP], opt const[EBT_SO_GET_ENTRIES], val ptr[in, ebt_get_entries], len ptr[in, len[val, int32]])
getsockopt$EBT_SO_GET_INIT_ENTRIES(fd sock_in, level const[SOL_IP], opt const[EBT_SO_GET_INIT_ENTRIES], val ptr[in, ebt_get_entries], len ptr[in, len[val, int32]])
ebt_replace [
filter ebt_replace_t["filter", EBT_FILTER_VALID_HOOKS, ebt_filter_targets]
nat ebt_replace_t["nat", EBT_NAT_VALID_HOOKS, ebt_nat_targets]
broute ebt_replace_t["broute", EBT_BROUTE_VALID_HOOKS, ebt_broute_targets]
] [varlen]
define NF_BR_PRE_ROUTING_BIT 1 << NF_BR_PRE_ROUTING
define NF_BR_LOCAL_IN_BIT 1 << NF_BR_LOCAL_IN
define NF_BR_FORWARD_BIT 1 << NF_BR_FORWARD
define NF_BR_LOCAL_OUT_BIT 1 << NF_BR_LOCAL_OUT
define NF_BR_POST_ROUTING_BIT 1 << NF_BR_POST_ROUTING
define NF_BR_BROUTING_BIT 1 << NF_BR_BROUTING
define EBT_FILTER_VALID_HOOKS NF_BR_LOCAL_IN_BIT | NF_BR_FORWARD_BIT | NF_BR_LOCAL_OUT_BIT
define EBT_NAT_VALID_HOOKS NF_BR_PRE_ROUTING_BIT | NF_BR_LOCAL_OUT_BIT | NF_BR_POST_ROUTING_BIT
define EBT_BROUTE_VALID_HOOKS NF_BR_BROUTING_BIT
type ebt_replace_t[NAME, HOOKS, TARGETS] {
name string[NAME, XT_TABLE_MAXNAMELEN]
valid_hooks const[HOOKS, int32]
nentries const[0, int32]
entries_size bytesize[entries, int32]
hook_entry array[intptr, NF_BR_NUMHOOKS]
num_counters const[0, int32]
counters ptr[out, array[xt_counters, 1]]
entries ptr[in, array[ebt_entries[TARGETS], 3:4]]
}
type ebt_entries[TARGETS] {
distinguisher const[0, int32]
name string["", EBT_CHAIN_MAXNAMELEN]
counter_offset const[0, int32]
policy flags[ebt_entries_policy, int32]
nentries len[entries, int32]
entries array[ebt_entry[TARGETS], 0:2]
}
ebt_entries_policy = EBT_DROP, EBT_ACCEPT, EBT_RETURN
ebt_verdicts = EBT_DROP, EBT_ACCEPT, EBT_RETURN, EBT_CONTINUE
type ebt_entry[TARGETS] {
bitmask flags[ebt_entry_bitmask, int32]
invflags flags[ebt_entry_invflags, int32]
ethproto flags[ether_types, int16be]
in devname
logical_in devname
out devname
logical_out devname
sourcemac mac_addr
sourcemsk mac_addr_mask
destmac mac_addr
destmsk mac_addr_mask
watchers_offset offsetof[watchers, int32]
target_offset offsetof[target, int32]
next_offset bytesize[parent, int32]
matches array[ebt_matches, 0:2]
watchers array[TARGETS, 0:2]
target TARGETS
} [packed]
ebt_entry_bitmask = EBT_NOPROTO_F, EBT_802_3_F, EBT_SOURCEMAC_F, EBT_DESTMAC_F
ebt_entry_invflags = EBT_IPROTO, EBT_IIN, EBT_IOUT, EBT_ISOURCE, EBT_IDEST, EBT_ILOGICALIN, EBT_ILOGICALOUT
define EBT_NOPROTO_F EBT_ENTRY_OR_ENTRIES | EBT_NOPROTO
define EBT_802_3_F EBT_ENTRY_OR_ENTRIES | EBT_802_3
define EBT_SOURCEMAC_F EBT_ENTRY_OR_ENTRIES | EBT_SOURCEMAC
define EBT_DESTMAC_F EBT_ENTRY_OR_ENTRIES | EBT_DESTMAC
ebt_tables = "filter", "nat", "broute"
ebt_counters_info {
name string[ebt_tables, XT_TABLE_MAXNAMELEN]
valid_hooks const[0, int32]
nentries const[0, int32]
entries_size const[0, int32]
hook_entry array[intptr, NF_BR_NUMHOOKS]
num_counters len[counters1, int32]
counters ptr[out, array[xt_counters]]
entries const[0, intptr]
counters1 array[xt_counters]
}
ebt_getinfo {
name string[ebt_tables, XT_TABLE_MAXNAMELEN]
valid_hooks const[0, int32]
nentries const[0, int32]
entries_size const[0, int32]
hook_entry array[intptr, NF_BR_NUMHOOKS]
num_counters const[0, int32]
counters const[0, intptr]
entries const[0, intptr]
}
ebt_get_entries {
name string[ebt_tables, XT_TABLE_MAXNAMELEN]
valid_hooks const[0, int32]
nentries int32[3:4]
entries_size bytesize[entries, int32]
hook_entry array[intptr, NF_BR_NUMHOOKS]
num_counters len[counters, int32]
counters ptr[out, array[xt_counters]]
entries ptr[out, array[int8]]
}
# MATCHES:
type ebt_entry_match[NAME] {
name string[NAME, EBT_EXTENSION_MAXNAMELEN]
revision const[0, int8]
match_size bytesize[ebt_entry_match_t:data, int32]
} [align[PTR_SIZE]]
type ebt_entry_match_t[NAME, DATA] {
header ebt_entry_match[NAME]
data xt_padded[DATA]
}
type xt_padded[TYPE] {
data TYPE
} [align[PTR_SIZE]]
ebt_matches [
m802_3 ebt_entry_match_t["802_3", ebt_802_3_info]
among ebt_entry_match_t["among", ebt_among_info]
arp ebt_entry_match_t["arp", ebt_arp_info]
ip ebt_entry_match_t["ip", ebt_ip_info]
ip6 ebt_entry_match_t["ip6", ebt_ip6_info]
limit ebt_entry_match_t["limit", ebt_limit_info]
mark_m ebt_entry_match_t["mark_m", ebt_mark_m_info]
pkttype ebt_entry_match_t["pkttype", ebt_pkttype_info]
stp ebt_entry_match_t["stp", ebt_stp_info]
vlan ebt_entry_match_t["vlan", ebt_vlan_info]
# AF_UNSPEC matches (only version 0 and not overriden by AF_BRIDGE).
cgroup0 ebt_entry_match_t["cgroup", xt_cgroup_info_v0]
helper ebt_entry_match_t["helper", xt_helper_info]
rateest ebt_entry_match_t["rateest", xt_rateest_match_info]
time ebt_entry_match_t["time", xt_time_info]
bpf0 ebt_entry_match_t["bpf", xt_bpf_info]
realm ebt_entry_match_t["realm", xt_realm_info]
connbytes ebt_entry_match_t["connbytes", xt_connbytes_info]
quota ebt_entry_match_t["quota", xt_quota_info]
ipvs ebt_entry_match_t["ipvs", xt_ipvs_mtinfo]
nfacct ebt_entry_match_t["nfacct", xt_nfacct_match_info]
mac ebt_entry_match_t["mac", xt_mac_info]
comment ebt_entry_match_t["comment", xt_comment_info]
statistic ebt_entry_match_t["statistic", xt_statistic_info]
physdev ebt_entry_match_t["physdev", xt_physdev_info]
connlabel ebt_entry_match_t["connlabel", xt_connlabel_mtinfo]
devgroup ebt_entry_match_t["devgroup", xt_devgroup_info]
cluster ebt_entry_match_t["cluster", xt_cluster_match_info]
owner ebt_entry_match_t["owner", xt_owner_match_info]
u32 ebt_entry_match_t["u32", xt_u32]
cpu ebt_entry_match_t["cpu", xt_cpu_info]
state ebt_entry_match_t["state", xt_state_info]
] [varlen]
ebt_802_3_info {
sap flags[sap_values, int8]
type int16be
bitmask flags[ebt_802_3_flags, int8]
invflags flags[ebt_802_3_flags, int8]
}
ebt_802_3_flags = EBT_802_3_SAP, EBT_802_3_TYPE, EBT_802_3
ebt_among_info {
wh_dst_ofs ebt_among_info_offset[dst]
wh_src_ofs ebt_among_info_offset[src]
bitmask flags[ebt_among_flags, int32]
dst ebt_mac_wormhash
src ebt_mac_wormhash
} [packed]
type ebt_among_info_offset[FIELD] [
offset offsetof[ebt_among_info:FIELD, int32]
zero const[0, int32]
]
ebt_mac_wormhash {
table array[int32, 257]
poolsize len[pool, int32]
pool array[ebt_mac_wormhash_tuple]
}
ebt_mac_wormhash_tuple {
cmp array[int32, 2]
ip ipv4_addr
}
ebt_among_flags = EBT_AMONG_DST_NEG, EBT_AMONG_SRC_NEG
ebt_arp_info {
htype flags[arp_htypes, int16be]
ptype flags[ether_types, int16be]
op flags[arp_ops, int16be]
saddr ipv4_addr
smsk ipv4_addr_mask
daddr ipv4_addr
dmsk ipv4_addr_mask
smaddr mac_addr
smmsk mac_addr_mask
dmaddr mac_addr
dmmsk mac_addr_mask
bitmask flags[ebt_arp_flags, int8]
invflags flags[ebt_arp_flags, int8]
}
ebt_arp_flags = EBT_ARP_OPCODE, EBT_ARP_HTYPE, EBT_ARP_PTYPE, EBT_ARP_SRC_IP, EBT_ARP_DST_IP, EBT_ARP_SRC_MAC, EBT_ARP_DST_MAC, EBT_ARP_GRAT
ebt_ip_info {
saddr ipv4_addr
daddr ipv4_addr
smsk ipv4_addr_mask
dmsk ipv4_addr_mask
tos int8
protocol flags[ipv4_types, int8]
bitmask flags[ebt_ip_flags, int8]
invflags flags[ebt_ip_flags, int8]
sport_min sock_port
sport_max sock_port
dport_min sock_port
dport_max sock_port
}
ebt_ip_flags = EBT_IP_SOURCE, EBT_IP_DEST, EBT_IP_TOS, EBT_IP_PROTO, EBT_IP_SPORT, EBT_IP_DPORT
ebt_ip6_info {
saddr ipv6_addr
daddr ipv6_addr
smsk ipv6_addr_mask
dmsk ipv6_addr_mask
tclass int8
protocol flags[ipv6_types, int8]
bitmask flags[ebt_ip6_flags, int8]
invflags flags[ebt_ip6_flags, int8]
sport_min sock_port
sport_max sock_port
dport_min sock_port
dport_max sock_port
}
ebt_ip6_flags = EBT_IP6_SOURCE, EBT_IP6_DEST, EBT_IP6_TCLASS, EBT_IP6_PROTO, EBT_IP6_SPORT, EBT_IP6_DPORT, EBT_IP6_ICMP6
ebt_limit_info {
avg int32
burst int32
prev intptr
credit int32
credit_cap int32
cost int32
}
ebt_mark_m_info {
mark intptr
mask intptr
invert flags[ebt_mark_m_flags, int8]
bitmask flags[ebt_mark_m_flags, int8]
}
ebt_mark_m_flags = EBT_MARK_AND, EBT_MARK_OR
ebt_pkttype_info {
pkt_type int8[0:7]
invert bool8
}
ebt_stp_info {
type int8
config ebt_stp_config_info
bitmask flags[ebt_stp_flags, int16]
invflags flags[ebt_stp_flags, int16]
}
ebt_stp_config_info {
flags int8
root_priol int16
root_priou int16
root_addr mac_addr
root_addrmsk mac_addr_mask
root_costl int32
root_costu int32
sender_priol int16
sender_priou int16
sender_addr mac_addr
sender_addrmsk mac_addr_mask
portl sock_port
portu sock_port
msg_agel int16
msg_ageu int16
max_agel int16
max_ageu int16
hello_timel int16
hello_timeu int16
forward_delayl int16
forward_delayu int16
}
ebt_stp_flags = EBT_STP_TYPE, EBT_STP_FLAGS, EBT_STP_ROOTPRIO, EBT_STP_ROOTADDR, EBT_STP_ROOTCOST, EBT_STP_SENDERPRIO, EBT_STP_SENDERADDR, EBT_STP_PORT, EBT_STP_MSGAGE, EBT_STP_MAXAGE, EBT_STP_HELLOTIME, EBT_STP_FWDD
ebt_vlan_info {
id int16[0:4]
prio int8[0:7]
encap flags[ether_types, int16be]
bitmask flags[ebt_vlan_flags, int8]
invflags flags[ebt_vlan_flags, int8]
}
ebt_vlan_flags = EBT_VLAN_ID, EBT_VLAN_PRIO, EBT_VLAN_ENCAP
# TARGETS:
type ebt_entry_target[NAME, DATA] {
name string[NAME, EBT_FUNCTION_MAXNAMELEN]
target_size bytesize[data, int32]
data xt_padded[DATA]
}
ebt_targets [
dnat ebt_entry_target["dnat", ebt_nat_info]
log ebt_entry_target["log", ebt_log_info]
mark ebt_entry_target["mark", ebt_mark_t_info]
nflog ebt_entry_target["nflog", ebt_nflog_info]
redirect ebt_entry_target["redirect", ebt_redirect_info]
# AF_UNSPEC targets (only version 0).
STANDARD ebt_entry_target["", flags[nf_verdicts, int32]]
ERROR ebt_entry_target["ERROR", array[int8, XT_FUNCTION_MAXNAMELEN]]
LED ebt_entry_target["LED", xt_led_info]
RATEEST ebt_entry_target["RATEEST", xt_rateest_target_info]
NFQUEUE0 ebt_entry_target["NFQUEUE", xt_NFQ_info]
CLASSIFY ebt_entry_target["CLASSIFY", xt_classify_target_info]
IDLETIMER ebt_entry_target["IDLETIMER", idletimer_tg_info]
AUDIT ebt_entry_target["AUDIT", xt_audit_info]
CONNSECMARK ebt_entry_target["CONNSECMARK", xt_connsecmark_target_info]
SECMARK ebt_entry_target["SECMARK", xt_secmark_target_info]
NFLOG ebt_entry_target["NFLOG", xt_nflog_info]
] [varlen]
ebt_filter_targets [
common ebt_targets
] [varlen]
ebt_nat_targets [
common ebt_targets
arpreply ebt_entry_target["arpreply", ebt_arpreply_info]
snat ebt_entry_target["snat", ebt_nat_info]
] [varlen]
ebt_broute_targets [
common ebt_targets
] [varlen]
ebt_arpreply_info {
mac mac_addr
# TODO: can also be jump target
target flags[ebt_verdicts, int32]
}
ebt_nat_info {
mac mac_addr
# TODO: can also be jump target
target flags[ebt_nat_verdicts, int32]
}
ebt_nat_verdicts = NAT_ARP_BIT, ebt_verdicts
ebt_log_info {
loglevel int8
prefix array[int8, EBT_LOG_PREFIX_SIZE]
bitmask flags[ebt_log_bitmask, int32]
}
ebt_log_bitmask = EBT_LOG_IP, EBT_LOG_ARP, EBT_LOG_NFLOG, EBT_LOG_IP6
ebt_mark_t_info {
mark flags[ebt_mark_marks, intptr]
# TODO: can also be jump target
target flags[ebt_verdicts, int32]
}
ebt_mark_marks = MARK_SET_VALUE, MARK_OR_VALUE, MARK_AND_VALUE, MARK_XOR_VALUE
ebt_nflog_info {
len int32
group int16
threshold int16
flags const[0, int16]
pad const[0, int16]
prefix array[int8, EBT_NFLOG_PREFIX_SIZE]
}
ebt_redirect_info {
# TODO: can also be jump target
target flags[ebt_verdicts, int32]
}
|