summaryrefslogtreecommitdiffstats
path: root/docs/ebtables-hacking/ebtables-hacking-HOWTO-3.html
blob: 4b53955e8bf06eeeb8d960ab97e442409685b95d (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
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<title>Ebtables Hacking HOWTO: Reference manual</title>
</head>
<body>
<a HREF="ebtables-hacking-HOWTO-4.html">Next</a>
<a HREF="ebtables-hacking-HOWTO-2.html">Previous</a>
<a HREF="ebtables-hacking-HOWTO.html#toc3">Contents</a>
<hr>
<h2><a NAME="s3">3.</a> <a HREF="netfilter-hacking-HOWTO.html#toc3">Reference manual</a></h2>
<p>
This section (claims that it) contains the knowledge necessary to write an extension. For a first time reader
it's probably less boring to first read the examples section and come back here when necessary.
</p>
<h2><a NAME="ss3.1">3.1</a> <a HREF="ebtables-hacking-HOWTO.html#toc3.1">Userspace</a>
</h2>
<p>
The userspace modules are responsible for putting the user's input into the right form to be given to
the kernel.
</p>
<h3><a NAME="ss3.1.1">3.1.1</a> <a HREF="ebtables-hacking-HOWTO.html#toc3.1.1">Matches</a>
</h3>
<p>
A match module is a piece of code that looks at frames passing by and decides whether that frame
matches certain conditions or not. The userspace match is contained in a
<CODE>struct ebt_u_match</CODE>, of which the fields important to the match implementor will be
described now:
<ol>
<li><CODE>char name[EBT_FUNCTION_MAXNAMELEN]<CODE>
<p>The name of the match, for example <CODE>ip</CODE>. Try to keep yourself from using capitals.</p>
</li>
<li><CODE>unsigned int size</CODE>
<p>The size of the match data</p>
</li>
<li><CODE>void (*help)(void)</CODE>
<p>This function should print out the help information for the match, when the user asks for it
with the <CODE>-h &#60match&#62</CODE> command. The function can expect a '\n' to have been
printed right before it is executed and should end with at least one '\n'. The output should
explain the usage of the module, with its look similar to that of the standard help.
</p>
</li>
<li><CODE>void (*init)(struct ebt_entry_match *m)</CODE>
<p>This function is executed when the ebtables program starts execution, before any user commands
are processed. Initializing any private data should be done at this time. The data inside the
match struct can be initialized too, using the function's argument <CODE>m</CODE>.
</p>
</li>
<li><CODE>int (*parse)(int c, char **argv, int argc,<BR>
	        const struct ebt_u_entry *entry, unsigned int *flags,<BR>
	        struct ebt_entry_match **match)<CODE>
<p>This function parses a user option given on the command line. The function can abort execution
of the program using ebtables' <CODE>print_error()</CODE> function when appropriate. The return
value for success is 1, in case of failure it is 0.<br>
<CODE>c</CODE> contains the option the user used on the command line, <CODE>argv</CODE> and <CODE>argc</CODE>
are the same two parameters given to the <CODE>main</CODE> function. <CODE>entry</CODE> points to the
complete new rule that is being constructed. <CODE>flags</CODE> points to an unsigned int private to the
module that can have any value the module wants. In practice it is used to contain flags for which options
are already processed. <CODE>match</CODE> points to the data of the match, as you can see it's a double pointer,
meaning you are allowed to change the address of the match's data.
</p>
</li>
<li><CODE>void (*final_check)(const struct ebt_u_entry *entry,<BR>
	   const struct ebt_entry_match *match,<BR>
	   const char *name, unsigned int hookmask, unsigned int time)</CODE>
<p>This function is executed after the new rule has been completely parsed without errors. Here you can see
if there is no invalid use of different options. For example, if the match only works for protocol XyZ, then
you should check that the user specified <CODE>-p XyZ</CODE>. The <CODE>name</CODE> argument contains the name
of the table the rule will be put in, <CODE>hookmask</CODE> contains the mask that describes from which base
chains the rule can be accessed. Because this function can be called twice during the execution of the
program, the value <CODE>time</CODE> equals 0 for the first execution and 1 for the second. In some situations
it is necessary to have this knowledge.
</p>
</li>
<li><CODE>void (*print)(const struct ebt_u_entry *entry,<BR>
	   const struct ebt_entry_match *match)</CODE>
<p>
This function is executed when the user wants to list the rules and if a rule contains this match. The output should
be in a format the user could have used to make the rule.
</p>
</li>
<li><CODE>int (*compare)(const struct ebt_entry_match *m1,<BR>
	   const struct ebt_entry_match *m2)</CODE>
<p>
This function is executed when 2 rules have to be compared with eachother and both contain this match. A return value
of 1 means the matches in both rules are the same, otherwise the return value must be 0.
</p>
</li>
<li><CODE>const struct option *extra_ops</CODE>
<p>
This points to a <CODE>struct option</CODE>, recognized by the library function <CODE>getopt_long</CODE>. This contains
the options the user can use for the match module. Options specific to a match should start with a specific prefix, then
a minus, then the option specifying name. For example, the IP match has an option "ip-source" for matching the IP source address.
</p>
</li>
</ol>
</p>
<h3><a NAME="ss3.1.2">3.1.2</a> <a HREF="ebtables-hacking-HOWTO.html#toc3.1.2">Watchers</a>
</h3>
<p>
A watcher module is a piece of code that looks at frames passing by, after they have passed all matches of the rule in which the
watcher is contained. A watcher only looks at a frame and will probably log something or keep statistics. Watchers are in ebtables
because it allows to have a watcher and a target in the same rule. Therefore you can log stuff with the log watcher, while still
being able to give a target. Without watchers, you would need two rules for this, which is slower and ugly.<br><br>
The userspace watcher is contained in a <CODE>struct ebt_u_watcher</CODE> that has the same relevant fields as the match, so we refer
to the previous section (mentally replace match by watcher where necessary).
</p>
<h3><a NAME="ss3.1.3">3.1.3</a> <a HREF="ebtables-hacking-HOWTO.html#toc3.1.3">Targets</a>
</h3>
<p>
A target module is a piece of code that does a certain action when a all matches of a rule are passed and after the watchers in
the rule (if any) are executed.<br><br>
The userspace target is contained in a <CODE>struct ebt_u_target</CODE> that has the same relevant fields as the match, so we refer
to the first section (mentally replace match by target where necessary).
</p>
<h3><a NAME="ss3.1.4">3.1.4</a> <a HREF="ebtables-hacking-HOWTO.html#toc3.1.4">Miscellaneous</a>
</h3>
<p>
This section contains more general information that you could need.
</p>
<p>
<em>Macro's:</em>
</p>
<p>
The following macro's are defined in <CODE>include/ebtables_u.h</CODE>
<ol>
<li>
<CODE>print_bug()</CODE>
<p>
The arguments should look like arguments to <CODE>printf</CODE>, use this macro if you want to do sanity checks on your code.
</p>
</li>
<li>
<CODE>print_error()</CODE>
<p>
The arguments should look like arguments to <CODE>printf</CODE>, use this macro to tell the user she did something wrong.
A trailing '.' is added by the macro.
</p>
</li>
<li>
<CODE>print_memory()</CODE>
<p>
Use this macro when <CODE>malloc</CODE> and friends fail. No arguments allowed.
</p>
</li>
<li>
<CODE>FILL_TARGET(string, pos)</CODE>
<p>
This macro fills the integer <CODE>pos</CODE> with the value representing the target <CODE>string</CODE>. So, if you want <CODE>pos</CODE> to contain the value for RETURN,
use <CODE>FILL_TARGET("RETURN", pos);</CODE>
</p>
</li>
<li>
<CODE>TARGET_NAME(value)</CODE>
<p>
This macro produces the target string coreesponding to the given target <CODE>value</CODE>. Use this to convert a stored numeric value to a string that can be printed for
the user to read.
</p>
</li>
<li>
<CODE>BASE_CHAIN</CODE>
<p>
This macro produces a boolean with value true if the rule is in a base chain. This is used for example to prevent a RETURN target on a base chain.
</p>
</li>
<li>
<CODE>CLEAR_BASE_CHAIN_BIT</CODE>
<p>
This macro should be used (only once) before using the <CODE>hookmask</CODE> in the <CODE>final_check()</CODE> function.
If you want to use <CODE>BASE_CHAIN</CODE> you must use it earlier in the function.
</p>
</li>
</ol>
</p>
<p>
<em>The <CODE>time</CODE> argument to <CODE>final_check()</CODE>:</em>
</p>
<p>
Some extra explanation about the <CODE>time</CODE> argument of the <CODE>final_check()</CODE> function is perhaps needed. When a rule is added, this rule can have as
target a user defined chain. It can be, for example, that introducing this new rule makes a certain target accessible from a base chain that is not allowed for that target.
Before this rule was added, this was not so, but after the rule is added this is so. Therefore, after an add or insert, all the <CODE>final_check()</CODE> functions of all
the modules used in all chains are called, the value of <CODE>time</CODE> will be set to 1. We could ofcourse be lazy and let this checking up to the kernel, but it's the
policy of ebtables that any rejected table from the kernel is caused by an ebtables userspace bug. Userspace should make sure no invalid data can go to the kernel. This does
not mean that the kernel no longer has to check for validity, ofcourse.
</p>
<p>
<em>A complete rule:</em>
</p>
<p>
The <CODE>struct ebt_u_entry</CODE> contains the information of a rule. Most module functions that are called by the base ebtables code have this struct as an argument.
However, I feel there is only one field that can be needed by the userspace module:
<ol>
<li><CODE>uint16_t ethproto</CODE>
<p>
This contains the Ethernet protocol specified by the user, its value is zero if the user did not specify a specific protocol. The value is in host endian, so there is no need
for <CODE>ntohs()</CODE>. The <CODE>final_check()</CODE> can need this value to be sure the module is used with the right specified Ethernet protocol.
</p>
</li>
</ol>
</p>
<p>
<em>Adding a new table:</em>
</p>
<p>
A module for a new table can be added too, the table's information is stored in a <CODE>struct ebt_u_table</CODE> and has following relevant members:
<ol>
<li><CODE>char name[EBT_TABLE_MAXNAMELEN]</CODE>
<p>
The name of the table. Try to keep yourself from using capital letters.
</p>
</li>
<li><CODE>void (*check)(struct ebt_u_replace *repl)</CODE>
<p>
This function gets the complete table as an argument and can do all the checks it likes. It should use <CODE>print_error()</CODE> if the table is invalid. However, there
is probably no need to make this function.
</p>
</li>
<li><CODE>void (*help)(char **)</CODE>
<p>
This function gets executed when the user gives the '-h' command, it should at least print out the supported chains for the table. You can assume a '\n' has been printed
prior to the function's execution, it should also end with at least one '\n'.
</p>
</li>
</ol>
</p>
<p>
<em>Useful functions:</em>
</p>
<p>
Now follows a description of other functions that are useful for a module.
<ol>
<li><CODE>void register_table(struct ebt_u_table *)</CODE>
<p>
Is needed in the initialization function of a table module, to register the table's data, namely the <CODE>name</CODE> and the <CODE>check</CODE> and <CODE>help</CODE> functions.
</p>
</li>
<li><CODE>void register_match(struct ebt_u_match *)</CODE>
<p>
Is needed in the initialization function of a match module, to register its data.
</p>
</li>
<li><CODE>void register_watcher(struct ebt_u_watcher *)</CODE>
<p>
Is needed in the initialization function of a watcher module, to register its data.
</p>
</li>
<li><CODE>void register_target(struct ebt_u_target *t)</CODE>
<p>
Is needed in the initialization function of a target module, to register its data.
</p>
</li>
<li><CODE>int name_to_number(char *name, uint16_t *proto)</CODE>
<p>
Translate a name of an Ethernet protocol to the corresponding protocol number, which is put inside the variable pointed to by <CODE>proto</CODE>. The
translation is done using /etc/ethertypes. The return value is as follows: 0 = success, 1 = success but the name equals "LENGTH", -1 = no translation possible.
</p>
</li>
<li><CODE>int number_to_name(unsigned short proto, char *name)</CODE>
<p>
Translate a protocol number to a protocol name, using /etc/ethertypes. Returns 0 on success and puts the protocol name at the address pointed to
by <CODE>name</CODE>. This demands the <CODE>name</CODE> buffer to be of size at least 21.
</p>
</li>
<li><CODE>void check_option(unsigned int *flags, unsigned int mask)</CODE>
<p>
Checks the boolean <CODE>(*flags & mask)</CODE>. Normally, <CODE>mask</CODE> should be a power of 2 and <CODE>flags</CODE> points to an integer containing
all the options already processed for the specific module. If the boolean is true then an error message is printed to the screen about double usage
of the same option and the program exits. If the boolean is false, the bit in <CODE>*flags</CODE> for the specific option is put to 1.
</p>
</li>
<li><CODE>int check_inverse(const char option[])</CODE>
<p>
Checks if the string argument equals "!". If it does, <CODE>optind</CODE> is increased and 1 is returned, else 0 is returned. As this function can increase <CODE>optind</CODE>,
the code that comes behind the call to this function has to use <CODE>argv[optind - 1]</CODE>, not <CODE>optarg</CODE> because <CODE>optarg</CODE> can point to the "!".
</p>
</li>
</ol>
</p>
<p>
<em>The <CODE>hookmask</CODE> argument to <CODE>final_check()</CODE>:</em>
</p>
<p>
The usage of the <CODE>hookmask</CODE> argument for the <CODE>final_check()</CODE> function could use some extra explaining. This mask contains the information from which
base chain the rule in question (so the module's data in question) can be reached. If your module is only viable for certain base chains, you should check it isn't used
in an invalid chain. If the rule can be reached through the PREROUTING chain, then the NF_BR_PRE_ROUTING'th least significant bit will be set for <CODE>hookmask</CODE>. Here
is a list of all constants: NF_BR_PRE_ROUTING = 0, NF_BR_LOCAL_IN = 1, NF_BR_FORWARD = 2, NF_BR_LOCAL_OUT = 3, NF_BR_POST_ROUTING = 4, NF_BR_BROUTING = 5. See the already
implemented modules for examples.
</p>
<h2><a NAME="ss3.2">3.2</a> <a HREF="ebtables-hacking-HOWTO.html#toc3.2">Kernel</a>
</h2>
<p>
The kernel modules are responsible for checking the data received by userspace and its main task is doing whatever the
data tells the module to do, with a frame.
</p>
<h3><a NAME="ss3.2.1">3.2.1</a> <a HREF="ebtables-hacking-HOWTO.html#toc3.2.1">Matches</a>
</h3>
<p>
The kernel match module is contained in a <CODE>struct ebt_match</CODE> of which its relevant fields will be discussed now:
<ol>
<li><CODE>struct list_head list</CODE>
<p>
Set this to <CODE>{NULL, NULL}</CODE>.
</p></li>
<li><CODE>char name[EBT_FUNCTION_MAXNAMELEN]</CODE>
<p>
The name of the match, should be the same as the name of the corresponding userspace match.
</p></li>
<li><CODE>int (*match)(const struct sk_buff *skb, const struct net_device *in,<BR>
                       const struct net_device *out, const void *matchdata,<BR>
                       unsigned int datalen)</CODE>
<p>
Checks if the frame (<CODE>skb</CODE>) matches the data from the match (<CODE>matchdata</CODE>) contained in the rule. If it matches,
EBT_MATCH (=0) is returned, else EBT_NOMATCH (=1) is returned. This function is executed for every frame that
comes into contact with a rule utilizing the match in question.
</p></li>
<li><CODE>int (*check)(const char *tablename, unsigned int hookmask,<BR>
                       const struct ebt_entry *e, void *matchdata, unsigned int datalen)</CODE>
<p>
Checks the data of the match (<CODE>matchdata</CODE>) contained in the rule (<CODE>e</CODE>) to see if it is valid. This function is executed
when the user gives new table data to the kernel. Returns 0 on success, a negative value (e.g. <CODE>-EINVAL</CODE>) on failure.
</p></li>
<li><CODE>void (*destroy)(void *matchdata, unsigned int datalen)</CODE>
<p>
Contains the code executed when a rule utilizing the match is removed. Set to <CODE>NULL</CODE> if not used.
</p></li>
<li><CODE>struct module *me</CODE>
<p>
Always set to <CODE>THIS_MODULE</CODE>.
</p>
</li>
</ol>
</p>
<h3><a NAME="ss3.2.2">3.2.2</a> <a HREF="ebtables-hacking-HOWTO.html#toc3.2.2">Watchers</a>
</h3>
<p>
The watchers are contained in a <CODE>struct ebt_watcher</CODE>, its members are basically the same as
for the <CODE>struct ebt_match</CODE>, except that the <CODE>watcher()</CODE> function
(the analogue of the <CODE>match()</CODE> function) has no return value.
</p>
<h3><a NAME="ss3.2.3">3.2.3</a> <a HREF="ebtables-hacking-HOWTO.html#toc3.2.3">Targets</a>
</h3>
<p>
The targets are contained in a <CODE>struct ebt_target</CODE>, its members are basically the same as
for the <CODE>struct ebt_match</CODE>, except that it contains a <CODE>target()</CODE> member instead of a <CODE>match()</CODE> member.
This <CODE>target()</CODE> function gives back a basic decision to the main ebtables
code. This decision is <CODE>EBT_ACCEPT</CODE>, <CODE>EBT_DROP</CODE>, <CODE>EBT_CONTINUE</CODE> or <CODE>EBT_RETURN</CODE>.
The <CODE>target()</CODE> function should make sure the decision cannot be <CODE>EBT_RETURN</CODE> for a rule on a base chain.
</p>
<h3><a NAME="ss3.2.4">3.2.4</a> <a HREF="ebtables-hacking-HOWTO.html#toc3.2.4">Miscellaneous</a>
</h3>
<p>
<em>Macro's:</em>
</p>
<p>
Some macro's useful to ebtables kernel modules:
<ol>
<li><CODE>FWINV(bool,invflg)</CODE>
<p>
Used in the <CODE>match()</CODE> functions. The <CODE>bool</CODE> argument contains some boolean expression
and the <CODE>invflg</CODE> argument has the bit set for a specific option. See the implementation in <CODE>ebtables.h</CODE> and
the usage in f.e. <CODE>ebt_ip.c</CODE> for more details.
</p>
</li>
<li>
<CODE>BASE_CHAIN</CODE>
<p>
True if the hook mask denotes that the rule is in a base chain,
used in the <CODE>check()</CODE> functions.
</p>
</li>
<li><CODE>CLEAR_BASE_CHAIN_BIT</CODE>
<p>
This macro should be used (only once) before using the <CODE>hookmask</CODE> in the <CODE>check()</CODE> function.
If you want to use <CODE>BASE_CHAIN</CODE> you must use it earlier in the function.
See f.e. <CODE>ebt_dnat.c</CODE>.
</p>
</li>
<li><CODE>INVALID_TARGET</CODE>
<p>
True if the target (an integer) is not a standard target. See f.e. <CODE>ebt_dnat.c</CODE> for its usage.
</p>
</li>
</ol>
</p>
<p>
<em>Adding a new table:</em>
</p>
<p>
You can also make a new table, see the existing implementations (e.g. <CODE>ebtable_filter.c</CODE>) for details.
</p>
<p>
<em>Useful functions:</em>
</p>
<p>
<ol>
<li><CODE>int ebt_register_table(struct ebt_table *table)</CODE>
<p>
Registers the table with its data contained in the <CODE>struct ebt_table *table</CODE>. Returns a negative value on failure.
This is used in the initialization function of a table module.
</p>
</li>
<li><CODE>void ebt_unregister_table(struct ebt_table *table)</CODE>
<p>
Unregisters the table. This is used in the function that is called when the module is unloaded and also when something goes wrong
in the initialization function.
</p>
</li>
<li><CODE>int ebt_register_match(struct ebt_match *match)</CODE>
<p>
Registers the match with its data contained in the <CODE>struct ebt_match *match</CODE>. Returns a negative value on failure.
This is used in the initialization function of a match module.
</p>
</li>
<li><CODE>void ebt_unregister_match(struct ebt_match *match)</CODE>
<p>
Unregisters the match. This is used in the function that is called when the module is unloaded and also when something goes wrong
in the initialization function.
</p>
</li>
<li><CODE>int ebt_register_watcher(struct ebt_watcher *watcher)</CODE>
<p>
Registers the watcher with its data contained in the <CODE>struct ebt_watcher *watcher</CODE>. Returns a negative value on failure.
This is used in the initialization function of a watcher module.
</p>
</li>
<li><CODE>void ebt_unregister_watcher(struct ebt_watcher *watcher)</CODE>
<p>
Unregisters the watcher. This is used in the function that is called when the module is unloaded and also when something goes wrong
in the initialization function.
</p>
</li>
<li><CODE>int ebt_register_target(struct ebt_target *target)</CODE>
<p>
Registers the target with its data contained in the <CODE>struct ebt_target *target</CODE>. Returns a negative value on failure.
This is used in the initialization function of a target module.
</p>
</li>
<li><CODE>void ebt_unregister_target(struct ebt_target *target)</CODE>
<p>
Unregisters the target. This is used in the function that is called when the module is unloaded and also when something goes wrong
in the initialization function.
</p>
</li>
</ol>
</p>
<h2><a NAME="ss3.3">3.3</a> <a HREF="ebtables-hacking-HOWTO.html#toc3.3">General rules</a>
</h2>
<p>
<ol>
<li>
Indentation should be done using tabs.
</li>
<li>
No more than 80 columns should be used, taking into account tab width of 8 characters.
</li>
<li>
Bad or corrupt data should never be accepted by the kernel module's <CODE>check()</CODE> function. The userspace module should be
built so that no bad or corrupt data can ever be given to the kernel. If the kernel does not accept data given to it, this is considered
a userspace bug.
</li>
</ol>
</p>
<hr>
<a HREF="ebtables-hacking-HOWTO-4.html">Next</a>
<a HREF="ebtables-hacking-HOWTO-2.html">Previous</a>
<a HREF="ebtables-hacking-HOWTO.html#toc3">Contents</a>
</body>
</html>