summaryrefslogtreecommitdiffstats
path: root/docs/ebtables-hacking
diff options
context:
space:
mode:
authorBart De Schuymer <bdschuym@pandora.be>2003-11-11 18:51:00 +0000
committerBart De Schuymer <bdschuym@pandora.be>2003-11-11 18:51:00 +0000
commit2a6775bd1d5d81c578f78d10ffe4e757153f326e (patch)
tree5090b6a09646ecaaa1e38cf499fd4d9095e019c0 /docs/ebtables-hacking
parent75ad57a0f597c533b05271789a2303e7a36f7aba (diff)
update to 2.6
Diffstat (limited to 'docs/ebtables-hacking')
-rw-r--r--docs/ebtables-hacking/ebtables-hacking-HOWTO-3.html44
-rw-r--r--docs/ebtables-hacking/ebtables-hacking-HOWTO-4.html115
-rw-r--r--docs/ebtables-hacking/ebtables-hacking-HOWTO.html2
3 files changed, 99 insertions, 62 deletions
diff --git a/docs/ebtables-hacking/ebtables-hacking-HOWTO-3.html b/docs/ebtables-hacking/ebtables-hacking-HOWTO-3.html
index 4b53955..d80aa2b 100644
--- a/docs/ebtables-hacking/ebtables-hacking-HOWTO-3.html
+++ b/docs/ebtables-hacking/ebtables-hacking-HOWTO-3.html
@@ -31,13 +31,13 @@ described now:
<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>
+<p>The size of the match data, without the extra padding needed for alignment (this is added by the generic code).</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.
+explain the usage of the module and should look similar to the standard help.
</p>
</li>
<li><CODE>void (*init)(struct ebt_entry_match *m)</CODE>
@@ -57,7 +57,7 @@ are the same two parameters given to the <CODE>main</CODE> function. <CODE>entry
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.
+meaning you are allowed to change the address of the match's data (this is done f.e. in ebt_among.c).
</p>
</li>
<li><CODE>void (*final_check)(const struct ebt_u_entry *entry,<BR>
@@ -69,20 +69,20 @@ you should check that the user specified <CODE>-p XyZ</CODE>. The <CODE>name</CO
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.
+it is necessary to have this knowledge (see <a HREF="#ss3.1.4">section 3.1.4</a> for more information).
</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.
+be in a format the user could have used to make the rule, so that the option '--Lx' stays useful.
</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
+This function is executed when 2 rules have to be compared with each other 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>
@@ -108,7 +108,7 @@ to the previous section (mentally replace match by watcher where necessary).
<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
+A target module is a piece of code that does a certain action when 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).
@@ -153,7 +153,7 @@ use <CODE>FILL_TARGET("RETURN", pos);</CODE>
<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
+This macro produces the target string corresponding 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>
@@ -178,10 +178,11 @@ If you want to use <CODE>BASE_CHAIN</CODE> you must use it earlier in the functi
<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
+Before this rule was added, this target was not accessible from the base chain, but after the rule was added it is.
+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 of course 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.
+not mean that the kernel no longer has to check for validity, of course.
</p>
<p>
<em>A complete rule:</em>
@@ -249,16 +250,15 @@ Is needed in the initialization function of a watcher module, to register its da
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>
+<li><CODE>struct ethertypeent *getethertypebyname(const char *name)</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.
+Translate a name of an Ethernet protocol to the corresponding protocol number. The
+translation is done using /etc/ethertypes.
</p>
</li>
-<li><CODE>int number_to_name(unsigned short proto, char *name)</CODE>
+<li><CODE>struct ethertypeent *getethertypebynumber(int type)</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.
+Translate a protocol number to a protocol name, using /etc/ethertypes.
</p>
</li>
<li><CODE>void check_option(unsigned int *flags, unsigned int mask)</CODE>
@@ -297,10 +297,6 @@ data tells the module to do, with a frame.
<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.
@@ -335,7 +331,7 @@ Always set to <CODE>THIS_MODULE</CODE>.
<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.
+(which is analogous to 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>
@@ -349,10 +345,10 @@ The <CODE>target()</CODE> function should make sure the decision cannot be <CODE
<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>
+<em>Macros:</em>
</p>
<p>
-Some macro's useful to ebtables kernel modules:
+Some macros useful to ebtables kernel modules:
<ol>
<li><CODE>FWINV(bool,invflg)</CODE>
<p>
diff --git a/docs/ebtables-hacking/ebtables-hacking-HOWTO-4.html b/docs/ebtables-hacking/ebtables-hacking-HOWTO-4.html
index b6138b0..39f7ac7 100644
--- a/docs/ebtables-hacking/ebtables-hacking-HOWTO-4.html
+++ b/docs/ebtables-hacking/ebtables-hacking-HOWTO-4.html
@@ -215,15 +215,15 @@ Compares the data of two "instances" of the match module, returning 1 if the dat
<PRE>
static struct ebt_u_match ip_match =
{
- EBT_IP_MATCH,
- sizeof(struct ebt_ip_info),
- print_help,
- init,
- parse,
- final_check,
- print,
- compare,
- opts
+ .name = EBT_IP_MATCH,
+ .size = sizeof(struct ebt_ip_info),
+ .help = print_help,
+ .init = init,
+ .parse = parse,
+ .final_check = final_check,
+ .print = print,
+ .compare = compare,
+ .extra_ops = opts,
};
</PRE>
</td></tr>
@@ -276,8 +276,7 @@ static void final_check_d(const struct ebt_u_entry *entry,
</table>
</p>
<p>
-The target returned by the dnat kernel module (see the man page) is contained in the <CODE>target</CODE> field of the module's specific struct
-(<CODE>struct ebt_nat_info</CODE>). First we check that this target isn't RETURN on one of the standard (base) chains. Then we make
+First we check that this target isn't RETURN on one of the standard (base) chains. Then we make
<CODE>hookmask</CODE> ready for direct use by using the <CODE>CLEAR_BASE_CHAIN_BIT</CODE> macro. Next is checked if the rule containing this
"module instance" is accessible through illegal chains or tables.
Finally, the argument <CODE>time</CODE> is checked. If it equals zero, the function checks to be sure a destination IP address was specified.
@@ -317,20 +316,26 @@ static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in,
unsigned int datalen)
{
struct ebt_ip_info *info = (struct ebt_ip_info *)data;
+ union {struct iphdr iph; struct tcpudphdr ports;} u;
+ if (skb_copy_bits(skb, 0, &u.iph, sizeof(u.iph)))
+ return EBT_NOMATCH;
if (info->bitmask & EBT_IP_SOURCE &&
- FWINV((((*skb).nh.iph)->saddr & info->smsk) !=
+ FWINV((u.iph.saddr & info->smsk) !=
info->saddr, EBT_IP_SOURCE))
return EBT_NOMATCH;
- return EBT_MATCH;
}
</PRE>
</td></tr>
</table>
</p>
<p>
-This is the filtering function of the ip match module, it is executed for every frame that comes into contact with an ebtables rule that uses the ip match. All it does
-is tell the ebtables main code if the frame matches or not.
+This is the filtering function of the ip match module, it is executed for every
+frame that comes into contact with an ebtables rule that uses the ip match. All it does
+is tell the ebtables main code if the frame matches or not.<br>
+As the data isn't necessarily linearized in memory, meaning that the data isn't
+guaranteed to be in consecutive memory places, we need to use skb_copy_bits()
+to copy the IP header to the stack. We can then match the data on the stack.
</p>
<p>
<table BGCOLOR="#E0E0E0" WIDTH="100%">
@@ -363,8 +368,10 @@ This function is executed for every rule that uses the ip match, when the kernel
<PRE>
static struct ebt_match filter_ip =
{
- {NULL, NULL}, EBT_IP_MATCH, ebt_filter_ip, ebt_ip_check, NULL,
- THIS_MODULE
+ .name = EBT_IP_MATCH,
+ .match = ebt_filter_ip,
+ .check = ebt_ip_check,
+ .me = THIS_MODULE,
};
</PRE>
</td></tr>
@@ -406,7 +413,7 @@ MODULE_LICENSE("GPL");
</table>
</p>
<p>
-Ofcourse your module is released under the GPL.
+Of course your module is released under the GPL.
</p>
<p>
<em><h3>The ebtables kernel filter table</h3></em>
@@ -434,9 +441,18 @@ The valid netfilter hooks for the ebtables filter table are the bridge <CODE>LOC
<PRE>
static struct ebt_entries initial_chains[] =
{
- {0, "INPUT", 0, EBT_ACCEPT, 0},
- {0, "FORWARD", 0, EBT_ACCEPT, 0},
- {0, "OUTPUT", 0, EBT_ACCEPT, 0}
+ {
+ .name = "INPUT",
+ .policy = EBT_ACCEPT,
+ },
+ {
+ .name = "FORWARD",
+ .policy = EBT_ACCEPT,
+ },
+ {
+ .name = "OUTPUT",
+ .policy = EBT_ACCEPT,
+ },
};
</PRE>
@@ -452,9 +468,15 @@ The filter table consists of three chains, initially containing zero rules and h
<PRE>
static struct ebt_replace initial_table =
{
- "filter", FILTER_VALID_HOOKS, 0, 3 * sizeof(struct ebt_entries),
- { [NF_BR_LOCAL_IN]&initial_chains[0], [NF_BR_FORWARD]&initial_chains[1],
- [NF_BR_LOCAL_OUT]&initial_chains[2] }, 0, NULL, (char *)initial_chains
+ .name = "filter",
+ .valid_hooks = FILTER_VALID_HOOKS,
+ .entries_size = 3 * sizeof(struct ebt_entries),
+ .hook_entry = {
+ [NF_BR_LOCAL_IN] = &initial_chains[0],
+ [NF_BR_FORWARD] = &initial_chains[1],
+ [NF_BR_LOCAL_OUT] = &initial_chains[2],
+ },
+ .entries = (char *)initial_chains,
};
</PRE>
@@ -480,7 +502,7 @@ static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
</table>
</p>
<p>
-This function is executed when new table data is given to the kernel. We just check
+This function is executed when new table data is given to the kernel. We just check that
the valid hooks according to userspace are the same as those according to the kernel module.
</p>
<p>
@@ -489,8 +511,12 @@ the valid hooks according to userspace are the same as those according to the ke
<PRE>
static struct ebt_table frame_filter =
{
- {NULL, NULL}, "filter", &initial_table, FILTER_VALID_HOOKS,
- RW_LOCK_UNLOCKED, check, NULL
+ .name = "filter",
+ .table = &initial_table,
+ .valid_hooks = FILTER_VALID_HOOKS,
+ .lock = RW_LOCK_UNLOCKED,
+ .check = check,
+ .me = THIS_MODULE,
};
</PRE>
@@ -516,19 +542,34 @@ ebt_hook (unsigned int hook, struct sk_buff **pskb, const struct net_device *in,
</table>
</p>
<p>
-This function is executed for every frame that passes a netfilter hook on which this function is registered.
+This function is executed for every frame that passes through a netfilter hook on which this function is registered.
</p>
<p>
<table BGCOLOR="#E0E0E0" WIDTH="100%">
<tr><td>
<PRE>
static struct nf_hook_ops ebt_ops_filter[] = {
- { { NULL, NULL }, ebt_hook, PF_BRIDGE, NF_BR_LOCAL_IN,
- NF_BR_PRI_FILTER_BRIDGED},
- { { NULL, NULL }, ebt_hook, PF_BRIDGE, NF_BR_FORWARD,
- NF_BR_PRI_FILTER_BRIDGED},
- { { NULL, NULL }, ebt_hook, PF_BRIDGE, NF_BR_LOCAL_OUT,
- NF_BR_PRI_FILTER_OTHER}
+ {
+ .hook = ebt_hook,
+ .owner = THIS_MODULE,
+ .pf = PF_BRIDGE,
+ .hooknum = NF_BR_LOCAL_IN,
+ .priority = NF_BR_PRI_FILTER_BRIDGED,
+ },
+ {
+ .hook = ebt_hook,
+ .owner = THIS_MODULE,
+ .pf = PF_BRIDGE,
+ .hooknum = NF_BR_FORWARD,
+ .priority = NF_BR_PRI_FILTER_BRIDGED,
+ },
+ {
+ .hook = ebt_hook,
+ .owner = THIS_MODULE,
+ .pf = PF_BRIDGE,
+ .hooknum = NF_BR_LOCAL_OUT,
+ .priority = NF_BR_PRI_FILTER_OTHER,
+ },
};
</PRE>
@@ -551,7 +592,7 @@ static int __init init(void)
ret = ebt_register_table(&frame_filter);
if (ret &lt; 0)
return ret;
- for (i = 0; i &lt; sizeof(ebt_ops_filter) / sizeof(ebt_ops_filter[0]); i++)
+ for (i = 0; i &lt; ARRAY_SIZE(ebt_ops_filter); i++)
if ((ret = nf_register_hook(&ebt_ops_filter[i])) &lt; 0)
goto cleanup;
return ret;
@@ -567,7 +608,7 @@ cleanup:
</table>
</p>
<p>
-register the table to the main ebtables code; register <CODE>ebt_hook()</CODE> on the appropriate netfilter hooks.
+Register the table to the main ebtables code; register <CODE>ebt_hook()</CODE> on the appropriate netfilter hooks.
</p>
<p>
<table BGCOLOR="#E0E0E0" WIDTH="100%">
@@ -577,7 +618,7 @@ static void __exit fini(void)
{
int i;
- for (i = 0; i &lt; sizeof(ebt_ops_filter) / sizeof(ebt_ops_filter[0]); i++)
+ for (i = 0; i &lt; ARRAY_SIZE(ebt_ops_filter); i++)
nf_unregister_hook(&ebt_ops_filter[i]);
ebt_unregister_table(&frame_filter);
}
diff --git a/docs/ebtables-hacking/ebtables-hacking-HOWTO.html b/docs/ebtables-hacking/ebtables-hacking-HOWTO.html
index 7e8fa68..2e51142 100644
--- a/docs/ebtables-hacking/ebtables-hacking-HOWTO.html
+++ b/docs/ebtables-hacking/ebtables-hacking-HOWTO.html
@@ -10,7 +10,7 @@
<H2>Bart De Schuymer,<BR>
mailing lists <CODE>ebtables-devel@lists.sourceforge.net</CODE> and
<CODE>ebtables-user@lists.sourceforge.net</CODE></H2>
- Last updated: 6 September 2002
+ Last updated: November 11, 2003
<HR>
<EM>This document describes the ebtables v2.0.x architecture for Linux
and how to implement new modules on top of it.</EM>