Commit 524c4554 authored by Mark-André Hopf's avatar Mark-André Hopf Committed by David S. Miller

[EBTABLES]: Add tcp/udp port checking.

parent 575f5a13
/*
* 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
......@@ -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))
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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment