Commit 1d5cd909 authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller

[NETFILTER]: Convert ip_tables matches/targets to centralized error checking

Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3cdc7c95
...@@ -181,23 +181,6 @@ static int ipt_snat_checkentry(const char *tablename, ...@@ -181,23 +181,6 @@ static int ipt_snat_checkentry(const char *tablename,
printk("SNAT: multiple ranges no longer supported\n"); printk("SNAT: multiple ranges no longer supported\n");
return 0; return 0;
} }
if (targinfosize != IPT_ALIGN(sizeof(struct ip_nat_multi_range_compat))) {
DEBUGP("SNAT: Target size %u wrong for %u ranges\n",
targinfosize, mr->rangesize);
return 0;
}
/* Only allow these for NAT. */
if (strcmp(tablename, "nat") != 0) {
DEBUGP("SNAT: wrong table %s\n", tablename);
return 0;
}
if (hook_mask & ~(1 << NF_IP_POST_ROUTING)) {
DEBUGP("SNAT: hook mask 0x%x bad\n", hook_mask);
return 0;
}
return 1; return 1;
} }
...@@ -214,24 +197,6 @@ static int ipt_dnat_checkentry(const char *tablename, ...@@ -214,24 +197,6 @@ static int ipt_dnat_checkentry(const char *tablename,
printk("DNAT: multiple ranges no longer supported\n"); printk("DNAT: multiple ranges no longer supported\n");
return 0; return 0;
} }
if (targinfosize != IPT_ALIGN(sizeof(struct ip_nat_multi_range_compat))) {
DEBUGP("DNAT: Target size %u wrong for %u ranges\n",
targinfosize, mr->rangesize);
return 0;
}
/* Only allow these for NAT. */
if (strcmp(tablename, "nat") != 0) {
DEBUGP("DNAT: wrong table %s\n", tablename);
return 0;
}
if (hook_mask & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT))) {
DEBUGP("DNAT: hook mask 0x%x bad\n", hook_mask);
return 0;
}
return 1; return 1;
} }
...@@ -299,12 +264,18 @@ int ip_nat_rule_find(struct sk_buff **pskb, ...@@ -299,12 +264,18 @@ int ip_nat_rule_find(struct sk_buff **pskb,
static struct ipt_target ipt_snat_reg = { static struct ipt_target ipt_snat_reg = {
.name = "SNAT", .name = "SNAT",
.target = ipt_snat_target, .target = ipt_snat_target,
.targetsize = sizeof(struct ip_nat_multi_range_compat),
.table = "nat",
.hooks = 1 << NF_IP_POST_ROUTING,
.checkentry = ipt_snat_checkentry, .checkentry = ipt_snat_checkentry,
}; };
static struct ipt_target ipt_dnat_reg = { static struct ipt_target ipt_dnat_reg = {
.name = "DNAT", .name = "DNAT",
.target = ipt_dnat_target, .target = ipt_dnat_target,
.targetsize = sizeof(struct ip_nat_multi_range_compat),
.table = "nat",
.hooks = 1 << NF_IP_PRE_ROUTING,
.checkentry = ipt_dnat_checkentry, .checkentry = ipt_dnat_checkentry,
}; };
......
...@@ -477,21 +477,12 @@ standard_check(const struct ipt_entry_target *t, ...@@ -477,21 +477,12 @@ standard_check(const struct ipt_entry_target *t,
struct ipt_standard_target *targ = (void *)t; struct ipt_standard_target *targ = (void *)t;
/* Check standard info. */ /* Check standard info. */
if (t->u.target_size
!= IPT_ALIGN(sizeof(struct ipt_standard_target))) {
duprintf("standard_check: target size %u != %u\n",
t->u.target_size,
IPT_ALIGN(sizeof(struct ipt_standard_target)));
return 0;
}
if (targ->verdict >= 0 if (targ->verdict >= 0
&& targ->verdict > max_offset - sizeof(struct ipt_entry)) { && targ->verdict > max_offset - sizeof(struct ipt_entry)) {
duprintf("ipt_standard_check: bad verdict (%i)\n", duprintf("ipt_standard_check: bad verdict (%i)\n",
targ->verdict); targ->verdict);
return 0; return 0;
} }
if (targ->verdict < -NF_MAX_VERDICT - 1) { if (targ->verdict < -NF_MAX_VERDICT - 1) {
duprintf("ipt_standard_check: bad negative verdict (%i)\n", duprintf("ipt_standard_check: bad negative verdict (%i)\n",
targ->verdict); targ->verdict);
...@@ -1330,24 +1321,22 @@ icmp_checkentry(const char *tablename, ...@@ -1330,24 +1321,22 @@ icmp_checkentry(const char *tablename,
unsigned int matchsize, unsigned int matchsize,
unsigned int hook_mask) unsigned int hook_mask)
{ {
const struct ipt_ip *ip = info;
const struct ipt_icmp *icmpinfo = matchinfo; const struct ipt_icmp *icmpinfo = matchinfo;
/* Must specify proto == ICMP, and no unknown invflags */ /* Must specify no unknown invflags */
return ip->proto == IPPROTO_ICMP return !(icmpinfo->invflags & ~IPT_ICMP_INV);
&& !(ip->invflags & IPT_INV_PROTO)
&& matchsize == IPT_ALIGN(sizeof(struct ipt_icmp))
&& !(icmpinfo->invflags & ~IPT_ICMP_INV);
} }
/* The built-in targets: standard (NULL) and error. */ /* The built-in targets: standard (NULL) and error. */
static struct ipt_target ipt_standard_target = { static struct ipt_target ipt_standard_target = {
.name = IPT_STANDARD_TARGET, .name = IPT_STANDARD_TARGET,
.targetsize = sizeof(int),
}; };
static struct ipt_target ipt_error_target = { static struct ipt_target ipt_error_target = {
.name = IPT_ERROR_TARGET, .name = IPT_ERROR_TARGET,
.target = ipt_error, .target = ipt_error,
.targetsize = IPT_FUNCTION_MAXNAMELEN,
}; };
static struct nf_sockopt_ops ipt_sockopts = { static struct nf_sockopt_ops ipt_sockopts = {
...@@ -1362,8 +1351,10 @@ static struct nf_sockopt_ops ipt_sockopts = { ...@@ -1362,8 +1351,10 @@ static struct nf_sockopt_ops ipt_sockopts = {
static struct ipt_match icmp_matchstruct = { static struct ipt_match icmp_matchstruct = {
.name = "icmp", .name = "icmp",
.match = &icmp_match, .match = icmp_match,
.checkentry = &icmp_checkentry, .matchsize = sizeof(struct ipt_icmp),
.proto = IPPROTO_ICMP,
.checkentry = icmp_checkentry,
}; };
static int __init init(void) static int __init init(void)
......
...@@ -389,13 +389,6 @@ checkentry(const char *tablename, ...@@ -389,13 +389,6 @@ checkentry(const char *tablename,
struct clusterip_config *config; struct clusterip_config *config;
if (targinfosize != IPT_ALIGN(sizeof(struct ipt_clusterip_tgt_info))) {
printk(KERN_WARNING "CLUSTERIP: targinfosize %u != %Zu\n",
targinfosize,
IPT_ALIGN(sizeof(struct ipt_clusterip_tgt_info)));
return 0;
}
if (cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP && if (cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP &&
cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT && cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT &&
cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT_DPT) { cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT_DPT) {
...@@ -476,12 +469,13 @@ static void destroy(void *matchinfo, unsigned int matchinfosize) ...@@ -476,12 +469,13 @@ static void destroy(void *matchinfo, unsigned int matchinfosize)
clusterip_config_put(cipinfo->config); clusterip_config_put(cipinfo->config);
} }
static struct ipt_target clusterip_tgt = { static struct ipt_target clusterip_tgt = {
.name = "CLUSTERIP", .name = "CLUSTERIP",
.target = &target, .target = target,
.checkentry = &checkentry, .targetsize = sizeof(struct ipt_clusterip_tgt_info),
.destroy = &destroy, .checkentry = checkentry,
.me = THIS_MODULE .destroy = destroy,
.me = THIS_MODULE
}; };
......
...@@ -64,29 +64,18 @@ checkentry(const char *tablename, ...@@ -64,29 +64,18 @@ checkentry(const char *tablename,
{ {
const u_int8_t dscp = ((struct ipt_DSCP_info *)targinfo)->dscp; const u_int8_t dscp = ((struct ipt_DSCP_info *)targinfo)->dscp;
if (targinfosize != IPT_ALIGN(sizeof(struct ipt_DSCP_info))) {
printk(KERN_WARNING "DSCP: targinfosize %u != %Zu\n",
targinfosize,
IPT_ALIGN(sizeof(struct ipt_DSCP_info)));
return 0;
}
if (strcmp(tablename, "mangle") != 0) {
printk(KERN_WARNING "DSCP: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
return 0;
}
if ((dscp > IPT_DSCP_MAX)) { if ((dscp > IPT_DSCP_MAX)) {
printk(KERN_WARNING "DSCP: dscp %x out of range\n", dscp); printk(KERN_WARNING "DSCP: dscp %x out of range\n", dscp);
return 0; return 0;
} }
return 1; return 1;
} }
static struct ipt_target ipt_dscp_reg = { static struct ipt_target ipt_dscp_reg = {
.name = "DSCP", .name = "DSCP",
.target = target, .target = target,
.targetsize = sizeof(struct ipt_DSCP_info),
.table = "mangle",
.checkentry = checkentry, .checkentry = checkentry,
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -121,18 +121,6 @@ checkentry(const char *tablename, ...@@ -121,18 +121,6 @@ checkentry(const char *tablename,
const struct ipt_ECN_info *einfo = (struct ipt_ECN_info *)targinfo; const struct ipt_ECN_info *einfo = (struct ipt_ECN_info *)targinfo;
const struct ipt_entry *e = e_void; const struct ipt_entry *e = e_void;
if (targinfosize != IPT_ALIGN(sizeof(struct ipt_ECN_info))) {
printk(KERN_WARNING "ECN: targinfosize %u != %Zu\n",
targinfosize,
IPT_ALIGN(sizeof(struct ipt_ECN_info)));
return 0;
}
if (strcmp(tablename, "mangle") != 0) {
printk(KERN_WARNING "ECN: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
return 0;
}
if (einfo->operation & IPT_ECN_OP_MASK) { if (einfo->operation & IPT_ECN_OP_MASK) {
printk(KERN_WARNING "ECN: unsupported ECN operation %x\n", printk(KERN_WARNING "ECN: unsupported ECN operation %x\n",
einfo->operation); einfo->operation);
...@@ -143,20 +131,20 @@ checkentry(const char *tablename, ...@@ -143,20 +131,20 @@ checkentry(const char *tablename,
einfo->ip_ect); einfo->ip_ect);
return 0; return 0;
} }
if ((einfo->operation & (IPT_ECN_OP_SET_ECE|IPT_ECN_OP_SET_CWR)) if ((einfo->operation & (IPT_ECN_OP_SET_ECE|IPT_ECN_OP_SET_CWR))
&& (e->ip.proto != IPPROTO_TCP || (e->ip.invflags & IPT_INV_PROTO))) { && (e->ip.proto != IPPROTO_TCP || (e->ip.invflags & IPT_INV_PROTO))) {
printk(KERN_WARNING "ECN: cannot use TCP operations on a " printk(KERN_WARNING "ECN: cannot use TCP operations on a "
"non-tcp rule\n"); "non-tcp rule\n");
return 0; return 0;
} }
return 1; return 1;
} }
static struct ipt_target ipt_ecn_reg = { static struct ipt_target ipt_ecn_reg = {
.name = "ECN", .name = "ECN",
.target = target, .target = target,
.targetsize = sizeof(struct ipt_ECN_info),
.table = "mangle",
.checkentry = checkentry, .checkentry = checkentry,
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -443,29 +443,22 @@ static int ipt_log_checkentry(const char *tablename, ...@@ -443,29 +443,22 @@ static int ipt_log_checkentry(const char *tablename,
{ {
const struct ipt_log_info *loginfo = targinfo; const struct ipt_log_info *loginfo = targinfo;
if (targinfosize != IPT_ALIGN(sizeof(struct ipt_log_info))) {
DEBUGP("LOG: targinfosize %u != %u\n",
targinfosize, IPT_ALIGN(sizeof(struct ipt_log_info)));
return 0;
}
if (loginfo->level >= 8) { if (loginfo->level >= 8) {
DEBUGP("LOG: level %u >= 8\n", loginfo->level); DEBUGP("LOG: level %u >= 8\n", loginfo->level);
return 0; return 0;
} }
if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') { if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
DEBUGP("LOG: prefix term %i\n", DEBUGP("LOG: prefix term %i\n",
loginfo->prefix[sizeof(loginfo->prefix)-1]); loginfo->prefix[sizeof(loginfo->prefix)-1]);
return 0; return 0;
} }
return 1; return 1;
} }
static struct ipt_target ipt_log_reg = { static struct ipt_target ipt_log_reg = {
.name = "LOG", .name = "LOG",
.target = ipt_log_target, .target = ipt_log_target,
.targetsize = sizeof(struct ipt_log_info),
.checkentry = ipt_log_checkentry, .checkentry = ipt_log_checkentry,
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -47,19 +47,6 @@ masquerade_check(const char *tablename, ...@@ -47,19 +47,6 @@ masquerade_check(const char *tablename,
{ {
const struct ip_nat_multi_range_compat *mr = targinfo; const struct ip_nat_multi_range_compat *mr = targinfo;
if (strcmp(tablename, "nat") != 0) {
DEBUGP("masquerade_check: bad table `%s'.\n", tablename);
return 0;
}
if (targinfosize != IPT_ALIGN(sizeof(*mr))) {
DEBUGP("masquerade_check: size %u != %u.\n",
targinfosize, sizeof(*mr));
return 0;
}
if (hook_mask & ~(1 << NF_IP_POST_ROUTING)) {
DEBUGP("masquerade_check: bad hooks %x.\n", hook_mask);
return 0;
}
if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
DEBUGP("masquerade_check: bad MAP_IPS.\n"); DEBUGP("masquerade_check: bad MAP_IPS.\n");
return 0; return 0;
...@@ -179,6 +166,9 @@ static struct notifier_block masq_inet_notifier = { ...@@ -179,6 +166,9 @@ static struct notifier_block masq_inet_notifier = {
static struct ipt_target masquerade = { static struct ipt_target masquerade = {
.name = "MASQUERADE", .name = "MASQUERADE",
.target = masquerade_target, .target = masquerade_target,
.targetsize = sizeof(struct ip_nat_multi_range_compat),
.table = "nat",
.hooks = 1 << NF_IP_POST_ROUTING,
.checkentry = masquerade_check, .checkentry = masquerade_check,
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -38,19 +38,6 @@ check(const char *tablename, ...@@ -38,19 +38,6 @@ check(const char *tablename,
{ {
const struct ip_nat_multi_range_compat *mr = targinfo; const struct ip_nat_multi_range_compat *mr = targinfo;
if (strcmp(tablename, "nat") != 0) {
DEBUGP(MODULENAME":check: bad table `%s'.\n", tablename);
return 0;
}
if (targinfosize != IPT_ALIGN(sizeof(*mr))) {
DEBUGP(MODULENAME":check: size %u.\n", targinfosize);
return 0;
}
if (hook_mask & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_POST_ROUTING) |
(1 << NF_IP_LOCAL_OUT))) {
DEBUGP(MODULENAME":check: bad hooks %x.\n", hook_mask);
return 0;
}
if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) { if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) {
DEBUGP(MODULENAME":check: bad MAP_IPS.\n"); DEBUGP(MODULENAME":check: bad MAP_IPS.\n");
return 0; return 0;
...@@ -101,6 +88,10 @@ target(struct sk_buff **pskb, ...@@ -101,6 +88,10 @@ target(struct sk_buff **pskb,
static struct ipt_target target_module = { static struct ipt_target target_module = {
.name = MODULENAME, .name = MODULENAME,
.target = target, .target = target,
.targetsize = sizeof(struct ip_nat_multi_range_compat),
.table = "nat",
.hooks = (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_POST_ROUTING) |
(1 << NF_IP_LOCAL_OUT),
.checkentry = check, .checkentry = check,
.me = THIS_MODULE .me = THIS_MODULE
}; };
......
...@@ -40,18 +40,6 @@ redirect_check(const char *tablename, ...@@ -40,18 +40,6 @@ redirect_check(const char *tablename,
{ {
const struct ip_nat_multi_range_compat *mr = targinfo; const struct ip_nat_multi_range_compat *mr = targinfo;
if (strcmp(tablename, "nat") != 0) {
DEBUGP("redirect_check: bad table `%s'.\n", table);
return 0;
}
if (targinfosize != IPT_ALIGN(sizeof(*mr))) {
DEBUGP("redirect_check: size %u.\n", targinfosize);
return 0;
}
if (hook_mask & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT))) {
DEBUGP("redirect_check: bad hooks %x.\n", hook_mask);
return 0;
}
if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
DEBUGP("redirect_check: bad MAP_IPS.\n"); DEBUGP("redirect_check: bad MAP_IPS.\n");
return 0; return 0;
...@@ -115,6 +103,9 @@ redirect_target(struct sk_buff **pskb, ...@@ -115,6 +103,9 @@ redirect_target(struct sk_buff **pskb,
static struct ipt_target redirect_reg = { static struct ipt_target redirect_reg = {
.name = "REDIRECT", .name = "REDIRECT",
.target = redirect_target, .target = redirect_target,
.targetsize = sizeof(struct ip_nat_multi_range_compat),
.table = "nat",
.hooks = (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT),
.checkentry = redirect_check, .checkentry = redirect_check,
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -290,23 +290,6 @@ static int check(const char *tablename, ...@@ -290,23 +290,6 @@ static int check(const char *tablename,
const struct ipt_reject_info *rejinfo = targinfo; const struct ipt_reject_info *rejinfo = targinfo;
const struct ipt_entry *e = e_void; const struct ipt_entry *e = e_void;
if (targinfosize != IPT_ALIGN(sizeof(struct ipt_reject_info))) {
DEBUGP("REJECT: targinfosize %u != 0\n", targinfosize);
return 0;
}
/* Only allow these for packet filtering. */
if (strcmp(tablename, "filter") != 0) {
DEBUGP("REJECT: bad table `%s'.\n", tablename);
return 0;
}
if ((hook_mask & ~((1 << NF_IP_LOCAL_IN)
| (1 << NF_IP_FORWARD)
| (1 << NF_IP_LOCAL_OUT))) != 0) {
DEBUGP("REJECT: bad hook mask %X\n", hook_mask);
return 0;
}
if (rejinfo->with == IPT_ICMP_ECHOREPLY) { if (rejinfo->with == IPT_ICMP_ECHOREPLY) {
printk("REJECT: ECHOREPLY no longer supported.\n"); printk("REJECT: ECHOREPLY no longer supported.\n");
return 0; return 0;
...@@ -318,13 +301,16 @@ static int check(const char *tablename, ...@@ -318,13 +301,16 @@ static int check(const char *tablename,
return 0; return 0;
} }
} }
return 1; return 1;
} }
static struct ipt_target ipt_reject_reg = { static struct ipt_target ipt_reject_reg = {
.name = "REJECT", .name = "REJECT",
.target = reject, .target = reject,
.targetsize = sizeof(struct ipt_reject_info),
.table = "filter",
.hooks = (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) |
(1 << NF_IP_LOCAL_OUT),
.checkentry = check, .checkentry = check,
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -59,18 +59,6 @@ same_check(const char *tablename, ...@@ -59,18 +59,6 @@ same_check(const char *tablename,
mr->ipnum = 0; mr->ipnum = 0;
if (strcmp(tablename, "nat") != 0) {
DEBUGP("same_check: bad table `%s'.\n", tablename);
return 0;
}
if (targinfosize != IPT_ALIGN(sizeof(*mr))) {
DEBUGP("same_check: size %u.\n", targinfosize);
return 0;
}
if (hook_mask & ~(1 << NF_IP_PRE_ROUTING | 1 << NF_IP_POST_ROUTING)) {
DEBUGP("same_check: bad hooks %x.\n", hook_mask);
return 0;
}
if (mr->rangesize < 1) { if (mr->rangesize < 1) {
DEBUGP("same_check: need at least one dest range.\n"); DEBUGP("same_check: need at least one dest range.\n");
return 0; return 0;
...@@ -191,6 +179,9 @@ same_target(struct sk_buff **pskb, ...@@ -191,6 +179,9 @@ same_target(struct sk_buff **pskb,
static struct ipt_target same_reg = { static struct ipt_target same_reg = {
.name = "SAME", .name = "SAME",
.target = same_target, .target = same_target,
.targetsize = sizeof(struct ipt_same_info),
.table = "nat",
.hooks = (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_POST_ROUTING),
.checkentry = same_check, .checkentry = same_check,
.destroy = same_destroy, .destroy = same_destroy,
.me = THIS_MODULE, .me = THIS_MODULE,
......
...@@ -218,13 +218,6 @@ ipt_tcpmss_checkentry(const char *tablename, ...@@ -218,13 +218,6 @@ ipt_tcpmss_checkentry(const char *tablename,
const struct ipt_tcpmss_info *tcpmssinfo = targinfo; const struct ipt_tcpmss_info *tcpmssinfo = targinfo;
const struct ipt_entry *e = e_void; const struct ipt_entry *e = e_void;
if (targinfosize != IPT_ALIGN(sizeof(struct ipt_tcpmss_info))) {
DEBUGP("ipt_tcpmss_checkentry: targinfosize %u != %u\n",
targinfosize, IPT_ALIGN(sizeof(struct ipt_tcpmss_info)));
return 0;
}
if((tcpmssinfo->mss == IPT_TCPMSS_CLAMP_PMTU) && if((tcpmssinfo->mss == IPT_TCPMSS_CLAMP_PMTU) &&
((hook_mask & ~((1 << NF_IP_FORWARD) ((hook_mask & ~((1 << NF_IP_FORWARD)
| (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_LOCAL_OUT)
...@@ -233,11 +226,8 @@ ipt_tcpmss_checkentry(const char *tablename, ...@@ -233,11 +226,8 @@ ipt_tcpmss_checkentry(const char *tablename,
return 0; return 0;
} }
if (e->ip.proto == IPPROTO_TCP if (IPT_MATCH_ITERATE(e, find_syn_match))
&& !(e->ip.invflags & IPT_INV_PROTO)
&& IPT_MATCH_ITERATE(e, find_syn_match))
return 1; return 1;
printk("TCPMSS: Only works on TCP SYN packets\n"); printk("TCPMSS: Only works on TCP SYN packets\n");
return 0; return 0;
} }
...@@ -245,6 +235,8 @@ ipt_tcpmss_checkentry(const char *tablename, ...@@ -245,6 +235,8 @@ ipt_tcpmss_checkentry(const char *tablename,
static struct ipt_target ipt_tcpmss_reg = { static struct ipt_target ipt_tcpmss_reg = {
.name = "TCPMSS", .name = "TCPMSS",
.target = ipt_tcpmss_target, .target = ipt_tcpmss_target,
.targetsize = sizeof(struct ipt_tcpmss_info),
.proto = IPPROTO_TCP,
.checkentry = ipt_tcpmss_checkentry, .checkentry = ipt_tcpmss_checkentry,
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -59,18 +59,6 @@ checkentry(const char *tablename, ...@@ -59,18 +59,6 @@ checkentry(const char *tablename,
{ {
const u_int8_t tos = ((struct ipt_tos_target_info *)targinfo)->tos; const u_int8_t tos = ((struct ipt_tos_target_info *)targinfo)->tos;
if (targinfosize != IPT_ALIGN(sizeof(struct ipt_tos_target_info))) {
printk(KERN_WARNING "TOS: targinfosize %u != %Zu\n",
targinfosize,
IPT_ALIGN(sizeof(struct ipt_tos_target_info)));
return 0;
}
if (strcmp(tablename, "mangle") != 0) {
printk(KERN_WARNING "TOS: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
return 0;
}
if (tos != IPTOS_LOWDELAY if (tos != IPTOS_LOWDELAY
&& tos != IPTOS_THROUGHPUT && tos != IPTOS_THROUGHPUT
&& tos != IPTOS_RELIABILITY && tos != IPTOS_RELIABILITY
...@@ -79,13 +67,14 @@ checkentry(const char *tablename, ...@@ -79,13 +67,14 @@ checkentry(const char *tablename,
printk(KERN_WARNING "TOS: bad tos value %#x\n", tos); printk(KERN_WARNING "TOS: bad tos value %#x\n", tos);
return 0; return 0;
} }
return 1; return 1;
} }
static struct ipt_target ipt_tos_reg = { static struct ipt_target ipt_tos_reg = {
.name = "TOS", .name = "TOS",
.target = target, .target = target,
.targetsize = sizeof(struct ipt_tos_target_info),
.table = "mangle",
.checkentry = checkentry, .checkentry = checkentry,
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -73,34 +73,21 @@ static int ipt_ttl_checkentry(const char *tablename, ...@@ -73,34 +73,21 @@ static int ipt_ttl_checkentry(const char *tablename,
{ {
struct ipt_TTL_info *info = targinfo; struct ipt_TTL_info *info = targinfo;
if (targinfosize != IPT_ALIGN(sizeof(struct ipt_TTL_info))) {
printk(KERN_WARNING "ipt_TTL: targinfosize %u != %Zu\n",
targinfosize,
IPT_ALIGN(sizeof(struct ipt_TTL_info)));
return 0;
}
if (strcmp(tablename, "mangle")) {
printk(KERN_WARNING "ipt_TTL: can only be called from "
"\"mangle\" table, not \"%s\"\n", tablename);
return 0;
}
if (info->mode > IPT_TTL_MAXMODE) { if (info->mode > IPT_TTL_MAXMODE) {
printk(KERN_WARNING "ipt_TTL: invalid or unknown Mode %u\n", printk(KERN_WARNING "ipt_TTL: invalid or unknown Mode %u\n",
info->mode); info->mode);
return 0; return 0;
} }
if ((info->mode != IPT_TTL_SET) && (info->ttl == 0)) if ((info->mode != IPT_TTL_SET) && (info->ttl == 0))
return 0; return 0;
return 1; return 1;
} }
static struct ipt_target ipt_TTL = { static struct ipt_target ipt_TTL = {
.name = "TTL", .name = "TTL",
.target = ipt_ttl_target, .target = ipt_ttl_target,
.targetsize = sizeof(struct ipt_TTL_info),
.table = "mangle",
.checkentry = ipt_ttl_checkentry, .checkentry = ipt_ttl_checkentry,
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -345,36 +345,30 @@ static int ipt_ulog_checkentry(const char *tablename, ...@@ -345,36 +345,30 @@ static int ipt_ulog_checkentry(const char *tablename,
{ {
struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo; struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
if (targinfosize != IPT_ALIGN(sizeof(struct ipt_ulog_info))) {
DEBUGP("ipt_ULOG: targinfosize %u != 0\n", targinfosize);
return 0;
}
if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') { if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') {
DEBUGP("ipt_ULOG: prefix term %i\n", DEBUGP("ipt_ULOG: prefix term %i\n",
loginfo->prefix[sizeof(loginfo->prefix) - 1]); loginfo->prefix[sizeof(loginfo->prefix) - 1]);
return 0; return 0;
} }
if (loginfo->qthreshold > ULOG_MAX_QLEN) { if (loginfo->qthreshold > ULOG_MAX_QLEN) {
DEBUGP("ipt_ULOG: queue threshold %i > MAX_QLEN\n", DEBUGP("ipt_ULOG: queue threshold %i > MAX_QLEN\n",
loginfo->qthreshold); loginfo->qthreshold);
return 0; return 0;
} }
return 1; return 1;
} }
static struct ipt_target ipt_ulog_reg = { static struct ipt_target ipt_ulog_reg = {
.name = "ULOG", .name = "ULOG",
.target = ipt_ulog_target, .target = ipt_ulog_target,
.targetsize = sizeof(struct ipt_ulog_info),
.checkentry = ipt_ulog_checkentry, .checkentry = ipt_ulog_checkentry,
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
static struct nf_logger ipt_ulog_logger = { static struct nf_logger ipt_ulog_logger = {
.name = "ipt_ULOG", .name = "ipt_ULOG",
.logfn = &ipt_logfn, .logfn = ipt_logfn,
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -43,23 +43,10 @@ static int match(const struct sk_buff *skb, const struct net_device *in, ...@@ -43,23 +43,10 @@ static int match(const struct sk_buff *skb, const struct net_device *in,
return ret; return ret;
} }
static int checkentry(const char *tablename, const void *ip,
void *matchinfo, unsigned int matchsize,
unsigned int hook_mask)
{
if (matchsize != IPT_ALIGN(sizeof(struct ipt_addrtype_info))) {
printk(KERN_ERR "ipt_addrtype: invalid size (%u != %Zu)\n",
matchsize, IPT_ALIGN(sizeof(struct ipt_addrtype_info)));
return 0;
}
return 1;
}
static struct ipt_match addrtype_match = { static struct ipt_match addrtype_match = {
.name = "addrtype", .name = "addrtype",
.match = match, .match = match,
.checkentry = checkentry, .matchsize = sizeof(struct ipt_addrtype_info),
.me = THIS_MODULE .me = THIS_MODULE
}; };
......
...@@ -76,32 +76,21 @@ checkentry(const char *tablename, ...@@ -76,32 +76,21 @@ checkentry(const char *tablename,
unsigned int hook_mask) unsigned int hook_mask)
{ {
const struct ipt_ah *ahinfo = matchinfo; const struct ipt_ah *ahinfo = matchinfo;
const struct ipt_ip *ip = ip_void;
/* Must specify proto == AH, and no unknown invflags */ /* Must specify no unknown invflags */
if (ip->proto != IPPROTO_AH || (ip->invflags & IPT_INV_PROTO)) {
duprintf("ipt_ah: Protocol %u != %u\n", ip->proto,
IPPROTO_AH);
return 0;
}
if (matchinfosize != IPT_ALIGN(sizeof(struct ipt_ah))) {
duprintf("ipt_ah: matchsize %u != %u\n",
matchinfosize, IPT_ALIGN(sizeof(struct ipt_ah)));
return 0;
}
if (ahinfo->invflags & ~IPT_AH_INV_MASK) { if (ahinfo->invflags & ~IPT_AH_INV_MASK) {
duprintf("ipt_ah: unknown flags %X\n", duprintf("ipt_ah: unknown flags %X\n", ahinfo->invflags);
ahinfo->invflags);
return 0; return 0;
} }
return 1; return 1;
} }
static struct ipt_match ah_match = { static struct ipt_match ah_match = {
.name = "ah", .name = "ah",
.match = &match, .match = match,
.checkentry = &checkentry, .matchsize = sizeof(struct ipt_ah),
.proto = IPPROTO_AH,
.checkentry = checkentry,
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -31,20 +31,10 @@ static int match(const struct sk_buff *skb, const struct net_device *in, ...@@ -31,20 +31,10 @@ static int match(const struct sk_buff *skb, const struct net_device *in,
return ((iph->tos&IPT_DSCP_MASK) == sh_dscp) ^ info->invert; return ((iph->tos&IPT_DSCP_MASK) == sh_dscp) ^ info->invert;
} }
static int checkentry(const char *tablename, const void *ip,
void *matchinfo, unsigned int matchsize,
unsigned int hook_mask)
{
if (matchsize != IPT_ALIGN(sizeof(struct ipt_dscp_info)))
return 0;
return 1;
}
static struct ipt_match dscp_match = { static struct ipt_match dscp_match = {
.name = "dscp", .name = "dscp",
.match = &match, .match = match,
.checkentry = &checkentry, .matchsize = sizeof(struct ipt_dscp_info),
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -92,9 +92,6 @@ static int checkentry(const char *tablename, const void *ip_void, ...@@ -92,9 +92,6 @@ static int checkentry(const char *tablename, const void *ip_void,
const struct ipt_ecn_info *info = matchinfo; const struct ipt_ecn_info *info = matchinfo;
const struct ipt_ip *ip = ip_void; const struct ipt_ip *ip = ip_void;
if (matchsize != IPT_ALIGN(sizeof(struct ipt_ecn_info)))
return 0;
if (info->operation & IPT_ECN_OP_MATCH_MASK) if (info->operation & IPT_ECN_OP_MATCH_MASK)
return 0; return 0;
...@@ -113,8 +110,9 @@ static int checkentry(const char *tablename, const void *ip_void, ...@@ -113,8 +110,9 @@ static int checkentry(const char *tablename, const void *ip_void,
static struct ipt_match ecn_match = { static struct ipt_match ecn_match = {
.name = "ecn", .name = "ecn",
.match = &match, .match = match,
.checkentry = &checkentry, .matchsize = sizeof(struct ipt_ecn_info),
.checkentry = checkentry,
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -77,32 +77,21 @@ checkentry(const char *tablename, ...@@ -77,32 +77,21 @@ checkentry(const char *tablename,
unsigned int hook_mask) unsigned int hook_mask)
{ {
const struct ipt_esp *espinfo = matchinfo; const struct ipt_esp *espinfo = matchinfo;
const struct ipt_ip *ip = ip_void;
/* Must specify proto == ESP, and no unknown invflags */ /* Must specify no unknown invflags */
if (ip->proto != IPPROTO_ESP || (ip->invflags & IPT_INV_PROTO)) {
duprintf("ipt_esp: Protocol %u != %u\n", ip->proto,
IPPROTO_ESP);
return 0;
}
if (matchinfosize != IPT_ALIGN(sizeof(struct ipt_esp))) {
duprintf("ipt_esp: matchsize %u != %u\n",
matchinfosize, IPT_ALIGN(sizeof(struct ipt_esp)));
return 0;
}
if (espinfo->invflags & ~IPT_ESP_INV_MASK) { if (espinfo->invflags & ~IPT_ESP_INV_MASK) {
duprintf("ipt_esp: unknown flags %X\n", duprintf("ipt_esp: unknown flags %X\n", espinfo->invflags);
espinfo->invflags);
return 0; return 0;
} }
return 1; return 1;
} }
static struct ipt_match esp_match = { static struct ipt_match esp_match = {
.name = "esp", .name = "esp",
.match = &match, .match = match,
.checkentry = &checkentry, .matchsize = sizeof(struct ipt_esp),
.proto = IPPROTO_ESP,
.checkentry = checkentry,
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -512,9 +512,6 @@ hashlimit_checkentry(const char *tablename, ...@@ -512,9 +512,6 @@ hashlimit_checkentry(const char *tablename,
{ {
struct ipt_hashlimit_info *r = matchinfo; struct ipt_hashlimit_info *r = matchinfo;
if (matchsize != IPT_ALIGN(sizeof(struct ipt_hashlimit_info)))
return 0;
/* Check for overflow. */ /* Check for overflow. */
if (r->cfg.burst == 0 if (r->cfg.burst == 0
|| user2credits(r->cfg.avg * r->cfg.burst) < || user2credits(r->cfg.avg * r->cfg.burst) <
...@@ -565,12 +562,13 @@ hashlimit_destroy(void *matchinfo, unsigned int matchsize) ...@@ -565,12 +562,13 @@ hashlimit_destroy(void *matchinfo, unsigned int matchsize)
htable_put(r->hinfo); htable_put(r->hinfo);
} }
static struct ipt_match ipt_hashlimit = { static struct ipt_match ipt_hashlimit = {
.name = "hashlimit", .name = "hashlimit",
.match = hashlimit_match, .match = hashlimit_match,
.checkentry = hashlimit_checkentry, .matchsize = sizeof(struct ipt_hashlimit_info),
.destroy = hashlimit_destroy, .checkentry = hashlimit_checkentry,
.me = THIS_MODULE .destroy = hashlimit_destroy,
.me = THIS_MODULE
}; };
/* PROC stuff */ /* PROC stuff */
......
...@@ -62,27 +62,12 @@ match(const struct sk_buff *skb, ...@@ -62,27 +62,12 @@ match(const struct sk_buff *skb,
return 1; return 1;
} }
static int check(const char *tablename, static struct ipt_match iprange_match = {
const void *inf, .name = "iprange",
void *matchinfo, .match = match,
unsigned int matchsize, .matchsize = sizeof(struct ipt_iprange_info),
unsigned int hook_mask) .destroy = NULL,
{ .me = THIS_MODULE
/* verify size */
if (matchsize != IPT_ALIGN(sizeof(struct ipt_iprange_info)))
return 0;
return 1;
}
static struct ipt_match iprange_match =
{
.list = { NULL, NULL },
.name = "iprange",
.match = &match,
.checkentry = &check,
.destroy = NULL,
.me = THIS_MODULE
}; };
static int __init init(void) static int __init init(void)
......
...@@ -153,40 +153,19 @@ match_v1(const struct sk_buff *skb, ...@@ -153,40 +153,19 @@ match_v1(const struct sk_buff *skb,
return ports_match_v1(multiinfo, ntohs(pptr[0]), ntohs(pptr[1])); return ports_match_v1(multiinfo, ntohs(pptr[0]), ntohs(pptr[1]));
} }
/* Called when user tries to insert an entry of this type. */
static int
checkentry(const char *tablename,
const void *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
return (matchsize == IPT_ALIGN(sizeof(struct ipt_multiport)));
}
static int
checkentry_v1(const char *tablename,
const void *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
return (matchsize == IPT_ALIGN(sizeof(struct ipt_multiport_v1)));
}
static struct ipt_match multiport_match = { static struct ipt_match multiport_match = {
.name = "multiport", .name = "multiport",
.revision = 0, .revision = 0,
.match = &match, .match = match,
.checkentry = &checkentry, .matchsize = sizeof(struct ipt_multiport),
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
static struct ipt_match multiport_match_v1 = { static struct ipt_match multiport_match_v1 = {
.name = "multiport", .name = "multiport",
.revision = 1, .revision = 1,
.match = &match_v1, .match = match_v1,
.checkentry = &checkentry_v1, .matchsize = sizeof(struct ipt_multiport_v1),
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -59,31 +59,20 @@ checkentry(const char *tablename, ...@@ -59,31 +59,20 @@ checkentry(const char *tablename,
{ {
const struct ipt_owner_info *info = matchinfo; const struct ipt_owner_info *info = matchinfo;
if (hook_mask
& ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING))) {
printk("ipt_owner: only valid for LOCAL_OUT or POST_ROUTING.\n");
return 0;
}
if (matchsize != IPT_ALIGN(sizeof(struct ipt_owner_info))) {
printk("Matchsize %u != %Zu\n", matchsize,
IPT_ALIGN(sizeof(struct ipt_owner_info)));
return 0;
}
if (info->match & (IPT_OWNER_PID|IPT_OWNER_SID|IPT_OWNER_COMM)) { if (info->match & (IPT_OWNER_PID|IPT_OWNER_SID|IPT_OWNER_COMM)) {
printk("ipt_owner: pid, sid and command matching " printk("ipt_owner: pid, sid and command matching "
"not supported anymore\n"); "not supported anymore\n");
return 0; return 0;
} }
return 1; return 1;
} }
static struct ipt_match owner_match = { static struct ipt_match owner_match = {
.name = "owner", .name = "owner",
.match = &match, .match = match,
.checkentry = &checkentry, .matchsize = sizeof(struct ipt_owner_info),
.hooks = (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING),
.checkentry = checkentry,
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -125,11 +125,6 @@ static int checkentry(const char *tablename, const void *ip_void, ...@@ -125,11 +125,6 @@ static int checkentry(const char *tablename, const void *ip_void,
{ {
struct ipt_policy_info *info = matchinfo; struct ipt_policy_info *info = matchinfo;
if (matchsize != IPT_ALIGN(sizeof(*info))) {
printk(KERN_ERR "ipt_policy: matchsize %u != %zu\n",
matchsize, IPT_ALIGN(sizeof(*info)));
return 0;
}
if (!(info->flags & (IPT_POLICY_MATCH_IN|IPT_POLICY_MATCH_OUT))) { if (!(info->flags & (IPT_POLICY_MATCH_IN|IPT_POLICY_MATCH_OUT))) {
printk(KERN_ERR "ipt_policy: neither incoming nor " printk(KERN_ERR "ipt_policy: neither incoming nor "
"outgoing policy selected\n"); "outgoing policy selected\n");
...@@ -158,6 +153,7 @@ static int checkentry(const char *tablename, const void *ip_void, ...@@ -158,6 +153,7 @@ static int checkentry(const char *tablename, const void *ip_void,
static struct ipt_match policy_match = { static struct ipt_match policy_match = {
.name = "policy", .name = "policy",
.match = match, .match = match,
.matchsize = sizeof(struct ipt_policy_info),
.checkentry = checkentry, .checkentry = checkentry,
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -670,8 +670,6 @@ checkentry(const char *tablename, ...@@ -670,8 +670,6 @@ checkentry(const char *tablename,
if(debug) printk(KERN_INFO RECENT_NAME ": checkentry() entered.\n"); if(debug) printk(KERN_INFO RECENT_NAME ": checkentry() entered.\n");
#endif #endif
if (matchsize != IPT_ALIGN(sizeof(struct ipt_recent_info))) return 0;
/* seconds and hit_count only valid for CHECK/UPDATE */ /* seconds and hit_count only valid for CHECK/UPDATE */
if(info->check_set & IPT_RECENT_SET) { flag++; if(info->seconds || info->hit_count) return 0; } if(info->check_set & IPT_RECENT_SET) { flag++; if(info->seconds || info->hit_count) return 0; }
if(info->check_set & IPT_RECENT_REMOVE) { flag++; if(info->seconds || info->hit_count) return 0; } if(info->check_set & IPT_RECENT_REMOVE) { flag++; if(info->seconds || info->hit_count) return 0; }
...@@ -951,12 +949,13 @@ destroy(void *matchinfo, unsigned int matchsize) ...@@ -951,12 +949,13 @@ destroy(void *matchinfo, unsigned int matchsize)
/* This is the structure we pass to ipt_register to register our /* This is the structure we pass to ipt_register to register our
* module with iptables. * module with iptables.
*/ */
static struct ipt_match recent_match = { static struct ipt_match recent_match = {
.name = "recent", .name = "recent",
.match = &match, .match = match,
.checkentry = &checkentry, .matchsize = sizeof(struct ipt_recent_info),
.destroy = &destroy, .checkentry = checkentry,
.me = THIS_MODULE .destroy = destroy,
.me = THIS_MODULE
}; };
/* Kernel module initialization. */ /* Kernel module initialization. */
......
...@@ -31,23 +31,10 @@ match(const struct sk_buff *skb, ...@@ -31,23 +31,10 @@ match(const struct sk_buff *skb,
return (skb->nh.iph->tos == info->tos) ^ info->invert; return (skb->nh.iph->tos == info->tos) ^ info->invert;
} }
static int
checkentry(const char *tablename,
const void *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
if (matchsize != IPT_ALIGN(sizeof(struct ipt_tos_info)))
return 0;
return 1;
}
static struct ipt_match tos_match = { static struct ipt_match tos_match = {
.name = "tos", .name = "tos",
.match = &match, .match = match,
.checkentry = &checkentry, .matchsize = sizeof(struct ipt_tos_info),
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -47,20 +47,10 @@ static int match(const struct sk_buff *skb, const struct net_device *in, ...@@ -47,20 +47,10 @@ static int match(const struct sk_buff *skb, const struct net_device *in,
return 0; return 0;
} }
static int checkentry(const char *tablename, const void *ip,
void *matchinfo, unsigned int matchsize,
unsigned int hook_mask)
{
if (matchsize != IPT_ALIGN(sizeof(struct ipt_ttl_info)))
return 0;
return 1;
}
static struct ipt_match ttl_match = { static struct ipt_match ttl_match = {
.name = "ttl", .name = "ttl",
.match = &match, .match = match,
.checkentry = &checkentry, .matchsize = sizeof(struct ipt_ttl_info),
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
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