summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJérome Lefranc2009-11-19 23:57:29 +0100
committerJérome Lefranc2009-11-19 23:57:29 +0100
commit13f87a9d2ba9649c6e4b8891865a60a5391ee4a9 (patch)
tree2bd7834201c8559b5d94395ea6fe4ae61c337efb
parent88234692f294cda177580e0d6e682f2d9f6322e4 (diff)
[linux] added --vlan-ip-proto filter to ebt_vlan ebtables rule
-rw-r--r--application/ebtables/extensions/ebt_vlan.c81
-rw-r--r--application/ebtables/include/linux/netfilter_bridge/ebt_vlan.h12
-rw-r--r--linux-2.6.10/include/linux/netfilter_bridge/ebt_vlan.h25
-rwxr-xr-xlinux-2.6.10/net/bridge/netfilter/ebt_vlan.c20
4 files changed, 102 insertions, 36 deletions
diff --git a/application/ebtables/extensions/ebt_vlan.c b/application/ebtables/extensions/ebt_vlan.c
index dce6828a85..651391f0c1 100644
--- a/application/ebtables/extensions/ebt_vlan.c
+++ b/application/ebtables/extensions/ebt_vlan.c
@@ -48,15 +48,17 @@
#define CHECK_INV_FLAG(_INDEX_) if (check_inverse (optarg)) vlaninfo->invflags |= _INDEX_;
#define CHECK_RANGE(_RANGE_) if (_RANGE_) print_error ("Invalid %s range", opts[c].name);
-#define NAME_VLAN_ID "id"
-#define NAME_VLAN_PRIO "prio"
-#define NAME_VLAN_ENCAP "encap"
-#define NAME_VLAN_TOS "tos"
+#define NAME_VLAN_ID "id"
+#define NAME_VLAN_PRIO "prio"
+#define NAME_VLAN_ENCAP "encap"
+#define NAME_VLAN_TOS "tos"
+#define NAME_VLAN_IP_PROTO "ip-proto"
-#define VLAN_ID 0
-#define VLAN_PRIO 1
-#define VLAN_ENCAP 2
-#define VLAN_TOS 3
+#define VLAN_ID 0
+#define VLAN_PRIO 1
+#define VLAN_ENCAP 2
+#define VLAN_TOS 3
+#define VLAN_IP_PROTO 4
static struct option opts[] = {
{EBT_VLAN_MATCH "-" NAME_VLAN_ID, required_argument, NULL,
@@ -65,19 +67,23 @@ static struct option opts[] = {
VLAN_PRIO},
{EBT_VLAN_MATCH "-" NAME_VLAN_ENCAP, required_argument, NULL,
VLAN_ENCAP},
- {EBT_VLAN_MATCH "-" NAME_VLAN_TOS, required_argument, NULL,
+ {EBT_VLAN_MATCH "-" NAME_VLAN_TOS, required_argument, NULL,
VLAN_TOS},
+ {EBT_VLAN_MATCH "-" NAME_VLAN_IP_PROTO, required_argument, NULL,
+ VLAN_IP_PROTO},
{NULL}
};
/*
* option inverse flags definition
*/
-#define OPT_VLAN_ID 0x01
-#define OPT_VLAN_PRIO 0x02
-#define OPT_VLAN_ENCAP 0x04
-#define OPT_VLAN_TOS 0x08
-#define OPT_VLAN_FLAGS (OPT_VLAN_ID | OPT_VLAN_PRIO | OPT_VLAN_ENCAP | OPT_VLAN_TOS)
+#define OPT_VLAN_ID 0x01
+#define OPT_VLAN_PRIO 0x02
+#define OPT_VLAN_ENCAP 0x04
+#define OPT_VLAN_TOS 0x08
+#define OPT_VLAN_IP_PROTO 0x10
+
+#define OPT_VLAN_FLAGS (OPT_VLAN_ID | OPT_VLAN_PRIO | OPT_VLAN_ENCAP | OPT_VLAN_TOS | OPT_VLAN_IP_PROTO)
struct ethertypeent *ethent;
@@ -102,8 +108,12 @@ static void print_help()
OPT_VLAN_FLAGS & OPT_VLAN_ENCAP ? "[!] " : "");
printf("--" EBT_VLAN_MATCH "-" NAME_VLAN_TOS " %s"
NAME_VLAN_TOS
- " : IP TOS field (hexadecimal), default 0\n",
+ " : IP TOS field (hexadecimal), default 0x0\n",
OPT_VLAN_FLAGS & OPT_VLAN_TOS ? "[!] " : "");
+ printf("--" EBT_VLAN_MATCH "-" NAME_VLAN_IP_PROTO " %s"
+ NAME_VLAN_IP_PROTO
+ " : IP protocol field (hexadecimal), default 0x0\n",
+ OPT_VLAN_FLAGS & OPT_VLAN_IP_PROTO ? "[!] " : "");
}
/*
@@ -120,6 +130,7 @@ static void init(struct ebt_entry_match *match)
vlaninfo->prio = 0;
vlaninfo->encap = 0;
vlaninfo->tos = 0;
+ vlaninfo->ip_proto = 0;
vlaninfo->invflags = 0;
vlaninfo->bitmask = 0;
}
@@ -198,6 +209,17 @@ parse(int c,
SET_BITMASK(EBT_VLAN_TOS);
break;
+ case VLAN_IP_PROTO:
+ check_option(flags, OPT_VLAN_IP_PROTO);
+ CHECK_INV_FLAG(EBT_VLAN_IP_PROTO);
+ CHECK_IF_MISSING_VALUE;
+ (unsigned char) local.ip_proto =
+ strtoul(argv[optind - 1], &end, 16);
+ CHECK_RANGE(local.ip_proto >= 256 || *end != '\0');
+ vlaninfo->ip_proto = local.ip_proto;
+ SET_BITMASK(EBT_VLAN_IP_PROTO);
+ break;
+
default:
return 0;
@@ -243,14 +265,24 @@ final_check(const struct ebt_u_entry *entry,
}
/*
- * Check if specified vlan-id=0 (priority-tagged frame condition)
- * when vlan-prio was specified.
+ * Check if specified vlan encaps is IP
+ * when vlan-tos is specified
*/
if (GET_BITMASK(EBT_VLAN_TOS)) {
if (vlaninfo->encap != htons(0x0800))
print_error
("For use tos, the specified vlan-encap must be 0x0800");
}
+
+ /*
+ * Check if specified vlan encaps is IP
+ * when vlan-ip-proto is specified.
+ */
+ if (GET_BITMASK(EBT_VLAN_IP_PROTO)) {
+ if (vlaninfo->encap != htons(0x0800))
+ print_error
+ ("For use ip-proto, the specified vlan-encap must be 0x0800");
+ }
}
/*
@@ -299,6 +331,14 @@ print(const struct ebt_u_entry *entry, const struct ebt_entry_match *match)
opts[VLAN_TOS].name,
INV_FLAG(EBT_VLAN_TOS), vlaninfo->tos);
}
+ /*
+ * Print user ip-proto if they are specified
+ */
+ if (GET_BITMASK(EBT_VLAN_IP_PROTO)) {
+ printf("--%s %s0x%2.2x ",
+ opts[VLAN_IP_PROTO].name,
+ INV_FLAG(EBT_VLAN_IP_PROTO), vlaninfo->ip_proto);
+ }
}
@@ -348,6 +388,13 @@ compare(const struct ebt_entry_match *vlan1,
if (vlaninfo1->tos != vlaninfo2->tos)
return 0;
};
+ /*
+ * Compare VLAN ip-proto if they are present
+ */
+ if (vlaninfo1->bitmask & EBT_VLAN_IP_PROTO) {
+ if (vlaninfo1->ip_proto != vlaninfo2->ip_proto)
+ return 0;
+ };
return 1;
}
diff --git a/application/ebtables/include/linux/netfilter_bridge/ebt_vlan.h b/application/ebtables/include/linux/netfilter_bridge/ebt_vlan.h
index 52aa56b2f0..8964c8f5bc 100644
--- a/application/ebtables/include/linux/netfilter_bridge/ebt_vlan.h
+++ b/application/ebtables/include/linux/netfilter_bridge/ebt_vlan.h
@@ -1,11 +1,12 @@
#ifndef __LINUX_BRIDGE_EBT_VLAN_H
#define __LINUX_BRIDGE_EBT_VLAN_H
-#define EBT_VLAN_ID 0x01
-#define EBT_VLAN_PRIO 0x02
-#define EBT_VLAN_ENCAP 0x04
-#define EBT_VLAN_TOS 0x08
-#define EBT_VLAN_MASK (EBT_VLAN_ID | EBT_VLAN_PRIO | EBT_VLAN_ENCAP | EBT_VLAN_TOS)
+#define EBT_VLAN_ID 0x01
+#define EBT_VLAN_PRIO 0x02
+#define EBT_VLAN_ENCAP 0x04
+#define EBT_VLAN_TOS 0x08
+#define EBT_VLAN_IP_PROTO 0x10
+#define EBT_VLAN_MASK (EBT_VLAN_ID | EBT_VLAN_PRIO | EBT_VLAN_ENCAP | EBT_VLAN_TOS | EBT_VLAN_IP_PROTO)
#define EBT_VLAN_MATCH "vlan"
struct ebt_vlan_info {
@@ -13,6 +14,7 @@ struct ebt_vlan_info {
uint8_t prio; /* VLAN User Priority {0-7} */
uint16_t encap; /* VLAN Encapsulated frame code {0-65535} */
uint8_t tos; /* VLAN IP tos {0-255} */
+ uint8_t ip_proto; /* VLAN IP protocol {0-255} */
uint8_t bitmask; /* Args bitmask bit 1=1 - ID arg,
bit 2=1 User-Priority arg, bit 3=1 encap*/
uint8_t invflags; /* Inverse bitmask bit 1=1 - inversed ID arg,
diff --git a/linux-2.6.10/include/linux/netfilter_bridge/ebt_vlan.h b/linux-2.6.10/include/linux/netfilter_bridge/ebt_vlan.h
index 52aa56b2f0..5a2d0fc06a 100644
--- a/linux-2.6.10/include/linux/netfilter_bridge/ebt_vlan.h
+++ b/linux-2.6.10/include/linux/netfilter_bridge/ebt_vlan.h
@@ -1,21 +1,24 @@
#ifndef __LINUX_BRIDGE_EBT_VLAN_H
#define __LINUX_BRIDGE_EBT_VLAN_H
-#define EBT_VLAN_ID 0x01
-#define EBT_VLAN_PRIO 0x02
-#define EBT_VLAN_ENCAP 0x04
-#define EBT_VLAN_TOS 0x08
-#define EBT_VLAN_MASK (EBT_VLAN_ID | EBT_VLAN_PRIO | EBT_VLAN_ENCAP | EBT_VLAN_TOS)
+#define EBT_VLAN_ID 0x01
+#define EBT_VLAN_PRIO 0x02
+#define EBT_VLAN_ENCAP 0x04
+#define EBT_VLAN_TOS 0x08
+#define EBT_VLAN_IP_PROTO 0x10
+#define EBT_VLAN_MASK (EBT_VLAN_ID | EBT_VLAN_PRIO | EBT_VLAN_ENCAP | EBT_VLAN_TOS | EBT_VLAN_IP_PROTO)
#define EBT_VLAN_MATCH "vlan"
struct ebt_vlan_info {
- uint16_t id; /* VLAN ID {1-4095} */
- uint8_t prio; /* VLAN User Priority {0-7} */
- uint16_t encap; /* VLAN Encapsulated frame code {0-65535} */
- uint8_t tos; /* VLAN IP tos {0-255} */
- uint8_t bitmask; /* Args bitmask bit 1=1 - ID arg,
+ uint16_t id; /* VLAN ID {1-4095} */
+ uint8_t prio; /* VLAN User Priority {0-7} */
+ uint16_t encap; /* VLAN Encapsulated frame code {0-65535} */
+
+ uint8_t tos; /* VLAN IP tos {0-255} */
+ uint8_t ip_proto; /* VLAN IP proto {0-255} */
+ uint8_t bitmask; /* Args bitmask bit 1=1 - ID arg,
bit 2=1 User-Priority arg, bit 3=1 encap*/
- uint8_t invflags; /* Inverse bitmask bit 1=1 - inversed ID arg,
+ uint8_t invflags; /* Inverse bitmask bit 1=1 - inversed ID arg,
bit 2=1 - inversed Pirority arg */
};
diff --git a/linux-2.6.10/net/bridge/netfilter/ebt_vlan.c b/linux-2.6.10/net/bridge/netfilter/ebt_vlan.c
index 38346f0d1b..5c53789ae0 100755
--- a/linux-2.6.10/net/bridge/netfilter/ebt_vlan.c
+++ b/linux-2.6.10/net/bridge/netfilter/ebt_vlan.c
@@ -57,6 +57,7 @@ ebt_filter_vlan(const struct sk_buff *skb,
unsigned short id; /* VLAN ID, given from frame TCI */
unsigned char prio; /* user_priority, given from frame TCI */
unsigned char tos; /* IP TOS */
+ unsigned char ip_proto; /* IP protocol */
/* VLAN encapsulated Type/Length field, given from orig frame */
unsigned short encap;
@@ -77,9 +78,15 @@ ebt_filter_vlan(const struct sk_buff *skb,
encap = fp->h_vlan_encapsulated_proto;
ip = skb_header_pointer (skb, sizeof(_frame), sizeof(_iphdr), &_iphdr);
if(ip != NULL)
+ {
tos = ip->tos;
+ ip_proto = ip->protocol;
+ }
else
+ {
tos = 0;
+ ip_proto = 0;
+ }
/* Checking VLAN Identifier (VID) */
if (GET_BITMASK(EBT_VLAN_ID))
@@ -97,6 +104,9 @@ ebt_filter_vlan(const struct sk_buff *skb,
if (GET_BITMASK(EBT_VLAN_TOS) && (ip != NULL))
EXIT_ON_MISMATCH(tos, EBT_VLAN_TOS);
+ if (GET_BITMASK(EBT_VLAN_IP_PROTO) && (ip != NULL))
+ EXIT_ON_MISMATCH(ip_proto, EBT_VLAN_IP_PROTO);
+
return EBT_MATCH;
}
@@ -187,12 +197,16 @@ ebt_check_vlan(const char *tablename,
("encap must be IP type (0x0800)\n");
return -EINVAL;
}
+ }
- if ((unsigned char) info->encap > 255) {
+ /* Check for IP protocol range */
+ if (GET_BITMASK(EBT_VLAN_IP_PROTO)) {
+ if (!GET_BITMASK(EBT_VLAN_ENCAP) || ((unsigned short) ntohs(info->encap) != 0x0800)) {
DEBUG_MSG
- ("TOS value must be less than 256\n");
+ ("encap must be IP type (0x0800)\n");
return -EINVAL;
- }
+ }
+
}