summaryrefslogtreecommitdiffstats
path: root/docs/ebtables-hacking/ebtables-hacking-HOWTO-3.html
diff options
context:
space:
mode:
authorBart De Schuymer <bdschuym@pandora.be>2002-09-06 19:10:33 +0000
committerBart De Schuymer <bdschuym@pandora.be>2002-09-06 19:10:33 +0000
commit68bdce38b3794bd91b89c7e2e3cb0c0dfa0163bf (patch)
tree9f2b1e7a32aec65eafea28e2dcd0bc555fc4bc92 /docs/ebtables-hacking/ebtables-hacking-HOWTO-3.html
parent89cc15e186d810ee281466bac734edaf6d60b28b (diff)
*** empty log message ***
Diffstat (limited to 'docs/ebtables-hacking/ebtables-hacking-HOWTO-3.html')
-rw-r--r--docs/ebtables-hacking/ebtables-hacking-HOWTO-3.html468
1 files changed, 468 insertions, 0 deletions
diff --git a/docs/ebtables-hacking/ebtables-hacking-HOWTO-3.html b/docs/ebtables-hacking/ebtables-hacking-HOWTO-3.html
new file mode 100644
index 0000000..4b53955
--- /dev/null
+++ b/docs/ebtables-hacking/ebtables-hacking-HOWTO-3.html
@@ -0,0 +1,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>