All of lore.kernel.org
 help / color / mirror / Atom feed
* Corruption on mangle/INPUT when MARKing packets
@ 2003-01-04  1:47 Costa Tsaousis
  2003-01-06 12:52 ` Harald Welte
  0 siblings, 1 reply; 6+ messages in thread
From: Costa Tsaousis @ 2003-01-04  1:47 UTC (permalink / raw)
  To: netfilter-devel

Hi all, and happy new year...

I am the author of FireHOL (http://firehol.sf.net) an iptables firewall
generator. During a few experiments I made I believe I have found a bug in
iptables. I am very sorry if it has already been fixed, but I searched
last year's list archives and I didn't find it.

To reproduce the bug, type:

# /etc/init.d/iptables stop
# iptables -t mangle -A INPUT -p icmp -j MARK --set-mark 1

Now, this host will be unpingable.
If INPUT is changed to PREROUTING, pings work.

kernel: 2.4.18-19.8.0smp
iptables: 1.2.6a
Distro: RedHat 8.0

I experimented a bit more and found the following:

[root@194.30.193.23]# ping -c 1 195.97.5.206

Entries bellow belong to the log of 195.97.5.206
------------------------------------------------
[request] everything ok here
Jan  4 02:34:57 gateway kernel: PREROUTING/mangle [1]: IN=ppp0 OUT= MAC=
SRC=194.30.193.23 DST=195.97.5.206 LEN=84 TOS=0x00 PREC=0x00 TTL=61 ID=0
DF PROTO=ICMP TYPE=8 CODE=0 ID=34827 SEQ=0
Jan  4 02:34:57 gateway kernel: PREROUTING/nat    [1]: IN=ppp0 OUT= MAC=
SRC=194.30.193.23 DST=195.97.5.206 LEN=84 TOS=0x00 PREC=0x00 TTL=61 ID=0
DF PROTO=ICMP TYPE=8 CODE=0 ID=34827 SEQ=0
Jan  4 02:34:57 gateway kernel: INPUT/mangle [2]: IN=ppp0 OUT= MAC=
SRC=194.30.193.23 DST=195.97.5.206 LEN=84 TOS=0x00 PREC=0x00 TTL=61 ID=0
DF PROTO=ICMP TYPE=8 CODE=0 ID=34827 SEQ=0
Jan  4 02:34:57 gateway kernel: INPUT/filter [2]: IN=ppp0 OUT= MAC=
SRC=194.30.193.23 DST=195.97.5.206 LEN=84 TOS=0x00 PREC=0x00 TTL=61 ID=0
DF PROTO=ICMP TYPE=8 CODE=0 ID=34827 SEQ=0

[reply] !!! here is the error: source and destination are the same, TYPE
is 0, output device is lo.
Jan  4 02:34:57 gateway kernel: OUTPUT/mangle [4]: IN= OUT=lo
SRC=195.97.5.206 DST=195.97.5.206 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=9466
PROTO=ICMP TYPE=0 CODE=0 ID=34827 SEQ=0
Jan  4 02:34:57 gateway kernel: OUTPUT/filter [4]: IN= OUT=lo
SRC=195.97.5.206 DST=195.97.5.206 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=9466
PROTO=ICMP TYPE=0 CODE=0 ID=34827 SEQ=0
Jan  4 02:34:57 gateway kernel: POSTROUTING/mangle [5]: IN= OUT=lo
SRC=195.97.5.206 DST=195.97.5.206 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=9466
PROTO=ICMP TYPE=0 CODE=0 ID=34827 SEQ=0
Jan  4 02:34:57 gateway kernel: PREROUTING/mangle [1]: IN=lo OUT=
MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=195.97.5.206
DST=195.97.5.206 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=9466 PROTO=ICMP
TYPE=0 CODE=0 ID=34827 SEQ=0
Jan  4 02:34:57 gateway kernel: INPUT/mangle [2]: IN=lo OUT=
MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=195.97.5.206
DST=195.97.5.206 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=9466 PROTO=ICMP
TYPE=0 CODE=0 ID=34827 SEQ=0
Jan  4 02:34:57 gateway kernel: INPUT/filter [2]: IN=lo OUT=
MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=195.97.5.206
DST=195.97.5.206 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=9466 PROTO=ICMP
TYPE=0 CODE=0 ID=34827 SEQ=0

Keep up the good work...

Kind Regards
Costa Tsaousis

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Corruption on mangle/INPUT when MARKing packets
  2003-01-04  1:47 Corruption on mangle/INPUT when MARKing packets Costa Tsaousis
@ 2003-01-06 12:52 ` Harald Welte
  2003-01-06 13:13   ` Costa Tsaousis
  2003-01-06 16:26   ` Patrick McHardy
  0 siblings, 2 replies; 6+ messages in thread
