5 * Bart De Schuymer <bdschuym@pandora.be>
10 * added ip-sport and ip-dport
11 * Innominate Security Technologies AG <mhopf@innominate.com>
15 #include <linux/netfilter_bridge/ebtables.h>
16 #include <linux/netfilter_bridge/ebt_ip.h>
19 #include <linux/module.h>
21 #define PPPOE_HDR_OFFSET 8
28 static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in,
29 const struct net_device *out, const void *data,
32 struct ebt_ip_info *info = (struct ebt_ip_info *)data;
33 union {struct iphdr iph; struct tcpudphdr ports;} u;
34 if(ETH_P_PPP_SES!= skb->mac.ethernet->h_proto)
36 if (skb_copy_bits(skb, 0, &u.iph, sizeof(u.iph)))
38 if (info->bitmask & EBT_IP_TOS &&
39 FWINV(info->tos != u.iph.tos, EBT_IP_TOS))
41 if (info->bitmask & EBT_IP_SOURCE &&
42 FWINV((u.iph.saddr & info->smsk) !=
43 info->saddr, EBT_IP_SOURCE))
45 if ((info->bitmask & EBT_IP_DEST) &&
46 FWINV((u.iph.daddr & info->dmsk) !=
47 info->daddr, EBT_IP_DEST))
49 if (info->bitmask & EBT_IP_PROTO) {
50 if (FWINV(info->protocol != u.iph.protocol, EBT_IP_PROTO))
52 if (!(info->bitmask & EBT_IP_DPORT) &&
53 !(info->bitmask & EBT_IP_SPORT))
55 if (skb_copy_bits(skb, u.iph.ihl*4, &u.ports,
58 if (info->bitmask & EBT_IP_DPORT) {
59 u.ports.dst = ntohs(u.ports.dst);
60 if (FWINV(u.ports.dst < info->dport[0] ||
61 u.ports.dst > info->dport[1],
65 if (info->bitmask & EBT_IP_SPORT) {
66 u.ports.src = ntohs(u.ports.src);
67 if (FWINV(u.ports.src < info->sport[0] ||
68 u.ports.src > info->sport[1],
77 if (skb_copy_bits(skb, PPPOE_HDR_OFFSET, &u.iph, sizeof(u.iph)))
79 if (info->bitmask & EBT_IP_TOS &&
80 FWINV(info->tos != u.iph.tos, EBT_IP_TOS))
82 if (info->bitmask & EBT_IP_SOURCE &&
83 FWINV((u.iph.saddr & info->smsk) !=
84 info->saddr, EBT_IP_SOURCE))
86 if ((info->bitmask & EBT_IP_DEST) &&
87 FWINV((u.iph.daddr & info->dmsk) !=
88 info->daddr, EBT_IP_DEST))
90 if (info->bitmask & EBT_IP_PROTO) {
91 if (FWINV(info->protocol != u.iph.protocol, EBT_IP_PROTO))
93 if (!(info->bitmask & EBT_IP_DPORT) &&
94 !(info->bitmask & EBT_IP_SPORT))
96 if (skb_copy_bits(skb, u.iph.ihl*4+PPPOE_HDR_OFFSET, &u.ports,
99 if (info->bitmask & EBT_IP_DPORT) {
100 u.ports.dst = ntohs(u.ports.dst);
101 if (FWINV(u.ports.dst < info->dport[0] ||
102 u.ports.dst > info->dport[1],
106 if (info->bitmask & EBT_IP_SPORT) {
107 u.ports.src = ntohs(u.ports.src);
108 if (FWINV(u.ports.src < info->sport[0] ||
109 u.ports.src > info->sport[1],
118 static int ebt_ip_check(const char *tablename, unsigned int hookmask,
119 const struct ebt_entry *e, void *data, unsigned int datalen)
121 struct ebt_ip_info *info = (struct ebt_ip_info *)data;
123 if (datalen != EBT_ALIGN(sizeof(struct ebt_ip_info)))
125 if (e->ethproto != __constant_htons(ETH_P_IP) ||
126 e->invflags & EBT_IPROTO)
128 if (info->bitmask & ~EBT_IP_MASK || info->invflags & ~EBT_IP_MASK)
130 if (info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT)) {
131 if (info->invflags & EBT_IP_PROTO)
133 if (info->protocol != IPPROTO_TCP &&
134 info->protocol != IPPROTO_UDP)
137 if (info->bitmask & EBT_IP_DPORT && info->dport[0] > info->dport[1])
139 if (info->bitmask & EBT_IP_SPORT && info->sport[0] > info->sport[1])
144 static struct ebt_match filter_ip =
146 .name = EBT_IP_MATCH,
147 .match = ebt_filter_ip,
148 .check = ebt_ip_check,
152 static int __init init(void)
154 return ebt_register_match(&filter_ip);
157 static void __exit fini(void)
159 ebt_unregister_match(&filter_ip);
164 MODULE_LICENSE("GPL");