* [PATCH] addrtype match
@ 2003-04-08 16:02 Patrick McHardy
2003-04-08 20:31 ` Martin Josefsson
0 siblings, 1 reply; 10+ messages in thread
From: Patrick McHardy @ 2003-04-08 16:02 UTC (permalink / raw)
To: Netfilter Development Mailinglist
[-- Attachment #1: Type: text/plain, Size: 410 bytes --]
This patch adds a new match "addrtype" which can be used to match
the result of inet_addr_type, which is what routing thinks of an address.
We use it for automatic generated rules where DNAT rules can be
generated with just an interface match because the local ip may be
unknown at rule generation time. The match is then used to exclude
local addresses from DNAT. Please consider for inclusion.
Bye,
Patrick
[-- Attachment #2: nf-addrtype.diff --]
[-- Type: text/plain, Size: 12544 bytes --]
diff -urN a/patch-o-matic/extra/addrtype.patch b/patch-o-matic/extra/addrtype.patch
--- a/patch-o-matic/extra/addrtype.patch 1970-01-01 01:00:00.000000000 +0100
+++ b/patch-o-matic/extra/addrtype.patch 2003-04-08 16:50:05.000000000 +0200
@@ -0,0 +1,145 @@
+diff -urN a/include/linux/netfilter_ipv4/ipt_addrtype.h b/include/linux/netfilter_ipv4/ipt_addrtype.h
+--- a/include/linux/netfilter_ipv4/ipt_addrtype.h 1970-01-01 01:00:00.000000000 +0100
++++ b/include/linux/netfilter_ipv4/ipt_addrtype.h 2003-04-08 13:38:02.000000000 +0200
+@@ -0,0 +1,26 @@
++#ifndef _IPT_ADDRTYPE_H
++#define _IPT_ADDRTYPE_H
++
++/* 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 source;
++ u_int16_t dest;
++ int invert_source; /* -m addtype ! --source .. */
++ int invert_dest; /* -m addrtype ! --dest .. */
++};
++
++#endif
+diff -urN a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c
+--- a/net/ipv4/netfilter/ipt_addrtype.c 1970-01-01 01:00:00.000000000 +0100
++++ b/net/ipv4/netfilter/ipt_addrtype.c 2003-04-08 15:41:05.000000000 +0200
+@@ -0,0 +1,111 @@
++#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_type(u_int32_t addr, u_int16_t types)
++{
++ unsigned type = inet_addr_type(addr);
++
++ switch(type) {
++ case RTN_UNSPEC:
++ if (types&IPT_ADDRTYPE_RTN_UNSPEC)
++ return 1;
++ break;
++ case RTN_UNICAST:
++ if (types&IPT_ADDRTYPE_RTN_UNICAST)
++ return 1;
++ break;
++ case RTN_LOCAL:
++ if (types&IPT_ADDRTYPE_RTN_LOCAL)
++ return 1;
++ break;
++ case RTN_BROADCAST:
++ if (type&IPT_ADDRTYPE_RTN_BROADCAST)
++ return 1;
++ break;
++ case RTN_ANYCAST:
++ if (types&IPT_ADDRTYPE_RTN_ANYCAST)
++ return 1;
++ break;
++ case RTN_MULTICAST:
++ if (types&IPT_ADDRTYPE_RTN_MULTICAST)
++ return 1;
++ break;
++ case RTN_BLACKHOLE:
++ if (types&IPT_ADDRTYPE_RTN_BLACKHOLE)
++ return 1;
++ break;
++ case RTN_UNREACHABLE:
++ if (types&IPT_ADDRTYPE_RTN_UNREACHABLE)
++ return 1;
++ break;
++ case RTN_PROHIBIT:
++ if (types&IPT_ADDRTYPE_RTN_PROHIBIT)
++ return 1;
++ break;
++ case RTN_THROW:
++ if (types&IPT_ADDRTYPE_RTN_THROW)
++ return 1;
++ break;
++ case RTN_NAT:
++ if (types&IPT_ADDRTYPE_RTN_NAT)
++ return 1;
++ break;
++ case RTN_XRESOLVE:
++ if (types&IPT_ADDRTYPE_RTN_XRESOLVE)
++ return 1;
++ break;
++ }
++ return 0;
++}
++
++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;
++ int ret = 1;
++
++ if (info->source)
++ ret &= match_type(iph->saddr, info->source)^info->invert_source;
++ if (info->dest)
++ ret &= match_type(iph->daddr, info->dest)^info->invert_dest;
++
++ return ret;
++}
++
++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 a/patch-o-matic/extra/addrtype.patch.config.in b/patch-o-matic/extra/addrtype.patch.config.in
--- a/patch-o-matic/extra/addrtype.patch.config.in 1970-01-01 01:00:00.000000000 +0100
+++ b/patch-o-matic/extra/addrtype.patch.config.in 2003-04-08 16:50:05.000000000 +0200
@@ -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 a/patch-o-matic/extra/addrtype.patch.help b/patch-o-matic/extra/addrtype.patch.help
--- a/patch-o-matic/extra/addrtype.patch.help 1970-01-01 01:00:00.000000000 +0100
+++ b/patch-o-matic/extra/addrtype.patch.help 2003-04-08 16:50:05.000000000 +0200
@@ -0,0 +1,28 @@
+Author: Patrick McHardy <kaber@trash.net>
+Status: Working
+
+This match allows you to match address types as seen by the routing code.
+Valid types (from include/linux/rtnetlink.h) are:
+
+UNSPEC
+UNICAST
+LOCAL
+BROADCAST
+ANYCAST
+MULTICAST
+BLACKHOLE
+UNREACHABLE
+PROHIBIT
+THROW
+NAT
+XRESOLVE
+
+Usage:
+ -m addrtype --source type[,type..] --dest type[,type..]
+
+Example:
+
+ iptables ... -m addrtype --source LOCAL ...
+ iptables ... -m addrtype --dest ANYCAST ...
+
+
diff -urN a/patch-o-matic/extra/addrtype.patch.makefile b/patch-o-matic/extra/addrtype.patch.makefile
--- a/patch-o-matic/extra/addrtype.patch.makefile 1970-01-01 01:00:00.000000000 +0100
+++ b/patch-o-matic/extra/addrtype.patch.makefile 2003-04-08 16:50:05.000000000 +0200
@@ -0,0 +1,2 @@
+obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
+obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
diff -urN a/userspace/extensions/.addrtype-test b/userspace/extensions/.addrtype-test
--- a/userspace/extensions/.addrtype-test 1970-01-01 01:00:00.000000000 +0100
+++ b/userspace/extensions/.addrtype-test 2003-04-08 16:50:05.000000000 +0200
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+if test -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_addrtype.h; then
+ echo "addrtype"
+fi
diff -urN a/userspace/extensions/libipt_addrtype.c b/userspace/extensions/libipt_addrtype.c
--- a/userspace/extensions/libipt_addrtype.c 1970-01-01 01:00:00.000000000 +0100
+++ b/userspace/extensions/libipt_addrtype.c 2003-04-08 16:50:24.000000000 +0200
@@ -0,0 +1,245 @@
+/* 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 type[,...]"
+" Match source address type\n"
+" [!] --dest type[,...]"
+" Match destination address type\n"
+"\n"
+"Valid types: UNSPEC,UNICAST,LOCAL,BROADCAST,ANYCAST,MULTICAST,\n"
+" BLACKHOLE,UNREACHABLE,PROHIBIT,THROW,NAT,XRESOLVE\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, u_int16_t *i)
+{
+ if (strncasecmp(type, "UNSPEC", strlen) == 0)
+ *i |= IPT_ADDRTYPE_RTN_UNSPEC;
+ else if (strncasecmp(type, "UNICAST", strlen) == 0)
+ *i |= IPT_ADDRTYPE_RTN_UNICAST;
+ else if (strncasecmp(type, "LOCAL", strlen) == 0)
+ *i |= IPT_ADDRTYPE_RTN_LOCAL;
+ else if (strncasecmp(type, "BROADCAST", strlen) == 0)
+ *i |= IPT_ADDRTYPE_RTN_BROADCAST;
+ else if (strncasecmp(type, "ANYCAST", strlen) == 0)
+ *i |= IPT_ADDRTYPE_RTN_ANYCAST;
+ else if (strncasecmp(type, "MULTICAST", strlen) == 0)
+ *i |= IPT_ADDRTYPE_RTN_MULTICAST;
+ else if (strncasecmp(type, "BLACKHOLE", strlen) == 0)
+ *i |= IPT_ADDRTYPE_RTN_BLACKHOLE;
+ else if (strncasecmp(type, "UNREACHABLE", strlen) == 0)
+ *i |= IPT_ADDRTYPE_RTN_UNREACHABLE;
+ else if (strncasecmp(type, "PROHIBIT", strlen) == 0)
+ *i |= IPT_ADDRTYPE_RTN_PROHIBIT;
+ else if (strncasecmp(type, "THROW", strlen) == 0)
+ *i |= IPT_ADDRTYPE_RTN_THROW;
+ else if (strncasecmp(type, "NAT", strlen) == 0)
+ *i |= IPT_ADDRTYPE_RTN_NAT;
+ else if (strncasecmp(type, "XRESOLVE", strlen) == 0)
+ *i |= IPT_ADDRTYPE_RTN_XRESOLVE;
+ else
+ return 0;
+ return 1;
+}
+
+static void parse_types(const char *arg, u_int16_t *i)
+{
+ const char *comma;
+
+ while ((comma = strchr(arg, ',')) != NULL) {
+ if (comma == arg || !parse_type(arg, comma-arg, i))
+ exit_error(PARAMETER_PROBLEM, "Bad type `%s'", arg);
+ arg = comma + 1;
+ }
+
+ if (strlen(arg) == 0 || !parse_type(arg, strlen(arg), i))
+ exit_error(PARAMETER_PROBLEM, "Bad type `%s'", arg);
+}
+
+#define IPT_ADDRTYPE_OPT_SOURCE 0x1
+#define IPT_ADDRTYPE_OPT_DEST 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_SOURCE)
+ exit_error(PARAMETER_PROBLEM,
+ "Can't specify source twice");
+
+ check_inverse(optarg, &invert, &optind, 0);
+ parse_types(argv[optind-1], &info->source);
+ if (invert)
+ info->invert_source = 1;
+ *flags |= IPT_ADDRTYPE_OPT_SOURCE;
+ break;
+ case '2':
+ if (*flags&IPT_ADDRTYPE_OPT_DEST)
+ exit_error(PARAMETER_PROBLEM,
+ "Can't specify dest twice");
+
+ check_inverse(optarg, &invert, &optind, 0);
+ parse_types(argv[optind-1], &info->dest);
+ if (invert)
+ info->invert_dest = 1;
+ *flags |= IPT_ADDRTYPE_OPT_DEST;
+ break;
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+static void final_check(unsigned int flags)
+{
+ if (!(flags&(IPT_ADDRTYPE_OPT_SOURCE|IPT_ADDRTYPE_OPT_DEST)))
+ exit_error(PARAMETER_PROBLEM,
+ "addrtype: you must specify --source or --dest");
+}
+
+static void print_type(u_int16_t types) {
+ const char *sep = "";
+ if (types&IPT_ADDRTYPE_RTN_UNSPEC) {
+ printf("%sUNSPEC", sep);
+ sep = ",";
+ }
+ if (types&IPT_ADDRTYPE_RTN_UNICAST) {
+ printf("%sUNICAST", sep);
+ sep = ",";
+ }
+ if (types&IPT_ADDRTYPE_RTN_LOCAL) {
+ printf("%sLOCAL", sep);
+ sep = ",";
+ }
+ if (types&IPT_ADDRTYPE_RTN_BROADCAST) {
+ printf("%sBROADCAST", sep);
+ sep = ",";
+ }
+ if (types&IPT_ADDRTYPE_RTN_ANYCAST) {
+ printf("%sANYCAST", sep);
+ sep = ",";
+ }
+ if (types&IPT_ADDRTYPE_RTN_MULTICAST) {
+ printf("%sMULTICAST", sep);
+ sep = ",";
+ }
+ if (types&IPT_ADDRTYPE_RTN_BLACKHOLE) {
+ printf("%sBLACKHOLE", sep);
+ sep = ",";
+ }
+ if (types&IPT_ADDRTYPE_RTN_UNREACHABLE) {
+ printf("%sUNREACHABLE", sep);
+ sep = ",";
+ }
+ if (types&IPT_ADDRTYPE_RTN_PROHIBIT) {
+ printf("%sPROHIBIT", sep);
+ sep = ",";
+ }
+ if (types&IPT_ADDRTYPE_RTN_THROW) {
+ printf("%sTHROW", sep);
+ sep = ",";
+ }
+ if (types&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 ");
+
+ if (info->source) {
+ printf("source ");
+ if (info->invert_source)
+ printf("!");
+ print_type(info->source);
+ }
+ if (info->dest) {
+ printf("dest ");
+ if (info->invert_dest)
+ printf("!");
+ print_type(info->dest);
+ }
+}
+
+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;
+
+ if (info->source) {
+ printf("--source ");
+ if (info->invert_source)
+ printf("! ");
+ print_type(info->source);
+ }
+ if (info->dest) {
+ printf("--dest ");
+ if (info->invert_dest)
+ printf("! ");
+ print_type(info->dest);
+ }
+}
+
+static struct option opts[] = {
+ { "source", 1, 0, '1' },
+ { "dest", 1, 0, '2' },
+ { 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);
+}
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH] addrtype match
2003-04-08 16:02 [PATCH] addrtype match Patrick McHardy
@ 2003-04-08 20:31 ` Martin Josefsson
2003-04-08 23:28 ` Patrick McHardy
2003-04-09 1:37 ` Patrick McHardy
0 siblings, 2 replies; 10+ messages in thread
From: Martin Josefsson @ 2003-04-08 20:31 UTC (permalink / raw)
To: Patrick McHardy; +Cc: Netfilter Development Mailinglist
On Tue, 2003-04-08 at 18:02, Patrick McHardy wrote:
> This patch adds a new match "addrtype" which can be used to match
> the result of inet_addr_type, which is what routing thinks of an address.
> We use it for automatic generated rules where DNAT rules can be
> generated with just an interface match because the local ip may be
> unknown at rule generation time. The match is then used to exclude
> local addresses from DNAT. Please consider for inclusion.
Might come in handy.
> ++/* 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
Ok, duplicated and renumbered so you can use them as a bitmap.
Might deserve a comment as to why they were duplicated, might not be
totally obvious (took me a moment to realize it :)
> ++ switch(type) {
> ++ case RTN_UNSPEC:
> ++ if (types&IPT_ADDRTYPE_RTN_UNSPEC)
> ++ return 1;
> ++ break;
The kernel codingstyle says that there should be spaces around the & .
> ++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;
> ++}
A printk that tells the user what went wrong might be a nice thing. It's
missing from a lot of modules and I plan to fix that in the future.
> diff -urN a/userspace/extensions/libipt_addrtype.c b/userspace/extensions/libipt_addrtype.c
> --- a/userspace/extensions/libipt_addrtype.c 1970-01-01 01:00:00.000000000 +0100
> +++ b/userspace/extensions/libipt_addrtype.c 2003-04-08 16:50:24.000000000 +0200
> @@ -0,0 +1,245 @@
> +/* Shared library add-on to iptables to add TTL matching support
copy-and-forgot-to-edit? :)
> +static void print_type(u_int16_t types) {
> + const char *sep = "";
> + if (types&IPT_ADDRTYPE_RTN_UNSPEC) {
> + printf("%sUNSPEC", sep);
> + sep = ",";
> + }
Sure this is userspace but I'd like to see spaces around & here as well
:)
--
/Martin
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH] addrtype match
2003-04-08 20:31 ` Martin Josefsson
@ 2003-04-08 23:28 ` Patrick McHardy
2003-04-09 1:37 ` Patrick McHardy
1 sibling, 0 replies; 10+ messages in thread
From: Patrick McHardy @ 2003-04-08 23:28 UTC (permalink / raw)
To: Martin Josefsson; +Cc: Netfilter Development Mailinglist
Hi Martin,
thanks for your suggestions, i will make a new patch and resubmit it
tomorrow.
Bye,
Patrick
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] addrtype match
2003-04-08 20:31 ` Martin Josefsson
2003-04-08 23:28 ` Patrick McHardy
@ 2003-04-09 1:37 ` Patrick McHardy
2003-04-09 11:21 ` Martin Josefsson
1 sibling, 1 reply; 10+ messages in thread
From: Patrick McHardy @ 2003-04-09 1:37 UTC (permalink / raw)
To: Martin Josefsson; +Cc: Netfilter Development Mailinglist
[-- Attachment #1: Type: text/plain, Size: 206 bytes --]
Hi Martin,
this is an updated version of the addrtype match with the changes you
suggested. it's probably not be the most useful match in the world but as
you said, it might come handy ;)
Thanks,
Patrick
[-- Attachment #2: nf-addrtype.diff --]
[-- Type: text/plain, Size: 12774 bytes --]
diff -urN a/patch-o-matic/extra/addrtype.patch b/patch-o-matic/extra/addrtype.patch
--- a/patch-o-matic/extra/addrtype.patch 1970-01-01 01:00:00.000000000 +0100
+++ b/patch-o-matic/extra/addrtype.patch 2003-04-09 03:27:02.000000000 +0200
@@ -0,0 +1,148 @@
+diff -urN a/include/linux/netfilter_ipv4/ipt_addrtype.h b/include/linux/netfilter_ipv4/ipt_addrtype.h
+--- a/include/linux/netfilter_ipv4/ipt_addrtype.h 1970-01-01 01:00:00.000000000 +0100
++++ b/include/linux/netfilter_ipv4/ipt_addrtype.h 2003-04-09 03:20:01.000000000 +0200
+@@ -0,0 +1,26 @@
++#ifndef _IPT_ADDRTYPE_H
++#define _IPT_ADDRTYPE_H
++
++/* from linux/rtnetlink.h, renumbered to be useable as a bitmap */
++
++#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 source;
++ u_int16_t dest;
++ int invert_source; /* -m addtype ! --source .. */
++ int invert_dest; /* -m addrtype ! --dest .. */
++};
++
++#endif
+diff -urN a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c
+--- a/net/ipv4/netfilter/ipt_addrtype.c 1970-01-01 01:00:00.000000000 +0100
++++ b/net/ipv4/netfilter/ipt_addrtype.c 2003-04-09 03:22:18.000000000 +0200
+@@ -0,0 +1,114 @@
++#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_type(u_int32_t addr, u_int16_t types)
++{
++ unsigned type = inet_addr_type(addr);
++
++ switch(type) {
++ case RTN_UNSPEC:
++ if (types & IPT_ADDRTYPE_RTN_UNSPEC)
++ return 1;
++ break;
++ case RTN_UNICAST:
++ if (types & IPT_ADDRTYPE_RTN_UNICAST)
++ return 1;
++ break;
++ case RTN_LOCAL:
++ if (types & IPT_ADDRTYPE_RTN_LOCAL)
++ return 1;
++ break;
++ case RTN_BROADCAST:
++ if (type & IPT_ADDRTYPE_RTN_BROADCAST)
++ return 1;
++ break;
++ case RTN_ANYCAST:
++ if (types & IPT_ADDRTYPE_RTN_ANYCAST)
++ return 1;
++ break;
++ case RTN_MULTICAST:
++ if (types & IPT_ADDRTYPE_RTN_MULTICAST)
++ return 1;
++ break;
++ case RTN_BLACKHOLE:
++ if (types & IPT_ADDRTYPE_RTN_BLACKHOLE)
++ return 1;
++ break;
++ case RTN_UNREACHABLE:
++ if (types & IPT_ADDRTYPE_RTN_UNREACHABLE)
++ return 1;
++ break;
++ case RTN_PROHIBIT:
++ if (types & IPT_ADDRTYPE_RTN_PROHIBIT)
++ return 1;
++ break;
++ case RTN_THROW:
++ if (types & IPT_ADDRTYPE_RTN_THROW)
++ return 1;
++ break;
++ case RTN_NAT:
++ if (types & IPT_ADDRTYPE_RTN_NAT)
++ return 1;
++ break;
++ case RTN_XRESOLVE:
++ if (types & IPT_ADDRTYPE_RTN_XRESOLVE)
++ return 1;
++ break;
++ }
++ return 0;
++}
++
++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;
++ int ret = 1;
++
++ if (info->source)
++ ret &= match_type(iph->saddr, info->source)^info->invert_source;
++ if (info->dest)
++ ret &= match_type(iph->daddr, info->dest)^info->invert_dest;
++
++ return ret;
++}
++
++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))) {
++ printk(KERN_ERR "ipt_addrtype: invalid size (%u != %u)\n.",
++ 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 a/patch-o-matic/extra/addrtype.patch.config.in b/patch-o-matic/extra/addrtype.patch.config.in
--- a/patch-o-matic/extra/addrtype.patch.config.in 1970-01-01 01:00:00.000000000 +0100
+++ b/patch-o-matic/extra/addrtype.patch.config.in 2003-04-09 03:18:14.000000000 +0200
@@ -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 a/patch-o-matic/extra/addrtype.patch.help b/patch-o-matic/extra/addrtype.patch.help
--- a/patch-o-matic/extra/addrtype.patch.help 1970-01-01 01:00:00.000000000 +0100
+++ b/patch-o-matic/extra/addrtype.patch.help 2003-04-09 03:18:14.000000000 +0200
@@ -0,0 +1,28 @@
+Author: Patrick McHardy <kaber@trash.net>
+Status: Working
+
+This match allows you to match address types as seen by the routing code.
+Valid types (from include/linux/rtnetlink.h) are:
+
+UNSPEC
+UNICAST
+LOCAL
+BROADCAST
+ANYCAST
+MULTICAST
+BLACKHOLE
+UNREACHABLE
+PROHIBIT
+THROW
+NAT
+XRESOLVE
+
+Usage:
+ -m addrtype --source type[,type..] --dest type[,type..]
+
+Example:
+
+ iptables ... -m addrtype --source LOCAL ...
+ iptables ... -m addrtype --dest ANYCAST ...
+
+
diff -urN a/patch-o-matic/extra/addrtype.patch.makefile b/patch-o-matic/extra/addrtype.patch.makefile
--- a/patch-o-matic/extra/addrtype.patch.makefile 1970-01-01 01:00:00.000000000 +0100
+++ b/patch-o-matic/extra/addrtype.patch.makefile 2003-04-09 03:18:14.000000000 +0200
@@ -0,0 +1,2 @@
+obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
+obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
diff -urN a/userspace/extensions/.addrtype-test b/userspace/extensions/.addrtype-test
--- a/userspace/extensions/.addrtype-test 1970-01-01 01:00:00.000000000 +0100
+++ b/userspace/extensions/.addrtype-test 2003-04-09 03:18:14.000000000 +0200
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+if test -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_addrtype.h; then
+ echo "addrtype"
+fi
diff -urN a/userspace/extensions/libipt_addrtype.c b/userspace/extensions/libipt_addrtype.c
--- a/userspace/extensions/libipt_addrtype.c 1970-01-01 01:00:00.000000000 +0100
+++ b/userspace/extensions/libipt_addrtype.c 2003-04-09 03:29:47.000000000 +0200
@@ -0,0 +1,245 @@
+/* Shared library add-on to iptables to add addrtype 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 type[,...]"
+" Match source address type\n"
+" [!] --dest type[,...]"
+" Match destination address type\n"
+"\n"
+"Valid types: UNSPEC,UNICAST,LOCAL,BROADCAST,ANYCAST,MULTICAST,\n"
+" BLACKHOLE,UNREACHABLE,PROHIBIT,THROW,NAT,XRESOLVE\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, u_int16_t *i)
+{
+ if (strncasecmp(type, "UNSPEC", strlen) == 0)
+ *i |= IPT_ADDRTYPE_RTN_UNSPEC;
+ else if (strncasecmp(type, "UNICAST", strlen) == 0)
+ *i |= IPT_ADDRTYPE_RTN_UNICAST;
+ else if (strncasecmp(type, "LOCAL", strlen) == 0)
+ *i |= IPT_ADDRTYPE_RTN_LOCAL;
+ else if (strncasecmp(type, "BROADCAST", strlen) == 0)
+ *i |= IPT_ADDRTYPE_RTN_BROADCAST;
+ else if (strncasecmp(type, "ANYCAST", strlen) == 0)
+ *i |= IPT_ADDRTYPE_RTN_ANYCAST;
+ else if (strncasecmp(type, "MULTICAST", strlen) == 0)
+ *i |= IPT_ADDRTYPE_RTN_MULTICAST;
+ else if (strncasecmp(type, "BLACKHOLE", strlen) == 0)
+ *i |= IPT_ADDRTYPE_RTN_BLACKHOLE;
+ else if (strncasecmp(type, "UNREACHABLE", strlen) == 0)
+ *i |= IPT_ADDRTYPE_RTN_UNREACHABLE;
+ else if (strncasecmp(type, "PROHIBIT", strlen) == 0)
+ *i |= IPT_ADDRTYPE_RTN_PROHIBIT;
+ else if (strncasecmp(type, "THROW", strlen) == 0)
+ *i |= IPT_ADDRTYPE_RTN_THROW;
+ else if (strncasecmp(type, "NAT", strlen) == 0)
+ *i |= IPT_ADDRTYPE_RTN_NAT;
+ else if (strncasecmp(type, "XRESOLVE", strlen) == 0)
+ *i |= IPT_ADDRTYPE_RTN_XRESOLVE;
+ else
+ return 0;
+ return 1;
+}
+
+static void parse_types(const char *arg, u_int16_t *i)
+{
+ const char *comma;
+
+ while ((comma = strchr(arg, ',')) != NULL) {
+ if (comma == arg || !parse_type(arg, comma-arg, i))
+ exit_error(PARAMETER_PROBLEM, "Bad type `%s'", arg);
+ arg = comma + 1;
+ }
+
+ if (strlen(arg) == 0 || !parse_type(arg, strlen(arg), i))
+ exit_error(PARAMETER_PROBLEM, "Bad type `%s'", arg);
+}
+
+#define IPT_ADDRTYPE_OPT_SOURCE 0x1
+#define IPT_ADDRTYPE_OPT_DEST 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_SOURCE)
+ exit_error(PARAMETER_PROBLEM,
+ "Can't specify source twice");
+
+ check_inverse(optarg, &invert, &optind, 0);
+ parse_types(argv[optind-1], &info->source);
+ if (invert)
+ info->invert_source = 1;
+ *flags |= IPT_ADDRTYPE_OPT_SOURCE;
+ break;
+ case '2':
+ if (*flags&IPT_ADDRTYPE_OPT_DEST)
+ exit_error(PARAMETER_PROBLEM,
+ "Can't specify dest twice");
+
+ check_inverse(optarg, &invert, &optind, 0);
+ parse_types(argv[optind-1], &info->dest);
+ if (invert)
+ info->invert_dest = 1;
+ *flags |= IPT_ADDRTYPE_OPT_DEST;
+ break;
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+static void final_check(unsigned int flags)
+{
+ if (!(flags & (IPT_ADDRTYPE_OPT_SOURCE|IPT_ADDRTYPE_OPT_DEST)))
+ exit_error(PARAMETER_PROBLEM,
+ "addrtype: you must specify --source or --dest");
+}
+
+static void print_type(u_int16_t types) {
+ const char *sep = "";
+ if (types & IPT_ADDRTYPE_RTN_UNSPEC) {
+ printf("%sUNSPEC", sep);
+ sep = ",";
+ }
+ if (types & IPT_ADDRTYPE_RTN_UNICAST) {
+ printf("%sUNICAST", sep);
+ sep = ",";
+ }
+ if (types & IPT_ADDRTYPE_RTN_LOCAL) {
+ printf("%sLOCAL", sep);
+ sep = ",";
+ }
+ if (types & IPT_ADDRTYPE_RTN_BROADCAST) {
+ printf("%sBROADCAST", sep);
+ sep = ",";
+ }
+ if (types & IPT_ADDRTYPE_RTN_ANYCAST) {
+ printf("%sANYCAST", sep);
+ sep = ",";
+ }
+ if (types & IPT_ADDRTYPE_RTN_MULTICAST) {
+ printf("%sMULTICAST", sep);
+ sep = ",";
+ }
+ if (types & IPT_ADDRTYPE_RTN_BLACKHOLE) {
+ printf("%sBLACKHOLE", sep);
+ sep = ",";
+ }
+ if (types & IPT_ADDRTYPE_RTN_UNREACHABLE) {
+ printf("%sUNREACHABLE", sep);
+ sep = ",";
+ }
+ if (types & IPT_ADDRTYPE_RTN_PROHIBIT) {
+ printf("%sPROHIBIT", sep);
+ sep = ",";
+ }
+ if (types & IPT_ADDRTYPE_RTN_THROW) {
+ printf("%sTHROW", sep);
+ sep = ",";
+ }
+ if (types & 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 ");
+
+ if (info->source) {
+ printf("source ");
+ if (info->invert_source)
+ printf("!");
+ print_type(info->source);
+ }
+ if (info->dest) {
+ printf("dest ");
+ if (info->invert_dest)
+ printf("!");
+ print_type(info->dest);
+ }
+}
+
+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;
+
+ if (info->source) {
+ printf("--source ");
+ if (info->invert_source)
+ printf("! ");
+ print_type(info->source);
+ }
+ if (info->dest) {
+ printf("--dest ");
+ if (info->invert_dest)
+ printf("! ");
+ print_type(info->dest);
+ }
+}
+
+static struct option opts[] = {
+ { "source", 1, 0, '1' },
+ { "dest", 1, 0, '2' },
+ { 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);
+}
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH] addrtype match
2003-04-09 1:37 ` Patrick McHardy
@ 2003-04-09 11:21 ` Martin Josefsson
2003-04-09 11:29 ` Patrick McHardy
2003-04-09 12:50 ` Patrick McHardy
0 siblings, 2 replies; 10+ messages in thread
From: Martin Josefsson @ 2003-04-09 11:21 UTC (permalink / raw)
To: Patrick McHardy; +Cc: Netfilter Development Mailinglist
On Wed, 2003-04-09 at 03:37, Patrick McHardy wrote:
> Hi Martin,
> this is an updated version of the addrtype match with the changes you
> suggested. it's probably not be the most useful match in the world but as
> you said, it might come handy ;)
Don't know why I didn't think of this last night... I plead temporary
insanity :)
>
> ______________________________________________________________________
> ++/* from linux/rtnetlink.h, renumbered to be useable as a bitmap */
> ++
> ++#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
There actually isn't any real need to duplicate and renumber.. just use
(1 << RTN_UNSPEC) .... I think enum starts at 1 but that will only mean
you loose one bit, you don't need 32 bits anyway :)
> ++static int match_type(u_int32_t addr, u_int16_t types)
> ++{
> ++ unsigned type = inet_addr_type(addr);
> ++
if (type <= 31)
if (types & (1 << type))
return 1;
> ++ return 0;
> ++}
Maybe that would do it? I don't like big switch statements if they can
be avoided.
userspace below:
> +static int
> +parse_type(const char *type, size_t strlen, u_int16_t *i)
> +{
> + if (strncasecmp(type, "UNSPEC", strlen) == 0)
> + *i |= IPT_ADDRTYPE_RTN_UNSPEC;
> + else if (strncasecmp(type, "UNICAST", strlen) == 0)
> + *i |= IPT_ADDRTYPE_RTN_UNICAST;
Maybe this can be solved by a table that's looped through?
> +static void print_type(u_int16_t types) {
> + const char *sep = "";
> + if (types & IPT_ADDRTYPE_RTN_UNSPEC) {
> + printf("%sUNSPEC", sep);
> + sep = ",";
> + }
Same table could be used here
Oh, it could be used in the help() function as well.
Sorry about all the extra comments now after you've already made a new
patch... the only thing I really want to see is the removal of the code
duplication in the kernel. The table in userspace would just be a lot
nicer than all the if-statements, and to me almost more readable.
--
/Martin
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH] addrtype match
2003-04-09 11:21 ` Martin Josefsson
@ 2003-04-09 11:29 ` Patrick McHardy
2003-04-09 12:50 ` Patrick McHardy
1 sibling, 0 replies; 10+ messages in thread
From: Patrick McHardy @ 2003-04-09 11:29 UTC (permalink / raw)
To: Martin Josefsson; +Cc: Patrick McHardy, Netfilter Development Mailinglist
Hi Martin,
On 9 Apr 2003, Martin Josefsson wrote:
> There actually isn't any real need to duplicate and renumber.. just use
> (1 << RTN_UNSPEC) .... I think enum starts at 1 but that will only mean
> you loose one bit, you don't need 32 bits anyway :)
...
> Sorry about all the extra comments now after you've already made a new
> patch... the only thing I really want to see is the removal of the code
> duplication in the kernel. The table in userspace would just be a lot
> nicer than all the if-statements, and to me almost more readable.
No harm done, i was just starting to make some of the changes you
suggested when your mail arrived, i too don't like big switch statements ;)
Thanks again,
Patrick
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] addrtype match
2003-04-09 11:21 ` Martin Josefsson
2003-04-09 11:29 ` Patrick McHardy
@ 2003-04-09 12:50 ` Patrick McHardy
2003-04-09 13:28 ` Patrick McHardy
1 sibling, 1 reply; 10+ messages in thread
From: Patrick McHardy @ 2003-04-09 12:50 UTC (permalink / raw)
To: Martin Josefsson; +Cc: Netfilter Development Mailinglist
[-- Attachment #1: Type: text/plain, Size: 175 bytes --]
Hi Martin,
this is an updated version of the addrtype match, matching is now
done with a bitmask of types built in userspace. Code is a lot smaller
and nicer ;)
Bye,
Patrick
[-- Attachment #2: nf-addrtype.diff --]
[-- Type: text/plain, Size: 9686 bytes --]
diff -urN a/patch-o-matic/extra/addrtype.patch b/patch-o-matic/extra/addrtype.patch
--- a/patch-o-matic/extra/addrtype.patch 1970-01-01 01:00:00.000000000 +0100
+++ b/patch-o-matic/extra/addrtype.patch 2003-04-09 14:19:04.000000000 +0200
@@ -0,0 +1,84 @@
+diff -urN a/include/linux/netfilter_ipv4/ipt_addrtype.h b/include/linux/netfilter_ipv4/ipt_addrtype.h
+--- a/include/linux/netfilter_ipv4/ipt_addrtype.h 1970-01-01 01:00:00.000000000 +0100
++++ b/include/linux/netfilter_ipv4/ipt_addrtype.h 2003-04-09 13:42:03.000000000 +0200
+@@ -0,0 +1,11 @@
++#ifndef _IPT_ADDRTYPE_H
++#define _IPT_ADDRTYPE_H
++
++struct ipt_addrtype_info {
++ u_int16_t source; /* source-type mask */
++ u_int16_t dest; /* dest-type mask */
++ int invert_source;
++ int invert_dest;
++};
++
++#endif
+diff -urN a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c
+--- a/net/ipv4/netfilter/ipt_addrtype.c 1970-01-01 01:00:00.000000000 +0100
++++ b/net/ipv4/netfilter/ipt_addrtype.c 2003-04-09 13:43:50.000000000 +0200
+@@ -0,0 +1,65 @@
++/*
++ * iptables module to match inet_addr_type() of an ip.
++ */
++
++#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 inline int match_type(u_int32_t addr, u_int16_t mask)
++{
++ return !!(mask & (1 << inet_addr_type(addr)));
++}
++
++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;
++ int ret = 1;
++
++ if (info->source)
++ ret &= match_type(iph->saddr, info->source)^info->invert_source;
++ if (info->dest)
++ ret &= match_type(iph->daddr, info->dest)^info->invert_dest;
++
++ return ret;
++}
++
++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))) {
++ printk(KERN_ERR "ipt_addrtype: invalid size (%u != %u)\n.",
++ 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 a/patch-o-matic/extra/addrtype.patch.config.in b/patch-o-matic/extra/addrtype.patch.config.in
--- a/patch-o-matic/extra/addrtype.patch.config.in 1970-01-01 01:00:00.000000000 +0100
+++ b/patch-o-matic/extra/addrtype.patch.config.in 2003-04-09 14:19:04.000000000 +0200
@@ -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 a/patch-o-matic/extra/addrtype.patch.help b/patch-o-matic/extra/addrtype.patch.help
--- a/patch-o-matic/extra/addrtype.patch.help 1970-01-01 01:00:00.000000000 +0100
+++ b/patch-o-matic/extra/addrtype.patch.help 2003-04-09 14:19:04.000000000 +0200
@@ -0,0 +1,28 @@
+Author: Patrick McHardy <kaber@trash.net>
+Status: Working
+
+This match allows you to match address types as seen by the routing code.
+Valid types (from include/linux/rtnetlink.h) are:
+
+UNSPEC
+UNICAST
+LOCAL
+BROADCAST
+ANYCAST
+MULTICAST
+BLACKHOLE
+UNREACHABLE
+PROHIBIT
+THROW
+NAT
+XRESOLVE
+
+Usage:
+ -m addrtype --source type[,type..] --dest type[,type..]
+
+Example:
+
+ iptables ... -m addrtype --source LOCAL ...
+ iptables ... -m addrtype --dest ANYCAST ...
+
+
diff -urN a/patch-o-matic/extra/addrtype.patch.makefile b/patch-o-matic/extra/addrtype.patch.makefile
--- a/patch-o-matic/extra/addrtype.patch.makefile 1970-01-01 01:00:00.000000000 +0100
+++ b/patch-o-matic/extra/addrtype.patch.makefile 2003-04-09 14:19:04.000000000 +0200
@@ -0,0 +1,2 @@
+obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
+obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
diff -urN a/userspace/extensions/.addrtype-test b/userspace/extensions/.addrtype-test
--- a/userspace/extensions/.addrtype-test 1970-01-01 01:00:00.000000000 +0100
+++ b/userspace/extensions/.addrtype-test 2003-04-09 14:19:04.000000000 +0200
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+if test -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_addrtype.h; then
+ echo "addrtype"
+fi
diff -urN a/userspace/extensions/libipt_addrtype.c b/userspace/extensions/libipt_addrtype.c
--- a/userspace/extensions/libipt_addrtype.c 1970-01-01 01:00:00.000000000 +0100
+++ b/userspace/extensions/libipt_addrtype.c 2003-04-09 14:22:05.000000000 +0200
@@ -0,0 +1,216 @@
+/* Shared library add-on to iptables to add addrtype 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>
+
+/* from linux/rtnetlink.h, must match order of enumeration */
+static char *rtn_names[] = {
+ "UNSPEC",
+ "UNICAST",
+ "LOCAL",
+ "BROADCAST",
+ "ANYCAST",
+ "MULTICAST",
+ "BLACKHOLE",
+ "UNREACHABLE",
+ "PROHIBIT",
+ "THROW",
+ "NAT",
+ "XRESOLVE",
+ NULL
+};
+
+static void help_types(void)
+{
+ int i;
+
+ for (i = 0; rtn_names[i]; i++)
+ printf(" %s\n", rtn_names[i]);
+}
+
+static void help(void)
+{
+ printf(
+"Address type match v%s options:\n"
+" [!] --source type[,...]\n"
+" Match source address type\n"
+" [!] --dest type[,...]\n"
+" Match destination address type\n"
+"\n"
+"Valid types: \n"
+, IPTABLES_VERSION);
+ help_types();
+}
+
+static void init(struct ipt_entry_match *m, unsigned int *nfcache)
+{
+ /* caching not yet implemented */
+ *nfcache |= NFC_UNKNOWN;
+}
+
+static int
+parse_type(const char *name, size_t strlen, u_int16_t *mask)
+{
+ int i;
+
+ for (i = 0; rtn_names[i]; i++)
+ if (strncasecmp(name, rtn_names[i], strlen) == 0) {
+ /* build up bitmask for kernel module */
+ *mask |= (1 << i);
+ return 1;
+ }
+
+ return 0;
+}
+
+static void parse_types(const char *arg, u_int16_t *mask)
+{
+ const char *comma;
+
+ while ((comma = strchr(arg, ',')) != NULL) {
+ if (comma == arg || !parse_type(arg, comma-arg, mask))
+ exit_error(PARAMETER_PROBLEM,
+ "addrtype: bad type `%s'", arg);
+ arg = comma + 1;
+ }
+
+ if (strlen(arg) == 0 || !parse_type(arg, strlen(arg), mask))
+ exit_error(PARAMETER_PROBLEM, "addrtype: bad type `%s'", arg);
+}
+
+#define IPT_ADDRTYPE_OPT_SOURCE 0x1
+#define IPT_ADDRTYPE_OPT_DEST 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_SOURCE)
+ exit_error(PARAMETER_PROBLEM,
+ "addrtype: can't specify source twice");
+ check_inverse(optarg, &invert, &optind, 0);
+ parse_types(argv[optind-1], &info->source);
+ if (invert)
+ info->invert_source = 1;
+ *flags |= IPT_ADDRTYPE_OPT_SOURCE;
+ break;
+ case '2':
+ if (*flags&IPT_ADDRTYPE_OPT_DEST)
+ exit_error(PARAMETER_PROBLEM,
+ "addrtype: can't specify dest twice");
+ check_inverse(optarg, &invert, &optind, 0);
+ parse_types(argv[optind-1], &info->dest);
+ if (invert)
+ info->invert_dest = 1;
+ *flags |= IPT_ADDRTYPE_OPT_DEST;
+ break;
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+static void final_check(unsigned int flags)
+{
+ if (!(flags & (IPT_ADDRTYPE_OPT_SOURCE|IPT_ADDRTYPE_OPT_DEST)))
+ exit_error(PARAMETER_PROBLEM,
+ "addrtype: you must specify --source or --dest");
+}
+
+static void print_types(u_int16_t mask)
+{
+ const char *sep = "";
+ int i;
+
+ for (i = 0; rtn_names[i]; i++)
+ if (mask & (1 << i)) {
+ printf("%s%s", sep, rtn_names[i]);
+ 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 ");
+ if (info->source) {
+ printf("source ");
+ if (info->invert_source)
+ printf("!");
+ print_types(info->source);
+ }
+ if (info->dest) {
+ printf("dest ");
+ if (info->invert_dest)
+ printf("!");
+ print_types(info->dest);
+ }
+}
+
+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;
+
+ if (info->source) {
+ printf("--source ");
+ if (info->invert_source)
+ printf("! ");
+ print_types(info->source);
+ }
+ if (info->dest) {
+ printf("--dest ");
+ if (info->invert_dest)
+ printf("! ");
+ print_types(info->dest);
+ }
+}
+
+static struct option opts[] = {
+ { "source", 1, 0, '1' },
+ { "dest", 1, 0, '2' },
+ { 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);
+}
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH] addrtype match
2003-04-09 12:50 ` Patrick McHardy
@ 2003-04-09 13:28 ` Patrick McHardy
2003-04-11 10:01 ` Jozsef Kadlecsik
0 siblings, 1 reply; 10+ messages in thread
From: Patrick McHardy @ 2003-04-09 13:28 UTC (permalink / raw)
To: Martin Josefsson; +Cc: Netfilter Development Mailinglist
[-- Attachment #1: Type: text/plain, Size: 444 bytes --]
Once again a new patch, it seems it wasn't very clever to name the options
--source and --dest, iptables ate the --source option before it was passed
to the match. they are now renamed to --stype and --dtype.
Bye
Patrick
Patrick McHardy wrote:
> Hi Martin,
> this is an updated version of the addrtype match, matching is now
> done with a bitmask of types built in userspace. Code is a lot smaller
> and nicer ;)
>
> Bye,
> Patrick
>
>
>
[-- Attachment #2: nf-CLASSIFY.diff --]
[-- Type: text/plain, Size: 8053 bytes --]
diff -urN a/patch-o-matic/extra/CLASSIFY.patch b/patch-o-matic/extra/CLASSIFY.patch
--- a/patch-o-matic/extra/CLASSIFY.patch 1970-01-01 01:00:00.000000000 +0100
+++ b/patch-o-matic/extra/CLASSIFY.patch 2003-04-09 03:04:18.000000000 +0200
@@ -0,0 +1,89 @@
+diff -urN a/include/linux/netfilter_ipv4/ipt_CLASSIFY.h b/include/linux/netfilter_ipv4/ipt_CLASSIFY.h
+--- a/include/linux/netfilter_ipv4/ipt_CLASSIFY.h 1970-01-01 01:00:00.000000000 +0100
++++ b/include/linux/netfilter_ipv4/ipt_CLASSIFY.h 2003-04-09 02:50:19.000000000 +0200
+@@ -0,0 +1,8 @@
++#ifndef _IPT_CLASSIFY_H
++#define _IPT_CLASSIFY_H
++
++struct ipt_classify_target_info {
++ unsigned int priority;
++};
++
++#endif /*_IPT_CLASSIFY_H */
+diff -urN a/net/ipv4/netfilter/ipt_CLASSIFY.c b/net/ipv4/netfilter/ipt_CLASSIFY.c
+--- a/net/ipv4/netfilter/ipt_CLASSIFY.c 1970-01-01 01:00:00.000000000 +0100
++++ b/net/ipv4/netfilter/ipt_CLASSIFY.c 2003-04-09 02:58:08.000000000 +0200
+@@ -0,0 +1,73 @@
++/* This is a module which is used for setting the skb->priority field of an skb for qdisc classification. */
++#include <linux/module.h>
++#include <linux/skbuff.h>
++#include <linux/ip.h>
++#include <net/checksum.h>
++
++#include <linux/netfilter_ipv4/ip_tables.h>
++#include <linux/netfilter_ipv4/ipt_CLASSIFY.h>
++
++static unsigned int
++target(struct sk_buff **pskb,
++ unsigned int hooknum,
++ const struct net_device *in,
++ const struct net_device *out,
++ const void *targinfo,
++ void *userinfo)
++{
++ const struct ipt_classify_target_info *clinfo = targinfo;
++
++ if((*pskb)->priority != clinfo->priority) {
++ (*pskb)->priority = clinfo->priority;
++ (*pskb)->nfcache |= NFC_ALTERED;
++ }
++
++ return IPT_CONTINUE;
++}
++
++static int
++checkentry(const char *tablename,
++ const struct ipt_entry *e,
++ void *targinfo,
++ unsigned int targinfosize,
++ unsigned int hook_mask)
++{
++ if (targinfosize != IPT_ALIGN(sizeof(struct ipt_classify_target_info))){
++ printk(KERN_ERR "CLASSIFY: invalid size (%u != %u).\n",
++ targinfosize,
++ IPT_ALIGN(sizeof(struct ipt_classify_target_info)));
++ return 0;
++ }
++
++ if (hook_mask & ~(1 << NF_IP_POST_ROUTING)) {
++ printk(KERN_ERR "CLASSIFY: only valid in POST_ROUTING.\n");
++ return 0;
++ }
++
++ if (strcmp(tablename, "mangle") != 0) {
++ printk(KERN_WARNING "CLASSIFY: can only be called from \"mangle\" table, not \"%s\".\n", tablename);
++ return 0;
++ }
++
++ return 1;
++}
++
++static struct ipt_target ipt_classify_reg
++= { { NULL, NULL }, "CLASSIFY", target, checkentry, NULL, THIS_MODULE };
++
++static int __init init(void)
++{
++ if (ipt_register_target(&ipt_classify_reg))
++ return -EINVAL;
++
++ return 0;
++}
++
++static void __exit fini(void)
++{
++ ipt_unregister_target(&ipt_classify_reg);
++}
++
++module_init(init);
++module_exit(fini);
++MODULE_LICENSE("GPL");
diff -urN a/patch-o-matic/extra/CLASSIFY.patch.config.in b/patch-o-matic/extra/CLASSIFY.patch.config.in
--- a/patch-o-matic/extra/CLASSIFY.patch.config.in 1970-01-01 01:00:00.000000000 +0100
+++ b/patch-o-matic/extra/CLASSIFY.patch.config.in 2003-04-09 02:47:07.000000000 +0200
@@ -0,0 +1,2 @@
+ dep_tristate ' MARK target support' CONFIG_IP_NF_TARGET_MARK $CONFIG_IP_NF_MANGLE
+ dep_tristate ' CLASSIFY target support (EXPERIMENTAL)' CONFIG_IP_NF_TARGET_CLASSIFY $CONFIG_IP_NF_FILTER
diff -urN a/patch-o-matic/extra/CLASSIFY.patch.help b/patch-o-matic/extra/CLASSIFY.patch.help
--- a/patch-o-matic/extra/CLASSIFY.patch.help 1970-01-01 01:00:00.000000000 +0100
+++ b/patch-o-matic/extra/CLASSIFY.patch.help 2003-04-09 03:05:05.000000000 +0200
@@ -0,0 +1,18 @@
+Author: Patrick McHardy <kaber@trash.net>
+Status: working
+
+This patch adds support for the CLASSIFY target which sets skb->priority.
+Some qdiscs can use this value for classification, among these are
+
+- atm
+- cbq
+- dsmark
+- pfifo_fast
+- htb
+- prio
+
+This target is only valid in the POST_ROUTING chain of the mangle table.
+
+Usage:
+ iptables -t mangle -A POSTROUTING .. -j CLASSIFY --set-class MAJOR:MINOR
+
diff -urN a/patch-o-matic/extra/CLASSIFY.patch.makefile b/patch-o-matic/extra/CLASSIFY.patch.makefile
--- a/patch-o-matic/extra/CLASSIFY.patch.makefile 1970-01-01 01:00:00.000000000 +0100
+++ b/patch-o-matic/extra/CLASSIFY.patch.makefile 2003-04-09 02:47:07.000000000 +0200
@@ -0,0 +1,2 @@
+obj-$(CONFIG_IP_NF_TARGET_MIRROR) += ipt_MIRROR.o
+obj-$(CONFIG_IP_NF_TARGET_CLASSIFY) += ipt_CLASSIFY.o
diff -urN a/userspace/extensions/.CLASSIFY-test b/userspace/extensions/.CLASSIFY-test
--- a/userspace/extensions/.CLASSIFY-test 1970-01-01 01:00:00.000000000 +0100
+++ b/userspace/extensions/.CLASSIFY-test 2003-04-09 02:47:07.000000000 +0200
@@ -0,0 +1,3 @@
+#! /bin/sh
+[ -f $KERNEL_DIR/net/ipv4/netfilter/ipt_CLASSIFY.c ] && echo CLASSIFY
+
diff -urN a/userspace/extensions/libipt_CLASSIFY.c b/userspace/extensions/libipt_CLASSIFY.c
--- a/userspace/extensions/libipt_CLASSIFY.c 1970-01-01 01:00:00.000000000 +0100
+++ b/userspace/extensions/libipt_CLASSIFY.c 2003-04-09 02:47:07.000000000 +0200
@@ -0,0 +1,130 @@
+/* Shared library add-on to iptables to add CLASSIFY target support. */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#include <iptables.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_CLASSIFY.h>
+#include <linux/types.h>
+#include <linux/pkt_sched.h>
+
+/* Function which prints out usage message. */
+static void
+help(void)
+{
+ printf(
+"CLASSIFY target v%s options:\n"
+" --set-class [MAJOR:MINOR] Set skb->priority value\n"
+"\n",
+IPTABLES_VERSION);
+}
+
+static struct option opts[] = {
+ { "set-class", 1, 0, '1' },
+ { 0 }
+};
+
+/* Initialize the target. */
+static void
+init(struct ipt_entry_target *t, unsigned int *nfcache)
+{
+}
+
+int string_to_priority(const unsigned char *s, unsigned int *p)
+{
+ unsigned int i, j;
+
+ if (sscanf(s, "%x:%x", &i, &j) != 2)
+ return 1;
+
+ *p = TC_H_MAKE(i<<16, j);
+ return 0;
+}
+
+/* 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)
+{
+ struct ipt_classify_target_info *clinfo
+ = (struct ipt_classify_target_info *)(*target)->data;
+
+ switch (c) {
+ case '1':
+ if (string_to_priority(optarg, &clinfo->priority))
+ exit_error(PARAMETER_PROBLEM,
+ "Bad class value `%s'", optarg);
+ if (*flags)
+ exit_error(PARAMETER_PROBLEM,
+ "CLASSIFY: Can't specify --set-class twice");
+ *flags = 1;
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+static void
+final_check(unsigned int flags)
+{
+ if (!flags)
+ exit_error(PARAMETER_PROBLEM,
+ "CLASSIFY: Parameter --set-class is required");
+}
+
+static void
+print_class(unsigned int priority, int numeric)
+{
+ printf("%x:%x ", TC_H_MAJ(priority)>>16, TC_H_MIN(priority));
+}
+
+/* Prints out the targinfo. */
+static void
+print(const struct ipt_ip *ip,
+ const struct ipt_entry_target *target,
+ int numeric)
+{
+ const struct ipt_classify_target_info *clinfo =
+ (const struct ipt_classify_target_info *)target->data;
+ printf("CLASSIFY set ");
+ print_class(clinfo->priority, numeric);
+}
+
+/* Saves the union ipt_targinfo in parsable form to stdout. */
+static void
+save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
+{
+ const struct ipt_classify_target_info *clinfo =
+ (const struct ipt_classify_target_info *)target->data;
+
+ printf("--set-class %.4x:%.4x ",
+ TC_H_MAJ(clinfo->priority)>>16, TC_H_MIN(clinfo->priority));
+}
+
+static
+struct iptables_target classify
+= { NULL,
+ "CLASSIFY",
+ IPTABLES_VERSION,
+ IPT_ALIGN(sizeof(struct ipt_classify_target_info)),
+ IPT_ALIGN(sizeof(struct ipt_classify_target_info)),
+ &help,
+ &init,
+ &parse,
+ &final_check,
+ &print,
+ &save,
+ opts
+};
+
+void _init(void)
+{
+ register_target(&classify);
+}
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH] addrtype match
2003-04-09 13:28 ` Patrick McHardy
@ 2003-04-11 10:01 ` Jozsef Kadlecsik
2003-04-11 14:27 ` Patrick McHardy
0 siblings, 1 reply; 10+ messages in thread
From: Jozsef Kadlecsik @ 2003-04-11 10:01 UTC (permalink / raw)
To: Patrick McHardy; +Cc: Martin Josefsson, Netfilter Development Mailinglist
On Wed, 9 Apr 2003, Patrick McHardy wrote:
> Once again a new patch, it seems it wasn't very clever to name the options
> --source and --dest, iptables ate the --source option before it was passed
> to the match. they are now renamed to --stype and --dtype.
You attached the CLASSIFY target patch instead of the corrected addrtype
patch :-)
Before sending the real patch, please add an addrtype.configure.help.
That was missing from the previous versions.
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] 10+ messages in thread* Re: [PATCH] addrtype match
2003-04-11 10:01 ` Jozsef Kadlecsik
@ 2003-04-11 14:27 ` Patrick McHardy
0 siblings, 0 replies; 10+ messages in thread
From: Patrick McHardy @ 2003-04-11 14:27 UTC (permalink / raw)
To: Jozsef Kadlecsik; +Cc: Martin Josefsson, Netfilter Development Mailinglist
[-- Attachment #1: Type: text/plain, Size: 302 bytes --]
Hi Jozsef,
thanks for applying all the other patches. Here is the addrtype match
again, with configure.help.
Thanks,
Patrick
Jozsef Kadlecsik wrote:
>Before sending the real patch, please add an addrtype.configure.help.
>That was missing from the previous versions.
>
>Best regards,
>Jozsef
>
>
>
[-- Attachment #2: nf-addrtype.diff --]
[-- Type: text/plain, Size: 10271 bytes --]
diff -urN a/patch-o-matic/extra/addrtype.patch b/patch-o-matic/extra/addrtype.patch
--- a/patch-o-matic/extra/addrtype.patch 1970-01-01 01:00:00.000000000 +0100
+++ b/patch-o-matic/extra/addrtype.patch 2003-04-11 15:59:00.000000000 +0200
@@ -0,0 +1,84 @@
+diff -urN a/include/linux/netfilter_ipv4/ipt_addrtype.h b/include/linux/netfilter_ipv4/ipt_addrtype.h
+--- a/include/linux/netfilter_ipv4/ipt_addrtype.h 1970-01-01 01:00:00.000000000 +0100
++++ b/include/linux/netfilter_ipv4/ipt_addrtype.h 2003-04-09 13:42:03.000000000 +0200
+@@ -0,0 +1,11 @@
++#ifndef _IPT_ADDRTYPE_H
++#define _IPT_ADDRTYPE_H
++
++struct ipt_addrtype_info {
++ u_int16_t source; /* source-type mask */
++ u_int16_t dest; /* dest-type mask */
++ int invert_source;
++ int invert_dest;
++};
++
++#endif
+diff -urN a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c
+--- a/net/ipv4/netfilter/ipt_addrtype.c 1970-01-01 01:00:00.000000000 +0100
++++ b/net/ipv4/netfilter/ipt_addrtype.c 2003-04-09 13:43:50.000000000 +0200
+@@ -0,0 +1,65 @@
++/*
++ * iptables module to match inet_addr_type() of an ip.
++ */
++
++#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 inline int match_type(u_int32_t addr, u_int16_t mask)
++{
++ return !!(mask & (1 << inet_addr_type(addr)));
++}
++
++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;
++ int ret = 1;
++
++ if (info->source)
++ ret &= match_type(iph->saddr, info->source)^info->invert_source;
++ if (info->dest)
++ ret &= match_type(iph->daddr, info->dest)^info->invert_dest;
++
++ return ret;
++}
++
++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))) {
++ printk(KERN_ERR "ipt_addrtype: invalid size (%u != %u)\n.",
++ 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 a/patch-o-matic/extra/addrtype.patch.config.in b/patch-o-matic/extra/addrtype.patch.config.in
--- a/patch-o-matic/extra/addrtype.patch.config.in 1970-01-01 01:00:00.000000000 +0100
+++ b/patch-o-matic/extra/addrtype.patch.config.in 2003-04-11 15:59:00.000000000 +0200
@@ -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 a/patch-o-matic/extra/addrtype.patch.configure.help b/patch-o-matic/extra/addrtype.patch.configure.help
--- a/patch-o-matic/extra/addrtype.patch.configure.help 1970-01-01 01:00:00.000000000 +0100
+++ b/patch-o-matic/extra/addrtype.patch.configure.help 2003-04-11 16:17:02.000000000 +0200
@@ -0,0 +1,8 @@
+CONFIG_IP_NF_MATCH_LIMIT
+addrtype match support
+CONFIG_IP_NF_MATCH_ADDRTYPE
+ This option allows you to match what routing thinks of an address,
+ eg. UNICAST, LOCAL, BROADCAST, ...
+
+ If you want to compile it as a module, say M here and read
+ Documentation/modules.txt. If unsure, say `N'.
diff -urN a/patch-o-matic/extra/addrtype.patch.help b/patch-o-matic/extra/addrtype.patch.help
--- a/patch-o-matic/extra/addrtype.patch.help 1970-01-01 01:00:00.000000000 +0100
+++ b/patch-o-matic/extra/addrtype.patch.help 2003-04-11 15:59:00.000000000 +0200
@@ -0,0 +1,28 @@
+Author: Patrick McHardy <kaber@trash.net>
+Status: Working
+
+This match allows you to match address types as seen by the routing code.
+Valid types (from include/linux/rtnetlink.h) are:
+
+UNSPEC
+UNICAST
+LOCAL
+BROADCAST
+ANYCAST
+MULTICAST
+BLACKHOLE
+UNREACHABLE
+PROHIBIT
+THROW
+NAT
+XRESOLVE
+
+Usage:
+ -m addrtype --stype type[,type..] --dtype type[,type..]
+
+Example:
+
+ iptables ... -m addrtype --stype LOCAL ...
+ iptables ... -m addrtype --dtype ANYCAST ...
+
+
diff -urN a/patch-o-matic/extra/addrtype.patch.makefile b/patch-o-matic/extra/addrtype.patch.makefile
--- a/patch-o-matic/extra/addrtype.patch.makefile 1970-01-01 01:00:00.000000000 +0100
+++ b/patch-o-matic/extra/addrtype.patch.makefile 2003-04-11 15:59:00.000000000 +0200
@@ -0,0 +1,2 @@
+obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
+obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
diff -urN a/userspace/extensions/.addrtype-test b/userspace/extensions/.addrtype-test
--- a/userspace/extensions/.addrtype-test 1970-01-01 01:00:00.000000000 +0100
+++ b/userspace/extensions/.addrtype-test 2003-04-11 15:59:00.000000000 +0200
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+if test -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_addrtype.h; then
+ echo "addrtype"
+fi
diff -urN a/userspace/extensions/libipt_addrtype.c b/userspace/extensions/libipt_addrtype.c
--- a/userspace/extensions/libipt_addrtype.c 1970-01-01 01:00:00.000000000 +0100
+++ b/userspace/extensions/libipt_addrtype.c 2003-04-11 16:12:36.000000000 +0200
@@ -0,0 +1,214 @@
+/* Shared library add-on to iptables to add addrtype 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>
+
+/* from linux/rtnetlink.h, must match order of enumeration */
+static char *rtn_names[] = {
+ "UNSPEC",
+ "UNICAST",
+ "LOCAL",
+ "BROADCAST",
+ "ANYCAST",
+ "MULTICAST",
+ "BLACKHOLE",
+ "UNREACHABLE",
+ "PROHIBIT",
+ "THROW",
+ "NAT",
+ "XRESOLVE",
+ NULL
+};
+
+static void help_types(void)
+{
+ int i;
+
+ for (i = 0; rtn_names[i]; i++)
+ printf(" %s\n", rtn_names[i]);
+}
+
+static void help(void)
+{
+ printf(
+"Address type match v%s options:\n"
+" [!] --stype type[,...] Match source address type\n"
+" [!] --dtype type[,...] Match destination address type\n"
+"\n"
+"Valid types: \n"
+, IPTABLES_VERSION);
+ help_types();
+}
+
+static void init(struct ipt_entry_match *m, unsigned int *nfcache)
+{
+ /* caching not yet implemented */
+ *nfcache |= NFC_UNKNOWN;
+}
+
+static int
+parse_type(const char *name, size_t strlen, u_int16_t *mask)
+{
+ int i;
+
+ for (i = 0; rtn_names[i]; i++)
+ if (strncasecmp(name, rtn_names[i], strlen) == 0) {
+ /* build up bitmask for kernel module */
+ *mask |= (1 << i);
+ return 1;
+ }
+
+ return 0;
+}
+
+static void parse_types(const char *arg, u_int16_t *mask)
+{
+ const char *comma;
+
+ while ((comma = strchr(arg, ',')) != NULL) {
+ if (comma == arg || !parse_type(arg, comma-arg, mask))
+ exit_error(PARAMETER_PROBLEM,
+ "addrtype: bad type `%s'", arg);
+ arg = comma + 1;
+ }
+
+ if (strlen(arg) == 0 || !parse_type(arg, strlen(arg), mask))
+ exit_error(PARAMETER_PROBLEM, "addrtype: bad type `%s'", arg);
+}
+
+#define IPT_ADDRTYPE_OPT_STYPE 0x1
+#define IPT_ADDRTYPE_OPT_DTYPE 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_STYPE)
+ exit_error(PARAMETER_PROBLEM,
+ "addrtype: can't specify stype twice");
+ check_inverse(optarg, &invert, &optind, 0);
+ parse_types(argv[optind-1], &info->source);
+ if (invert)
+ info->invert_source = 1;
+ *flags |= IPT_ADDRTYPE_OPT_STYPE;
+ break;
+ case '2':
+ if (*flags&IPT_ADDRTYPE_OPT_DTYPE)
+ exit_error(PARAMETER_PROBLEM,
+ "addrtype: can't specify dtype twice");
+ check_inverse(optarg, &invert, &optind, 0);
+ parse_types(argv[optind-1], &info->dest);
+ if (invert)
+ info->invert_dest = 1;
+ *flags |= IPT_ADDRTYPE_OPT_DTYPE;
+ break;
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+static void final_check(unsigned int flags)
+{
+ if (!(flags & (IPT_ADDRTYPE_OPT_STYPE|IPT_ADDRTYPE_OPT_DTYPE)))
+ exit_error(PARAMETER_PROBLEM,
+ "addrtype: you must specify --stype or --dtype");
+}
+
+static void print_types(u_int16_t mask)
+{
+ const char *sep = "";
+ int i;
+
+ for (i = 0; rtn_names[i]; i++)
+ if (mask & (1 << i)) {
+ printf("%s%s", sep, rtn_names[i]);
+ 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 ");
+ if (info->source) {
+ printf("stype ");
+ if (info->invert_source)
+ printf("!");
+ print_types(info->source);
+ }
+ if (info->dest) {
+ printf("dtype ");
+ if (info->invert_dest)
+ printf("!");
+ print_types(info->dest);
+ }
+}
+
+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;
+
+ if (info->source) {
+ printf("--stype ");
+ if (info->invert_source)
+ printf("! ");
+ print_types(info->source);
+ }
+ if (info->dest) {
+ printf("--dtype ");
+ if (info->invert_dest)
+ printf("! ");
+ print_types(info->dest);
+ }
+}
+
+static struct option opts[] = {
+ { "stype", 1, 0, '1' },
+ { "dtype", 1, 0, '2' },
+ { 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);
+}
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2003-04-11 14:27 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-04-08 16:02 [PATCH] addrtype match Patrick McHardy
2003-04-08 20:31 ` Martin Josefsson
2003-04-08 23:28 ` Patrick McHardy
2003-04-09 1:37 ` Patrick McHardy
2003-04-09 11:21 ` Martin Josefsson
2003-04-09 11:29 ` Patrick McHardy
2003-04-09 12:50 ` Patrick McHardy
2003-04-09 13:28 ` Patrick McHardy
2003-04-11 10:01 ` Jozsef Kadlecsik
2003-04-11 14:27 ` 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.