* Follow packets in rules
@ 2007-06-12 18:08 Fabrice Rafart
2007-06-12 21:41 ` Simon
` (2 more replies)
0 siblings, 3 replies; 28+ messages in thread
From: Fabrice Rafart @ 2007-06-12 18:08 UTC (permalink / raw)
To: netfilter-devel
Hello,
I look for a tool to follow a packets into rules of netfilter.
For example :
# iptables-test -s 192.168.1.1 -d 192.168.2.1 -p tcp --dport 25
--> FORWARD line 1 : -p tcp --dport 25 -j SMTP
--> SMTP line 3 : -s 192.168.1.0/24 -j DROP
This show me which rules matches the packet until the end.
Does this exist ?
Thank and sorry for my poor english.
Cordialement,
--
Fabrice Rafart
Administrateur systèmes et réseaux
Etablissement français du sang, Ile de France.
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: Follow packets in rules 2007-06-12 18:08 Follow packets in rules Fabrice Rafart @ 2007-06-12 21:41 ` Simon 2007-06-13 7:31 ` Fabrice Rafart 2007-06-13 8:57 ` Pablo Neira Ayuso 2007-07-03 15:07 ` Fabrice Rafart 2 siblings, 1 reply; 28+ messages in thread From: Simon @ 2007-06-12 21:41 UTC (permalink / raw) To: Fabrice Rafart; +Cc: netfilter-devel On 6/12/07, Fabrice Rafart <fabrice.rafart@efs.sante.fr> wrote: > Hello, Salut Fabrice! > I look for a tool to follow a packets into rules of netfilter. [...] > This show me which rules matches the packet until the end. I'm not sure if such a tool exists, but there is a way to follow the packets very well. Using the LOG target, you can log packets as they match certain rules and you can put a message to be put in the log to identify that line. After, you just have to grep the logfile for patterns matching the ip address and you should see the history of each packets that came in. You could make your own target queues like LOGDROP or LOGACCEPT and have a log rule followed by the drop/accept rule. Note that logging things this way takes a lot of disk space and should only be used in a lan for experimentation. Good luck, Simon ^ permalink raw reply [flat|nested] 28+ messages in thread
* RE: Follow packets in rules 2007-06-12 21:41 ` Simon @ 2007-06-13 7:31 ` Fabrice Rafart 2007-06-18 16:12 ` Simon 0 siblings, 1 reply; 28+ messages in thread From: Fabrice Rafart @ 2007-06-13 7:31 UTC (permalink / raw) To: 'Simon'; +Cc: netfilter-devel > -----Message d'origine----- > De : netfilter-devel-bounces@lists.netfilter.org > [mailto:netfilter-devel-bounces@lists.netfilter.org] De la > part de Simon > Envoyé : mardi 12 juin 2007 23:41 > À : Fabrice Rafart > Cc : netfilter-devel@lists.netfilter.org > Objet : Re: Follow packets in rules > > On 6/12/07, Fabrice Rafart <fabrice.rafart@efs.sante.fr> wrote: > > Hello, > > Salut Fabrice! > > > I look for a tool to follow a packets into rules of netfilter. > [...] > > This show me which rules matches the packet until the end. > > I'm not sure if such a tool exists, but there is a way to follow the > packets very well. > Using the LOG target, you can log packets as they match certain rules > and you can put a message to be put in the log to identify that line. > > After, you just have to grep the logfile for patterns matching the ip > address and you should see the history of each packets that came in. > > You could make your own target queues like LOGDROP or LOGACCEPT and > have a log rule followed by the drop/accept rule. Thanks for your answer. I know this possibility and I use it for log some packets but I can't double all my rules (almost 200) by a log rule. Cordialement, -- Fabrice Rafart Administrateur systèmes et réseaux Etablissement français du sang, Ile de France. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Follow packets in rules 2007-06-13 7:31 ` Fabrice Rafart @ 2007-06-18 16:12 ` Simon 2007-06-18 16:14 ` Patrick McHardy 0 siblings, 1 reply; 28+ messages in thread From: Simon @ 2007-06-18 16:12 UTC (permalink / raw) To: Fabrice Rafart; +Cc: netfilter-devel > I know this possibility and I use it for log some packets but I can't double > all my rules (almost 200) by a log rule. Hi Fabrice, I don't log everything too. I usually choose some types of information to log, and some IP's to log from. For example, a friend connected to my pc and logged in to a secure website, at that moment, i stop logging this guy, the website logs in its own way. Somebody that is still trying stuff and has not yet connected for X minutes will then get flagged as a suspect and different logging takes place (to avoid DoS, and others). One last detail, is if your rules are done well, you don't need to log much. Logging more would be for "debuging" or "development" in my opinion. So when I was suggesting to have a log identify each rules passed by each packets it wasn't for a production environment. But then again, if you asked this kind of question, i hope it wasn't for a prod system! As for testing the rules, I think the best way is to craft packets and send them to the interface. There are some hacking tools that permit to make raw ethernet frames and provide "easy" way of modifying packets at the ip or tcp level and they work like scripts that you execute. Good luck! Simon ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Follow packets in rules 2007-06-18 16:12 ` Simon @ 2007-06-18 16:14 ` Patrick McHardy 0 siblings, 0 replies; 28+ messages in thread From: Patrick McHardy @ 2007-06-18 16:14 UTC (permalink / raw) To: Simon; +Cc: Fabrice Rafart, netfilter-devel Simon wrote: >> I know this possibility and I use it for log some packets but I can't >> double >> all my rules (almost 200) by a log rule. > > > Hi Fabrice, > I don't log everything too. I usually choose some types of > information to log, and some IP's to log from. For example, a friend > connected to my pc and logged in to a secure website, at that moment, > i stop logging this guy, the website logs in its own way. Somebody > that is still trying stuff and has not yet connected for X minutes > will then get flagged as a suspect and different logging takes place > (to avoid DoS, and others). > > One last detail, is if your rules are done well, you don't need to > log much. Logging more would be for "debuging" or "development" in my > opinion. So when I was suggesting to have a log identify each rules > passed by each packets it wasn't for a production environment. But > then again, if you asked this kind of question, i hope it wasn't for a > prod system! > > As for testing the rules, I think the best way is to craft packets > and send them to the interface. There are some hacking tools that > permit to make raw ethernet frames and provide "easy" way of modifying > packets at the ip or tcp level and they work like scripts that you > execute. Just FYI, Jozsef sent a patch to merge TRACE into mainline today, I'll most likely send it upstream for 2.6.23. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Follow packets in rules 2007-06-12 18:08 Follow packets in rules Fabrice Rafart 2007-06-12 21:41 ` Simon @ 2007-06-13 8:57 ` Pablo Neira Ayuso 2007-06-13 15:43 ` Juan León 2007-07-03 15:07 ` Fabrice Rafart 2 siblings, 1 reply; 28+ messages in thread From: Pablo Neira Ayuso @ 2007-06-13 8:57 UTC (permalink / raw) To: Fabrice Rafart; +Cc: netfilter-devel Fabrice Rafart wrote: > I look for a tool to follow a packets into rules of netfilter. > > For example : > > # iptables-test -s 192.168.1.1 -d 192.168.2.1 -p tcp --dport 25 > --> FORWARD line 1 : -p tcp --dport 25 -j SMTP > --> SMTP line 3 : -s 192.168.1.0/24 -j DROP > > This show me which rules matches the packet until the end. > > Does this exist ? check nfsim: http://ozlabs.org/~jk/projects/nfsim/ AFAIK, it's not actively maintained so probably you'll have to hack on it a bit. -- The dawn of the fourth age of Linux firewalling is coming; a time of great struggle and heroic deeds -- J.Kadlecsik got inspired by J.Morris ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Follow packets in rules 2007-06-13 8:57 ` Pablo Neira Ayuso @ 2007-06-13 15:43 ` Juan León 2007-06-13 16:28 ` Samuel Jean 0 siblings, 1 reply; 28+ messages in thread From: Juan León @ 2007-06-13 15:43 UTC (permalink / raw) To: Fabrice Rafart, netfilter-devel, pablo Hi Fabrice, 2007/6/13, Pablo Neira Ayuso <pablo@netfilter.org>: > Fabrice Rafart wrote: > > I look for a tool to follow a packets into rules of netfilter. > > > > For example : > > > > # iptables-test -s 192.168.1.1 -d 192.168.2.1 -p tcp --dport 25 > > --> FORWARD line 1 : -p tcp --dport 25 -j SMTP > > --> SMTP line 3 : -s 192.168.1.0/24 -j DROP > > > > This show me which rules matches the packet until the end. > > > > Does this exist ? You can try using iptables command line to know if the package matchs with your rules. In the example bellow you'll see something familiar. debian:~# iptables -nvL FORWARD Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 125 25 ACCEPT 0 -- * * 192.168.132.25 192.126.132.56 Let's take a close look at this part. pkts bytes 125 25 Every time your rule matchs, you'll see the packages changes. Use the line bellow to check it. debian:~# watch -n 1 'iptables -nvL FORWARD' > check nfsim: http://ozlabs.org/~jk/projects/nfsim/ > > AFAIK, it's not actively maintained so probably you'll have to hack on > it a bit. As far as read, it's not longer maintained. I hope this help. Best Regards. > -- > The dawn of the fourth age of Linux firewalling is coming; a time of > great struggle and heroic deeds -- J.Kadlecsik got inspired by J.Morris > > ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Follow packets in rules 2007-06-13 15:43 ` Juan León @ 2007-06-13 16:28 ` Samuel Jean 2007-06-13 16:53 ` Patrick McHardy 0 siblings, 1 reply; 28+ messages in thread From: Samuel Jean @ 2007-06-13 16:28 UTC (permalink / raw) To: Juan León, Fabrice Rafart, netfilter-devel, pablo, kaber, nicboul [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 894 bytes --] On Wed, Jun 13, 2007, Juan León <debjuanca@gmail.com> said: > Hi Fabrice, > > > 2007/6/13, Pablo Neira Ayuso <pablo@netfilter.org>: >> Fabrice Rafart wrote: >> > I look for a tool to follow a packets into rules of netfilter. >> > >> > For example : >> > >> > # iptables-test -s 192.168.1.1 -d 192.168.2.1 -p tcp --dport 25 >> > --> FORWARD line 1 : -p tcp --dport 25 -j SMTP >> > --> SMTP line 3 : -s 192.168.1.0/24 -j DROP >> > >> > This show me which rules matches the packet until the end. >> > >> > Does this exist ? There was the TRACE target born for this purpose a couple years ago. http://svn.netfilter.org/cgi-bin/viewcvs.cgi/branches/patch-o-matic-ng/linux-2.6.11/TRACE/?rev=3680 It sure will require a bit of hacking for recent kernels. Pablo, Patrick -- Is this an interesting feature that worths merging in mainline, or patch-o-matic at least ? Best regards, Samuel ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Follow packets in rules 2007-06-13 16:28 ` Samuel Jean @ 2007-06-13 16:53 ` Patrick McHardy 2007-06-13 19:43 ` Jozsef Kadlecsik 0 siblings, 1 reply; 28+ messages in thread From: Patrick McHardy @ 2007-06-13 16:53 UTC (permalink / raw) To: jix; +Cc: Fabrice Rafart, netfilter-devel, nicboul, pablo, Juan León Samuel Jean wrote: > There was the TRACE target born for this purpose a couple years ago. > > http://svn.netfilter.org/cgi-bin/viewcvs.cgi/branches/patch-o-matic-ng/linux-2.6.11/TRACE/?rev=3680 > > It sure will require a bit of hacking for recent kernels. > > Pablo, Patrick -- > > Is this an interesting feature that worths merging in mainline, or > patch-o-matic at least ? It would be interesting for the kernel if it can be done in a non-intrusive way. I can't remember what the old patches exactly did, but I believe it was kind of a hack. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Follow packets in rules 2007-06-13 16:53 ` Patrick McHardy @ 2007-06-13 19:43 ` Jozsef Kadlecsik 2007-06-14 7:55 ` Fabrice Rafart 2007-06-14 13:13 ` Patrick McHardy 0 siblings, 2 replies; 28+ messages in thread From: Jozsef Kadlecsik @ 2007-06-13 19:43 UTC (permalink / raw) To: netfilter-devel On Wed, 13 Jun 2007, Patrick McHardy wrote: > Samuel Jean wrote: >> There was the TRACE target born for this purpose a couple years ago. >> >> http://svn.netfilter.org/cgi-bin/viewcvs.cgi/branches/patch-o-matic-ng/linux-2.6.11/TRACE/?rev=3680 >> >> It sure will require a bit of hacking for recent kernels. >> >> Pablo, Patrick -- >> >> Is this an interesting feature that worths merging in mainline, or >> patch-o-matic at least ? > > It would be interesting for the kernel if it can be done in a > non-intrusive way. I can't remember what the old patches exactly > did, but I believe it was kind of a hack. It was just a little bit of hack ;-). I could not find the patch lying around here, fortunately there is an old copy from the patch-o-matic era in svn: http://svn.netfilter.org/cgi-bin/viewcvs.cgi/old_stuff/netfilter/trunk/patch-o-matic/extra/TRACE.patch?rev=3069 Best regards, Jozsef - E-mail : kadlec@blackhole.kfki.hu, kadlec@sunserv.kfki.hu PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt Address : KFKI Research Institute for Particle and Nuclear Physics H-1525 Budapest 114, POB. 49, Hungary ^ permalink raw reply [flat|nested] 28+ messages in thread
* RE: Follow packets in rules 2007-06-13 19:43 ` Jozsef Kadlecsik @ 2007-06-14 7:55 ` Fabrice Rafart 2007-06-14 13:13 ` Patrick McHardy 1 sibling, 0 replies; 28+ messages in thread From: Fabrice Rafart @ 2007-06-14 7:55 UTC (permalink / raw) To: netfilter-devel Hello, Thanks for all your answers. I can't use LOG destination or the packet/byes count : - LOG : I must double all my rules by a LOG rules : heavy and too verbose. - counter : My fw is in use, so I can't make difference between real packet and the test one. Netfilter had all the code to parse his rules, I think about a little hack to give some parameter on a command line and print the matches on stdin. But, there is a but ! I'm not a programmer. Cordialement, -- Fabrice Rafart Administrateur systèmes et réseaux Etablissement français du sang, Ile de France. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Follow packets in rules 2007-06-13 19:43 ` Jozsef Kadlecsik 2007-06-14 7:55 ` Fabrice Rafart @ 2007-06-14 13:13 ` Patrick McHardy 2007-06-14 14:18 ` Jozsef Kadlecsik 1 sibling, 1 reply; 28+ messages in thread From: Patrick McHardy @ 2007-06-14 13:13 UTC (permalink / raw) To: Jozsef Kadlecsik; +Cc: netfilter-devel Jozsef Kadlecsik wrote: > On Wed, 13 Jun 2007, Patrick McHardy wrote: > >> It would be interesting for the kernel if it can be done in a >> non-intrusive way. I can't remember what the old patches exactly >> did, but I believe it was kind of a hack. > > > It was just a little bit of hack ;-). I could not find the patch lying > around here, fortunately there is an old copy from the patch-o-matic era > in svn: > > http://svn.netfilter.org/cgi-bin/viewcvs.cgi/old_stuff/netfilter/trunk/patch-o-matic/extra/TRACE.patch?rev=3069 Yeah, it doesn't look too bad. Unfortunately it breaks userspace compatibility. How about just adding a new match that prints a user-supplied string for specially marked packets? ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Follow packets in rules 2007-06-14 13:13 ` Patrick McHardy @ 2007-06-14 14:18 ` Jozsef Kadlecsik 2007-06-14 14:23 ` Patrick McHardy 0 siblings, 1 reply; 28+ messages in thread From: Jozsef Kadlecsik @ 2007-06-14 14:18 UTC (permalink / raw) To: Patrick McHardy; +Cc: netfilter-devel Hi Patrick, On Thu, 14 Jun 2007, Patrick McHardy wrote: >> http://svn.netfilter.org/cgi-bin/viewcvs.cgi/old_stuff/netfilter/trunk/patch-o-matic/extra/TRACE.patch?rev=3069 > > Yeah, it doesn't look too bad. Unfortunately it breaks userspace > compatibility. Sigh. > How about just adding a new match that prints a user-supplied string for > specially marked packets? That'd be hard to use in practice: imagine, you have hundred of rules in multiple, multilevel chains. You should have to modify all your rules and add meaningful, different log strings to every one of them if you'd need to check how given packets traverse the rules. Also, it'd be about the same as writing a log match. But in longer term we'd better support multiple targets instead of a log match. The "beauty" of the TRACE target is that there is no need to tweak the rules: just "mark" the packets (we don't use the standard mark, so we cannot clash with any rule) you are interested in to check how they traverse the rulesets and that's all. Simple and clean. An earlier version of the patch did not suffer from backward incompatibility: when we hit a marked packet and a matched rule, it searched the chain name and computed the rule number internally. But it can slow down packet processing if there are many matching rules and large number of rules in the chains so I introduced stored rulenumbers. What about going back to that approach? Tracing packets should not be considered as normal (and thus performance efficient) mode. Best regards, Jozsef - E-mail : kadlec@blackhole.kfki.hu, kadlec@sunserv.kfki.hu PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt Address : KFKI Research Institute for Particle and Nuclear Physics H-1525 Budapest 114, POB. 49, Hungary ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Follow packets in rules 2007-06-14 14:18 ` Jozsef Kadlecsik @ 2007-06-14 14:23 ` Patrick McHardy 2007-06-18 10:16 ` Jozsef Kadlecsik 0 siblings, 1 reply; 28+ messages in thread From: Patrick McHardy @ 2007-06-14 14:23 UTC (permalink / raw) To: Jozsef Kadlecsik; +Cc: netfilter-devel Jozsef Kadlecsik wrote: > Hi Patrick, > > On Thu, 14 Jun 2007, Patrick McHardy wrote: > >>> http://svn.netfilter.org/cgi-bin/viewcvs.cgi/old_stuff/netfilter/trunk/patch-o-matic/extra/TRACE.patch?rev=3069 >>> >> >> >> Yeah, it doesn't look too bad. Unfortunately it breaks userspace >> compatibility. > > > Sigh. > >> How about just adding a new match that prints a user-supplied string >> for specially marked packets? > > > That'd be hard to use in practice: imagine, you have hundred of rules in > multiple, multilevel chains. You should have to modify all your rules > and add meaningful, different log strings to every one of them if you'd > need to check how given packets traverse the rules. > > Also, it'd be about the same as writing a log match. But in longer term > we'd better support multiple targets instead of a log match. Indeed. I was thinking that iptables could automatically insert the match into rules, so you wouldn't have to modify your ruleset. But that could also be done with multiple targets. > The "beauty" of the TRACE target is that there is no need to tweak the > rules: just "mark" the packets (we don't use the standard mark, so we > cannot clash with any rule) you are interested in to check how they > traverse the rulesets and that's all. Simple and clean. > > An earlier version of the patch did not suffer from backward > incompatibility: when we hit a marked packet and a matched rule, it > searched the chain name and computed the rule number internally. But it > can slow down packet processing if there are many matching rules and > large number of rules in the chains so I introduced stored rulenumbers. > What about going back to that approach? Tracing packets should not be > considered as normal (and thus performance efficient) mode. Yes, that sounds reasonable. Performance doesn't matter much for this. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Follow packets in rules 2007-06-14 14:23 ` Patrick McHardy @ 2007-06-18 10:16 ` Jozsef Kadlecsik 2007-06-18 12:49 ` Patrick McHardy 2007-06-22 14:20 ` Patrick McHardy 0 siblings, 2 replies; 28+ messages in thread From: Jozsef Kadlecsik @ 2007-06-18 10:16 UTC (permalink / raw) To: Patrick McHardy; +Cc: netfilter-devel [-- Attachment #1: Type: TEXT/PLAIN, Size: 1220 bytes --] Hi Patrick, On Thu, 14 Jun 2007, Patrick McHardy wrote: >> An earlier version of the patch did not suffer from backward >> incompatibility: when we hit a marked packet and a matched rule, it >> searched the chain name and computed the rule number internally. But it >> can slow down packet processing if there are many matching rules and >> large number of rules in the chains so I introduced stored rulenumbers. >> What about going back to that approach? Tracing packets should not be >> considered as normal (and thus performance efficient) mode. > > Yes, that sounds reasonable. Performance doesn't matter much for this. Attached you can find the reworked TRACE target, which does not suffer from backward incompatibility. Unfortunately I had to steal one unused bit from skbuff to be able to mark the packets so that it surely does not clash with any rules using the standard "MARK" target. Logging level, flags and type are hardcoded. What do you think? Best regards, Jozsef - E-mail : kadlec@blackhole.kfki.hu, kadlec@sunserv.kfki.hu PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt Address : KFKI Research Institute for Particle and Nuclear Physics H-1525 Budapest 114, POB. 49, Hungary [-- Attachment #2: TRACE.patch --] [-- Type: TEXT/PLAIN, Size: 12456 bytes --] diff -urN --exclude-from=/usr/src/diff.exclude linux-2.6.21-orig/include/linux/skbuff.h linux-2.6.21-TRACE/include/linux/skbuff.h --- linux-2.6.21-orig/include/linux/skbuff.h 2007-04-26 05:08:32.000000000 +0200 +++ linux-2.6.21-TRACE/include/linux/skbuff.h 2007-06-14 16:35:25.000000000 +0200 @@ -217,6 +217,7 @@ * @mark: Generic packet mark * @nfct: Associated connection, if any * @ipvs_property: skbuff is owned by ipvs + * @nf_trace: netfilter packet trace flag * @nfctinfo: Relationship of this skb to the connection * @nfct_reasm: netfilter conntrack re-assembly pointer * @nf_bridge: Saved data about a bridged frame - see br_netfilter.c @@ -285,7 +286,8 @@ nfctinfo:3; __u8 pkt_type:3, fclone:2, - ipvs_property:1; + ipvs_property:1, + nf_trace:1; __be16 protocol; void (*destructor)(struct sk_buff *skb); diff -urN --exclude-from=/usr/src/diff.exclude linux-2.6.21-orig/net/ipv4/netfilter/ip_tables.c linux-2.6.21-TRACE/net/ipv4/netfilter/ip_tables.c --- linux-2.6.21-orig/net/ipv4/netfilter/ip_tables.c 2007-04-26 05:08:32.000000000 +0200 +++ linux-2.6.21-TRACE/net/ipv4/netfilter/ip_tables.c 2007-06-18 11:20:10.000000000 +0200 @@ -210,6 +210,110 @@ return (struct ipt_entry *)(base + offset); } +/* All zeroes == unconditional rule. */ +static inline int +unconditional(const struct ipt_ip *ip) +{ + unsigned int i; + + for (i = 0; i < sizeof(*ip)/sizeof(__u32); i++) + if (((__u32 *)ip)[i]) + return 0; + + return 1; +} + +static const char *hooknames[] = { + [NF_IP_PRE_ROUTING] = "PREROUTING", + [NF_IP_LOCAL_IN] = "INPUT", + [NF_IP_FORWARD] = "FORWARD", + [NF_IP_LOCAL_OUT] = "OUTPUT", + [NF_IP_POST_ROUTING] = "POSTROUTING", +}; + +enum nf_ip_trace_comments { + NF_IP_TRACE_COMMENT_RULE, + NF_IP_TRACE_COMMENT_RETURN, + NF_IP_TRACE_COMMENT_POLICY, +}; + +static const char *comments[] = { + [NF_IP_TRACE_COMMENT_RULE] = "rule", + [NF_IP_TRACE_COMMENT_RETURN] = "return", + [NF_IP_TRACE_COMMENT_POLICY] = "policy", +}; + +static struct nf_loginfo trace_loginfo = { + .type = NF_LOG_TYPE_LOG, + .u = { + .log = { + .level = 4, + .logflags = NF_LOG_MASK, + }, + }, +}; + +static inline int +get_chainname_rulenum(struct ipt_entry *s, struct ipt_entry *e, + char *hookname, char **chainname, + char **comment, unsigned int *rulenum) +{ + struct ipt_standard_target *t = (void *)ipt_get_target(s); + + if (strcmp(t->target.u.kernel.target->name, IPT_ERROR_TARGET) == 0) { + /* Head of user chain: ERROR target with chainname */ + *chainname = t->target.data; + (*rulenum) = 0; + } else if (s == e) { + (*rulenum)++; + + if (s->target_offset == sizeof(struct ipt_entry) + && strcmp(t->target.u.kernel.target->name, + IPT_STANDARD_TARGET) == 0 + && t->verdict < 0 + && unconditional(&s->ip)) { + /* Tail of chains: STANDARD target (return/policy) */ + *comment = *chainname == hookname + ? (char *)comments[NF_IP_TRACE_COMMENT_POLICY] + : (char *)comments[NF_IP_TRACE_COMMENT_RETURN]; + } + return 1; + } else + (*rulenum)++; + + return 0; +} + + +static inline void trace_packet(struct sk_buff *skb, + unsigned int hook, + const struct net_device *in, + const struct net_device *out, + char *tablename, + struct xt_table_info *private, + struct ipt_entry *e) +{ + void *table_base; + struct ipt_entry *root; + char *hookname, *chainname, *comment; + unsigned int rulenum = 0; + + table_base = (void *)private->entries[smp_processor_id()]; + root = get_entry(table_base, private->hook_entry[hook]); + + hookname = chainname = (char *)hooknames[hook]; + comment = (char *)comments[NF_IP_TRACE_COMMENT_RULE]; + + IPT_ENTRY_ITERATE(root, + private->size - private->hook_entry[hook], + get_chainname_rulenum, + e, hookname, &chainname, &comment, &rulenum); + + nf_log_packet(AF_INET, hook, skb, in, out, &trace_loginfo, + "TRACE: %s:%s:%s:%u ", + tablename, chainname, comment, rulenum); +} + /* Returns one of the generic firewall policies, like NF_ACCEPT. */ unsigned int ipt_do_table(struct sk_buff **pskb, @@ -267,6 +371,12 @@ t = ipt_get_target(e); IP_NF_ASSERT(t->u.kernel.target); + + /* The packet is traced: log it */ + if ((*pskb)->nf_trace) + trace_packet(*pskb, hook, in, out, + table->name, private, e); + /* Standard target? */ if (!t->u.kernel.target->target) { int v; @@ -347,19 +457,6 @@ #endif } -/* All zeroes == unconditional rule. */ -static inline int -unconditional(const struct ipt_ip *ip) -{ - unsigned int i; - - for (i = 0; i < sizeof(*ip)/sizeof(__u32); i++) - if (((__u32 *)ip)[i]) - return 0; - - return 1; -} - /* Figures out from what hook each rule can be called: returns 0 if there are loops. Puts hook bitmask in comefrom. */ static int diff -urN --exclude-from=/usr/src/diff.exclude linux-2.6.21-orig/net/ipv6/netfilter/ip6_tables.c linux-2.6.21-TRACE/net/ipv6/netfilter/ip6_tables.c --- linux-2.6.21-orig/net/ipv6/netfilter/ip6_tables.c 2007-04-26 05:08:32.000000000 +0200 +++ linux-2.6.21-TRACE/net/ipv6/netfilter/ip6_tables.c 2007-06-18 11:22:17.000000000 +0200 @@ -250,6 +250,111 @@ return (struct ip6t_entry *)(base + offset); } +/* All zeroes == unconditional rule. */ +static inline int +unconditional(const struct ip6t_ip6 *ipv6) +{ + unsigned int i; + + for (i = 0; i < sizeof(*ipv6); i++) + if (((char *)ipv6)[i]) + break; + + return (i == sizeof(*ipv6)); +} + +/* This cries for unification! */ +static const char *hooknames[] = { + [NF_IP6_PRE_ROUTING] = "PREROUTING", + [NF_IP6_LOCAL_IN] = "INPUT", + [NF_IP6_FORWARD] = "FORWARD", + [NF_IP6_LOCAL_OUT] = "OUTPUT", + [NF_IP6_POST_ROUTING] = "POSTROUTING", +}; + +enum nf_ip_trace_comments { + NF_IP6_TRACE_COMMENT_RULE, + NF_IP6_TRACE_COMMENT_RETURN, + NF_IP6_TRACE_COMMENT_POLICY, +}; + +static const char *comments[] = { + [NF_IP6_TRACE_COMMENT_RULE] = "rule", + [NF_IP6_TRACE_COMMENT_RETURN] = "return", + [NF_IP6_TRACE_COMMENT_POLICY] = "policy", +}; + +static struct nf_loginfo trace_loginfo = { + .type = NF_LOG_TYPE_LOG, + .u = { + .log = { + .level = 4, + .logflags = NF_LOG_MASK, + }, + }, +}; + +static inline int +get_chainname_rulenum(struct ip6t_entry *s, struct ip6t_entry *e, + char *hookname, char **chainname, + char **comment, unsigned int *rulenum) +{ + struct ip6t_standard_target *t = (void *)ip6t_get_target(s); + + if (strcmp(t->target.u.kernel.target->name, IP6T_ERROR_TARGET) == 0) { + /* Head of user chain: ERROR target with chainname */ + *chainname = t->target.data; + (*rulenum) = 0; + } else if (s == e) { + (*rulenum)++; + + if (s->target_offset == sizeof(struct ip6t_entry) + && strcmp(t->target.u.kernel.target->name, + IP6T_STANDARD_TARGET) == 0 + && t->verdict < 0 + && unconditional(&s->ipv6)) { + /* Tail of chains: STANDARD target (return/policy) */ + *comment = *chainname == hookname + ? (char *)comments[NF_IP6_TRACE_COMMENT_POLICY] + : (char *)comments[NF_IP6_TRACE_COMMENT_RETURN]; + } + return 1; + } else + (*rulenum)++; + + return 0; +} + + +static inline void trace_packet(struct sk_buff *skb, + unsigned int hook, + const struct net_device *in, + const struct net_device *out, + char *tablename, + struct xt_table_info *private, + struct ip6t_entry *e) +{ + void *table_base; + struct ip6t_entry *root; + char *hookname, *chainname, *comment; + unsigned int rulenum = 0; + + table_base = (void *)private->entries[smp_processor_id()]; + root = get_entry(table_base, private->hook_entry[hook]); + + hookname = chainname = (char *)hooknames[hook]; + comment = (char *)comments[NF_IP6_TRACE_COMMENT_RULE]; + + IP6T_ENTRY_ITERATE(root, + private->size - private->hook_entry[hook], + get_chainname_rulenum, + e, hookname, &chainname, &comment, &rulenum); + + nf_log_packet(AF_INET6, hook, skb, in, out, &trace_loginfo, + "TRACE: %s:%s:%s:%u ", + tablename, chainname, comment, rulenum); +} + /* Returns one of the generic firewall policies, like NF_ACCEPT. */ unsigned int ip6t_do_table(struct sk_buff **pskb, @@ -307,6 +412,12 @@ t = ip6t_get_target(e); IP_NF_ASSERT(t->u.kernel.target); + + /* The packet is traced: log it */ + if ((*pskb)->nf_trace) + trace_packet(*pskb, hook, in, out, + table->name, private, e); + /* Standard target? */ if (!t->u.kernel.target->target) { int v; @@ -386,19 +497,6 @@ #endif } -/* All zeroes == unconditional rule. */ -static inline int -unconditional(const struct ip6t_ip6 *ipv6) -{ - unsigned int i; - - for (i = 0; i < sizeof(*ipv6); i++) - if (((char *)ipv6)[i]) - break; - - return (i == sizeof(*ipv6)); -} - /* Figures out from what hook each rule can be called: returns 0 if there are loops. Puts hook bitmask in comefrom. */ static int diff -urN --exclude-from=/usr/src/diff.exclude linux-2.6.21-orig/net/netfilter/Kconfig linux-2.6.21-TRACE/net/netfilter/Kconfig --- linux-2.6.21-orig/net/netfilter/Kconfig 2007-04-26 05:08:32.000000000 +0200 +++ linux-2.6.21-TRACE/net/netfilter/Kconfig 2007-06-14 22:06:57.000000000 +0200 @@ -376,6 +376,18 @@ If you want to compile it as a module, say M here and read <file:Documentation/modules.txt>. If unsure, say `N'. +config NETFILTER_XT_TARGET_TRACE + tristate '"TRACE" target support' + depends on NETFILTER_XTABLES + depends on IP_NF_RAW || IP6_NF_RAW + help + The TRACE target allows you to mark packets so that the kernel + will log every rule which match the packets as those traverse + the tables, chains, rules. + + If you want to compile it as a module, say M here and read + <file:Documentation/modules.txt>. If unsure, say `N'. + config NETFILTER_XT_TARGET_SECMARK tristate '"SECMARK" target support' depends on NETFILTER_XTABLES && NETWORK_SECMARK diff -urN --exclude-from=/usr/src/diff.exclude linux-2.6.21-orig/net/netfilter/Makefile linux-2.6.21-TRACE/net/netfilter/Makefile --- linux-2.6.21-orig/net/netfilter/Makefile 2007-04-26 05:08:32.000000000 +0200 +++ linux-2.6.21-TRACE/net/netfilter/Makefile 2007-06-14 22:04:39.000000000 +0200 @@ -44,6 +44,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o +obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o diff -urN --exclude-from=/usr/src/diff.exclude linux-2.6.21-orig/net/netfilter/xt_TRACE.c linux-2.6.21-TRACE/net/netfilter/xt_TRACE.c --- linux-2.6.21-orig/net/netfilter/xt_TRACE.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.21-TRACE/net/netfilter/xt_TRACE.c 2007-06-14 22:04:12.000000000 +0200 @@ -0,0 +1,52 @@ +/* This is a module which is used to mark packets for tracing. + */ +#include <linux/module.h> +#include <linux/skbuff.h> + +#include <linux/netfilter/x_tables.h> + +MODULE_LICENSE("GPL"); +MODULE_ALIAS("ipt_TRACE"); + +static unsigned int +target(struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + unsigned int hooknum, + const struct xt_target *target, + const void *targinfo) +{ + (*pskb)->nf_trace = 1; + return XT_CONTINUE; +} + +static struct xt_target xt_trace_target[] = { + { + .name = "TRACE", + .family = AF_INET, + .target = target, + .table = "raw", + .me = THIS_MODULE, + }, + { + .name = "TRACE", + .family = AF_INET6, + .target = target, + .table = "raw", + .me = THIS_MODULE, + }, +}; + +static int __init xt_trace_init(void) +{ + return xt_register_targets(xt_trace_target, + ARRAY_SIZE(xt_trace_target)); +} + +static void __exit xt_trace_fini(void) +{ + xt_unregister_targets(xt_trace_target, ARRAY_SIZE(xt_trace_target)); +} + +module_init(xt_trace_init); +module_exit(xt_trace_fini); [-- Attachment #3: iptables-trace.patch --] [-- Type: TEXT/PLAIN, Size: 5397 bytes --] diff -urN --exclude=.svn iptables/extensions/.TRACE-test iptables-trace/extensions/.TRACE-test --- iptables/extensions/.TRACE-test 1970-01-01 01:00:00.000000000 +0100 +++ iptables-trace/extensions/.TRACE-test 2007-06-14 22:30:03.000000000 +0200 @@ -0,0 +1,2 @@ +#! /bin/sh +[ -f $KERNEL_DIR/net/netfilter/xt_TRACE.c ] && echo TRACE diff -urN --exclude=.svn iptables/extensions/.TRACE-test6 iptables-trace/extensions/.TRACE-test6 --- iptables/extensions/.TRACE-test6 1970-01-01 01:00:00.000000000 +0100 +++ iptables-trace/extensions/.TRACE-test6 2007-06-18 11:40:26.000000000 +0200 @@ -0,0 +1,2 @@ +#! /bin/sh +[ -f $KERNEL_DIR/net/netfilter/xt_TRACE.c ] && echo TRACE diff -urN --exclude=.svn iptables/extensions/libip6t_TRACE.c iptables-trace/extensions/libip6t_TRACE.c --- iptables/extensions/libip6t_TRACE.c 1970-01-01 01:00:00.000000000 +0100 +++ iptables-trace/extensions/libip6t_TRACE.c 2007-06-18 11:41:40.000000000 +0200 @@ -0,0 +1,63 @@ +/* Shared library add-on to ip6tables to add TRACE target support. */ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <getopt.h> + +#include <ip6tables.h> +#include <linux/netfilter_ipv6/ip6_tables.h> + +/* Function which prints out usage message. */ +static void +help(void) +{ + printf( +"TRACE target v%s takes no options\n", +IPTABLES_VERSION); +} + +static struct option opts[] = { + { 0 } +}; + +/* Initialize the target. */ +static void +init(struct ip6t_entry_target *t, unsigned int *nfcache) +{ +} + +/* Function which parses command options; returns true if it + ate an option */ +static int +parse(int c, char **argv, int invert, unsigned int *flags, + const struct ip6t_entry *entry, + struct ip6t_entry_target **target) +{ + return 0; +} + +static void +final_check(unsigned int flags) +{ +} + +static +struct ip6tables_target trace += { .next = NULL, + .name = "TRACE", + .version = IPTABLES_VERSION, + .size = IP6T_ALIGN(0), + .userspacesize = IP6T_ALIGN(0), + .help = &help, + .init = &init, + .parse = &parse, + .final_check = &final_check, + .print = NULL, /* print */ + .save = NULL, /* save */ + .extra_opts = opts +}; + +void _init(void) +{ + register_target6(&trace); +} diff -urN --exclude=.svn iptables/extensions/libip6t_TRACE.man iptables-trace/extensions/libip6t_TRACE.man --- iptables/extensions/libip6t_TRACE.man 1970-01-01 01:00:00.000000000 +0100 +++ iptables-trace/extensions/libip6t_TRACE.man 2007-06-18 11:51:13.000000000 +0200 @@ -0,0 +1,10 @@ +This target marks packes so that the kernel will log every rule which match +the packets as those traverse the tables, chains, rules. (The ip6t_LOG module +is required for the logging.) The packets are logged with the string prefix: +"TRACE: tablename:chainname:type:rulenum " where type can be "rule" for +plain rule, "return" for implicit rule at the end of a user defined chain +and "policy" for the policy of the built in chains. +.br +It can only be used in the +.BR raw +table. diff -urN --exclude=.svn iptables/extensions/libipt_TRACE.c iptables-trace/extensions/libipt_TRACE.c --- iptables/extensions/libipt_TRACE.c 1970-01-01 01:00:00.000000000 +0100 +++ iptables-trace/extensions/libipt_TRACE.c 2007-06-14 22:20:12.000000000 +0200 @@ -0,0 +1,63 @@ +/* Shared library add-on to iptables to add TRACE target support. */ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <getopt.h> + +#include <iptables.h> +#include <linux/netfilter_ipv4/ip_tables.h> + +/* Function which prints out usage message. */ +static void +help(void) +{ + printf( +"TRACE target v%s takes no options\n", +IPTABLES_VERSION); +} + +static struct option opts[] = { + { 0 } +}; + +/* Initialize the target. */ +static void +init(struct ipt_entry_target *t, unsigned int *nfcache) +{ +} + +/* Function which parses command options; returns true if it + ate an option */ +static int +parse(int c, char **argv, int invert, unsigned int *flags, + const struct ipt_entry *entry, + struct ipt_entry_target **target) +{ + return 0; +} + +static void +final_check(unsigned int flags) +{ +} + +static +struct iptables_target trace += { .next = NULL, + .name = "TRACE", + .version = IPTABLES_VERSION, + .size = IPT_ALIGN(0), + .userspacesize = IPT_ALIGN(0), + .help = &help, + .init = &init, + .parse = &parse, + .final_check = &final_check, + .print = NULL, /* print */ + .save = NULL, /* save */ + .extra_opts = opts +}; + +void _init(void) +{ + register_target(&trace); +} diff -urN --exclude=.svn iptables/extensions/libipt_TRACE.man iptables-trace/extensions/libipt_TRACE.man --- iptables/extensions/libipt_TRACE.man 1970-01-01 01:00:00.000000000 +0100 +++ iptables-trace/extensions/libipt_TRACE.man 2007-06-18 11:50:49.000000000 +0200 @@ -0,0 +1,10 @@ +This target marks packes so that the kernel will log every rule which match +the packets as those traverse the tables, chains, rules. (The ipt_LOG module +is required for the logging.) The packets are logged with the string prefix: +"TRACE: tablename:chainname:type:rulenum " where type can be "rule" for +plain rule, "return" for implicit rule at the end of a user defined chain +and "policy" for the policy of the built in chains. +.br +It can only be used in the +.BR raw +table. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Follow packets in rules 2007-06-18 10:16 ` Jozsef Kadlecsik @ 2007-06-18 12:49 ` Patrick McHardy 2007-06-18 13:05 ` Jozsef Kadlecsik 2007-06-22 14:20 ` Patrick McHardy 1 sibling, 1 reply; 28+ messages in thread From: Patrick McHardy @ 2007-06-18 12:49 UTC (permalink / raw) To: Jozsef Kadlecsik; +Cc: netfilter-devel Jozsef Kadlecsik wrote: > Attached you can find the reworked TRACE target, which does not suffer > from backward incompatibility. Unfortunately I had to steal one unused > bit from skbuff to be able to mark the packets so that it surely does > not clash with any rules using the standard "MARK" target. Logging > level, flags and type are hardcoded. What do you think? Looks pretty good. Maybe we can avoid using the skb bit though, what do you think about letting the user set a special "trace-mark" value through /proc and using that? Not sure if thats better or worse :) ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Follow packets in rules 2007-06-18 12:49 ` Patrick McHardy @ 2007-06-18 13:05 ` Jozsef Kadlecsik 2007-06-18 13:08 ` Patrick McHardy 0 siblings, 1 reply; 28+ messages in thread From: Jozsef Kadlecsik @ 2007-06-18 13:05 UTC (permalink / raw) To: Patrick McHardy; +Cc: netfilter-devel On Mon, 18 Jun 2007, Patrick McHardy wrote: > Jozsef Kadlecsik wrote: >> Attached you can find the reworked TRACE target, which does not suffer >> from backward incompatibility. Unfortunately I had to steal one unused >> bit from skbuff to be able to mark the packets so that it surely does >> not clash with any rules using the standard "MARK" target. Logging >> level, flags and type are hardcoded. What do you think? > > Looks pretty good. Maybe we can avoid using the skb bit though, what > do you think about letting the user set a special "trace-mark" value > through /proc and using that? Not sure if thats better or worse :) If one uses 'MARK --set-mark' and would want to trace a living ruleset, he'd be forced to change the ruleset in order to be able to use tracing. And that's a full can of worms... Hey, we returned the all 32 bit of nfcache! This is just one bit getting back ;-) Best regards, Jozsef - E-mail : kadlec@blackhole.kfki.hu, kadlec@sunserv.kfki.hu PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt Address : KFKI Research Institute for Particle and Nuclear Physics H-1525 Budapest 114, POB. 49, Hungary ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Follow packets in rules 2007-06-18 13:05 ` Jozsef Kadlecsik @ 2007-06-18 13:08 ` Patrick McHardy 0 siblings, 0 replies; 28+ messages in thread From: Patrick McHardy @ 2007-06-18 13:08 UTC (permalink / raw) To: Jozsef Kadlecsik; +Cc: netfilter-devel Jozsef Kadlecsik wrote: > On Mon, 18 Jun 2007, Patrick McHardy wrote: > >> Jozsef Kadlecsik wrote: >> >>> Attached you can find the reworked TRACE target, which does not suffer >>> from backward incompatibility. Unfortunately I had to steal one unused >>> bit from skbuff to be able to mark the packets so that it surely does >>> not clash with any rules using the standard "MARK" target. Logging >>> level, flags and type are hardcoded. What do you think? >> >> >> Looks pretty good. Maybe we can avoid using the skb bit though, what >> do you think about letting the user set a special "trace-mark" value >> through /proc and using that? Not sure if thats better or worse :) > > > If one uses 'MARK --set-mark' and would want to trace a living ruleset, > he'd be forced to change the ruleset in order to be able to use tracing. > And that's a full can of worms... Good point. > Hey, we returned the all 32 bit of nfcache! This is just one bit getting > back ;-) Fair enough I guess :) The bit is unused anyway, so at least for now it won't do any harm. I'll do some more thoroughly review in the next days and queue it for 2.6.23 if no other issues come up. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Follow packets in rules 2007-06-18 10:16 ` Jozsef Kadlecsik 2007-06-18 12:49 ` Patrick McHardy @ 2007-06-22 14:20 ` Patrick McHardy 2007-06-23 16:45 ` Jozsef Kadlecsik 1 sibling, 1 reply; 28+ messages in thread From: Patrick McHardy @ 2007-06-22 14:20 UTC (permalink / raw) To: Jozsef Kadlecsik; +Cc: netfilter-devel Jozsef Kadlecsik wrote: > Attached you can find the reworked TRACE target, which does not suffer > from backward incompatibility. Unfortunately I had to steal one unused > bit from skbuff to be able to mark the packets so that it surely does > not clash with any rules using the standard "MARK" target. Logging > level, flags and type are hardcoded. What do you think? Could you send me a Signed-off-by: line so I can queue this for 2.6.23? > +static inline void trace_packet(struct sk_buff *skb, > + unsigned int hook, > + const struct net_device *in, > + const struct net_device *out, > + char *tablename, > + struct xt_table_info *private, > + struct ipt_entry *e) I'm going to remove the inline here .. > /* Returns one of the generic firewall policies, like NF_ACCEPT. */ > unsigned int > ipt_do_table(struct sk_buff **pskb, > @@ -267,6 +371,12 @@ > > t = ipt_get_target(e); > IP_NF_ASSERT(t->u.kernel.target); > + > + /* The packet is traced: log it */ > + if ((*pskb)->nf_trace) > + trace_packet(*pskb, hook, in, out, > + table->name, private, e); > + and mark this unlikely so we don't bloat the main loop of ipt_do_table. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Follow packets in rules 2007-06-22 14:20 ` Patrick McHardy @ 2007-06-23 16:45 ` Jozsef Kadlecsik 2007-06-24 14:48 ` Patrick McHardy 0 siblings, 1 reply; 28+ messages in thread From: Jozsef Kadlecsik @ 2007-06-23 16:45 UTC (permalink / raw) To: Patrick McHardy; +Cc: netfilter-devel On Fri, 22 Jun 2007, Patrick McHardy wrote: > Jozsef Kadlecsik wrote: >> Attached you can find the reworked TRACE target, which does not suffer >> from backward incompatibility. Unfortunately I had to steal one unused >> bit from skbuff to be able to mark the packets so that it surely does >> not clash with any rules using the standard "MARK" target. Logging >> level, flags and type are hardcoded. What do you think? > > Could you send me a Signed-off-by: line so I can queue this for 2.6.23? Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> >> +static inline void trace_packet(struct sk_buff *skb, >> + unsigned int hook, >> + const struct net_device *in, >> + const struct net_device *out, >> + char *tablename, >> + struct xt_table_info *private, >> + struct ipt_entry *e) > > > I'm going to remove the inline here .. Yes, that's better. > >> /* Returns one of the generic firewall policies, like NF_ACCEPT. */ >> unsigned int >> ipt_do_table(struct sk_buff **pskb, >> @@ -267,6 +371,12 @@ >> >> t = ipt_get_target(e); >> IP_NF_ASSERT(t->u.kernel.target); >> + >> + /* The packet is traced: log it */ >> + if ((*pskb)->nf_trace) >> + trace_packet(*pskb, hook, in, out, >> + table->name, private, e); >> + > > and mark this unlikely so we don't bloat the main loop of ipt_do_table. OK, fine and thanks! Best regards, Jozsef - E-mail : kadlec@blackhole.kfki.hu, kadlec@sunserv.kfki.hu PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt Address : KFKI Research Institute for Particle and Nuclear Physics H-1525 Budapest 114, POB. 49, Hungary ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Follow packets in rules 2007-06-23 16:45 ` Jozsef Kadlecsik @ 2007-06-24 14:48 ` Patrick McHardy 2007-06-25 12:19 ` Patrick McHardy 0 siblings, 1 reply; 28+ messages in thread From: Patrick McHardy @ 2007-06-24 14:48 UTC (permalink / raw) To: Jozsef Kadlecsik; +Cc: netfilter-devel Jozsef Kadlecsik wrote: > On Fri, 22 Jun 2007, Patrick McHardy wrote: > >> Jozsef Kadlecsik wrote: >> >>> Attached you can find the reworked TRACE target, which does not suffer >>> from backward incompatibility. Unfortunately I had to steal one unused >>> bit from skbuff to be able to mark the packets so that it surely does >>> not clash with any rules using the standard "MARK" target. Logging >>> level, flags and type are hardcoded. What do you think? >> >> >> Could you send me a Signed-off-by: line so I can queue this for 2.6.23? > > > Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> Thanks Jozsef, applied. I've also added the missing ip6t_TRACE alias to xt_TRACE.c. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Follow packets in rules 2007-06-24 14:48 ` Patrick McHardy @ 2007-06-25 12:19 ` Patrick McHardy 2007-06-25 12:49 ` Jan Engelhardt 0 siblings, 1 reply; 28+ messages in thread From: Patrick McHardy @ 2007-06-25 12:19 UTC (permalink / raw) To: Jozsef Kadlecsik; +Cc: netfilter-devel [-- Attachment #1: Type: text/plain, Size: 1092 bytes --] Patrick McHardy wrote: > Thanks Jozsef, applied. I've also added the missing ip6t_TRACE alias > to xt_TRACE.c. > And missing copying of the nf_trace bit. This is really cool: RACE: raw:PREROUTING:policy:2 IN=eth0 OUT= MAC=00:15:f2:24:91:f8:00:0d:60:ca:60:12:08:00 SRC=192.168.0.102 DST=192.168.0.100 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=47932 DF PROTO=TCP SPT=58555 DPT=12345 SEQ=3478324482 ACK=0 WINDOW=5840 RES=0x00 SYN URGP=0 OPT (020405B40402080A0C78BE3E0000000001030305) TRACE: filter:INPUT:rule:1 IN=eth0 OUT= MAC=00:15:f2:24:91:f8:00:0d:60:ca:60:12:08:00 SRC=192.168.0.102 DST=192.168.0.100 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=47932 DF PROTO=TCP SPT=58555 DPT=12345 SEQ=3478324482 ACK=0 WINDOW=5840 RES=0x00 SYN URGP=0 OPT (020405B40402080A0C78BE3E0000000001030305) TRACE: filter:INPUT:rule:2 IN=eth0 OUT= MAC=00:15:f2:24:91:f8:00:0d:60:ca:60:12:08:00 SRC=192.168.0.102 DST=192.168.0.100 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=47932 DF PROTO=TCP SPT=58555 DPT=12345 SEQ=3478324482 ACK=0 WINDOW=5840 RES=0x00 SYN URGP=0 OPT (020405B40402080A0C78BE3E0000000001030305) :) [-- Attachment #2: x --] [-- Type: text/plain, Size: 15031 bytes --] [NETFILTER]: x_tables: add TRACE target The TRACE target can be used to follow IP and IPv6 packets through the ruleset. Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> Signed-off-by: Patrick NcHardy <kaber@trash.net> --- commit b8a85c673f041bd0acc1346150512eab5aa93b08 tree 62240ddb32f7a480a34b78b7e0deb09d84f88489 parent 69c897e7476fb6aa1adae6a57863e2c2eb278588 author Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> Mon, 25 Jun 2007 14:17:16 +0200 committer Patrick McHardy <kaber@trash.net> Mon, 25 Jun 2007 14:17:16 +0200 include/linux/skbuff.h | 4 + net/core/skbuff.c | 8 ++ net/ipv4/ip_output.c | 4 + net/ipv4/netfilter/ip_tables.c | 127 +++++++++++++++++++++++++++++++++++---- net/ipv6/ip6_output.c | 4 + net/ipv6/netfilter/ip6_tables.c | 128 +++++++++++++++++++++++++++++++++++---- net/netfilter/Kconfig | 12 ++++ net/netfilter/Makefile | 1 net/netfilter/xt_TRACE.c | 53 ++++++++++++++++ 9 files changed, 314 insertions(+), 27 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 6f0b2f7..52bba8c 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -227,6 +227,7 @@ typedef unsigned char *sk_buff_data_t; * @mark: Generic packet mark * @nfct: Associated connection, if any * @ipvs_property: skbuff is owned by ipvs + * @nf_trace: netfilter packet trace flag * @nfctinfo: Relationship of this skb to the connection * @nfct_reasm: netfilter conntrack re-assembly pointer * @nf_bridge: Saved data about a bridged frame - see br_netfilter.c @@ -277,7 +278,8 @@ struct sk_buff { nfctinfo:3; __u8 pkt_type:3, fclone:2, - ipvs_property:1; + ipvs_property:1, + nf_trace:1; __be16 protocol; void (*destructor)(struct sk_buff *skb); diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 27cfe5f..d2878a3 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -426,6 +426,10 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask) n->destructor = NULL; C(mark); __nf_copy(n, skb); +#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ + defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) + C(nf_trace); +#endif #ifdef CONFIG_NET_SCHED C(tc_index); #ifdef CONFIG_NET_CLS_ACT @@ -482,6 +486,10 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) new->destructor = NULL; new->mark = old->mark; __nf_copy(new, old); +#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ + defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) + new->nf_trace = old->nf_trace; +#endif #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) new->ipvs_property = old->ipvs_property; #endif diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 34ea454..7ea6144 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -399,6 +399,10 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from) to->tc_index = from->tc_index; #endif nf_copy(to, from); +#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ + defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) + to->nf_trace = from->nf_trace; +#endif #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) to->ipvs_property = from->ipvs_property; #endif diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 7962306..cdfdf88 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -204,6 +204,112 @@ get_entry(void *base, unsigned int offset) return (struct ipt_entry *)(base + offset); } +/* All zeroes == unconditional rule. */ +static inline int +unconditional(const struct ipt_ip *ip) +{ + unsigned int i; + + for (i = 0; i < sizeof(*ip)/sizeof(__u32); i++) + if (((__u32 *)ip)[i]) + return 0; + + return 1; +} + +#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ + defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) +static const char *hooknames[] = { + [NF_IP_PRE_ROUTING] = "PREROUTING", + [NF_IP_LOCAL_IN] = "INPUT", + [NF_IP_FORWARD] = "FORWARD", + [NF_IP_LOCAL_OUT] = "OUTPUT", + [NF_IP_POST_ROUTING] = "POSTROUTING", +}; + +enum nf_ip_trace_comments { + NF_IP_TRACE_COMMENT_RULE, + NF_IP_TRACE_COMMENT_RETURN, + NF_IP_TRACE_COMMENT_POLICY, +}; + +static const char *comments[] = { + [NF_IP_TRACE_COMMENT_RULE] = "rule", + [NF_IP_TRACE_COMMENT_RETURN] = "return", + [NF_IP_TRACE_COMMENT_POLICY] = "policy", +}; + +static struct nf_loginfo trace_loginfo = { + .type = NF_LOG_TYPE_LOG, + .u = { + .log = { + .level = 4, + .logflags = NF_LOG_MASK, + }, + }, +}; + +static inline int +get_chainname_rulenum(struct ipt_entry *s, struct ipt_entry *e, + char *hookname, char **chainname, + char **comment, unsigned int *rulenum) +{ + struct ipt_standard_target *t = (void *)ipt_get_target(s); + + if (strcmp(t->target.u.kernel.target->name, IPT_ERROR_TARGET) == 0) { + /* Head of user chain: ERROR target with chainname */ + *chainname = t->target.data; + (*rulenum) = 0; + } else if (s == e) { + (*rulenum)++; + + if (s->target_offset == sizeof(struct ipt_entry) + && strcmp(t->target.u.kernel.target->name, + IPT_STANDARD_TARGET) == 0 + && t->verdict < 0 + && unconditional(&s->ip)) { + /* Tail of chains: STANDARD target (return/policy) */ + *comment = *chainname == hookname + ? (char *)comments[NF_IP_TRACE_COMMENT_POLICY] + : (char *)comments[NF_IP_TRACE_COMMENT_RETURN]; + } + return 1; + } else + (*rulenum)++; + + return 0; +} + +static void trace_packet(struct sk_buff *skb, + unsigned int hook, + const struct net_device *in, + const struct net_device *out, + char *tablename, + struct xt_table_info *private, + struct ipt_entry *e) +{ + void *table_base; + struct ipt_entry *root; + char *hookname, *chainname, *comment; + unsigned int rulenum = 0; + + table_base = (void *)private->entries[smp_processor_id()]; + root = get_entry(table_base, private->hook_entry[hook]); + + hookname = chainname = (char *)hooknames[hook]; + comment = (char *)comments[NF_IP_TRACE_COMMENT_RULE]; + + IPT_ENTRY_ITERATE(root, + private->size - private->hook_entry[hook], + get_chainname_rulenum, + e, hookname, &chainname, &comment, &rulenum); + + nf_log_packet(AF_INET, hook, skb, in, out, &trace_loginfo, + "TRACE: %s:%s:%s:%u ", + tablename, chainname, comment, rulenum); +} +#endif + /* Returns one of the generic firewall policies, like NF_ACCEPT. */ unsigned int ipt_do_table(struct sk_buff **pskb, @@ -261,6 +367,14 @@ ipt_do_table(struct sk_buff **pskb, t = ipt_get_target(e); IP_NF_ASSERT(t->u.kernel.target); + +#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ + defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) + /* The packet is traced: log it */ + if (unlikely((*pskb)->nf_trace)) + trace_packet(*pskb, hook, in, out, + table->name, private, e); +#endif /* Standard target? */ if (!t->u.kernel.target->target) { int v; @@ -341,19 +455,6 @@ ipt_do_table(struct sk_buff **pskb, #endif } -/* All zeroes == unconditional rule. */ -static inline int -unconditional(const struct ipt_ip *ip) -{ - unsigned int i; - - for (i = 0; i < sizeof(*ip)/sizeof(__u32); i++) - if (((__u32 *)ip)[i]) - return 0; - - return 1; -} - /* Figures out from what hook each rule can be called: returns 0 if there are loops. Puts hook bitmask in comefrom. */ static int diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 4704b5f..db47321 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -521,6 +521,10 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from) to->tc_index = from->tc_index; #endif nf_copy(to, from); +#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ + defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) + to->nf_trace = from->nf_trace; +#endif skb_copy_secmark(to, from); } diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 7fe4d29..a67cec8 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -241,6 +241,113 @@ get_entry(void *base, unsigned int offset) return (struct ip6t_entry *)(base + offset); } +/* All zeroes == unconditional rule. */ +static inline int +unconditional(const struct ip6t_ip6 *ipv6) +{ + unsigned int i; + + for (i = 0; i < sizeof(*ipv6); i++) + if (((char *)ipv6)[i]) + break; + + return (i == sizeof(*ipv6)); +} + +#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ + defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) +/* This cries for unification! */ +static const char *hooknames[] = { + [NF_IP6_PRE_ROUTING] = "PREROUTING", + [NF_IP6_LOCAL_IN] = "INPUT", + [NF_IP6_FORWARD] = "FORWARD", + [NF_IP6_LOCAL_OUT] = "OUTPUT", + [NF_IP6_POST_ROUTING] = "POSTROUTING", +}; + +enum nf_ip_trace_comments { + NF_IP6_TRACE_COMMENT_RULE, + NF_IP6_TRACE_COMMENT_RETURN, + NF_IP6_TRACE_COMMENT_POLICY, +}; + +static const char *comments[] = { + [NF_IP6_TRACE_COMMENT_RULE] = "rule", + [NF_IP6_TRACE_COMMENT_RETURN] = "return", + [NF_IP6_TRACE_COMMENT_POLICY] = "policy", +}; + +static struct nf_loginfo trace_loginfo = { + .type = NF_LOG_TYPE_LOG, + .u = { + .log = { + .level = 4, + .logflags = NF_LOG_MASK, + }, + }, +}; + +static inline int +get_chainname_rulenum(struct ip6t_entry *s, struct ip6t_entry *e, + char *hookname, char **chainname, + char **comment, unsigned int *rulenum) +{ + struct ip6t_standard_target *t = (void *)ip6t_get_target(s); + + if (strcmp(t->target.u.kernel.target->name, IP6T_ERROR_TARGET) == 0) { + /* Head of user chain: ERROR target with chainname */ + *chainname = t->target.data; + (*rulenum) = 0; + } else if (s == e) { + (*rulenum)++; + + if (s->target_offset == sizeof(struct ip6t_entry) + && strcmp(t->target.u.kernel.target->name, + IP6T_STANDARD_TARGET) == 0 + && t->verdict < 0 + && unconditional(&s->ipv6)) { + /* Tail of chains: STANDARD target (return/policy) */ + *comment = *chainname == hookname + ? (char *)comments[NF_IP6_TRACE_COMMENT_POLICY] + : (char *)comments[NF_IP6_TRACE_COMMENT_RETURN]; + } + return 1; + } else + (*rulenum)++; + + return 0; +} + +static void trace_packet(struct sk_buff *skb, + unsigned int hook, + const struct net_device *in, + const struct net_device *out, + char *tablename, + struct xt_table_info *private, + struct ip6t_entry *e) +{ + void *table_base; + struct ip6t_entry *root; + char *hookname, *chainname, *comment; + unsigned int rulenum = 0; + + table_base = (void *)private->entries[smp_processor_id()]; + root = get_entry(table_base, private->hook_entry[hook]); + + hookname = chainname = (char *)hooknames[hook]; + comment = (char *)comments[NF_IP6_TRACE_COMMENT_RULE]; + + IP6T_ENTRY_ITERATE(root, + private->size - private->hook_entry[hook], + get_chainname_rulenum, + e, hookname, &chainname, &comment, &rulenum); + + nf_log_packet(AF_INET6, hook, skb, in, out, &trace_loginfo, + "TRACE: %s:%s:%s:%u ", + tablename, chainname, comment, rulenum); +} +#endif + /* Returns one of the generic firewall policies, like NF_ACCEPT. */ unsigned int ip6t_do_table(struct sk_buff **pskb, @@ -298,6 +405,14 @@ ip6t_do_table(struct sk_buff **pskb, t = ip6t_get_target(e); IP_NF_ASSERT(t->u.kernel.target); + +#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ + defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) + /* The packet is traced: log it */ + if (unlikely((*pskb)->nf_trace)) + trace_packet(*pskb, hook, in, out, + table->name, private, e); +#endif /* Standard target? */ if (!t->u.kernel.target->target) { int v; @@ -377,19 +492,6 @@ ip6t_do_table(struct sk_buff **pskb, #endif } -/* All zeroes == unconditional rule. */ -static inline int -unconditional(const struct ip6t_ip6 *ipv6) -{ - unsigned int i; - - for (i = 0; i < sizeof(*ipv6); i++) - if (((char *)ipv6)[i]) - break; - - return (i == sizeof(*ipv6)); -} - /* Figures out from what hook each rule can be called: returns 0 if there are loops. Puts hook bitmask in comefrom. */ static int diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index aa567fa..df5e8da 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -343,6 +343,18 @@ config NETFILTER_XT_TARGET_NOTRACK If you want to compile it as a module, say M here and read <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. +config NETFILTER_XT_TARGET_TRACE + tristate '"TRACE" target support' + depends on NETFILTER_XTABLES + depends on IP_NF_RAW || IP6_NF_RAW + help + The TRACE target allows you to mark packets so that the kernel + will log every rule which match the packets as those traverse + the tables, chains, rules. + + If you want to compile it as a module, say M here and read + <file:Documentation/modules.txt>. If unsure, say `N'. + config NETFILTER_XT_TARGET_SECMARK tristate '"SECMARK" target support' depends on NETFILTER_XTABLES && NETWORK_SECMARK diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index 3cf5b9c..3b79268 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile @@ -44,6 +44,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o +obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o diff --git a/net/netfilter/xt_TRACE.c b/net/netfilter/xt_TRACE.c new file mode 100644 index 0000000..b82fc46 --- /dev/null +++ b/net/netfilter/xt_TRACE.c @@ -0,0 +1,53 @@ +/* This is a module which is used to mark packets for tracing. + */ +#include <linux/module.h> +#include <linux/skbuff.h> + +#include <linux/netfilter/x_tables.h> + +MODULE_LICENSE("GPL"); +MODULE_ALIAS("ipt_TRACE"); +MODULE_ALIAS("ip6t_TRACE"); + +static unsigned int +target(struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + unsigned int hooknum, + const struct xt_target *target, + const void *targinfo) +{ + (*pskb)->nf_trace = 1; + return XT_CONTINUE; +} + +static struct xt_target xt_trace_target[] = { + { + .name = "TRACE", + .family = AF_INET, + .target = target, + .table = "raw", + .me = THIS_MODULE, + }, + { + .name = "TRACE", + .family = AF_INET6, + .target = target, + .table = "raw", + .me = THIS_MODULE, + }, +}; + +static int __init xt_trace_init(void) +{ + return xt_register_targets(xt_trace_target, + ARRAY_SIZE(xt_trace_target)); +} + +static void __exit xt_trace_fini(void) +{ + xt_unregister_targets(xt_trace_target, ARRAY_SIZE(xt_trace_target)); +} + +module_init(xt_trace_init); +module_exit(xt_trace_fini); ^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: Follow packets in rules 2007-06-25 12:19 ` Patrick McHardy @ 2007-06-25 12:49 ` Jan Engelhardt 2007-06-25 12:52 ` Patrick McHardy 2007-06-25 13:00 ` Patrick McHardy 0 siblings, 2 replies; 28+ messages in thread From: Jan Engelhardt @ 2007-06-25 12:49 UTC (permalink / raw) To: Patrick McHardy; +Cc: netfilter-devel, Jozsef Kadlecsik Hi, On Jun 25 2007 14:19, Patrick McHardy wrote: > > What was that about inline patches ... take the following with a bit of ":)" +static const char *hooknames[] = { + [NF_IP_PRE_ROUTING] = "PREROUTING", + [NF_IP_LOCAL_IN] = "INPUT", + [NF_IP_FORWARD] = "FORWARD", + [NF_IP_LOCAL_OUT] = "OUTPUT", + [NF_IP_POST_ROUTING] = "POSTROUTING", +}; Align it up. >--- a/net/netfilter/Kconfig >@@ -343,6 +343,18 @@ config NETFILTER_XT_TARGET_NOTRACK > >[...] > >--- a/net/netfilter/Makefile >+++ b/net/netfilter/Makefile >@@ -44,6 +44,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o > obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o > obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o > obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o >+obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o > obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o > obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o > obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o I don't know about your locale, but in mine, SECMARK < TCPMSS < TRACE holds. (Including CONNSECMARK < SECMARK, but that seems to be another thing.) >+MODULE_LICENSE("GPL"); >+MODULE_ALIAS("ipt_TRACE"); >+MODULE_ALIAS("ip6t_TRACE"); No MODULE_AUTHOR/MODULE_DESCRIPTION? >+static struct xt_target xt_trace_target[] = { >+ { >+ .name = "TRACE", ^ spaces? ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Follow packets in rules 2007-06-25 12:49 ` Jan Engelhardt @ 2007-06-25 12:52 ` Patrick McHardy 2007-06-25 13:00 ` Patrick McHardy 1 sibling, 0 replies; 28+ messages in thread From: Patrick McHardy @ 2007-06-25 12:52 UTC (permalink / raw) To: Jan Engelhardt; +Cc: netfilter-devel, Jozsef Kadlecsik Jan Engelhardt wrote: > > +static const char *hooknames[] = { > + [NF_IP_PRE_ROUTING] = "PREROUTING", > + [NF_IP_LOCAL_IN] = "INPUT", > + [NF_IP_FORWARD] = "FORWARD", > + [NF_IP_LOCAL_OUT] = "OUTPUT", > + [NF_IP_POST_ROUTING] = "POSTROUTING", > +}; > > Align it up. > Yeah, I like that better as well. > > >> --- a/net/netfilter/Kconfig >> @@ -343,6 +343,18 @@ config NETFILTER_XT_TARGET_NOTRACK >> >> [...] >> >> --- a/net/netfilter/Makefile >> +++ b/net/netfilter/Makefile >> @@ -44,6 +44,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o >> obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o >> obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o >> obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o >> +obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o >> obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o >> obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o >> obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o >> > > I don't know about your locale, but in mine, > SECMARK < TCPMSS < TRACE holds. > (Including CONNSECMARK < SECMARK, but that seems to be another thing.) > They're not strictly alphabetically ordered. TRACE is next to NOTRACK because they're both raw table targets. In the TRACE case I think it would make sense to lift that restriction though. > >> +MODULE_LICENSE("GPL"); >> +MODULE_ALIAS("ipt_TRACE"); >> +MODULE_ALIAS("ip6t_TRACE"); >> > > No MODULE_AUTHOR/MODULE_DESCRIPTION? > Not required. How really reads those anyway? > >> +static struct xt_target xt_trace_target[] = { >> + { >> + .name = "TRACE", >> > ^ spaces? > Thanks, will fix. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Follow packets in rules 2007-06-25 12:49 ` Jan Engelhardt 2007-06-25 12:52 ` Patrick McHardy @ 2007-06-25 13:00 ` Patrick McHardy 2007-06-25 13:52 ` Jan Engelhardt 1 sibling, 1 reply; 28+ messages in thread From: Patrick McHardy @ 2007-06-25 13:00 UTC (permalink / raw) To: Jan Engelhardt; +Cc: netfilter-devel, Jozsef Kadlecsik [-- Attachment #1: Type: text/plain, Size: 71 bytes --] Jan Engelhardt wrote: > ... Whitespace issues fixed, texts aligned. [-- Attachment #2: x --] [-- Type: text/plain, Size: 14940 bytes --] [NETFILTER]: x_tables: add TRACE target The TRACE target can be used to follow IP and IPv6 packets through the ruleset. Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> Signed-off-by: Patrick NcHardy <kaber@trash.net> --- commit cd9e0f04391e5fa3e0a289fcb646e2770013e3c7 tree 3628c2e1254ba709e685a71f6f81ea493a9256b5 parent 69c897e7476fb6aa1adae6a57863e2c2eb278588 author Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> Mon, 25 Jun 2007 14:59:24 +0200 committer Patrick McHardy <kaber@trash.net> Mon, 25 Jun 2007 14:59:24 +0200 include/linux/skbuff.h | 4 + net/core/skbuff.c | 8 ++ net/ipv4/ip_output.c | 4 + net/ipv4/netfilter/ip_tables.c | 127 +++++++++++++++++++++++++++++++++++---- net/ipv6/ip6_output.c | 4 + net/ipv6/netfilter/ip6_tables.c | 128 +++++++++++++++++++++++++++++++++++---- net/netfilter/Kconfig | 12 ++++ net/netfilter/Makefile | 1 net/netfilter/xt_TRACE.c | 53 ++++++++++++++++ 9 files changed, 314 insertions(+), 27 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 6f0b2f7..52bba8c 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -227,6 +227,7 @@ typedef unsigned char *sk_buff_data_t; * @mark: Generic packet mark * @nfct: Associated connection, if any * @ipvs_property: skbuff is owned by ipvs + * @nf_trace: netfilter packet trace flag * @nfctinfo: Relationship of this skb to the connection * @nfct_reasm: netfilter conntrack re-assembly pointer * @nf_bridge: Saved data about a bridged frame - see br_netfilter.c @@ -277,7 +278,8 @@ struct sk_buff { nfctinfo:3; __u8 pkt_type:3, fclone:2, - ipvs_property:1; + ipvs_property:1, + nf_trace:1; __be16 protocol; void (*destructor)(struct sk_buff *skb); diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 27cfe5f..d2878a3 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -426,6 +426,10 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask) n->destructor = NULL; C(mark); __nf_copy(n, skb); +#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ + defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) + C(nf_trace); +#endif #ifdef CONFIG_NET_SCHED C(tc_index); #ifdef CONFIG_NET_CLS_ACT @@ -482,6 +486,10 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) new->destructor = NULL; new->mark = old->mark; __nf_copy(new, old); +#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ + defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) + new->nf_trace = old->nf_trace; +#endif #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) new->ipvs_property = old->ipvs_property; #endif diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 34ea454..7ea6144 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -399,6 +399,10 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from) to->tc_index = from->tc_index; #endif nf_copy(to, from); +#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ + defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) + to->nf_trace = from->nf_trace; +#endif #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) to->ipvs_property = from->ipvs_property; #endif diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 7962306..650ab52 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -204,6 +204,112 @@ get_entry(void *base, unsigned int offset) return (struct ipt_entry *)(base + offset); } +/* All zeroes == unconditional rule. */ +static inline int +unconditional(const struct ipt_ip *ip) +{ + unsigned int i; + + for (i = 0; i < sizeof(*ip)/sizeof(__u32); i++) + if (((__u32 *)ip)[i]) + return 0; + + return 1; +} + +#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ + defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) +static const char *hooknames[] = { + [NF_IP_PRE_ROUTING] = "PREROUTING", + [NF_IP_LOCAL_IN] = "INPUT", + [NF_IP_FORWARD] = "FORWARD", + [NF_IP_LOCAL_OUT] = "OUTPUT", + [NF_IP_POST_ROUTING] = "POSTROUTING", +}; + +enum nf_ip_trace_comments { + NF_IP_TRACE_COMMENT_RULE, + NF_IP_TRACE_COMMENT_RETURN, + NF_IP_TRACE_COMMENT_POLICY, +}; + +static const char *comments[] = { + [NF_IP_TRACE_COMMENT_RULE] = "rule", + [NF_IP_TRACE_COMMENT_RETURN] = "return", + [NF_IP_TRACE_COMMENT_POLICY] = "policy", +}; + +static struct nf_loginfo trace_loginfo = { + .type = NF_LOG_TYPE_LOG, + .u = { + .log = { + .level = 4, + .logflags = NF_LOG_MASK, + }, + }, +}; + +static inline int +get_chainname_rulenum(struct ipt_entry *s, struct ipt_entry *e, + char *hookname, char **chainname, + char **comment, unsigned int *rulenum) +{ + struct ipt_standard_target *t = (void *)ipt_get_target(s); + + if (strcmp(t->target.u.kernel.target->name, IPT_ERROR_TARGET) == 0) { + /* Head of user chain: ERROR target with chainname */ + *chainname = t->target.data; + (*rulenum) = 0; + } else if (s == e) { + (*rulenum)++; + + if (s->target_offset == sizeof(struct ipt_entry) + && strcmp(t->target.u.kernel.target->name, + IPT_STANDARD_TARGET) == 0 + && t->verdict < 0 + && unconditional(&s->ip)) { + /* Tail of chains: STANDARD target (return/policy) */ + *comment = *chainname == hookname + ? (char *)comments[NF_IP_TRACE_COMMENT_POLICY] + : (char *)comments[NF_IP_TRACE_COMMENT_RETURN]; + } + return 1; + } else + (*rulenum)++; + + return 0; +} + +static void trace_packet(struct sk_buff *skb, + unsigned int hook, + const struct net_device *in, + const struct net_device *out, + char *tablename, + struct xt_table_info *private, + struct ipt_entry *e) +{ + void *table_base; + struct ipt_entry *root; + char *hookname, *chainname, *comment; + unsigned int rulenum = 0; + + table_base = (void *)private->entries[smp_processor_id()]; + root = get_entry(table_base, private->hook_entry[hook]); + + hookname = chainname = (char *)hooknames[hook]; + comment = (char *)comments[NF_IP_TRACE_COMMENT_RULE]; + + IPT_ENTRY_ITERATE(root, + private->size - private->hook_entry[hook], + get_chainname_rulenum, + e, hookname, &chainname, &comment, &rulenum); + + nf_log_packet(AF_INET, hook, skb, in, out, &trace_loginfo, + "TRACE: %s:%s:%s:%u ", + tablename, chainname, comment, rulenum); +} +#endif + /* Returns one of the generic firewall policies, like NF_ACCEPT. */ unsigned int ipt_do_table(struct sk_buff **pskb, @@ -261,6 +367,14 @@ ipt_do_table(struct sk_buff **pskb, t = ipt_get_target(e); IP_NF_ASSERT(t->u.kernel.target); + +#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ + defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) + /* The packet is traced: log it */ + if (unlikely((*pskb)->nf_trace)) + trace_packet(*pskb, hook, in, out, + table->name, private, e); +#endif /* Standard target? */ if (!t->u.kernel.target->target) { int v; @@ -341,19 +455,6 @@ ipt_do_table(struct sk_buff **pskb, #endif } -/* All zeroes == unconditional rule. */ -static inline int -unconditional(const struct ipt_ip *ip) -{ - unsigned int i; - - for (i = 0; i < sizeof(*ip)/sizeof(__u32); i++) - if (((__u32 *)ip)[i]) - return 0; - - return 1; -} - /* Figures out from what hook each rule can be called: returns 0 if there are loops. Puts hook bitmask in comefrom. */ static int diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 4704b5f..db47321 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -521,6 +521,10 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from) to->tc_index = from->tc_index; #endif nf_copy(to, from); +#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ + defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) + to->nf_trace = from->nf_trace; +#endif skb_copy_secmark(to, from); } diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 7fe4d29..4f93b79 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -241,6 +241,113 @@ get_entry(void *base, unsigned int offset) return (struct ip6t_entry *)(base + offset); } +/* All zeroes == unconditional rule. */ +static inline int +unconditional(const struct ip6t_ip6 *ipv6) +{ + unsigned int i; + + for (i = 0; i < sizeof(*ipv6); i++) + if (((char *)ipv6)[i]) + break; + + return (i == sizeof(*ipv6)); +} + +#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ + defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) +/* This cries for unification! */ +static const char *hooknames[] = { + [NF_IP6_PRE_ROUTING] = "PREROUTING", + [NF_IP6_LOCAL_IN] = "INPUT", + [NF_IP6_FORWARD] = "FORWARD", + [NF_IP6_LOCAL_OUT] = "OUTPUT", + [NF_IP6_POST_ROUTING] = "POSTROUTING", +}; + +enum nf_ip_trace_comments { + NF_IP6_TRACE_COMMENT_RULE, + NF_IP6_TRACE_COMMENT_RETURN, + NF_IP6_TRACE_COMMENT_POLICY, +}; + +static const char *comments[] = { + [NF_IP6_TRACE_COMMENT_RULE] = "rule", + [NF_IP6_TRACE_COMMENT_RETURN] = "return", + [NF_IP6_TRACE_COMMENT_POLICY] = "policy", +}; + +static struct nf_loginfo trace_loginfo = { + .type = NF_LOG_TYPE_LOG, + .u = { + .log = { + .level = 4, + .logflags = NF_LOG_MASK, + }, + }, +}; + +static inline int +get_chainname_rulenum(struct ip6t_entry *s, struct ip6t_entry *e, + char *hookname, char **chainname, + char **comment, unsigned int *rulenum) +{ + struct ip6t_standard_target *t = (void *)ip6t_get_target(s); + + if (strcmp(t->target.u.kernel.target->name, IP6T_ERROR_TARGET) == 0) { + /* Head of user chain: ERROR target with chainname */ + *chainname = t->target.data; + (*rulenum) = 0; + } else if (s == e) { + (*rulenum)++; + + if (s->target_offset == sizeof(struct ip6t_entry) + && strcmp(t->target.u.kernel.target->name, + IP6T_STANDARD_TARGET) == 0 + && t->verdict < 0 + && unconditional(&s->ipv6)) { + /* Tail of chains: STANDARD target (return/policy) */ + *comment = *chainname == hookname + ? (char *)comments[NF_IP6_TRACE_COMMENT_POLICY] + : (char *)comments[NF_IP6_TRACE_COMMENT_RETURN]; + } + return 1; + } else + (*rulenum)++; + + return 0; +} + +static void trace_packet(struct sk_buff *skb, + unsigned int hook, + const struct net_device *in, + const struct net_device *out, + char *tablename, + struct xt_table_info *private, + struct ip6t_entry *e) +{ + void *table_base; + struct ip6t_entry *root; + char *hookname, *chainname, *comment; + unsigned int rulenum = 0; + + table_base = (void *)private->entries[smp_processor_id()]; + root = get_entry(table_base, private->hook_entry[hook]); + + hookname = chainname = (char *)hooknames[hook]; + comment = (char *)comments[NF_IP6_TRACE_COMMENT_RULE]; + + IP6T_ENTRY_ITERATE(root, + private->size - private->hook_entry[hook], + get_chainname_rulenum, + e, hookname, &chainname, &comment, &rulenum); + + nf_log_packet(AF_INET6, hook, skb, in, out, &trace_loginfo, + "TRACE: %s:%s:%s:%u ", + tablename, chainname, comment, rulenum); +} +#endif + /* Returns one of the generic firewall policies, like NF_ACCEPT. */ unsigned int ip6t_do_table(struct sk_buff **pskb, @@ -298,6 +405,14 @@ ip6t_do_table(struct sk_buff **pskb, t = ip6t_get_target(e); IP_NF_ASSERT(t->u.kernel.target); + +#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ + defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) + /* The packet is traced: log it */ + if (unlikely((*pskb)->nf_trace)) + trace_packet(*pskb, hook, in, out, + table->name, private, e); +#endif /* Standard target? */ if (!t->u.kernel.target->target) { int v; @@ -377,19 +492,6 @@ ip6t_do_table(struct sk_buff **pskb, #endif } -/* All zeroes == unconditional rule. */ -static inline int -unconditional(const struct ip6t_ip6 *ipv6) -{ - unsigned int i; - - for (i = 0; i < sizeof(*ipv6); i++) - if (((char *)ipv6)[i]) - break; - - return (i == sizeof(*ipv6)); -} - /* Figures out from what hook each rule can be called: returns 0 if there are loops. Puts hook bitmask in comefrom. */ static int diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index aa567fa..df5e8da 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -343,6 +343,18 @@ config NETFILTER_XT_TARGET_NOTRACK If you want to compile it as a module, say M here and read <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. +config NETFILTER_XT_TARGET_TRACE + tristate '"TRACE" target support' + depends on NETFILTER_XTABLES + depends on IP_NF_RAW || IP6_NF_RAW + help + The TRACE target allows you to mark packets so that the kernel + will log every rule which match the packets as those traverse + the tables, chains, rules. + + If you want to compile it as a module, say M here and read + <file:Documentation/modules.txt>. If unsure, say `N'. + config NETFILTER_XT_TARGET_SECMARK tristate '"SECMARK" target support' depends on NETFILTER_XTABLES && NETWORK_SECMARK diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index 3cf5b9c..3b79268 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile @@ -44,6 +44,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o +obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o diff --git a/net/netfilter/xt_TRACE.c b/net/netfilter/xt_TRACE.c new file mode 100644 index 0000000..b82fc46 --- /dev/null +++ b/net/netfilter/xt_TRACE.c @@ -0,0 +1,53 @@ +/* This is a module which is used to mark packets for tracing. + */ +#include <linux/module.h> +#include <linux/skbuff.h> + +#include <linux/netfilter/x_tables.h> + +MODULE_LICENSE("GPL"); +MODULE_ALIAS("ipt_TRACE"); +MODULE_ALIAS("ip6t_TRACE"); + +static unsigned int +target(struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + unsigned int hooknum, + const struct xt_target *target, + const void *targinfo) +{ + (*pskb)->nf_trace = 1; + return XT_CONTINUE; +} + +static struct xt_target xt_trace_target[] = { + { + .name = "TRACE", + .family = AF_INET, + .target = target, + .table = "raw", + .me = THIS_MODULE, + }, + { + .name = "TRACE", + .family = AF_INET6, + .target = target, + .table = "raw", + .me = THIS_MODULE, + }, +}; + +static int __init xt_trace_init(void) +{ + return xt_register_targets(xt_trace_target, + ARRAY_SIZE(xt_trace_target)); +} + +static void __exit xt_trace_fini(void) +{ + xt_unregister_targets(xt_trace_target, ARRAY_SIZE(xt_trace_target)); +} + +module_init(xt_trace_init); +module_exit(xt_trace_fini); ^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: Follow packets in rules 2007-06-25 13:00 ` Patrick McHardy @ 2007-06-25 13:52 ` Jan Engelhardt 2007-06-25 13:55 ` Patrick McHardy 0 siblings, 1 reply; 28+ messages in thread From: Jan Engelhardt @ 2007-06-25 13:52 UTC (permalink / raw) To: Patrick McHardy; +Cc: netfilter-devel, Jozsef Kadlecsik On Jun 25 2007 15:00, Patrick McHardy wrote: +static const char *hooknames[] = { + [NF_IP_PRE_ROUTING] = "PREROUTING", ^ Well I meant: Where are the spaces? Try looking at it with tab width 4 and you'll see the alignment breaks :) Jan -- ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Follow packets in rules 2007-06-25 13:52 ` Jan Engelhardt @ 2007-06-25 13:55 ` Patrick McHardy 0 siblings, 0 replies; 28+ messages in thread From: Patrick McHardy @ 2007-06-25 13:55 UTC (permalink / raw) To: Jan Engelhardt; +Cc: netfilter-devel, Jozsef Kadlecsik Jan Engelhardt wrote: > On Jun 25 2007 15:00, Patrick McHardy wrote: > +static const char *hooknames[] = { > + [NF_IP_PRE_ROUTING] = "PREROUTING", > ^ > Well I meant: Where are the spaces? Try looking at it with tab width 4 > and you'll see the alignment breaks :) I don't really care how it looks with tab width 4. ^ permalink raw reply [flat|nested] 28+ messages in thread
* RE: Follow packets in rules 2007-06-12 18:08 Follow packets in rules Fabrice Rafart 2007-06-12 21:41 ` Simon 2007-06-13 8:57 ` Pablo Neira Ayuso @ 2007-07-03 15:07 ` Fabrice Rafart 2 siblings, 0 replies; 28+ messages in thread From: Fabrice Rafart @ 2007-07-03 15:07 UTC (permalink / raw) To: netfilter-devel Hi to all ! I see that my post is not useless ! :) Finally, it doesn't exist a user friendly solution to my problem ... Maybe later. Regards to all. Ps : I'll not keep my subscription to this list. Cordialement, -- Fabrice Rafart Administrateur systèmes et réseaux Etablissement français du sang, Ile de France. ^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2007-07-03 15:07 UTC | newest] Thread overview: 28+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2007-06-12 18:08 Follow packets in rules Fabrice Rafart 2007-06-12 21:41 ` Simon 2007-06-13 7:31 ` Fabrice Rafart 2007-06-18 16:12 ` Simon 2007-06-18 16:14 ` Patrick McHardy 2007-06-13 8:57 ` Pablo Neira Ayuso 2007-06-13 15:43 ` Juan León 2007-06-13 16:28 ` Samuel Jean 2007-06-13 16:53 ` Patrick McHardy 2007-06-13 19:43 ` Jozsef Kadlecsik 2007-06-14 7:55 ` Fabrice Rafart 2007-06-14 13:13 ` Patrick McHardy 2007-06-14 14:18 ` Jozsef Kadlecsik 2007-06-14 14:23 ` Patrick McHardy 2007-06-18 10:16 ` Jozsef Kadlecsik 2007-06-18 12:49 ` Patrick McHardy 2007-06-18 13:05 ` Jozsef Kadlecsik 2007-06-18 13:08 ` Patrick McHardy 2007-06-22 14:20 ` Patrick McHardy 2007-06-23 16:45 ` Jozsef Kadlecsik 2007-06-24 14:48 ` Patrick McHardy 2007-06-25 12:19 ` Patrick McHardy 2007-06-25 12:49 ` Jan Engelhardt 2007-06-25 12:52 ` Patrick McHardy 2007-06-25 13:00 ` Patrick McHardy 2007-06-25 13:52 ` Jan Engelhardt 2007-06-25 13:55 ` Patrick McHardy 2007-07-03 15:07 ` Fabrice Rafart
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.