summaryrefslogtreecommitdiffstats
path: root/include/payload.h
blob: 8f5398b7ceaf8f737f7607e9bd722c961196c70e (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
#ifndef NFTABLES_PAYLOAD_H
#define NFTABLES_PAYLOAD_H

#include <nftables.h>

/**
 * enum payload_bases
 *
 * @PAYLOAD_BASE_INVALID:	uninitialised, does not happen
 * @PAYLOAD_BASE_LL_HDR:	link layer header
 * @PAYLOAD_BASE_NETWORK_HDR:	network layer header
 * @PAYLOAD_BASE_TRANSPORT_HDR:	transport layer header
 */
enum payload_bases {
	PAYLOAD_BASE_INVALID,
	PAYLOAD_BASE_LL_HDR,
	PAYLOAD_BASE_NETWORK_HDR,
	PAYLOAD_BASE_TRANSPORT_HDR,
	__PAYLOAD_BASE_MAX
};
#define PAYLOAD_BASE_MAX	(__PAYLOAD_BASE_MAX - 1)

/**
 * enum payload_expr_flags
 *
 * @PAYLOAD_PROTOCOL_EXPR:	payload expression contains upper layer protocol
 */
enum payload_expr_flags {
	PAYLOAD_PROTOCOL_EXPR		= 0x1,
};

/**
 * struct payload_template - template for a payload header expression
 *
 * @token:	parser token describing the header field
 * @dtype:	data type of the expression
 * @offset:	offset from base
 * @len:	length of header field
 */
struct payload_template {
	const char			*token;
	const struct datatype		*dtype;
	uint16_t			offset;
	uint16_t			len;
};

#define PAYLOAD_TEMPLATE(__token, __dtype,  __offset, __len)		\
	{								\
		.token		= (__token),				\
		.dtype		= (__dtype),				\
		.offset		= (__offset),				\
		.len		= (__len),				\
	}

#define PAYLOAD_PROTO_MAX		16
#define PAYLOAD_TEMPLATE_MAX		20

/**
 * struct payload_desc - payload protocol description
 *
 * @name:	protocol name
 * @base:	header base
 * @protocol_key: key of template containing upper layer protocol description
 * @protocols:	link to upper layer protocol description indexed by protocol value
 * @templates:	header templates
 */
struct payload_desc {
	const char			*name;
	enum payload_bases		base;
	unsigned int			protocol_key;
	struct {
		unsigned int			num;
		const struct payload_desc	*desc;
	}				protocols[PAYLOAD_PROTO_MAX];
	struct payload_template		templates[PAYLOAD_TEMPLATE_MAX];
};

#define PAYLOAD_PROTO(__num, __desc)	{ .num = (__num), .desc = (__desc), }

/**
 * struct payload_hook_desc - description of constraints imposed by hook family
 *
 * @base:	protocol base of packets
 * @desc:	protocol description of packets
 */
struct payload_hook_desc {
	enum payload_bases		base;
	const struct payload_desc	*desc;
};

#define PAYLOAD_HOOK(__base, __desc)	{ .base = (__base), .desc = (__desc), }

/**
 * struct dev_payload_desc - description of device LL protocol
 *
 * @desc:	protocol description
 * @type:	arphrd value
 */
struct dev_payload_desc {
	const struct payload_desc	*desc;
	uint16_t			type;
};

#define DEV_PAYLOAD_DESC(__type, __desc) { .type = (__type), .desc = (__desc), }

/**
 * struct payload_ctx - payload expression protocol context
 *
 * @family:	hook family
 * @location:	location of expression defining the context
 * @desc:	payload description for this layer
 *
 * The location of the context is the location of the relational expression
 * defining it, either directly through a protocol match or indirectly
 * through a dependency.
 */
struct payload_ctx {
	unsigned int			family;
	struct {
		struct location			location;
		const struct payload_desc	*desc;
	} protocol[PAYLOAD_BASE_MAX + 1];
};

extern struct expr *payload_expr_alloc(const struct location *loc,
				       const struct payload_desc *desc,
				       unsigned int type);
extern void payload_init_raw(struct expr *expr, enum payload_bases base,
			     unsigned int offset, unsigned int len);

extern void payload_ctx_init(struct payload_ctx *ctx, unsigned int family);
extern void payload_ctx_update_meta(struct payload_ctx *ctx,
				    const struct expr *expr);
extern void payload_ctx_update(struct payload_ctx *ctx,
			       const struct expr *expr);

struct eval_ctx;
extern int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
				  struct expr **res);

