summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--extensions/libipt_DNAT.c1
-rw-r--r--extensions/libipt_LOG.c1
-rw-r--r--extensions/libipt_MARK.c1
-rw-r--r--extensions/libipt_REJECT.c1
-rw-r--r--extensions/libipt_SNAT.c1
-rw-r--r--extensions/libipt_TOS.c1
-rw-r--r--extensions/libipt_icmp.c1
-rw-r--r--extensions/libipt_limit.c1
-rw-r--r--extensions/libipt_mac.c1
-rw-r--r--extensions/libipt_mark.c1
-rw-r--r--extensions/libipt_multiport.c1
-rw-r--r--extensions/libipt_owner.c1
-rw-r--r--extensions/libipt_standard.c1
-rw-r--r--extensions/libipt_state.c1
-rw-r--r--extensions/libipt_tcp.c17
-rw-r--r--extensions/libipt_tos.c1
-rw-r--r--extensions/libipt_udp.c1
-rw-r--r--extensions/libipt_unclean.c1
-rw-r--r--include/iptables.h6
-rw-r--r--include/libiptc/libiptc.h4
-rw-r--r--libiptc/libiptc.c61
21 files changed, 74 insertions, 31 deletions
diff --git a/extensions/libipt_DNAT.c b/extensions/libipt_DNAT.c
index e3c37222..6251cf1c 100644
--- a/extensions/libipt_DNAT.c
+++ b/extensions/libipt_DNAT.c
@@ -229,6 +229,7 @@ struct iptables_target dnat
"DNAT",
NETFILTER_VERSION,
sizeof(struct ip_nat_multi_range),
+ sizeof(struct ip_nat_multi_range),
&help,
&init,
&parse,
diff --git a/extensions/libipt_LOG.c b/extensions/libipt_LOG.c
index ce4adb23..d634cd55 100644
--- a/extensions/libipt_LOG.c
+++ b/extensions/libipt_LOG.c
@@ -245,6 +245,7 @@ struct iptables_target log
"LOG",
NETFILTER_VERSION,
sizeof(struct ipt_log_info),
+ sizeof(struct ipt_log_info),
&help,
&init,
&parse,
diff --git a/extensions/libipt_MARK.c b/extensions/libipt_MARK.c
index a7cb60c0..b8afe550 100644
--- a/extensions/libipt_MARK.c
+++ b/extensions/libipt_MARK.c
@@ -105,6 +105,7 @@ struct iptables_target mark
"MARK",
NETFILTER_VERSION,
sizeof(struct ipt_mark_target_info),
+ sizeof(struct ipt_mark_target_info),
&help,
&init,
&parse,
diff --git a/extensions/libipt_REJECT.c b/extensions/libipt_REJECT.c
index 3f5c128a..2c0b85b7 100644
--- a/extensions/libipt_REJECT.c
+++ b/extensions/libipt_REJECT.c
@@ -142,6 +142,7 @@ struct iptables_target reject
"REJECT",
NETFILTER_VERSION,
sizeof(struct ipt_reject_info),
+ sizeof(struct ipt_reject_info),
&help,
&init,
&parse,
diff --git a/extensions/libipt_SNAT.c b/extensions/libipt_SNAT.c
index 86ba39b9..f769cd4e 100644
--- a/extensions/libipt_SNAT.c
+++ b/extensions/libipt_SNAT.c
@@ -229,6 +229,7 @@ struct iptables_target snat
"SNAT",
NETFILTER_VERSION,
sizeof(struct ip_nat_multi_range),
+ sizeof(struct ip_nat_multi_range),
&help,
&init,
&parse,
diff --git a/extensions/libipt_TOS.c b/extensions/libipt_TOS.c
index f01fc264..ed599005 100644
--- a/extensions/libipt_TOS.c
+++ b/extensions/libipt_TOS.c
@@ -158,6 +158,7 @@ struct iptables_target tos
"TOS",
NETFILTER_VERSION,
sizeof(struct ipt_tos_target_info),
+ sizeof(struct ipt_tos_target_info),
&help,
&init,
&parse,
diff --git a/extensions/libipt_icmp.c b/extensions/libipt_icmp.c
index 65857ce3..0a47e412 100644
--- a/extensions/libipt_icmp.c
+++ b/extensions/libipt_icmp.c
@@ -280,6 +280,7 @@ struct iptables_match icmp
"icmp",
NETFILTER_VERSION,
sizeof(struct ipt_icmp),
+ sizeof(struct ipt_icmp),
&help,
&init,
&parse,
diff --git a/extensions/libipt_limit.c b/extensions/libipt_limit.c
index b6cc74f2..822109bf 100644
--- a/extensions/libipt_limit.c
+++ b/extensions/libipt_limit.c
@@ -181,6 +181,7 @@ struct iptables_match limit
"limit",
NETFILTER_VERSION,
sizeof(struct ipt_rateinfo),
+ offsetof(struct ipt_rateinfo, prev),
&help,
&init,
&parse,
diff --git a/extensions/libipt_mac.c b/extensions/libipt_mac.c
index 36d89692..f740ecc5 100644
--- a/extensions/libipt_mac.c
+++ b/extensions/libipt_mac.c
@@ -129,6 +129,7 @@ struct iptables_match mac
"mac",
NETFILTER_VERSION,
sizeof(struct ipt_mac_info),
+ sizeof(struct ipt_mac_info),
&help,
&init,
&parse,
diff --git a/extensions/libipt_mark.c b/extensions/libipt_mark.c
index dcf54488..2cd6193b 100644
--- a/extensions/libipt_mark.c
+++ b/extensions/libipt_mark.c
@@ -113,6 +113,7 @@ struct iptables_match mark
"mark",
NETFILTER_VERSION,
sizeof(struct ipt_mark_info),
+ sizeof(struct ipt_mark_info),
&help,
&init,
&parse,
diff --git a/extensions/libipt_multiport.c b/extensions/libipt_multiport.c
index 727f95fc..8c58bddd 100644
--- a/extensions/libipt_multiport.c
+++ b/extensions/libipt_multiport.c
@@ -246,6 +246,7 @@ struct iptables_match multiport
"multiport",
NETFILTER_VERSION,
sizeof(struct ipt_multiport),
+ sizeof(struct ipt_multiport),
&help,
&init,
&parse,
diff --git a/extensions/libipt_owner.c b/extensions/libipt_owner.c
index 29311022..027f5383 100644
--- a/extensions/libipt_owner.c
+++ b/extensions/libipt_owner.c
@@ -204,6 +204,7 @@ struct iptables_match owner
"owner",
NETFILTER_VERSION,
sizeof(struct ipt_owner_info),
+ sizeof(struct ipt_owner_info),
&help,
&init,
&parse,
diff --git a/extensions/libipt_standard.c b/extensions/libipt_standard.c
index 9a746b2d..c63669f0 100644
--- a/extensions/libipt_standard.c
+++ b/extensions/libipt_standard.c
@@ -52,6 +52,7 @@ struct iptables_target standard
"standard",
NETFILTER_VERSION,
sizeof(int),
+ sizeof(int),
&help,
&init,
&parse,
diff --git a/extensions/libipt_state.c b/extensions/libipt_state.c
index 19751d72..d3dcbc2d 100644
--- a/extensions/libipt_state.c
+++ b/extensions/libipt_state.c
@@ -147,6 +147,7 @@ struct iptables_match state
"state",
NETFILTER_VERSION,
sizeof(struct ipt_state_info),
+ sizeof(struct ipt_state_info),
&help,
&init,
&parse,
diff --git a/extensions/libipt_tcp.c b/extensions/libipt_tcp.c
index 2febc28c..276d0e2a 100644
--- a/extensions/libipt_tcp.c
+++ b/extensions/libipt_tcp.c
@@ -308,21 +308,23 @@ print_option(u_int8_t option, int invert, int numeric)
static void
print_tcpf(u_int8_t flags)
{
- int sole_flag = 1;
+ int have_flag = 0;
- do {
+ while (flags) {
unsigned int i;
- /* Terminates because last flag is 0 */
- for (i = 0; !(flags & tcp_flag_names[i].flag); i++);
+ for (i = 0; (flags & tcp_flag_names[i].flag) == 0; i++);
- if (!sole_flag)
+ if (have_flag)
printf(",");
printf("%s", tcp_flag_names[i].name);
- sole_flag = 0;
+ have_flag = 1;
flags &= ~tcp_flag_names[i].flag;
- } while (flags);
+ }
+
+ if (!have_flag)
+ printf("NONE");
}
static void
@@ -424,6 +426,7 @@ struct iptables_match tcp
"tcp",
NETFILTER_VERSION,
sizeof(struct ipt_tcp),
+ sizeof(struct ipt_tcp),
&help,
&init,
&parse,
diff --git a/extensions/libipt_tos.c b/extensions/libipt_tos.c
index 6d2d7724..99c89ea7 100644
--- a/extensions/libipt_tos.c
+++ b/extensions/libipt_tos.c
@@ -156,6 +156,7 @@ struct iptables_match tos
"tos",
NETFILTER_VERSION,
sizeof(struct ipt_tos_info),
+ sizeof(struct ipt_tos_info),
&help,
&init,
&parse,
diff --git a/extensions/libipt_udp.c b/extensions/libipt_udp.c
index 603a4860..507937b1 100644
--- a/extensions/libipt_udp.c
+++ b/extensions/libipt_udp.c
@@ -236,6 +236,7 @@ struct iptables_match udp
"udp",
NETFILTER_VERSION,
sizeof(struct ipt_udp),
+ sizeof(struct ipt_udp),
&help,
&init,
&parse,
diff --git a/extensions/libipt_unclean.c b/extensions/libipt_unclean.c
index 50f62bdc..bef513e6 100644
--- a/extensions/libipt_unclean.c
+++ b/extensions/libipt_unclean.c
@@ -51,6 +51,7 @@ struct iptables_match unclean
"unclean",
NETFILTER_VERSION,
0,
+ 0,
&help,
&init,
&parse,
diff --git a/include/iptables.h b/include/iptables.h
index 9b1a4a16..1ddd8712 100644
--- a/include/iptables.h
+++ b/include/iptables.h
@@ -15,6 +15,9 @@ struct iptables_match
/* Size of match data. */
size_t size;
+ /* Size of match data relevent for userspace comparison purposes */
+ size_t userspacesize;
+
/* Function which prints out usage message. */
void (*help)(void);
@@ -59,6 +62,9 @@ struct iptables_target
/* Size of target data. */
size_t size;
+ /* Size of target data relevent for userspace comparison purposes */
+ size_t userspacesize;
+
/* Function which prints out usage message. */
void (*help)(void);
diff --git a/include/libiptc/libiptc.h b/include/libiptc/libiptc.h
index 4a964e03..0a491071 100644
--- a/include/libiptc/libiptc.h
+++ b/include/libiptc/libiptc.h
@@ -73,9 +73,11 @@ int iptc_append_entry(const ipt_chainlabel chain,
const struct ipt_entry *e,
iptc_handle_t *handle);
-/* Delete the first rule in `chain' which matches `e'. */
+/* Delete the first rule in `chain' which matches `e', subject to
+ matchmask (array of length == origfw) */
int iptc_delete_entry(const ipt_chainlabel chain,
const struct ipt_entry *origfw,
+ unsigned char *matchmask,
iptc_handle_t *handle);
/* Delete the rule in position `rulenum' in `chain'. */
diff --git a/libiptc/libiptc.c b/libiptc/libiptc.c
index de819f2b..a90d46ea 100644
--- a/libiptc/libiptc.c
+++ b/libiptc/libiptc.c
@@ -16,13 +16,14 @@
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
-#include <linux/netfilter_ipv4/ipt_limit.h>
+#include <limits.h>
#if !defined(__GLIBC__) || (__GLIBC__ < 2)
typedef unsigned int socklen_t;
#endif
#include <libiptc/libiptc.h>
+#include <linux/netfilter_ipv4/ipt_limit.h>
#define IP_VERSION 4
#define IP_OFFSET 0x1FFF
@@ -1000,10 +1001,12 @@ iptc_append_entry(const ipt_chainlabel chain,
static inline int
match_different(const struct ipt_entry_match *a,
- const char *a_elems,
- const char *b_elems)
+ const unsigned char *a_elems,
+ const unsigned char *b_elems,
+ unsigned char **maskptr)
{
const struct ipt_entry_match *b;
+ unsigned int i;
/* Offset of b is the same as a. */
b = (void *)b_elems + ((char *)a-a_elems);
@@ -1014,28 +1017,38 @@ match_different(const struct ipt_entry_match *a,
if (strcmp(a->u.name, b->u.name) != 0)
return 1;
- /* FIXME: This is really, really gross --RR */
- if (strcmp(a->u.name,"limit") == 0) {
- /* Special case, the kernel writes in this data, so we
- * need to make sure that we only check the parts
- * that are user specified */
- if (((struct ipt_rateinfo *)a->data)->avg
- != ((struct ipt_rateinfo *)b->data)->avg
- || ((struct ipt_rateinfo *)a->data)->burst
- != ((struct ipt_rateinfo *)b->data)->burst)
+ *maskptr += sizeof(*a);
+
+ for (i = 0; i < a->match_size - sizeof(*a); i++)
+ if (((a->data[i] ^ b->data[i]) & (*maskptr)[i]) != 0)
+ return 1;
+ *maskptr += i;
+ return 0;
+}
+
+static inline int
+target_different(const unsigned char *a_targdata,
+ const unsigned char *b_targdata,
+ unsigned int tdatasize,
+ const unsigned char *mask)
+{
+ unsigned int i;
+ for (i = 0; i < tdatasize; i++)
+ if (((a_targdata[i] ^ b_targdata[i]) & mask[i]) != 0)
return 1;
- } else if (memcmp(a->data, b->data, a->match_size - sizeof(*a)) != 0)
- return 1;
return 0;
}
static inline int
-is_same(const struct ipt_entry *a, const struct ipt_entry *b)
+is_same(const struct ipt_entry *a, const struct ipt_entry *b,
+ unsigned char *matchmask)
{
unsigned int i;
struct ipt_entry_target *ta, *tb;
+ unsigned char *mptr;
+ /* Always compare head structures: ignore mask here. */
if (a->ip.src.s_addr != b->ip.src.s_addr
|| a->ip.dst.s_addr != b->ip.dst.s_addr
|| a->ip.smsk.s_addr != b->ip.smsk.s_addr
@@ -1063,7 +1076,8 @@ is_same(const struct ipt_entry *a, const struct ipt_entry *b)
|| a->next_offset != b->next_offset)
return 0;
- if (IPT_MATCH_ITERATE(a, match_different, a->elems, b->elems))
+ mptr = matchmask + sizeof(struct ipt_entry);
+ if (IPT_MATCH_ITERATE(a, match_different, a->elems, b->elems, &mptr))
return 0;
ta = ipt_get_target((struct ipt_entry *)a);
@@ -1072,12 +1086,12 @@ is_same(const struct ipt_entry *a, const struct ipt_entry *b)
return 0;
if (strcmp(ta->u.name, tb->u.name) != 0)
return 0;
-
- /* FIXME: If kernel modifies these, then we never match --RR */
-
- if (memcmp(ta->data, tb->data, ta->target_size - sizeof(*ta)) != 0)
- return 0;
-
+
+ mptr += sizeof(*ta)
+ if (target_different(ta->data, tb->data,
+ ta->target_size - sizeof(*ta), mptr))
+ return 0;
+
return 1;
}
@@ -1085,6 +1099,7 @@ is_same(const struct ipt_entry *a, const struct ipt_entry *b)
int
iptc_delete_entry(const ipt_chainlabel chain,
const struct ipt_entry *origfw,
+ unsigned char *matchmask,
iptc_handle_t *handle)
{
unsigned int offset, lastoff;
@@ -1120,7 +1135,7 @@ iptc_delete_entry(const ipt_chainlabel chain,
printf("Deleting:\n");
dump_entry(newe);
#endif
- if (is_same(e, fw)) {
+ if (is_same(e, fw, matchmask)) {
int ret;
ret = delete_rules(1, e->next_offset,
offset, entry2index(*handle, e),