5 * Bart De Schuymer <bdschuym@pandora.be>
10 * added ip-sport and ip-dport
11 * Innominate Security Technologies AG <mhopf@innominate.com>
17 #include <linux/module.h>
18 #include <linux/netfilter/x_tables.h>
19 #include <linux/netfilter_bridge/ebtables.h>
20 #include <linux/netfilter_bridge/ebt_ip.h>
37 ebt_ip_mt(const struct sk_buff
*skb
, struct xt_action_param
*par
)
39 const struct ebt_ip_info
*info
= par
->matchinfo
;
40 const struct iphdr
*ih
;
42 const union pkthdr
*pptr
;
45 ih
= skb_header_pointer(skb
, 0, sizeof(_iph
), &_iph
);
48 if ((info
->bitmask
& EBT_IP_TOS
) &&
49 NF_INVF(info
, EBT_IP_TOS
, info
->tos
!= ih
->tos
))
51 if ((info
->bitmask
& EBT_IP_SOURCE
) &&
52 NF_INVF(info
, EBT_IP_SOURCE
,
53 (ih
->saddr
& info
->smsk
) != info
->saddr
))
55 if ((info
->bitmask
& EBT_IP_DEST
) &&
56 NF_INVF(info
, EBT_IP_DEST
,
57 (ih
->daddr
& info
->dmsk
) != info
->daddr
))
59 if (info
->bitmask
& EBT_IP_PROTO
) {
60 if (NF_INVF(info
, EBT_IP_PROTO
, info
->protocol
!= ih
->protocol
))
62 if (!(info
->bitmask
& (EBT_IP_DPORT
| EBT_IP_SPORT
|
63 EBT_IP_ICMP
| EBT_IP_IGMP
)))
65 if (ntohs(ih
->frag_off
) & IP_OFFSET
)
68 /* min icmp/igmp headersize is 4, so sizeof(_pkthdr) is ok. */
69 pptr
= skb_header_pointer(skb
, ih
->ihl
*4,
70 sizeof(_pkthdr
), &_pkthdr
);
73 if (info
->bitmask
& EBT_IP_DPORT
) {
74 u32 dst
= ntohs(pptr
->tcpudphdr
.dst
);
75 if (NF_INVF(info
, EBT_IP_DPORT
,
76 dst
< info
->dport
[0] ||
77 dst
> info
->dport
[1]))
80 if (info
->bitmask
& EBT_IP_SPORT
) {
81 u32 src
= ntohs(pptr
->tcpudphdr
.src
);
82 if (NF_INVF(info
, EBT_IP_SPORT
,
83 src
< info
->sport
[0] ||
84 src
> info
->sport
[1]))
87 if ((info
->bitmask
& EBT_IP_ICMP
) &&
88 NF_INVF(info
, EBT_IP_ICMP
,
89 pptr
->icmphdr
.type
< info
->icmp_type
[0] ||
90 pptr
->icmphdr
.type
> info
->icmp_type
[1] ||
91 pptr
->icmphdr
.code
< info
->icmp_code
[0] ||
92 pptr
->icmphdr
.code
> info
->icmp_code
[1]))
94 if ((info
->bitmask
& EBT_IP_IGMP
) &&
95 NF_INVF(info
, EBT_IP_IGMP
,
96 pptr
->igmphdr
.type
< info
->igmp_type
[0] ||
97 pptr
->igmphdr
.type
> info
->igmp_type
[1]))
103 static int ebt_ip_mt_check(const struct xt_mtchk_param
*par
)
105 const struct ebt_ip_info
*info
= par
->matchinfo
;
106 const struct ebt_entry
*e
= par
->entryinfo
;
108 if (e
->ethproto
!= htons(ETH_P_IP
) ||
109 e
->invflags
& EBT_IPROTO
)
111 if (info
->bitmask
& ~EBT_IP_MASK
|| info
->invflags
& ~EBT_IP_MASK
)
113 if (info
->bitmask
& (EBT_IP_DPORT
| EBT_IP_SPORT
)) {
114 if (info
->invflags
& EBT_IP_PROTO
)
116 if (info
->protocol
!= IPPROTO_TCP
&&
117 info
->protocol
!= IPPROTO_UDP
&&
118 info
->protocol
!= IPPROTO_UDPLITE
&&
119 info
->protocol
!= IPPROTO_SCTP
&&
120 info
->protocol
!= IPPROTO_DCCP
)
123 if (info
->bitmask
& EBT_IP_DPORT
&& info
->dport
[0] > info
->dport
[1])
125 if (info
->bitmask
& EBT_IP_SPORT
&& info
->sport
[0] > info
->sport
[1])
127 if (info
->bitmask
& EBT_IP_ICMP
) {
128 if ((info
->invflags
& EBT_IP_PROTO
) ||
129 info
->protocol
!= IPPROTO_ICMP
)
131 if (info
->icmp_type
[0] > info
->icmp_type
[1] ||
132 info
->icmp_code
[0] > info
->icmp_code
[1])
135 if (info
->bitmask
& EBT_IP_IGMP
) {
136 if ((info
->invflags
& EBT_IP_PROTO
) ||
137 info
->protocol
!= IPPROTO_IGMP
)
139 if (info
->igmp_type
[0] > info
->igmp_type
[1])
145 static struct xt_match ebt_ip_mt_reg __read_mostly
= {
148 .family
= NFPROTO_BRIDGE
,
150 .checkentry
= ebt_ip_mt_check
,
151 .matchsize
= sizeof(struct ebt_ip_info
),
155 static int __init
ebt_ip_init(void)
157 return xt_register_match(&ebt_ip_mt_reg
);
160 static void __exit
ebt_ip_fini(void)
162 xt_unregister_match(&ebt_ip_mt_reg
);
165 module_init(ebt_ip_init
);
166 module_exit(ebt_ip_fini
);
167 MODULE_DESCRIPTION("Ebtables: IPv4 protocol packet match");
168 MODULE_LICENSE("GPL");