xt_PROTO: style fixes

This commit is contained in:
Jan Engelhardt
2019-09-06 10:02:57 +02:00
parent 2bbdcb1d58
commit 358991306c
3 changed files with 34 additions and 58 deletions

View File

@@ -60,36 +60,28 @@ static void PROTO_check(struct xt_fcheck_call *cb)
static void PROTO_save(const void *ip, const struct xt_entry_target *target) static void PROTO_save(const void *ip, const struct xt_entry_target *target)
{ {
const struct xt_PROTO_info *info = const struct xt_PROTO_info *info = (void *)target->data;
(struct xt_PROTO_info *) target->data;
if(info->mode & (1 << XT_PROTO_SET)){ if (info->mode & (1 << XT_PROTO_SET))
printf(" --proto-set %u", info->proto); printf(" --proto-set %u", info->proto);
} if (info->mode & (1 << XT_PROTO_STOP_AT_FRAG))
if(info->mode & (1 << XT_PROTO_STOP_AT_FRAG)){
printf(" --stop-at-frag"); printf(" --stop-at-frag");
} if (info->mode & (1 << XT_PROTO_STOP_AT_AUTH))
if(info->mode & (1 << XT_PROTO_STOP_AT_AUTH)){
printf(" --stop-at-auth"); printf(" --stop-at-auth");
}
} }
static void PROTO_print(const void *ip, const struct xt_entry_target *target, static void PROTO_print(const void *ip, const struct xt_entry_target *target,
int numeric) int numeric)
{ {
const struct xt_PROTO_info *info = const struct xt_PROTO_info *info = (void *)target->data;
(struct xt_PROTO_info *) target->data;
printf(" PROTO "); printf(" PROTO ");
if(info->mode & (1 << XT_PROTO_SET)){ if (info->mode & (1 << XT_PROTO_SET))
printf("set to %u", info->proto); printf("set to %u", info->proto);
} if (info->mode & (1 << XT_PROTO_STOP_AT_FRAG))
if(info->mode & (1 << XT_PROTO_STOP_AT_FRAG)){
printf(" stop-at-frag"); printf(" stop-at-frag");
} if (info->mode & (1 << XT_PROTO_STOP_AT_AUTH))
if(info->mode & (1 << XT_PROTO_STOP_AT_AUTH)){
printf(" stop-at-auth"); printf(" stop-at-auth");
}
} }
static struct xtables_target proto_tg_reg = { static struct xtables_target proto_tg_reg = {

View File

@@ -20,11 +20,11 @@ For IPv6 packets, the scenario can be more complex due to the introduction of
the extension headers mechanism. By default, the PROTO target will scan the IPv6 the extension headers mechanism. By default, the PROTO target will scan the IPv6
packet, finding the last extension header and modify its \fBNext-header\fP field. packet, finding the last extension header and modify its \fBNext-header\fP field.
Normally, the following headers will be seen as an extension header: Normally, the following headers will be seen as an extension header:
\fINEXTHDR_HOP\fP, \fINEXTHDR_HOP\fP,
\fINEXTHDR_ROUTING\fP, \fINEXTHDR_ROUTING\fP,
\fINEXTHDR_FRAGMENT\fP, \fINEXTHDR_FRAGMENT\fP,
\fINEXTHDR_AUTH\fP, \fINEXTHDR_AUTH\fP,
\fINEXTHDR_DEST\fP. \fINEXTHDR_DEST\fP.
.PP .PP
For fragmented packets, only the first fragment is processed and other fragments For fragmented packets, only the first fragment is processed and other fragments
are not touched. are not touched.

View File

@@ -12,8 +12,6 @@
#include <linux/ipv6.h> #include <linux/ipv6.h>
#include <net/ipv6.h> #include <net/ipv6.h>
#include <net/checksum.h> #include <net/checksum.h>
#include <linux/netfilter/x_tables.h> #include <linux/netfilter/x_tables.h>
#include "xt_PROTO.h" #include "xt_PROTO.h"
@@ -32,14 +30,12 @@ proto_tg(struct sk_buff *skb, const struct xt_action_param *par)
return NF_DROP; return NF_DROP;
iph = ip_hdr(skb); iph = ip_hdr(skb);
new_proto = iph->protocol; new_proto = iph->protocol;
if(info->mode & (1 << XT_PROTO_SET)){ if (info->mode & (1 << XT_PROTO_SET))
new_proto = info->proto; new_proto = info->proto;
}
if (new_proto != iph->protocol) { if (new_proto != iph->protocol) {
csum_replace2(&iph->check, htons(iph->protocol & 0xff), csum_replace2(&iph->check, htons(iph->protocol & 0xff),
htons(new_proto & 0xff)); htons(new_proto & 0xff));
iph->protocol = new_proto; iph->protocol = new_proto;
} }
@@ -51,7 +47,7 @@ proto_tg6(struct sk_buff *skb, const struct xt_action_param *par)
{ {
struct ipv6hdr *ip6h; struct ipv6hdr *ip6h;
const struct xt_PROTO_info *info = par->targinfo; const struct xt_PROTO_info *info = par->targinfo;
u8 *nexthdr; u8 *nexthdr;
unsigned int hdr_offset; unsigned int hdr_offset;
__be16 *fp; __be16 *fp;
@@ -60,60 +56,49 @@ proto_tg6(struct sk_buff *skb, const struct xt_action_param *par)
ip6h = ipv6_hdr(skb); ip6h = ipv6_hdr(skb);
nexthdr = &ip6h->nexthdr; nexthdr = &ip6h->nexthdr;
hdr_offset = sizeof(struct ipv6hdr); hdr_offset = sizeof(struct ipv6hdr);
for(;;){ for (;;) {
struct ipv6_opt_hdr _opthdr, *opthp; struct ipv6_opt_hdr _opthdr, *opthp;
unsigned int hdrlen; unsigned int hdrlen;
unsigned short _frag_off; unsigned short _frag_off;
if ((!ipv6_ext_hdr(*nexthdr)) || *nexthdr == NEXTHDR_NONE) { if (!ipv6_ext_hdr(*nexthdr) || *nexthdr == NEXTHDR_NONE)
break; break;
}
opthp = skb_header_pointer(skb, skb_network_offset(skb) + hdr_offset, sizeof(_opthdr), &_opthdr); opthp = skb_header_pointer(skb, skb_network_offset(skb) + hdr_offset, sizeof(_opthdr), &_opthdr);
if(!opthp){ if (!opthp)
return NF_DROP; return NF_DROP;
} if (*nexthdr == NEXTHDR_FRAGMENT) {
if(*nexthdr == NEXTHDR_FRAGMENT){ if (info->mode & (1 << XT_PROTO_STOP_AT_FRAG))
if(info->mode & (1 << XT_PROTO_STOP_AT_FRAG)){
break; break;
} fp = skb_header_pointer(skb, skb_network_offset(skb) +
fp = skb_header_pointer(skb, hdr_offset + offsetof(struct frag_hdr, frag_off),
skb_network_offset(skb) + hdr_offset + sizeof(_frag_off), &_frag_off);
offsetof(struct frag_hdr,
frag_off),
sizeof(_frag_off),
&_frag_off);
if (!fp) if (!fp)
return NF_DROP; return NF_DROP;
_frag_off = ntohs(*fp) & ~0x7; _frag_off = ntohs(*fp) & ~0x7;
if(_frag_off){ // if the packet is not the first fragment if (_frag_off) { // if the packet is not the first fragment
if ((!ipv6_ext_hdr(opthp->nexthdr)) || opthp->nexthdr == NEXTHDR_NONE || if (!ipv6_ext_hdr(opthp->nexthdr) || opthp->nexthdr == NEXTHDR_NONE ||
((info->mode & (1 << XT_PROTO_STOP_AT_AUTH)) && opthp->nexthdr == NEXTHDR_AUTH) (info->mode & (1 << XT_PROTO_STOP_AT_AUTH) && opthp->nexthdr == NEXTHDR_AUTH)) {
) { nexthdr = &((struct ipv6_opt_hdr *)(skb_network_header(skb) + hdr_offset))->nexthdr;
nexthdr = &((struct ipv6_opt_hdr*)(skb_network_header(skb) + hdr_offset))->nexthdr;
break; break;
}else{ } else {
return XT_CONTINUE; return XT_CONTINUE;
} }
} }
hdrlen = 8; hdrlen = 8;
}else if(*nexthdr == NEXTHDR_AUTH){ } else if(*nexthdr == NEXTHDR_AUTH) {
if(info->mode & (1 << XT_PROTO_STOP_AT_AUTH)){ if (info->mode & (1 << XT_PROTO_STOP_AT_AUTH))
break; break;
}
hdrlen = (opthp->hdrlen + 2) << 2; hdrlen = (opthp->hdrlen + 2) << 2;
}else{ } else {
hdrlen = ipv6_optlen(opthp); hdrlen = ipv6_optlen(opthp);
} }
nexthdr = &((struct ipv6_opt_hdr*)(skb_network_header(skb) + hdr_offset))->nexthdr; nexthdr = &((struct ipv6_opt_hdr *)(skb_network_header(skb) + hdr_offset))->nexthdr;
hdr_offset += hdrlen; hdr_offset += hdrlen;
} }
if(info->mode & (1 << XT_PROTO_SET)){ if (info->mode & (1 << XT_PROTO_SET))
*nexthdr = info->proto; *nexthdr = info->proto;
}
return XT_CONTINUE; return XT_CONTINUE;
} }
@@ -121,12 +106,12 @@ static int proto_tg_check(const struct xt_tgchk_param *par)
{ {
const struct xt_PROTO_info *info = par->targinfo; const struct xt_PROTO_info *info = par->targinfo;
if ((info->mode & (1 << XT_PROTO_SET)) == 0){ if ((info->mode & (1 << XT_PROTO_SET)) == 0) {
pr_info_ratelimited("Did not specify any proto to set\n"); pr_info_ratelimited("Did not specify any proto to set\n");
return -EINVAL; return -EINVAL;
} }
if ((par->family != NFPROTO_IPV6) && ((info->mode & ((1 << XT_PROTO_STOP_AT_FRAG) | (1 << XT_PROTO_STOP_AT_AUTH))) != 0)){ if (par->family != NFPROTO_IPV6 && (info->mode & ((1 << XT_PROTO_STOP_AT_FRAG) | (1 << XT_PROTO_STOP_AT_AUTH))) != 0) {
pr_info_ratelimited("Must not specify stop-at-frag and stop-at-auth on non-ipv6 targets\n"); pr_info_ratelimited("Must not specify stop-at-frag and stop-at-auth on non-ipv6 targets\n");
return -EPROTOTYPE; return -EPROTOTYPE;
} }
return 0; return 0;
@@ -169,4 +154,3 @@ module_init(proto_tg_init);
module_exit(proto_tg_exit); module_exit(proto_tg_exit);
MODULE_ALIAS("ipt_PROTO"); MODULE_ALIAS("ipt_PROTO");
MODULE_ALIAS("ip6t_PROTO"); MODULE_ALIAS("ip6t_PROTO");