Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[NETFILTER]: x_tables: add TCPOPTSTRIP target

Signed-off-by: Sven Schnelle <svens@bitebene.org>
Signed-off-by: Jan Engelhardt <jengelh@gmx.de>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Sven Schnelle and committed by
David S. Miller
338e8a79 0eeb8ffc

+169
+13
include/linux/netfilter/xt_TCPOPTSTRIP.h
··· 1 + #ifndef _XT_TCPOPTSTRIP_H 2 + #define _XT_TCPOPTSTRIP_H 3 + 4 + #define tcpoptstrip_set_bit(bmap, idx) \ 5 + (bmap[(idx) >> 5] |= 1U << (idx & 31)) 6 + #define tcpoptstrip_test_bit(bmap, idx) \ 7 + (((1U << (idx & 31)) & bmap[(idx) >> 5]) != 0) 8 + 9 + struct xt_tcpoptstrip_target_info { 10 + u_int32_t strip_bmap[8]; 11 + }; 12 + 13 + #endif /* _XT_TCPOPTSTRIP_H */
+8
net/netfilter/Kconfig
··· 411 411 412 412 To compile it as a module, choose M here. If unsure, say N. 413 413 414 + config NETFILTER_XT_TARGET_TCPOPTSTRIP 415 + tristate '"TCPOPTSTRIP" target support (EXPERIMENTAL)' 416 + depends on EXPERIMENTAL && NETFILTER_XTABLES 417 + depends on IP_NF_MANGLE || IP6_NF_MANGLE 418 + help 419 + This option adds a "TCPOPTSTRIP" target, which allows you to strip 420 + TCP options from TCP packets. 421 + 414 422 config NETFILTER_XT_MATCH_COMMENT 415 423 tristate '"comment" match support' 416 424 depends on NETFILTER_XTABLES
+1
net/netfilter/Makefile
··· 48 48 obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o 49 49 obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o 50 50 obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o 51 + obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP) += xt_TCPOPTSTRIP.o 51 52 obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o 52 53 53 54 # matches
+147
net/netfilter/xt_TCPOPTSTRIP.c
··· 1 + /* 2 + * A module for stripping a specific TCP option from TCP packets. 3 + * 4 + * Copyright (C) 2007 Sven Schnelle <svens@bitebene.org> 5 + * Copyright © CC Computer Consultants GmbH, 2007 6 + * Contact: Jan Engelhardt <jengelh@computergmbh.de> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #include <linux/module.h> 14 + #include <linux/skbuff.h> 15 + #include <linux/ip.h> 16 + #include <linux/ipv6.h> 17 + #include <linux/tcp.h> 18 + #include <net/ipv6.h> 19 + #include <net/tcp.h> 20 + #include <linux/netfilter/x_tables.h> 21 + #include <linux/netfilter/xt_TCPOPTSTRIP.h> 22 + 23 + static inline unsigned int optlen(const u_int8_t *opt, unsigned int offset) 24 + { 25 + /* Beware zero-length options: make finite progress */ 26 + if (opt[offset] <= TCPOPT_NOP || opt[offset+1] == 0) 27 + return 1; 28 + else 29 + return opt[offset+1]; 30 + } 31 + 32 + static unsigned int 33 + tcpoptstrip_mangle_packet(struct sk_buff *skb, 34 + const struct xt_tcpoptstrip_target_info *info, 35 + unsigned int tcphoff, unsigned int minlen) 36 + { 37 + unsigned int optl, i, j; 38 + struct tcphdr *tcph; 39 + u_int16_t n, o; 40 + u_int8_t *opt; 41 + 42 + if (!skb_make_writable(skb, skb->len)) 43 + return NF_DROP; 44 + 45 + tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff); 46 + opt = (u_int8_t *)tcph; 47 + 48 + /* 49 + * Walk through all TCP options - if we find some option to remove, 50 + * set all octets to %TCPOPT_NOP and adjust checksum. 51 + */ 52 + for (i = sizeof(struct tcphdr); i < tcp_hdrlen(skb); i += optl) { 53 + optl = optlen(opt, i); 54 + 55 + if (i + optl > tcp_hdrlen(skb)) 56 + break; 57 + 58 + if (!tcpoptstrip_test_bit(info->strip_bmap, opt[i])) 59 + continue; 60 + 61 + for (j = 0; j < optl; ++j) { 62 + o = opt[i+j]; 63 + n = TCPOPT_NOP; 64 + if ((i + j) % 2 == 0) { 65 + o <<= 8; 66 + n <<= 8; 67 + } 68 + inet_proto_csum_replace2(&tcph->check, skb, htons(o), 69 + htons(n), 0); 70 + } 71 + memset(opt + i, TCPOPT_NOP, optl); 72 + } 73 + 74 + return XT_CONTINUE; 75 + } 76 + 77 + static unsigned int 78 + tcpoptstrip_tg4(struct sk_buff *skb, const struct net_device *in, 79 + const struct net_device *out, unsigned int hooknum, 80 + const struct xt_target *target, const void *targinfo) 81 + { 82 + return tcpoptstrip_mangle_packet(skb, targinfo, ip_hdrlen(skb), 83 + sizeof(struct iphdr) + sizeof(struct tcphdr)); 84 + } 85 + 86 + #if defined(CONFIG_IP6_NF_MANGLE) || defined(CONFIG_IP6_NF_MANGLE_MODULE) 87 + static unsigned int 88 + tcpoptstrip_tg6(struct sk_buff *skb, const struct net_device *in, 89 + const struct net_device *out, unsigned int hooknum, 90 + const struct xt_target *target, const void *targinfo) 91 + { 92 + struct ipv6hdr *ipv6h = ipv6_hdr(skb); 93 + unsigned int tcphoff; 94 + u_int8_t nexthdr; 95 + 96 + nexthdr = ipv6h->nexthdr; 97 + tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr); 98 + if (tcphoff < 0) 99 + return NF_DROP; 100 + 101 + return tcpoptstrip_mangle_packet(skb, targinfo, tcphoff, 102 + sizeof(*ipv6h) + sizeof(struct tcphdr)); 103 + } 104 + #endif 105 + 106 + static struct xt_target tcpoptstrip_tg_reg[] __read_mostly = { 107 + { 108 + .name = "TCPOPTSTRIP", 109 + .family = AF_INET, 110 + .table = "mangle", 111 + .proto = IPPROTO_TCP, 112 + .target = tcpoptstrip_tg4, 113 + .targetsize = sizeof(struct xt_tcpoptstrip_target_info), 114 + .me = THIS_MODULE, 115 + }, 116 + #if defined(CONFIG_IP6_NF_MANGLE) || defined(CONFIG_IP6_NF_MANGLE_MODULE) 117 + { 118 + .name = "TCPOPTSTRIP", 119 + .family = AF_INET6, 120 + .table = "mangle", 121 + .proto = IPPROTO_TCP, 122 + .target = tcpoptstrip_tg6, 123 + .targetsize = sizeof(struct xt_tcpoptstrip_target_info), 124 + .me = THIS_MODULE, 125 + }, 126 + #endif 127 + }; 128 + 129 + static int __init tcpoptstrip_tg_init(void) 130 + { 131 + return xt_register_targets(tcpoptstrip_tg_reg, 132 + ARRAY_SIZE(tcpoptstrip_tg_reg)); 133 + } 134 + 135 + static void __exit tcpoptstrip_tg_exit(void) 136 + { 137 + xt_unregister_targets(tcpoptstrip_tg_reg, 138 + ARRAY_SIZE(tcpoptstrip_tg_reg)); 139 + } 140 + 141 + module_init(tcpoptstrip_tg_init); 142 + module_exit(tcpoptstrip_tg_exit); 143 + MODULE_AUTHOR("Sven Schnelle <svens@bitebene.org>, Jan Engelhardt <jengelh@computergmbh.de>"); 144 + MODULE_DESCRIPTION("netfilter \"TCPOPTSTRIP\" target module"); 145 + MODULE_LICENSE("GPL"); 146 + MODULE_ALIAS("ipt_TCPOPTSTRIP"); 147 + MODULE_ALIAS("ip6t_TCPOPTSTRIP");