--- linux-2.4.20-pre7/net/bridge/netfilter/ebt_ip.c Thu Oct 17 23:35:25 2002 +++ linux-2.4.20-pre7-bcnt/net/bridge/netfilter/ebt_ip.c Thu Oct 17 23:22:58 2002 @@ -6,13 +6,28 @@ * * April, 2002 * + * Changes: + * added ip-sport and ip-dport + * Innominate Security Technologies AG + * September, 2002 */ #include #include #include +#include #include +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 @@ 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)) @@ -47,6 +84,17 @@ e->invflags & EBT_IPROTO) 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; } --- linux-2.4.20-pre7/net/bridge/netfilter/ebtables.c Thu Oct 17 23:35:25 2002 +++ linux-2.4.20-pre7-bcnt/net/bridge/netfilter/ebtables.c Thu Oct 17 21:58:08 2002 @@ -194,6 +194,7 @@ // increase counter (*(counter_base + i)).pcnt++; + (*(counter_base + i)).bcnt+=(**pskb).len; // these should only watch: not modify, nor tell us // what to do with the packet @@ -885,8 +886,10 @@ // add other counters to those of cpu 0 for (cpu = 1; cpu < smp_num_cpus; cpu++) { counter_base = COUNTER_BASE(oldcounters, nentries, cpu); - for (i = 0; i < nentries; i++) + for (i = 0; i < nentries; i++) { counters[i].pcnt += counter_base[i].pcnt; + counters[i].bcnt += counter_base[i].bcnt; + } } } @@ -1245,8 +1248,10 @@ write_lock_bh(&t->lock); // we add to the counters of the first cpu - for (i = 0; i < hlp.num_counters; i++) + for (i = 0; i < hlp.num_counters; i++) { t->private->counters[i].pcnt += tmp[i].pcnt; + t->private->counters[i].bcnt += tmp[i].bcnt; + } write_unlock_bh(&t->lock); ret = 0; --- linux-2.4.20-pre7/include/linux/netfilter_bridge/ebtables.h Thu Oct 17 23:35:25 2002 +++ linux-2.4.20-pre7-bcnt/include/linux/netfilter_bridge/ebtables.h Thu Oct 17 22:41:32 2002 @@ -30,6 +30,7 @@ struct ebt_counter { uint64_t pcnt; + uint64_t bcnt; }; struct ebt_entries { @@ -161,8 +162,6 @@ char *entries; }; -#ifdef __KERNEL__ - // [gs]etsockopt numbers #define EBT_BASE_CTL 128 @@ -175,6 +174,8 @@ #define EBT_SO_GET_INIT_INFO (EBT_SO_GET_ENTRIES+1) #define EBT_SO_GET_INIT_ENTRIES (EBT_SO_GET_INIT_INFO+1) #define EBT_SO_GET_MAX (EBT_SO_GET_INIT_ENTRIES+1) + +#ifdef __KERNEL__ // return values for match() functions #define EBT_MATCH 0 --- linux-2.4.20-pre7/include/linux/netfilter_bridge/ebt_ip.h Thu Oct 17 23:35:25 2002 +++ linux-2.4.20-pre7-bcnt/include/linux/netfilter_bridge/ebt_ip.h Thu Oct 17 23:22:45 2002 @@ -1,3 +1,17 @@ +/* + * ebt_ip + * + * Authors: + * Bart De Schuymer + * + * April, 2002 + * + * Changes: + * added ip-sport and ip-dport + * Innominate Security Technologies AG + * 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 @@ uint8_t protocol; uint8_t bitmask; uint8_t invflags; + uint16_t sport[2]; + uint16_t dport[2]; }; #endif