extern bool payload_is_adjacent(const struct expr *e1, const struct expr *e2);
extern struct expr *payload_expr_join(const struct expr *e1,
				      const struct expr *e2);

extern void payload_expr_expand(struct list_head *list, struct expr *expr,
				const struct payload_ctx *ctx);
extern void payload_expr_complete(struct expr *expr,
				  const struct payload_ctx *ctx);

enum eth_hdr_fields {
	ETHHDR_INVALID,
	ETHHDR_DADDR,
	ETHHDR_SADDR,
	ETHHDR_TYPE,
};

enum vlan_hdr_fields {
	VLANHDR_INVALID,
	VLANHDR_VID,
	VLANHDR_CFI,
	VLANHDR_PCP,
	VLANHDR_TYPE,
};

enum arp_hdr_fields {
	ARPHDR_INVALID,
	ARPHDR_HRD,
	ARPHDR_PRO,
	ARPHDR_HLN,
	ARPHDR_PLN,
	ARPHDR_OP,
};

enum ip_hdr_fields {
	IPHDR_INVALID,
	IPHDR_VERSION,
	IPHDR_HDRLENGTH,
	IPHDR_TOS,
	IPHDR_LENGTH,
	IPHDR_ID,
	IPHDR_FRAG_OFF,
	IPHDR_TTL,
	IPHDR_PROTOCOL,
	IPHDR_CHECKSUM,
	IPHDR_SADDR,
	IPHDR_DADDR,
};

enum icmp_hdr_fields {
	ICMPHDR_INVALID,
	ICMPHDR_TYPE,
	ICMPHDR_CODE,
	ICMPHDR_CHECKSUM,
	ICMPHDR_ID,
	ICMPHDR_SEQ,
	ICMPHDR_GATEWAY,
	ICMPHDR_MTU,
};

enum ip6_hdr_fields {
	IP6HDR_INVALID,
	IP6HDR_VERSION,
	IP6HDR_PRIORITY,
	IP6HDR_FLOWLABEL,
	IP6HDR_LENGTH,
	IP6HDR_NEXTHDR,
	IP6HDR_HOPLIMIT,
	IP6HDR_SADDR,
	IP6HDR_DADDR,
};

enum ah_hdr_fields {
	AHHDR_INVALID,
	AHHDR_NEXTHDR,
	AHHDR_HDRLENGTH,
	AHHDR_RESERVED,
	AHHDR_SPI,
	AHHDR_SEQUENCE,
};

enum esp_hdr_fields {
	ESPHDR_INVALID,
	ESPHDR_SPI,
	ESPHDR_SEQUENCE,
};

enum comp_hdr_fields {
	COMPHDR_INVALID,
	COMPHDR_NEXTHDR,
	COMPHDR_FLAGS,
	COMPHDR_CPI,
};

enum udp_hdr_fields {
	UDPHDR_INVALID,
	UDPHDR_SPORT,
	UDPHDR_DPORT,
	UDPHDR_LENGTH,
	UDPHDR_CSUMCOV = UDPHDR_LENGTH,
	UDPHDR_CHECKSUM,
};

enum tcp_hdr_fields {
	TCPHDR_INVALID,
	TCPHDR_SPORT,
	TCPHDR_DPORT,
	TCPHDR_SEQ,
	TCPHDR_ACKSEQ,
	TCPHDR_DOFF,
	TCPHDR_RESERVED,
	TCPHDR_FLAGS,
	TCPHDR_WINDOW,
	TCPHDR_CHECKSUM,
	TCPHDR_URGPTR,
};

enum dccp_hdr_fields {
	DCCPHDR_INVALID,
	DCCPHDR_SPORT,
	DCCPHDR_DPORT,
	DCCPHDR_TYPE,
};

enum sctp_hdr_fields {
	SCTPHDR_INVALID,
	SCTPHDR_SPORT,
	SCTPHDR_DPORT,
	SCTPHDR_VTAG,
	SCTPHDR_CHECKSUM,
};

extern const struct payload_desc payload_icmp;
extern const struct payload_desc payload_ah;
extern const struct payload_desc payload_esp;
extern const struct payload_desc payload_comp;
extern const struct payload_desc payload_udp;
extern const struct payload_desc payload_udplite;
extern const struct payload_desc payload_tcp;
extern const struct payload_desc payload_dccp;
extern const struct payload_desc payload_sctp;

extern const struct payload_desc payload_ip;
extern const struct payload_desc payload_ip6;

extern const struct payload_desc payload_arp;

extern const struct payload_desc payload_vlan;
extern const struct payload_desc payload_eth;

#endif /* NFTABLES_PAYLOAD_H */