aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorLaszlo Attila Toth <panther@balabit.hu>2007-12-05 02:30:18 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:55:56 -0500
commite2cf5ecbea861ff05105bbd40f4f0d7823d9e213 (patch)
treef1563dbe6d1e3c06f63d966e43d5c777c912ca4a /net/ipv4
parent0553811612a6178365f3b062c30234913b218a96 (diff)
[NETFILTER]: ipt_addrtype: limit address type checking to an interface
Addrtype match has a new revision (1), which lets address type checking limited to the interface the current packet belongs to. Either incoming or outgoing interface can be used depending on the current hook. In the FORWARD hook two maches should be used if both interfaces have to be checked. The new structure is ipt_addrtype_info_v1. Revision 0 lets older userspace programs use the match as earlier. ipt_addrtype_info is used. Signed-off-by: Laszlo Attila Toth <panther@balabit.hu> Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/netfilter/ipt_addrtype.c104
1 files changed, 88 insertions, 16 deletions
diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c
index b75421c5e087..14394c6a3c29 100644
--- a/net/ipv4/netfilter/ipt_addrtype.c
+++ b/net/ipv4/netfilter/ipt_addrtype.c
@@ -2,6 +2,7 @@
2 * iptables module to match inet_addr_type() of an ip. 2 * iptables module to match inet_addr_type() of an ip.
3 * 3 *
4 * Copyright (c) 2004 Patrick McHardy <kaber@trash.net> 4 * Copyright (c) 2004 Patrick McHardy <kaber@trash.net>
5 * (C) 2007 Laszlo Attila Toth <panther@balabit.hu>
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -22,45 +23,116 @@ MODULE_LICENSE("GPL");
22MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 23MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
23MODULE_DESCRIPTION("iptables addrtype match"); 24MODULE_DESCRIPTION("iptables addrtype match");
24 25
25static inline bool match_type(__be32 addr, u_int16_t mask) 26static inline bool match_type(const struct net_device *dev, __be32 addr,
27 u_int16_t mask)
26{ 28{
27 return !!(mask & (1 << inet_addr_type(addr))); 29 return !!(mask & (1 << inet_dev_addr_type(dev, addr)));
28} 30}
29 31
30static bool 32static bool
31addrtype_mt(const struct sk_buff *skb, const struct net_device *in, 33addrtype_mt_v0(const struct sk_buff *skb, const struct net_device *in,
32 const struct net_device *out, const struct xt_match *match, 34 const struct net_device *out, const struct xt_match *match,
33 const void *matchinfo, int offset, unsigned int protoff, 35 const void *matchinfo, int offset, unsigned int protoff,
34 bool *hotdrop) 36 bool *hotdrop)
35{ 37{
36 const struct ipt_addrtype_info *info = matchinfo; 38 const struct ipt_addrtype_info *info = matchinfo;
37 const struct iphdr *iph = ip_hdr(skb); 39 const struct iphdr *iph = ip_hdr(skb);
38 bool ret = true; 40 bool ret = true;
39 41
40 if (info->source) 42 if (info->source)
41 ret &= match_type(iph->saddr, info->source)^info->invert_source; 43 ret &= match_type(NULL, iph->saddr, info->source) ^
44 info->invert_source;
42 if (info->dest) 45 if (info->dest)
43 ret &= match_type(iph->daddr, info->dest)^info->invert_dest; 46 ret &= match_type(NULL, iph->daddr, info->dest) ^
47 info->invert_dest;
44 48
45 return ret; 49 return ret;
46} 50}
47 51
48static struct xt_match addrtype_mt_reg __read_mostly = { 52static bool
49 .name = "addrtype", 53addrtype_mt_v1(const struct sk_buff *skb, const struct net_device *in,
50 .family = AF_INET, 54 const struct net_device *out, const struct xt_match *match,
51 .match = addrtype_mt, 55 const void *matchinfo, int offset, unsigned int protoff,
52 .matchsize = sizeof(struct ipt_addrtype_info), 56 bool *hotdrop)
53 .me = THIS_MODULE 57{
58 const struct ipt_addrtype_info_v1 *info = matchinfo;
59 const struct iphdr *iph = ip_hdr(skb);
60 const struct net_device *dev = NULL;
61 bool ret = true;
62
63 if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN)
64 dev = in;
65 else if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT)
66 dev = out;
67
68 if (info->source)
69 ret &= match_type(dev, iph->saddr, info->source) ^
70 (info->flags & IPT_ADDRTYPE_INVERT_SOURCE);
71 if (ret && info->dest)
72 ret &= match_type(dev, iph->daddr, info->dest) ^
73 (info->flags & IPT_ADDRTYPE_INVERT_DEST);
74 return ret;
75}
76
77static bool
78addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void,
79 const struct xt_match *match, void *matchinfo,
80 unsigned int hook_mask)
81{
82 struct ipt_addrtype_info_v1 *info = matchinfo;
83
84 if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN &&
85 info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
86 printk(KERN_ERR "ipt_addrtype: both incoming and outgoing "
87 "interface limitation cannot be selected\n");
88 return false;
89 }
90
91 if (hook_mask & (1 << NF_INET_PRE_ROUTING | 1 << NF_INET_LOCAL_IN) &&
92 info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
93 printk(KERN_ERR "ipt_addrtype: output interface limitation "
94 "not valid in PRE_ROUTING and INPUT\n");
95 return false;
96 }
97
98 if (hook_mask & (1 << NF_INET_POST_ROUTING | 1 << NF_INET_LOCAL_OUT) &&
99 info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) {
100 printk(KERN_ERR "ipt_addrtype: input interface limitation "
101 "not valid in POST_ROUTING and OUTPUT\n");
102 return false;
103 }
104
105 return true;
106}
107
108static struct xt_match addrtype_mt_reg[] __read_mostly = {
109 {
110 .name = "addrtype",
111 .family = AF_INET,
112 .match = addrtype_mt_v0,
113 .matchsize = sizeof(struct ipt_addrtype_info),
114 .me = THIS_MODULE
115 },
116 {
117 .name = "addrtype",
118 .family = AF_INET,
119 .revision = 1,
120 .match = addrtype_mt_v1,
121 .checkentry = addrtype_mt_checkentry_v1,
122 .matchsize = sizeof(struct ipt_addrtype_info_v1),
123 .me = THIS_MODULE
124 }
54}; 125};
55 126
56static int __init addrtype_mt_init(void) 127static int __init addrtype_mt_init(void)
57{ 128{
58 return xt_register_match(&addrtype_mt_reg); 129 return xt_register_matches(addrtype_mt_reg,
130 ARRAY_SIZE(addrtype_mt_reg));
59} 131}
60 132
61static void __exit addrtype_mt_exit(void) 133static void __exit addrtype_mt_exit(void)
62{ 134{
63 xt_unregister_match(&addrtype_mt_reg); 135 xt_unregister_matches(addrtype_mt_reg, ARRAY_SIZE(addrtype_mt_reg));
64} 136}
65 137
66module_init(addrtype_mt_init); 138module_init(addrtype_mt_init);