diff options
author | Bart De Schuymer <bdschuym@pandora.be> | 2002-09-19 21:17:37 +0000 |
---|---|---|
committer | Bart De Schuymer <bdschuym@pandora.be> | 2002-09-19 21:17:37 +0000 |
commit | feb06ca5660d3dc0bcf481f130b4ff172313ecd3 (patch) | |
tree | d3029d5889f158abab64a39c26cfcc7f554f29fc /kernel | |
parent | 69f0b7bb9030477ccbc604a1cc2ae54bd6f3e38b (diff) | |
download | android_external_ebtables-feb06ca5660d3dc0bcf481f130b4ff172313ecd3.tar.gz android_external_ebtables-feb06ca5660d3dc0bcf481f130b4ff172313ecd3.tar.bz2 android_external_ebtables-feb06ca5660d3dc0bcf481f130b4ff172313ecd3.zip |
mhopf@innominate.com add tcp/udp ports
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/linux/include/linux/netfilter_bridge/ebt_ip.h | 21 | ||||
-rw-r--r-- | kernel/linux/net/bridge/netfilter/ebt_ip.c | 54 |
2 files changed, 71 insertions, 4 deletions
diff --git a/kernel/linux/include/linux/netfilter_bridge/ebt_ip.h b/kernel/linux/include/linux/netfilter_bridge/ebt_ip.h index b2791e0..499089b 100644 --- a/kernel/linux/include/linux/netfilter_bridge/ebt_ip.h +++ b/kernel/linux/include/linux/netfilter_bridge/ebt_ip.h @@ -1,3 +1,17 @@ +/* + * ebt_ip + * + * Authors: + * Bart De Schuymer <bart.de.schuymer@pandora.be> + * + * April, 2002 + * + * Changes: + * added ip-sport and ip-dport + * Innominate Security Technologies AG <mhopf@innominate.com> + * September, 2002 + */ + #ifndef __LINUX_BRIDGE_EBT_IP_H #define __LINUX_BRIDGE_EBT_IP_H @@ -5,7 +19,10 @@ #define EBT_IP_DEST 0x02 #define EBT_IP_TOS 0x04 #define EBT_IP_PROTO 0x08 -#define EBT_IP_MASK (EBT_IP_SOURCE | EBT_IP_DEST | EBT_IP_TOS | EBT_IP_PROTO) +#define EBT_IP_SPORT 0x10 +#define EBT_IP_DPORT 0x20 +#define EBT_IP_MASK (EBT_IP_SOURCE | EBT_IP_DEST | EBT_IP_TOS | EBT_IP_PROTO |\ + EBT_IP_SPORT | EBT_IP_DPORT ) #define EBT_IP_MATCH "ip" // the same values are used for the invflags @@ -19,6 +36,8 @@ struct ebt_ip_info uint8_t protocol; uint8_t bitmask; uint8_t invflags; + uint16_t sport[2]; + uint16_t dport[2]; }; #endif diff --git a/kernel/linux/net/bridge/netfilter/ebt_ip.c b/kernel/linux/net/bridge/netfilter/ebt_ip.c index 329ecd6..59c27bd 100644 --- a/kernel/linux/net/bridge/netfilter/ebt_ip.c +++ b/kernel/linux/net/bridge/netfilter/ebt_ip.c @@ -6,13 +6,28 @@ * * April, 2002 * + * Changes: + * added ip-sport and ip-dport + * Innominate Security Technologies AG <mhopf@innominate.com> + * September, 2002 */ #include <linux/netfilter_bridge/ebtables.h> #include <linux/netfilter_bridge/ebt_ip.h> #include <linux/ip.h> +#include <linux/in.h> #include <linux/module.h> +struct tcpudphdr { + uint16_t src; + uint16_t dst; +}; + +union h_u { + unsigned char *raw; + struct tcpudphdr *tuh; +}; + static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const void *data, unsigned int datalen) @@ -22,9 +37,31 @@ static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in, if (info->bitmask & EBT_IP_TOS && FWINV(info->tos != ((*skb).nh.iph)->tos, EBT_IP_TOS)) return EBT_NOMATCH; - if (info->bitmask & EBT_IP_PROTO && FWINV(info->protocol != - ((*skb).nh.iph)->protocol, EBT_IP_PROTO)) - return EBT_NOMATCH; + if (info->bitmask & EBT_IP_PROTO) { + if (FWINV(info->protocol != ((*skb).nh.iph)->protocol, + EBT_IP_PROTO)) + return EBT_NOMATCH; + if ( info->protocol == IPPROTO_TCP || + info->protocol == IPPROTO_UDP ) + { + union h_u h; + h.raw = skb->data + skb->nh.iph->ihl*4; + if (info->bitmask & EBT_IP_DPORT) { + uint16_t port = ntohs(h.tuh->dst); + if (FWINV(port < info->dport[0] || + port > info->dport[1], + EBT_IP_DPORT)) + return EBT_NOMATCH; + } + if (info->bitmask & EBT_IP_SPORT) { + uint16_t port = ntohs(h.tuh->src); + if (FWINV(port < info->sport[0] || + port > info->sport[1], + EBT_IP_SPORT)) + return EBT_NOMATCH; + } + } + } if (info->bitmask & EBT_IP_SOURCE && FWINV((((*skb).nh.iph)->saddr & info->smsk) != info->saddr, EBT_IP_SOURCE)) @@ -48,6 +85,17 @@ static int ebt_ip_check(const char *tablename, unsigned int hookmask, return -EINVAL; if (info->bitmask & ~EBT_IP_MASK || info->invflags & ~EBT_IP_MASK) return -EINVAL; + if (info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT)) { + if (!info->bitmask & EBT_IPROTO) + return -EINVAL; + if (info->protocol != IPPROTO_TCP && + info->protocol != IPPROTO_UDP) + return -EINVAL; + } + if (info->bitmask & EBT_IP_DPORT && info->dport[0] > info->dport[1]) + return -EINVAL; + if (info->bitmask & EBT_IP_SPORT && info->sport[0] > info->sport[1]) + return -EINVAL; return 0; } |