From: Harald Welte @ 2003-01-06 12:52 UTC (permalink / raw)
  To: Costa Tsaousis; +Cc: netfilter-devel

[-- Attachment #1: Type: text/plain, Size: 935 bytes --]

On Sat, Jan 04, 2003 at 03:47:21AM +0200, Costa Tsaousis wrote:

> During a few experiments I made I believe I have found a bug in
> iptables. 
> 
> To reproduce the bug, type:
> 
> # /etc/init.d/iptables stop
> # iptables -t mangle -A INPUT -p icmp -j MARK --set-mark 1
> 
> Now, this host will be unpingable.


This is really strange.  I can perfectly reproduce the bug, but I cannot
see how this happens.  the whole net/ipv4/icmp.c code doesn't do
anything with the nfmark of the original skb.

I'll have to investigate this further. Stay tuned.
 
Thanks for reporting the bug...

> Kind Regards
> Costa Tsaousis

-- 
- Harald Welte / laforge@gnumonks.org               http://www.gnumonks.org/
============================================================================
"If this were a dictatorship, it'd be a heck of a lot easier, just so long
 as I'm the dictator."  --  George W. Bush Dec 18, 2000

[-- Attachment #2: Type: application/pgp-signature, Size: 232 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Corruption on mangle/INPUT when MARKing packets
  2003-01-06 12:52 ` Harald Welte
@ 2003-01-06 13:13   ` Costa Tsaousis
  2003-01-06 16:26   ` Patrick McHardy
  1 sibling, 0 replies; 6+ messages in thread
From: Costa Tsaousis @ 2003-01-06 13:13 UTC (permalink / raw)
  To: netfilter-devel; +Cc: laforge


Harald Welte said:
> This is really strange.  I can perfectly reproduce the bug, but I cannot
> see how this happens.  the whole net/ipv4/icmp.c code doesn't do
> anything with the nfmark of the original skb.
>
> I'll have to investigate this further. Stay tuned.

Well, I don't think this is a problem in net/ipv4/icmp.c
If it was, setting the mark in PREROUTING should have the same effect, but
it does not.

So, my guess is that something is happenning in mangle/INPUT handling, or
due to the fact that the packet has changed after the routing decision, or
... (keep in mind that I have never seen the iptables code, so this is
really a guess out of nowhere...).

Kind regards

-- 
Costa Tsaousis

Author of
FireHOL (http://firehol.sf.net)
-------------------------------
An iptables stateful firewall generator,
that allows you to configure your firewall...
...the way you think of it!

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Corruption on mangle/INPUT when MARKing packets
  2003-01-06 12:52 ` Harald Welte
  2003-01-06 13:13   ` Costa Tsaousis
@ 2003-01-06 16:26   ` Patrick McHardy
  2003-01-08 17:07     ` Harald Welte
  1 sibling, 1 reply; 6+ messages in thread
From: Patrick McHardy @ 2003-01-06 16:26 UTC (permalink / raw)
  To: Harald Welte; +Cc: Costa Tsaousis, netfilter-devel

Harald Welte wrote:

>On Sat, Jan 04, 2003 at 03:47:21AM +0200, Costa Tsaousis wrote:
>
>  
>
>>During a few experiments I made I believe I have found a bug in
>>iptables. 
>>
>>To reproduce the bug, type:
>>
>># /etc/init.d/iptables stop
>># iptables -t mangle -A INPUT -p icmp -j MARK --set-mark 1
>>
>>Now, this host will be unpingable.
>>    
>>
>
>
>This is really strange.  I can perfectly reproduce the bug, but I cannot
>see how this happens.  the whole net/ipv4/icmp.c code doesn't do
>anything with the nfmark of the original skb.
>
>I'll have to investigate this further. Stay tuned.
> 
>Thanks for reporting the bug...
>
I think the problem lies within ip_route_me_harder. It is called on 
mangled packets in the INPUT chain
and changes skb->dst with new route after setting key.src = 0 if it's 
not a local address.
icmp_reply uses skb->dst to determine destination address: daddr = 
ipc.addr = rt->rt_src;

These log messages show i'm probably right:
PREROUTING IN=eth0 OUT= MAC=00:e0:7d:74:ab:cd:00:e0:7d:74:ab:cc:08:00 
SRC=192.168.0.1 DST=192.168.0.23 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=0 
DF PROTO=ICMP TYPE=8 CODE=0 ID=39444 SEQ=0
INPUT IN=eth0 OUT= MAC=00:e0:7d:74:ab:cd:00:e0:7d:74:ab:cc:08:00 
SRC=192.168.0.1 DST=192.168.0.23 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=0 
DF PROTO=ICMP TYPE=8 CODE=0 ID=39444 SEQ=0
OUTPUT IN= OUT=lo SRC=192.168.0.23 DST=192.168.0.23 LEN=84 TOS=0x00 
PREC=0x00 TTL=64 ID=17880 PROTO=ICMP TYPE=0 CODE=0 ID=39444 SEQ=0
^^^^ note SRC and DST are both the local ip
POSTROUTING IN= OUT=lo SRC=192.168.0.23 DST=192.168.0.23 LEN=84 TOS=0x00 
PREC=0x00 TTL=64 ID=17880 PROTO=ICMP TYPE=0 CODE=0 ID=39444 SEQ=0
PREROUTING IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 
SRC=192.168.0.23 DST=192.168.0.23 LEN=84 TOS=0x00 PREC=0x00 TTL=64 
ID=17880 PROTO=ICMP TYPE=0 CODE=0 ID=39444 SEQ=0
INPUT IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 
SRC=192.168.0.23 DST=192.168.0.23 LEN=84 TOS=0x00 PREC=0x00 TTL=64 
ID=17880 PROTO=ICMP TYPE=0 CODE=0 ID=39444 SEQ=0

Regards,
Patrick

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Corruption on mangle/INPUT when MARKing packets
  2003-01-06 16:26   ` Patrick McHardy
@ 2003-01-08 17:07     ` Harald Welte
  2003-01-08 18:23       ` Patrick McHardy
  0 siblings, 1 reply; 6+ messages in thread
From: Harald Welte @ 2003-01-08 17:07 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Costa Tsaousis, netfilter-devel

[-- Attachment #1: Type: text/plain, Size: 1207 bytes --]

On Mon, Jan 06, 2003 at 05:26:55PM +0100, Patrick McHardy wrote:
> I think the problem lies within ip_route_me_harder. It is called on 
> mangled packets in the INPUT chain
> and changes skb->dst with new route after setting key.src = 0 if it's 
> not a local address.

well spotted. This is exactly the problem.

So the question is: Do we really need to call route_me_harder() in the
INPUT chain?  We could argue that if somebody wants to do a change
affecting the routing decision should make that change before the
routing decison, not after it.  

If we agree on this change, the solution is easy. Just call
ipt_route_hook() instead of ipt_local_hook() at NF_IP_LOCAL_IN.

Otherwise we'd need a seperate route_me_harder function for the case of
non-local packets.  But I don't think this makes sense at all.

Patch attached (and put into 'pending'). 

Thanks.

> Regards,
> Patrick

-- 
- Harald Welte / laforge@gnumonks.org               http://www.gnumonks.org/
============================================================================
"If this were a dictatorship, it'd be a heck of a lot easier, just so long
 as I'm the dictator."  --  George W. Bush Dec 18, 2000

[-- Attachment #2: Type: application/pgp-signature, Size: 232 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Corruption on mangle/INPUT when MARKing packets
  2003-01-08 17:07     ` Harald Welte
@ 2003-01-08 18:23       ` Patrick McHardy
  0 siblings, 0 replies; 6+ messages in thread
From: Patrick McHardy @ 2003-01-08 18:23 UTC (permalink / raw)
  To: Harald Welte; +Cc: Costa Tsaousis, netfilter-devel

[-- Attachment #1: Type: text/plain, Size: 1593 bytes --]

Harald Welte wrote:

>On Mon, Jan 06, 2003 at 05:26:55PM +0100, Patrick McHardy wrote:
>  
>
>>I think the problem lies within ip_route_me_harder. It is called on 
>>mangled packets in the INPUT chain
>>and changes skb->dst with new route after setting key.src = 0 if it's 
>>not a local address.
>>    
>>
>
>well spotted. This is exactly the problem.
>
>So the question is: Do we really need to call route_me_harder() in the
>INPUT chain?  We could argue that if somebody wants to do a change
>affecting the routing decision should make that change before the
>routing decison, not after it.  
>
That sound reasonable. Besides, i think it is a rarely used feature anyways.
The difference as far as i can see between doing the change in PRE_ROUTING
and INPUT chain is that in PRE_ROUTING chain you may not know a packet
is addressed to a local address (in case it's a dynamically assigned ip).
I've written a match some time ago to match inet_addr_type
(rtm_types from include/linux/rtnetlink.h). We use it for DNAT to 
distinguish
between packets that are to-be-routed and packets that are addressed at 
a local ip
without having to know the ip in advance (for automatically generated 
rules).
I'm attaching the patch, perhaps you like it.

Regards,
Patrick

>
>If we agree on this change, the solution is easy. Just call
>ipt_route_hook() instead of ipt_local_hook() at NF_IP_LOCAL_IN.
>
>Otherwise we'd need a seperate route_me_harder function for the case of
>non-local packets.  But I don't think this makes sense at all.
>
>Patch attached (and put into 'pending'). 
>
>Thanks.
>
>  
>


[-- Attachment #2: addrtype-pom.diff --]
[-- Type: text/plain, Size: 12753 bytes --]

diff -urN patch-o-matic-20020823/extra/addrtype.patch patch-o-matic-addrtype/extra/addrtype.patch
--- patch-o-matic-20020823/extra/addrtype.patch	Thu Jan  1 01:00:00 1970
+++ patch-o-matic-addrtype/extra/addrtype.patch	Wed Sep 18 14:14:50 2002
@@ -0,0 +1,139 @@
+diff -urN -X dontdiff.txt linux-2.4.20-pre5-clean/include/linux/netfilter_ipv4/ipt_addrtype.h linux-2.4.20-pre5/include/linux/netfilter_ipv4/ipt_addrtype.h
+--- linux-2.4.20-pre5-clean/include/linux/netfilter_ipv4/ipt_addrtype.h	Thu Jan  1 01:00:00 1970
++++ linux-2.4.20-pre5/include/linux/netfilter_ipv4/ipt_addrtype.h	Wed Sep 18 12:36:06 2002
+@@ -0,0 +1,28 @@
++#ifndef _IPT_ADDRTYPE_H
++#define _IPT_ADDRTYPE_H
++
++#define IPT_ADDRTYPE_SOURCE	0x1
++#define IPT_ADDRTYPE_DEST	0x2
++
++/* from linux/rtnetlink.h */
++
++#define IPT_ADDRTYPE_RTN_UNSPEC		0x0001
++#define IPT_ADDRTYPE_RTN_UNICAST	0x0002
++#define IPT_ADDRTYPE_RTN_LOCAL		0x0004
++#define IPT_ADDRTYPE_RTN_BROADCAST	0x0008
++#define IPT_ADDRTYPE_RTN_ANYCAST	0x0010
++#define IPT_ADDRTYPE_RTN_MULTICAST	0x0020
++#define IPT_ADDRTYPE_RTN_BLACKHOLE	0x0040
++#define IPT_ADDRTYPE_RTN_UNREACHABLE	0x0080
++#define IPT_ADDRTYPE_RTN_PROHIBIT	0x0100
++#define IPT_ADDRTYPE_RTN_THROW		0x0200
++#define IPT_ADDRTYPE_RTN_NAT		0x0400
++#define IPT_ADDRTYPE_RTN_XRESOLVE	0x0800
++
++struct ipt_addrtype_info {
++	u_int16_t	type;
++	u_int8_t	mode;
++	u_int8_t	invert;
++};
++
++#endif
+diff -urN -X dontdiff.txt linux-2.4.20-pre5-clean/net/ipv4/netfilter/ipt_addrtype.c linux-2.4.20-pre5/net/ipv4/netfilter/ipt_addrtype.c
+--- linux-2.4.20-pre5-clean/net/ipv4/netfilter/ipt_addrtype.c	Thu Jan  1 01:00:00 1970
++++ linux-2.4.20-pre5/net/ipv4/netfilter/ipt_addrtype.c	Wed Sep 18 13:41:16 2002
+@@ -0,0 +1,103 @@
++#include <linux/module.h>
++#include <linux/skbuff.h>
++#include <linux/netdevice.h>
++
++#include <net/route.h>
++
++#include <linux/netfilter_ipv4/ipt_addrtype.h>
++#include <linux/netfilter_ipv4/ip_tables.h>
++
++MODULE_LICENSE("GPL");
++
++static int match(const struct sk_buff *skb, const struct net_device *in,
++		 const struct net_device *out, const void *matchinfo,
++		 int offset, const void *hdr, u_int16_t datalen,
++		 int *hotdrop)
++{
++	const struct ipt_addrtype_info *info = matchinfo;
++	const struct iphdr *iph = skb->nh.iph;
++	unsigned type;
++	u_int32_t addr =
++		(info->mode == IPT_ADDRTYPE_SOURCE) ? iph->saddr : iph->daddr;
++
++	type = inet_addr_type(addr);
++	switch (type) {
++		case RTN_UNSPEC:
++			if (info->type&IPT_ADDRTYPE_RTN_UNSPEC)
++				return 1 ^ info->invert;
++			break;
++		case RTN_UNICAST:
++			if (info->type&IPT_ADDRTYPE_RTN_UNICAST)
++				return 1 ^ info->invert;
++			break;
++		case RTN_LOCAL:
++			if (info->type&IPT_ADDRTYPE_RTN_LOCAL)
++				return 1 ^ info->invert;
++			break;
++		case RTN_BROADCAST:
++			if (info->type&IPT_ADDRTYPE_RTN_BROADCAST)
++				return 1 ^ info->invert;
++			break;
++		case RTN_ANYCAST:
++			if (info->type&IPT_ADDRTYPE_RTN_ANYCAST)
++				return 1 ^ info->invert;
++			break;
++		case RTN_MULTICAST:
++			if (info->type&IPT_ADDRTYPE_RTN_MULTICAST)
++				return 1 ^ info->invert;
++			break;
++		case RTN_BLACKHOLE:
++			if (info->type&IPT_ADDRTYPE_RTN_BLACKHOLE)
++				return 1 ^ info->invert;
++			break;
++		case RTN_UNREACHABLE:
++			if (info->type&IPT_ADDRTYPE_RTN_UNREACHABLE)
++				return 1 ^ info->invert;
++			break;
++		case RTN_PROHIBIT:
++			if (info->type&IPT_ADDRTYPE_RTN_PROHIBIT)
++				return 1 ^ info->invert;
++			break;
++		case RTN_THROW:
++			if (info->type&IPT_ADDRTYPE_RTN_THROW)
++				return 1 ^ info->invert;
++			break;
++		case RTN_NAT:
++			if (info->type&IPT_ADDRTYPE_RTN_NAT)
++				return 1 ^ info->invert;
++			break;
++		case RTN_XRESOLVE:
++			if (info->type&IPT_ADDRTYPE_RTN_XRESOLVE)
++				return 1 ^ info->invert;
++			break;
++	}
++	
++	return info->invert;
++}
++
++static int checkentry(const char *tablename, const struct ipt_ip *ip,
++		      void *matchinfo, unsigned int matchsize,
++		      unsigned int hook_mask)
++{
++	if (matchsize != IPT_ALIGN(sizeof(struct ipt_addrtype_info)))
++		return 0;
++
++	return 1;
++}
++
++static struct ipt_match addrtype_match = { { NULL, NULL }, "addrtype", &match,
++		&checkentry, NULL, THIS_MODULE };
++
++static int __init init(void)
++{
++	return ipt_register_match(&addrtype_match);
++}
++
++static void __exit fini(void)
++{
++	ipt_unregister_match(&addrtype_match);
++
++}
++
++module_init(init);
++module_exit(fini);
diff -urN patch-o-matic-20020823/extra/addrtype.patch.config.in patch-o-matic-addrtype/extra/addrtype.patch.config.in
--- patch-o-matic-20020823/extra/addrtype.patch.config.in	Thu Jan  1 01:00:00 1970
+++ patch-o-matic-addrtype/extra/addrtype.patch.config.in	Wed Sep 18 14:11:44 2002
@@ -0,0 +1,2 @@
+  dep_tristate '  TTL match support' CONFIG_IP_NF_MATCH_TTL $CONFIG_IP_NF_IPTABLES
+  dep_tristate '  address type match support' CONFIG_IP_NF_MATCH_ADDRTYPE $CONFIG_IP_NF_IPTABLES
diff -urN patch-o-matic-20020823/extra/addrtype.patch.help patch-o-matic-addrtype/extra/addrtype.patch.help
--- patch-o-matic-20020823/extra/addrtype.patch.help	Thu Jan  1 01:00:00 1970
+++ patch-o-matic-addrtype/extra/addrtype.patch.help	Wed Sep 18 13:55:27 2002
@@ -0,0 +1,20 @@
+Author: Patrick McHardy <kaber@trash.net>
+Status: Seems to work ..
+
+This match allows you to match address types.
+Valid types are:
+
+UNSPEC
+UNICAST
+LOCAL
+BROADCAST
+ANYCAST
+MULTICAST
+BLACKHOLE
+UNREACHABLE
+PROHIBIT
+THROW
+NAT
+XRESOLVE
+
+blabla
diff -urN patch-o-matic-20020823/extra/addrtype.patch.makefile patch-o-matic-addrtype/extra/addrtype.patch.makefile
--- patch-o-matic-20020823/extra/addrtype.patch.makefile	Thu Jan  1 01:00:00 1970
+++ patch-o-matic-addrtype/extra/addrtype.patch.makefile	Wed Sep 18 14:14:39 2002
@@ -0,0 +1,2 @@
+obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
+obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
diff -urN extensions/libipt_addrtype.c extensions/libipt_addrtype.c
--- extensions/libipt_addrtype.c	Thu Jan  1 01:00:00 1970
+++ extensions/libipt_addrtype.c	Wed Sep 18 15:14:35 2002
@@ -0,0 +1,256 @@
+/* Shared library add-on to iptables to add TTL matching support 
+ * 
+ * This program is released under the terms of GNU GPL */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <iptables.h>
+
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_addrtype.h>
+
+static void help(void) 
+{
+	printf(
+"Address type match v%s options:\n"
+"  --source             Match source address\n"
+"  --dest               Match destination address\n"
+" [!] --type		[UNSPEC|UNICAST|LOCAL|BROADCAST|ANYCAST|MULTICAST|\n"
+"                        BLACKHOLE|UNREACHABLE|PROHIBIT|THROW|NAT|XRESOLVE]\n"
+"                       [,...]\n"
+, IPTABLES_VERSION);
+}
+
+static void init(struct ipt_entry_match *m, unsigned int *nfcache)
+{
+	/* caching not yet implemented */
+	*nfcache |= NFC_UNKNOWN;
+}
+
+static int
+parse_type(const char *type, size_t strlen, struct ipt_addrtype_info *info)
+{
+	if (strncasecmp(type, "UNSPEC", strlen) == 0)
+		info->type |= IPT_ADDRTYPE_RTN_UNSPEC;
+	else if (strncasecmp(type, "UNICAST", strlen) == 0)
+		info->type |= IPT_ADDRTYPE_RTN_UNICAST;
+	else if (strncasecmp(type, "LOCAL", strlen) == 0)
+		info->type |= IPT_ADDRTYPE_RTN_LOCAL;
+	else if (strncasecmp(type, "BROADCAST", strlen) == 0)
+		info->type |= IPT_ADDRTYPE_RTN_BROADCAST;
+	else if (strncasecmp(type, "ANYCAST", strlen) == 0)
+		info->type |= IPT_ADDRTYPE_RTN_ANYCAST;
+	else if (strncasecmp(type, "MULTICAST", strlen) == 0)
+		info->type |= IPT_ADDRTYPE_RTN_MULTICAST;
+	else if (strncasecmp(type, "BLACKHOLE", strlen) == 0)
+		info->type |= IPT_ADDRTYPE_RTN_BLACKHOLE;
+	else if (strncasecmp(type, "UNREACHABLE", strlen) == 0)
+		info->type |= IPT_ADDRTYPE_RTN_UNREACHABLE;
+	else if (strncasecmp(type, "PROHIBIT", strlen) == 0)
+		info->type |= IPT_ADDRTYPE_RTN_PROHIBIT;
+	else if (strncasecmp(type, "THROW", strlen) == 0)
+		info->type |= IPT_ADDRTYPE_RTN_THROW;
+	else if (strncasecmp(type, "NAT", strlen) == 0)
+		info->type |= IPT_ADDRTYPE_RTN_NAT;
+	else if (strncasecmp(type, "XRESOLVE", strlen) == 0)
+		info->type |= IPT_ADDRTYPE_RTN_XRESOLVE;
+	else
+		return 0;
+	return 1;
+}
+
+static void parse_types(const char *arg, struct ipt_addrtype_info *info)
+{
+	const char *comma;
+
+	while ((comma = strchr(arg, ',')) != NULL) {
+		if (comma == arg || !parse_type(arg, comma-arg, info))
+			exit_error(PARAMETER_PROBLEM, "Bad type `%s'", arg);
+		arg = comma + 1;
+	}
+
+	if (strlen(arg) == 0 || !parse_type(arg, strlen(arg), info))
+		exit_error(PARAMETER_PROBLEM, "Bad type `%s'", arg);
+}
+	
+#define IPT_ADDRTYPE_OPT_DIR	0x1
+#define IPT_ADDRTYPE_OPT_TYPE	0x2
+
+static int parse(int c, char **argv, int invert, unsigned int *flags,
+		const struct ipt_entry *entry, unsigned int *nfcache,
+		struct ipt_entry_match **match)
+{
+	struct ipt_addrtype_info *info =
+		(struct ipt_addrtype_info *) (*match)->data;
+
+	switch (c) {
+		case '1':
+			if (*flags&IPT_ADDRTYPE_OPT_DIR)
+				exit_error(PARAMETER_PROBLEM,
+					   "Can't specify source/dest twice");
+
+			info->mode = IPT_ADDRTYPE_SOURCE;
+			*flags |= IPT_ADDRTYPE_OPT_DIR;
+			break;
+		case '2':
+			if (*flags&IPT_ADDRTYPE_OPT_DIR)
+				exit_error(PARAMETER_PROBLEM,
+					   "Can't specify source/dest twice");
+
+			info->mode = IPT_ADDRTYPE_DEST;
+			*flags |= IPT_ADDRTYPE_OPT_DIR;
+			break;
+		case '3':
+			if (*flags&IPT_ADDRTYPE_OPT_TYPE)
+				exit_error(PARAMETER_PROBLEM,
+					   "Can't specify --type twice");
+
+			check_inverse(optarg, &invert, &optind, 0);
+			parse_types(argv[optind-1], info);
+			if (invert)
+				info->invert = 1;
+			*flags |= IPT_ADDRTYPE_OPT_TYPE;
+			break;
+		default:
+			return 0;
+	}
+	
+	return 1;
+}
+
+static void final_check(unsigned int flags)
+{
+	if (!(flags&IPT_ADDRTYPE_OPT_DIR))
+		exit_error(PARAMETER_PROBLEM,
+			   "addrtype: you must specify --source or --dest");
+	if (!(flags&IPT_ADDRTYPE_OPT_TYPE))
+		exit_error(PARAMETER_PROBLEM,
+			   "addrtype: you must specify --type");
+}
+
+static void print_type(unsigned typemask) {
+	const char *sep = "";
+	if (typemask&IPT_ADDRTYPE_RTN_UNSPEC) {
+		printf("%sUNSPEC", sep);
+		sep = ",";
+	}
+	if (typemask&IPT_ADDRTYPE_RTN_UNICAST) {
+		printf("%sUNICAST", sep);
+		sep = ",";
+	}
+	if (typemask&IPT_ADDRTYPE_RTN_LOCAL) {
+		printf("%sLOCAL", sep);
+		sep = ",";
+	}
+	if (typemask&IPT_ADDRTYPE_RTN_BROADCAST) {
+		printf("%sBROADCAST", sep);
+		sep = ",";
+	}
+	if (typemask&IPT_ADDRTYPE_RTN_ANYCAST) {
+		printf("%sANYCAST", sep);
+		sep = ",";
+	}
+	if (typemask&IPT_ADDRTYPE_RTN_MULTICAST) {
+		printf("%sMULTICAST", sep);
+		sep = ",";
+	}
+	if (typemask&IPT_ADDRTYPE_RTN_BLACKHOLE) {
+		printf("%sBLACKHOLE", sep);
+		sep = ",";
+	}
+	if (typemask&IPT_ADDRTYPE_RTN_UNREACHABLE) {
+		printf("%sUNREACHABLE", sep);
+		sep = ",";
+	}
+	if (typemask&IPT_ADDRTYPE_RTN_PROHIBIT) {
+		printf("%sPROHIBIT", sep);
+		sep = ",";
+	}
+	if (typemask&IPT_ADDRTYPE_RTN_THROW) {
+		printf("%sTHROW", sep);
+		sep = ",";
+	}
+	if (typemask&IPT_ADDRTYPE_RTN_XRESOLVE) {
+		printf("%sXRESOLVE", sep);
+		sep = ",";
+	}
+	printf(" ");
+}
+
+static void print(const struct ipt_ip *ip, 
+		const struct ipt_entry_match *match,
+		int numeric)
+{
+	const struct ipt_addrtype_info *info = 
+		(struct ipt_addrtype_info *) match->data;
+
+	printf("ADDRTYPE match ");
+
+	switch (info->mode) {
+		case IPT_ADDRTYPE_SOURCE:
+			printf("sourceaddr ");
+			break;
+		case IPT_ADDRTYPE_DEST:
+			printf("destaddr ");
+			break;
+	}
+
+	if (info->invert)
+		printf("!");
+
+	print_type(info->type);
+}
+
+static void save(const struct ipt_ip *ip, 
+		const struct ipt_entry_match *match)
+{
+	const struct ipt_addrtype_info *info =
+		(struct ipt_addrtype_info *) match->data;
+
+	switch (info->mode) {
+		case IPT_ADDRTYPE_SOURCE:
+			printf("--source ");
+			break;
+		case IPT_ADDRTYPE_DEST:
+			printf("--dest ");
+			break;
+		default:
+			break;
+	}
+
+	if (info->invert)
+		printf("! ");
+	printf("--type ");
+	print_type(info->type);
+}
+
+static struct option opts[] = {
+	{ "source", 0, 0, '1' },
+	{ "dest", 0, 0, '2' },
+	{ "type", 1, 0, '3' },
+	{ 0 }
+};
+
+static
+struct iptables_match addrtype = {
+	NULL,
+	"addrtype",
+	IPTABLES_VERSION,
+	IPT_ALIGN(sizeof(struct ipt_addrtype_info)),
+	IPT_ALIGN(sizeof(struct ipt_addrtype_info)),
+	&help,
+	&init,
+	&parse,
+	&final_check,
+	&print,
+	&save,
+	opts
+};
+
+
+void _init(void) 
+{
+	register_match(&addrtype);
+}
diff -urN extensions/.addrtype-test extensions/.addrtype-test
--- extensions/.addrtype-test	Thu Jan  1 01:00:00 1970
+++ extensions/.addrtype-test	Wed Sep 18 15:18:25 2002
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+if test -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_addrtype.h; then
+	echo "addrtype"
+fi

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2003-01-08 18:23 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-01-04  1:47 Corruption on mangle/INPUT when MARKing packets Costa Tsaousis
2003-01-06 12:52 ` Harald Welte
2003-01-06 13:13   ` Costa Tsaousis
2003-01-06 16:26   ` Patrick McHardy
2003-01-08 17:07     ` Harald Welte
2003-01-08 18:23       ` Patrick McHardy

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.