* [PATCH] Named realm - updated
@ 2006-06-04 19:35 Simon Lodal
2006-06-19 15:50 ` Patrick McHardy
0 siblings, 1 reply; 5+ messages in thread
From: Simon Lodal @ 2006-06-04 19:35 UTC (permalink / raw)
To: Netfilter Developer
[-- Attachment #1: Type: text/plain, Size: 265 bytes --]
Make the realm match accept named realms, defined in /etc/iproute2/rt_realms.
First sent 2006-05-21, improved since then:
- Only load rt_realms once, keep in memory.
- Output realm by name if it was originally specified that way, except if
iptables -n.
Simon
[-- Attachment #2: realm_named_linux.diff --]
[-- Type: text/x-diff, Size: 374 bytes --]
Index: linux-2.6/include/linux/netfilter/xt_realm.h
===================================================================
--- linux-2.6/include/linux/netfilter/xt_realm.h (revision 44)
+++ linux-2.6/include/linux/netfilter/xt_realm.h (revision 45)
@@ -5,6 +5,7 @@
u_int32_t id;
u_int32_t mask;
u_int8_t invert;
+ u_int8_t is_named_realm;
};
#endif /* _XT_REALM_H */
[-- Attachment #3: realm_named_iptables.diff --]
[-- Type: text/x-diff, Size: 5577 bytes --]
diff -ruN iptables-1.3.5.base/extensions/libipt_realm.c iptables-1.3.5/extensions/libipt_realm.c
--- iptables-1.3.5.base/extensions/libipt_realm.c 2006-06-04 01:49:33.000000000 +0200
+++ iptables-1.3.5/extensions/libipt_realm.c 2006-06-04 01:50:06.000000000 +0200
@@ -3,6 +3,8 @@
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
+#include <errno.h>
+#include <ctype.h>
#include <getopt.h>
#if defined(__GLIBC__) && __GLIBC__ == 2
#include <net/ethernet.h>
@@ -28,6 +30,116 @@
{0}
};
+struct realmname {
+ int id;
+ char* name;
+ int len;
+ struct realmname* next;
+};
+
+/* array of realms from /etc/iproute2/rt_realms */
+static struct realmname *realms = NULL;
+/* 1 if loading failed */
+static int rdberr = 0;
+
+
+void load_realms()
+{
+ const char* rfnm = "/etc/iproute2/rt_realms";
+ char buf[512];
+ FILE *fil;
+ char *cur, *nxt;
+ int id;
+ struct realmname *oldnm = NULL, *newnm = NULL;
+
+ fil = fopen(rfnm, "r");
+ if (!fil) {
+ rdberr = 1;
+ return;
+ }
+
+ while (fgets(buf, sizeof(buf), fil)) {
+ cur = buf;
+ while ((*cur == ' ') || (*cur == '\t')) cur++;
+ if ((*cur == '#') || (*cur == '\n') || (*cur == 0))
+ continue;
+
+ /* iproute2 allows hex and dec format */
+ errno = 0;
+ id = strtoul(cur, &nxt, strncmp(cur, "0x", 2) ? 10 : 16);
+ if ((nxt == cur) || errno) {
+ continue;
+ }
+
+ /* same boundaries as in iproute2 */
+ if (id < 0 || id > 256) continue;
+ cur = nxt;
+
+ if (!isspace(*cur)) continue;
+ while ((*cur == ' ') || (*cur == '\t')) cur++;
+ if ((*cur == '#') || (*cur == '\n') || (*cur == 0))
+ continue;
+ nxt = cur;
+ while ((*nxt != 0) && !isspace(*nxt)) nxt++;
+ if (nxt == cur) continue;
+
+ /* found valid data */
+ newnm = (struct realmname*)malloc(sizeof(struct realmname));
+ if (NULL == newnm) {
+ perror("libipt_realm: malloc failed");
+ exit(1);
+ }
+ newnm->id = id;
+ newnm->len = nxt - cur;
+ newnm->name = (char*)malloc(newnm->len + 1);
+ if (NULL == newnm->name) {
+ perror("libipt_realm: malloc failed");
+ exit(1);
+ }
+ strncpy(newnm->name, cur, newnm->len);
+ newnm->name[newnm->len] = 0;
+ newnm->next = NULL;
+
+ if (oldnm) {
+ oldnm->next = newnm;
+ } else {
+ realms = newnm;
+ }
+ oldnm = newnm;
+ }
+
+ fclose(fil);
+}
+
+/* get realm id for name, -1 if error/not found */
+int realm_name2id(const char* name)
+{
+ if ((NULL == realms) && (0 == rdberr)) load_realms();
+ if (NULL == realms) return -1;
+
+ struct realmname* cur = realms;
+ while (cur) {
+ if (!strncmp(name, cur->name, cur->len + 1)) return cur->id;
+ cur = cur->next;
+ }
+ return -1;
+}
+
+/* get realm name for id, NULL if error/not found */
+const char* realm_id2name(int id)
+{
+ if ((NULL == realms) && (0 == rdberr)) load_realms();
+ if (NULL == realms) return NULL;
+
+ struct realmname* cur = realms;
+ while (cur) {
+ if (id == cur->id) return cur->name;
+ cur = cur->next;
+ }
+ return NULL;
+}
+
+
/* Function which parses command options; returns true if it
ate an option */
static int
@@ -42,14 +154,26 @@
char *end;
case '1':
check_inverse(argv[optind-1], &invert, &optind, 0);
- optarg = argv[optind-1];
+ end = optarg = argv[optind-1];
realminfo->id = strtoul(optarg, &end, 0);
- if (*end == '/') {
- realminfo->mask = strtoul(end+1, &end, 0);
- } else
+ if ((end != optarg) && (('/' == *end) || ('\0' == *end))) {
+ if (*end == '/') {
+ realminfo->mask = strtoul(end+1, &end, 0);
+ } else
+ realminfo->mask = 0xffffffff;
+ if (*end != '\0' || end == optarg)
+ exit_error(PARAMETER_PROBLEM,
+ "Bad realm value `%s'", optarg);
+ } else {
+ int id = realm_name2id(optarg);
+ if (-1 == id) {
+ exit_error(PARAMETER_PROBLEM,
+ "Realm `%s' not found", optarg);
+ }
+ realminfo->id = (u_int32_t)id;
realminfo->mask = 0xffffffff;
- if (*end != '\0' || end == optarg)
- exit_error(PARAMETER_PROBLEM, "Bad realm value `%s'", optarg);
+ realminfo->is_named_realm = 1;
+ }
if (invert)
realminfo->invert = 1;
*flags = 1;
@@ -62,12 +186,22 @@
}
static void
-print_realm(unsigned long id, unsigned long mask)
+print_realm(unsigned long id, unsigned long mask, int is_named)
{
+ const char* name = NULL;
+
if (mask != 0xffffffff)
printf("0x%lx/0x%lx ", id, mask);
- else
- printf("0x%lx ", id);
+ else {
+ if (1 == is_named) {
+ name = realm_id2name(id);
+ }
+ if (name) {
+ printf("%s ", name);
+ } else {
+ printf("0x%lx ", id);
+ }
+ }
}
/* Prints out the matchinfo. */
@@ -82,7 +216,7 @@
printf("! ");
printf("realm ");
- print_realm(ri->id, ri->mask);
+ print_realm(ri->id, ri->mask, numeric ? 0 : ri->is_named_realm);
}
@@ -96,7 +230,7 @@
printf("! ");
printf("--realm ");
- print_realm(ri->id, ri->mask);
+ print_realm(ri->id, ri->mask, ri->is_named_realm);
}
/* Final check; must have specified --mark. */
diff -ruN iptables-1.3.5.base/extensions/libipt_realm.man iptables-1.3.5/extensions/libipt_realm.man
--- iptables-1.3.5.base/extensions/libipt_realm.man 2004-10-10 11:56:27.000000000 +0200
+++ iptables-1.3.5/extensions/libipt_realm.man 2006-06-04 01:50:15.000000000 +0200
@@ -1,5 +1,7 @@
This matches the routing realm. Routing realms are used in complex routing
setups involving dynamic routing protocols like BGP.
.TP
-.BI "--realm " "[!]" "value[/mask]"
-Matches a given realm number (and optionally mask).
+.BI "--realm " "[!] " "value[/mask]"
+Matches a given realm number (and optionally mask). If not a number, value
+can be a named realm from /etc/iproute2/rt_realms (mask can not be used in
+that case).
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] Named realm - updated
2006-06-04 19:35 [PATCH] Named realm - updated Simon Lodal
@ 2006-06-19 15:50 ` Patrick McHardy
2006-09-01 23:27 ` Simon Lodal
0 siblings, 1 reply; 5+ messages in thread
From: Patrick McHardy @ 2006-06-19 15:50 UTC (permalink / raw)
To: Simon Lodal; +Cc: Netfilter Developer
Simon Lodal wrote:
> Make the realm match accept named realms, defined in /etc/iproute2/rt_realms.
>
> First sent 2006-05-21, improved since then:
> - Only load rt_realms once, keep in memory.
> - Output realm by name if it was originally specified that way, except if
> iptables -n.
Thanks. I still have a few points before we can merge this, please
see below.
> ------------------------------------------------------------------------
>
> Index: linux-2.6/include/linux/netfilter/xt_realm.h
> ===================================================================
> --- linux-2.6/include/linux/netfilter/xt_realm.h (revision 44)
> +++ linux-2.6/include/linux/netfilter/xt_realm.h (revision 45)
> @@ -5,6 +5,7 @@
> u_int32_t id;
> u_int32_t mask;
> u_int8_t invert;
> + u_int8_t is_named_realm;
No no no :) This breaks compatibility (well, it does not due to
structure padding, but still, structures shared between kernel and
userspace should be considered untouchable). Names are to be shown
when numeric == 0, otherwise not. It doesn't matter in which format
the user specified the rule.
> };
>
> #endif /* _XT_REALM_H */
>
>
> ------------------------------------------------------------------------
>
> diff -ruN iptables-1.3.5.base/extensions/libipt_realm.c iptables-1.3.5/extensions/libipt_realm.c
> --- iptables-1.3.5.base/extensions/libipt_realm.c 2006-06-04 01:49:33.000000000 +0200
> +++ iptables-1.3.5/extensions/libipt_realm.c 2006-06-04 01:50:06.000000000 +0200
> @@ -3,6 +3,8 @@
> #include <netdb.h>
> #include <string.h>
> #include <stdlib.h>
> +#include <errno.h>
> +#include <ctype.h>
> #include <getopt.h>
> #if defined(__GLIBC__) && __GLIBC__ == 2
> #include <net/ethernet.h>
> @@ -28,6 +30,116 @@
> {0}
> };
>
> +struct realmname {
> + int id;
> + char* name;
> + int len;
> + struct realmname* next;
> +};
> +
> +/* array of realms from /etc/iproute2/rt_realms */
> +static struct realmname *realms = NULL;
> +/* 1 if loading failed */
> +static int rdberr = 0;
> +
> +
> +void load_realms()
> +{
> + const char* rfnm = "/etc/iproute2/rt_realms";
> + char buf[512];
> + FILE *fil;
> + char *cur, *nxt;
> + int id;
> + struct realmname *oldnm = NULL, *newnm = NULL;
> +
> + fil = fopen(rfnm, "r");
> + if (!fil) {
> + rdberr = 1;
> + return;
> + }
> +
> + while (fgets(buf, sizeof(buf), fil)) {
> + cur = buf;
> + while ((*cur == ' ') || (*cur == '\t')) cur++;
> + if ((*cur == '#') || (*cur == '\n') || (*cur == 0))
> + continue;
> +
> + /* iproute2 allows hex and dec format */
> + errno = 0;
Why do you need to fiddle with errno? Unless you missed to check it
before that shouldn't be necessary.
> + id = strtoul(cur, &nxt, strncmp(cur, "0x", 2) ? 10 : 16);
> + if ((nxt == cur) || errno) {
> + continue;
> + }
> +
> + /* same boundaries as in iproute2 */
> + if (id < 0 || id > 256) continue;
That doesn't look right. There is a limit of 256 for tables, but realms
are 32 bit values.
> + cur = nxt;
> +
> + if (!isspace(*cur)) continue;
> + while ((*cur == ' ') || (*cur == '\t')) cur++;
> + if ((*cur == '#') || (*cur == '\n') || (*cur == 0))
> + continue;
> + nxt = cur;
> + while ((*nxt != 0) && !isspace(*nxt)) nxt++;
nxt++ goes on the next line
> + if (nxt == cur) continue;
continue goes on the next line. There are more instances of this, please
just fix all of them.
> +
> + /* found valid data */
> + newnm = (struct realmname*)malloc(sizeof(struct realmname));
> + if (NULL == newnm) {
Please stick to the coding style used commonly within iptables, i.e.
newnm == NULL. Same for the other comparisons.
> + perror("libipt_realm: malloc failed");
> + exit(1);
> + }
> + newnm->id = id;
> + newnm->len = nxt - cur;
> + newnm->name = (char*)malloc(newnm->len + 1);
> + if (NULL == newnm->name) {
> + perror("libipt_realm: malloc failed");
> + exit(1);
> + }
> + strncpy(newnm->name, cur, newnm->len);
> + newnm->name[newnm->len] = 0;
> + newnm->next = NULL;
> +
> + if (oldnm) {
> + oldnm->next = newnm;
> + } else {
> + realms = newnm;
> + }
> + oldnm = newnm;
> + }
> +
> + fclose(fil);
> +}
> +
> +/* get realm id for name, -1 if error/not found */
> +int realm_name2id(const char* name)
> +{
> + if ((NULL == realms) && (0 == rdberr)) load_realms();
> + if (NULL == realms) return -1;
> +
> + struct realmname* cur = realms;
Besided beeing ugly in my opinion, declarations after statements are not
supported by gcc-2.95.
> + while (cur) {
> + if (!strncmp(name, cur->name, cur->len + 1)) return cur->id;
> + cur = cur->next;
> + }
> + return -1;
> +}
> +
> +/* get realm name for id, NULL if error/not found */
> +const char* realm_id2name(int id)
> +{
> + if ((NULL == realms) && (0 == rdberr)) load_realms();
> + if (NULL == realms) return NULL;
> +
> + struct realmname* cur = realms;
> + while (cur) {
> + if (id == cur->id) return cur->name;
> + cur = cur->next;
> + }
> + return NULL;
> +}
> +
> +
> /* Function which parses command options; returns true if it
> ate an option */
> static int
> @@ -42,14 +154,26 @@
> char *end;
> case '1':
> check_inverse(argv[optind-1], &invert, &optind, 0);
> - optarg = argv[optind-1];
> + end = optarg = argv[optind-1];
> realminfo->id = strtoul(optarg, &end, 0);
> - if (*end == '/') {
> - realminfo->mask = strtoul(end+1, &end, 0);
> - } else
> + if ((end != optarg) && (('/' == *end) || ('\0' == *end))) {
> + if (*end == '/') {
> + realminfo->mask = strtoul(end+1, &end, 0);
> + } else
> + realminfo->mask = 0xffffffff;
> + if (*end != '\0' || end == optarg)
> + exit_error(PARAMETER_PROBLEM,
> + "Bad realm value `%s'", optarg);
> + } else {
> + int id = realm_name2id(optarg);
> + if (-1 == id) {
> + exit_error(PARAMETER_PROBLEM,
> + "Realm `%s' not found", optarg);
> + }
> + realminfo->id = (u_int32_t)id;
> realminfo->mask = 0xffffffff;
> - if (*end != '\0' || end == optarg)
> - exit_error(PARAMETER_PROBLEM, "Bad realm value `%s'", optarg);
> + realminfo->is_named_realm = 1;
> + }
> if (invert)
> realminfo->invert = 1;
> *flags = 1;
> @@ -62,12 +186,22 @@
> }
>
> static void
> -print_realm(unsigned long id, unsigned long mask)
> +print_realm(unsigned long id, unsigned long mask, int is_named)
> {
> + const char* name = NULL;
> +
> if (mask != 0xffffffff)
> printf("0x%lx/0x%lx ", id, mask);
> - else
> - printf("0x%lx ", id);
> + else {
> + if (1 == is_named) {
> + name = realm_id2name(id);
> + }
> + if (name) {
> + printf("%s ", name);
> + } else {
> + printf("0x%lx ", id);
> + }
> + }
> }
>
> /* Prints out the matchinfo. */
> @@ -82,7 +216,7 @@
> printf("! ");
>
> printf("realm ");
> - print_realm(ri->id, ri->mask);
> + print_realm(ri->id, ri->mask, numeric ? 0 : ri->is_named_realm);
> }
>
>
> @@ -96,7 +230,7 @@
> printf("! ");
>
> printf("--realm ");
> - print_realm(ri->id, ri->mask);
> + print_realm(ri->id, ri->mask, ri->is_named_realm);
> }
>
> /* Final check; must have specified --mark. */
> diff -ruN iptables-1.3.5.base/extensions/libipt_realm.man iptables-1.3.5/extensions/libipt_realm.man
> --- iptables-1.3.5.base/extensions/libipt_realm.man 2004-10-10 11:56:27.000000000 +0200
> +++ iptables-1.3.5/extensions/libipt_realm.man 2006-06-04 01:50:15.000000000 +0200
> @@ -1,5 +1,7 @@
> This matches the routing realm. Routing realms are used in complex routing
> setups involving dynamic routing protocols like BGP.
> .TP
> -.BI "--realm " "[!]" "value[/mask]"
> -Matches a given realm number (and optionally mask).
> +.BI "--realm " "[!] " "value[/mask]"
> +Matches a given realm number (and optionally mask). If not a number, value
> +can be a named realm from /etc/iproute2/rt_realms (mask can not be used in
> +that case).
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] Named realm - updated
2006-06-19 15:50 ` Patrick McHardy
@ 2006-09-01 23:27 ` Simon Lodal
2006-09-02 12:09 ` Patrick McHardy
0 siblings, 1 reply; 5+ messages in thread
From: Simon Lodal @ 2006-09-01 23:27 UTC (permalink / raw)
To: Patrick McHardy; +Cc: Netfilter Developer
[-- Attachment #1: Type: text/plain, Size: 8850 bytes --]
Ok, here is a new version.
On Monday 19 June 2006 17:50, Patrick McHardy wrote:
> Simon Lodal wrote:
> > Make the realm match accept named realms, defined in
> > /etc/iproute2/rt_realms.
> >
> > First sent 2006-05-21, improved since then:
> > - Only load rt_realms once, keep in memory.
> > - Output realm by name if it was originally specified that way, except if
> > iptables -n.
>
> Thanks. I still have a few points before we can merge this, please
> see below.
>
> > ------------------------------------------------------------------------
> >
> > Index: linux-2.6/include/linux/netfilter/xt_realm.h
> > ===================================================================
> > --- linux-2.6/include/linux/netfilter/xt_realm.h (revision 44)
> > +++ linux-2.6/include/linux/netfilter/xt_realm.h (revision 45)
> > @@ -5,6 +5,7 @@
> > u_int32_t id;
> > u_int32_t mask;
> > u_int8_t invert;
> > + u_int8_t is_named_realm;
>
> No no no :) This breaks compatibility (well, it does not due to
> structure padding, but still, structures shared between kernel and
> userspace should be considered untouchable). Names are to be shown
> when numeric == 0, otherwise not. It doesn't matter in which format
> the user specified the rule.
The compatibility policy is good at preventing a lot of good ideas from
becoming anything but that.
Anyway, ok.
> > };
> >
> > #endif /* _XT_REALM_H */
> >
> >
> > ------------------------------------------------------------------------
> >
> > diff -ruN iptables-1.3.5.base/extensions/libipt_realm.c
> > iptables-1.3.5/extensions/libipt_realm.c ---
> > iptables-1.3.5.base/extensions/libipt_realm.c 2006-06-04
> > 01:49:33.000000000 +0200 +++
> > iptables-1.3.5/extensions/libipt_realm.c 2006-06-04 01:50:06.000000000
> > +0200 @@ -3,6 +3,8 @@
> > #include <netdb.h>
> > #include <string.h>
> > #include <stdlib.h>
> > +#include <errno.h>
> > +#include <ctype.h>
> > #include <getopt.h>
> > #if defined(__GLIBC__) && __GLIBC__ == 2
> > #include <net/ethernet.h>
> > @@ -28,6 +30,116 @@
> > {0}
> > };
> >
> > +struct realmname {
> > + int id;
> > + char* name;
> > + int len;
> > + struct realmname* next;
> > +};
> > +
> > +/* array of realms from /etc/iproute2/rt_realms */
> > +static struct realmname *realms = NULL;
> > +/* 1 if loading failed */
> > +static int rdberr = 0;
> > +
> > +
> > +void load_realms()
> > +{
> > + const char* rfnm = "/etc/iproute2/rt_realms";
> > + char buf[512];
> > + FILE *fil;
> > + char *cur, *nxt;
> > + int id;
> > + struct realmname *oldnm = NULL, *newnm = NULL;
> > +
> > + fil = fopen(rfnm, "r");
> > + if (!fil) {
> > + rdberr = 1;
> > + return;
> > + }
> > +
> > + while (fgets(buf, sizeof(buf), fil)) {
> > + cur = buf;
> > + while ((*cur == ' ') || (*cur == '\t')) cur++;
> > + if ((*cur == '#') || (*cur == '\n') || (*cur == 0))
> > + continue;
> > +
> > + /* iproute2 allows hex and dec format */
> > + errno = 0;
>
> Why do you need to fiddle with errno? Unless you missed to check it
> before that shouldn't be necessary.
I am not sure it is set to zero on success, and can not hurt anyway.
> > + id = strtoul(cur, &nxt, strncmp(cur, "0x", 2) ? 10 : 16);
> > + if ((nxt == cur) || errno) {
> > + continue;
> > + }
> > +
> > + /* same boundaries as in iproute2 */
> > + if (id < 0 || id > 256) continue;
>
> That doesn't look right. There is a limit of 256 for tables, but realms
> are 32 bit values.
I checked again, it is really the way iproute2 does it. You can have 32bit
id's, but only the first 256 can be named.
iproute2-2.6.16-060323/lib/rt_names.c rtnl_tab_initialize() is called with
size=256 so named ID's are limited to 0-255.
>
> > + cur = nxt;
> > +
> > + if (!isspace(*cur)) continue;
> > + while ((*cur == ' ') || (*cur == '\t')) cur++;
> > + if ((*cur == '#') || (*cur == '\n') || (*cur == 0))
> > + continue;
> > + nxt = cur;
> > + while ((*nxt != 0) && !isspace(*nxt)) nxt++;
>
> nxt++ goes on the next line
ok
> > + if (nxt == cur) continue;
>
> continue goes on the next line. There are more instances of this, please
> just fix all of them.
ok
> > +
> > + /* found valid data */
> > + newnm = (struct realmname*)malloc(sizeof(struct realmname));
> > + if (NULL == newnm) {
>
> Please stick to the coding style used commonly within iptables, i.e.
> newnm == NULL. Same for the other comparisons.
ok
> > + perror("libipt_realm: malloc failed");
> > + exit(1);
> > + }
> > + newnm->id = id;
> > + newnm->len = nxt - cur;
> > + newnm->name = (char*)malloc(newnm->len + 1);
> > + if (NULL == newnm->name) {
> > + perror("libipt_realm: malloc failed");
> > + exit(1);
> > + }
> > + strncpy(newnm->name, cur, newnm->len);
> > + newnm->name[newnm->len] = 0;
> > + newnm->next = NULL;
> > +
> > + if (oldnm) {
> > + oldnm->next = newnm;
> > + } else {
> > + realms = newnm;
> > + }
> > + oldnm = newnm;
> > + }
> > +
> > + fclose(fil);
> > +}
> > +
> > +/* get realm id for name, -1 if error/not found */
> > +int realm_name2id(const char* name)
> > +{
> > + if ((NULL == realms) && (0 == rdberr)) load_realms();
> > + if (NULL == realms) return -1;
> > +
> > + struct realmname* cur = realms;
>
> Besided beeing ugly in my opinion, declarations after statements are not
> supported by gcc-2.95.
ok
> > + while (cur) {
> > + if (!strncmp(name, cur->name, cur->len + 1)) return cur->id;
> > + cur = cur->next;
> > + }
> > + return -1;
> > +}
> > +
> > +/* get realm name for id, NULL if error/not found */
> > +const char* realm_id2name(int id)
> > +{
> > + if ((NULL == realms) && (0 == rdberr)) load_realms();
> > + if (NULL == realms) return NULL;
> > +
> > + struct realmname* cur = realms;
> > + while (cur) {
> > + if (id == cur->id) return cur->name;
> > + cur = cur->next;
> > + }
> > + return NULL;
> > +}
> > +
> > +
> > /* Function which parses command options; returns true if it
> > ate an option */
> > static int
> > @@ -42,14 +154,26 @@
> > char *end;
> > case '1':
> > check_inverse(argv[optind-1], &invert, &optind, 0);
> > - optarg = argv[optind-1];
> > + end = optarg = argv[optind-1];
> > realminfo->id = strtoul(optarg, &end, 0);
> > - if (*end == '/') {
> > - realminfo->mask = strtoul(end+1, &end, 0);
> > - } else
> > + if ((end != optarg) && (('/' == *end) || ('\0' == *end))) {
> > + if (*end == '/') {
> > + realminfo->mask = strtoul(end+1, &end, 0);
> > + } else
> > + realminfo->mask = 0xffffffff;
> > + if (*end != '\0' || end == optarg)
> > + exit_error(PARAMETER_PROBLEM,
> > + "Bad realm value `%s'", optarg);
> > + } else {
> > + int id = realm_name2id(optarg);
> > + if (-1 == id) {
> > + exit_error(PARAMETER_PROBLEM,
> > + "Realm `%s' not found", optarg);
> > + }
> > + realminfo->id = (u_int32_t)id;
> > realminfo->mask = 0xffffffff;
> > - if (*end != '\0' || end == optarg)
> > - exit_error(PARAMETER_PROBLEM, "Bad realm value `%s'", optarg);
> > + realminfo->is_named_realm = 1;
> > + }
> > if (invert)
> > realminfo->invert = 1;
> > *flags = 1;
> > @@ -62,12 +186,22 @@
> > }
> >
> > static void
> > -print_realm(unsigned long id, unsigned long mask)
> > +print_realm(unsigned long id, unsigned long mask, int is_named)
> > {
> > + const char* name = NULL;
> > +
> > if (mask != 0xffffffff)
> > printf("0x%lx/0x%lx ", id, mask);
> > - else
> > - printf("0x%lx ", id);
> > + else {
> > + if (1 == is_named) {
> > + name = realm_id2name(id);
> > + }
> > + if (name) {
> > + printf("%s ", name);
> > + } else {
> > + printf("0x%lx ", id);
> > + }
> > + }
> > }
> >
> > /* Prints out the matchinfo. */
> > @@ -82,7 +216,7 @@
> > printf("! ");
> >
> > printf("realm ");
> > - print_realm(ri->id, ri->mask);
> > + print_realm(ri->id, ri->mask, numeric ? 0 : ri->is_named_realm);
> > }
> >
> >
> > @@ -96,7 +230,7 @@
> > printf("! ");
> >
> > printf("--realm ");
> > - print_realm(ri->id, ri->mask);
> > + print_realm(ri->id, ri->mask, ri->is_named_realm);
> > }
> >
> > /* Final check; must have specified --mark. */
> > diff -ruN iptables-1.3.5.base/extensions/libipt_realm.man
> > iptables-1.3.5/extensions/libipt_realm.man ---
> > iptables-1.3.5.base/extensions/libipt_realm.man 2004-10-10
> > 11:56:27.000000000 +0200 +++
> > iptables-1.3.5/extensions/libipt_realm.man 2006-06-04 01:50:15.000000000
> > +0200 @@ -1,5 +1,7 @@
> > This matches the routing realm. Routing realms are used in complex
> > routing setups involving dynamic routing protocols like BGP.
> > .TP
> > -.BI "--realm " "[!]" "value[/mask]"
> > -Matches a given realm number (and optionally mask).
> > +.BI "--realm " "[!] " "value[/mask]"
> > +Matches a given realm number (and optionally mask). If not a number,
> > value +can be a named realm from /etc/iproute2/rt_realms (mask can not be
> > used in +that case).
Simon
[-- Attachment #2: realm_named_realm.2006-09-02.diff --]
[-- Type: text/x-diff, Size: 5774 bytes --]
diff -ruN iptables_svn_2006-09-02.orig/extensions/libipt_realm.c iptables_svn_2006-09-02.mod/extensions/libipt_realm.c
--- iptables_svn_2006-09-02.orig/extensions/libipt_realm.c 2006-09-01 23:47:21.000000000 +0200
+++ iptables_svn_2006-09-02.mod/extensions/libipt_realm.c 2006-09-02 00:16:27.000000000 +0200
@@ -3,6 +3,8 @@
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
+#include <errno.h>
+#include <ctype.h>
#include <getopt.h>
#if defined(__GLIBC__) && __GLIBC__ == 2
#include <net/ethernet.h>
@@ -28,6 +30,129 @@
{0}
};
+struct realmname {
+ int id;
+ char* name;
+ int len;
+ struct realmname* next;
+};
+
+/* array of realms from /etc/iproute2/rt_realms */
+static struct realmname *realms = NULL;
+/* 1 if loading failed */
+static int rdberr = 0;
+
+
+void load_realms()
+{
+ const char* rfnm = "/etc/iproute2/rt_realms";
+ char buf[512];
+ FILE *fil;
+ char *cur, *nxt;
+ int id;
+ struct realmname *oldnm = NULL, *newnm = NULL;
+
+ fil = fopen(rfnm, "r");
+ if (!fil) {
+ rdberr = 1;
+ return;
+ }
+
+ while (fgets(buf, sizeof(buf), fil)) {
+ cur = buf;
+ while ((*cur == ' ') || (*cur == '\t'))
+ cur++;
+ if ((*cur == '#') || (*cur == '\n') || (*cur == 0))
+ continue;
+
+ /* iproute2 allows hex and dec format */
+ errno = 0;
+ id = strtoul(cur, &nxt, strncmp(cur, "0x", 2) ? 10 : 16);
+ if ((nxt == cur) || errno)
+ continue;
+
+ /* same boundaries as in iproute2 */
+ if (id < 0 || id > 255)
+ continue;
+ cur = nxt;
+
+ if (!isspace(*cur))
+ continue;
+ while ((*cur == ' ') || (*cur == '\t'))
+ cur++;
+ if ((*cur == '#') || (*cur == '\n') || (*cur == 0))
+ continue;
+ nxt = cur;
+ while ((*nxt != 0) && !isspace(*nxt))
+ nxt++;
+ if (nxt == cur)
+ continue;
+
+ /* found valid data */
+ newnm = (struct realmname*)malloc(sizeof(struct realmname));
+ if (newnm == NULL) {
+ perror("libipt_realm: malloc failed");
+ exit(1);
+ }
+ newnm->id = id;
+ newnm->len = nxt - cur;
+ newnm->name = (char*)malloc(newnm->len + 1);
+ if (newnm->name == NULL) {
+ perror("libipt_realm: malloc failed");
+ exit(1);
+ }
+ strncpy(newnm->name, cur, newnm->len);
+ newnm->name[newnm->len] = 0;
+ newnm->next = NULL;
+
+ if (oldnm) {
+ oldnm->next = newnm;
+ } else {
+ realms = newnm;
+ }
+ oldnm = newnm;
+ }
+
+ fclose(fil);
+}
+
+/* get realm id for name, -1 if error/not found */
+int realm_name2id(const char* name)
+{
+ struct realmname* cur;
+
+ if ((realms == NULL) && (rdberr == 0))
+ load_realms();
+ cur = realms;
+ if (cur == NULL)
+ return -1;
+ while (cur) {
+ if (!strncmp(name, cur->name, cur->len + 1))
+ return cur->id;
+ cur = cur->next;
+ }
+ return -1;
+}
+
+/* get realm name for id, NULL if error/not found */
+const char* realm_id2name(int id)
+{
+ struct realmname* cur;
+
+ if ((realms == NULL) && (rdberr == 0))
+ load_realms();
+ cur = realms;
+ if (cur == NULL)
+ return NULL;
+ while (cur) {
+ if (id == cur->id)
+ return cur->name;
+ cur = cur->next;
+ }
+ return NULL;
+}
+
+
/* Function which parses command options; returns true if it
ate an option */
static int
@@ -37,19 +162,31 @@
struct ipt_entry_match **match)
{
struct ipt_realm_info *realminfo = (struct ipt_realm_info *)(*match)->data;
+ int id;
switch (c) {
char *end;
case '1':
check_inverse(argv[optind-1], &invert, &optind, 0);
- optarg = argv[optind-1];
+ end = optarg = argv[optind-1];
realminfo->id = strtoul(optarg, &end, 0);
- if (*end == '/') {
- realminfo->mask = strtoul(end+1, &end, 0);
- } else
+ if ((end != optarg) && ((*end == '/') || (*end == '\0'))) {
+ if (*end == '/') {
+ realminfo->mask = strtoul(end+1, &end, 0);
+ } else
+ realminfo->mask = 0xffffffff;
+ if (*end != '\0' || end == optarg)
+ exit_error(PARAMETER_PROBLEM,
+ "Bad realm value `%s'", optarg);
+ } else {
+ id = realm_name2id(optarg);
+ if (id == -1) {
+ exit_error(PARAMETER_PROBLEM,
+ "Realm `%s' not found", optarg);
+ }
+ realminfo->id = (u_int32_t)id;
realminfo->mask = 0xffffffff;
- if (*end != '\0' || end == optarg)
- exit_error(PARAMETER_PROBLEM, "Bad realm value `%s'", optarg);
+ }
if (invert)
realminfo->invert = 1;
*flags = 1;
@@ -62,12 +199,22 @@
}
static void
-print_realm(unsigned long id, unsigned long mask)
+print_realm(unsigned long id, unsigned long mask, int numeric)
{
+ const char* name = NULL;
+
if (mask != 0xffffffff)
printf("0x%lx/0x%lx ", id, mask);
- else
- printf("0x%lx ", id);
+ else {
+ if (numeric == 0) {
+ name = realm_id2name(id);
+ }
+ if (name) {
+ printf("%s ", name);
+ } else {
+ printf("0x%lx ", id);
+ }
+ }
}
/* Prints out the matchinfo. */
@@ -82,7 +229,7 @@
printf("! ");
printf("realm ");
- print_realm(ri->id, ri->mask);
+ print_realm(ri->id, ri->mask, numeric);
}
@@ -96,7 +243,7 @@
printf("! ");
printf("--realm ");
- print_realm(ri->id, ri->mask);
+ print_realm(ri->id, ri->mask, 0);
}
/* Final check; must have specified --mark. */
diff -ruN iptables_svn_2006-09-02.orig/extensions/libipt_realm.man iptables_svn_2006-09-02.mod/extensions/libipt_realm.man
--- iptables_svn_2006-09-02.orig/extensions/libipt_realm.man 2006-09-01 23:47:21.000000000 +0200
+++ iptables_svn_2006-09-02.mod/extensions/libipt_realm.man 2006-09-02 00:16:30.000000000 +0200
@@ -1,5 +1,7 @@
This matches the routing realm. Routing realms are used in complex routing
setups involving dynamic routing protocols like BGP.
.TP
-.BI "--realm " "[!]" "value[/mask]"
-Matches a given realm number (and optionally mask).
+.BI "--realm " "[!] " "value[/mask]"
+Matches a given realm number (and optionally mask). If not a number, value
+can be a named realm from /etc/iproute2/rt_realms (mask can not be used in
+that case).
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] Named realm - updated
2006-09-01 23:27 ` Simon Lodal
@ 2006-09-02 12:09 ` Patrick McHardy
2006-09-02 12:21 ` Simon Lodal
0 siblings, 1 reply; 5+ messages in thread
From: Patrick McHardy @ 2006-09-02 12:09 UTC (permalink / raw)
To: Simon Lodal; +Cc: Netfilter Developer
Simon Lodal wrote:
> Ok, here is a new version.
Applied, thanks Simon. I have a patch to add support for named
fwmarks for iptables and iproute, so I'm probably going to move
parts of this to some central place.
>>>Index: linux-2.6/include/linux/netfilter/xt_realm.h
>>>===================================================================
>>>--- linux-2.6/include/linux/netfilter/xt_realm.h (revision 44)
>>>+++ linux-2.6/include/linux/netfilter/xt_realm.h (revision 45)
>>>@@ -5,6 +5,7 @@
>>> u_int32_t id;
>>> u_int32_t mask;
>>> u_int8_t invert;
>>>+ u_int8_t is_named_realm;
>>
> The compatibility policy is good at preventing a lot of good ideas from
> becoming anything but that.
Well, this idea just wasn't good :)
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] Named realm - updated
2006-09-02 12:09 ` Patrick McHardy
@ 2006-09-02 12:21 ` Simon Lodal
0 siblings, 0 replies; 5+ messages in thread
From: Simon Lodal @ 2006-09-02 12:21 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel
> > The compatibility policy is good at preventing a lot of good ideas from
> > becoming anything but that.
>
> Well, this idea just wasn't good :)
Admitted. I just had to air my general frustration :)
Simon
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2006-09-02 12:21 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-06-04 19:35 [PATCH] Named realm - updated Simon Lodal
2006-06-19 15:50 ` Patrick McHardy
2006-09-01 23:27 ` Simon Lodal
2006-09-02 12:09 ` Patrick McHardy
2006-09-02 12:21 ` Simon Lodal
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.