Blame view
net/netfilter/xt_TCPOPTSTRIP.c
3.77 KB
d2912cb15 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-only |
338e8a792 [NETFILTER]: x_ta... |
2 3 4 5 6 |
/* * A module for stripping a specific TCP option from TCP packets. * * Copyright (C) 2007 Sven Schnelle <svens@bitebene.org> * Copyright © CC Computer Consultants GmbH, 2007 |
338e8a792 [NETFILTER]: x_ta... |
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
*/ #include <linux/module.h> #include <linux/skbuff.h> #include <linux/ip.h> #include <linux/ipv6.h> #include <linux/tcp.h> #include <net/ipv6.h> #include <net/tcp.h> #include <linux/netfilter/x_tables.h> #include <linux/netfilter/xt_TCPOPTSTRIP.h> static inline unsigned int optlen(const u_int8_t *opt, unsigned int offset) { /* Beware zero-length options: make finite progress */ if (opt[offset] <= TCPOPT_NOP || opt[offset+1] == 0) return 1; else return opt[offset+1]; } static unsigned int tcpoptstrip_mangle_packet(struct sk_buff *skb, |
bc6bcb59d netfilter: xt_TCP... |
30 |
const struct xt_action_param *par, |
fb2eb1c13 netfilter: tcpmss... |
31 |
unsigned int tcphoff) |
338e8a792 [NETFILTER]: x_ta... |
32 |
{ |
bc6bcb59d netfilter: xt_TCP... |
33 |
const struct xt_tcpoptstrip_target_info *info = par->targinfo; |
fb2eb1c13 netfilter: tcpmss... |
34 |
struct tcphdr *tcph, _th; |
338e8a792 [NETFILTER]: x_ta... |
35 |
unsigned int optl, i, j; |
338e8a792 [NETFILTER]: x_ta... |
36 37 |
u_int16_t n, o; u_int8_t *opt; |
fb2eb1c13 netfilter: tcpmss... |
38 |
int tcp_hdrlen; |
bc6bcb59d netfilter: xt_TCP... |
39 40 41 42 |
/* This is a fragment, no TCP header is available */ if (par->fragoff != 0) return XT_CONTINUE; |
338e8a792 [NETFILTER]: x_ta... |
43 |
|
fb2eb1c13 netfilter: tcpmss... |
44 45 |
tcph = skb_header_pointer(skb, tcphoff, sizeof(_th), &_th); if (!tcph) |
338e8a792 [NETFILTER]: x_ta... |
46 |
return NF_DROP; |
a206bcb3b netfilter: xt_TCP... |
47 |
tcp_hdrlen = tcph->doff * 4; |
fb2eb1c13 netfilter: tcpmss... |
48 49 |
if (tcp_hdrlen < sizeof(struct tcphdr)) return NF_DROP; |
a206bcb3b netfilter: xt_TCP... |
50 |
|
fb2eb1c13 netfilter: tcpmss... |
51 |
if (skb_ensure_writable(skb, tcphoff + tcp_hdrlen)) |
ed82c4373 netfilter: xt_TCP... |
52 |
return NF_DROP; |
fb2eb1c13 netfilter: tcpmss... |
53 54 55 |
/* must reload tcph, might have been moved */ tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff); opt = (u8 *)tcph; |
338e8a792 [NETFILTER]: x_ta... |
56 57 58 59 60 |
/* * Walk through all TCP options - if we find some option to remove, * set all octets to %TCPOPT_NOP and adjust checksum. */ |
a206bcb3b netfilter: xt_TCP... |
61 |
for (i = sizeof(struct tcphdr); i < tcp_hdrlen - 1; i += optl) { |
338e8a792 [NETFILTER]: x_ta... |
62 |
optl = optlen(opt, i); |
a206bcb3b netfilter: xt_TCP... |
63 |
if (i + optl > tcp_hdrlen) |
338e8a792 [NETFILTER]: x_ta... |
64 65 66 67 68 69 70 71 72 73 74 75 76 |
break; if (!tcpoptstrip_test_bit(info->strip_bmap, opt[i])) continue; for (j = 0; j < optl; ++j) { o = opt[i+j]; n = TCPOPT_NOP; if ((i + j) % 2 == 0) { o <<= 8; n <<= 8; } inet_proto_csum_replace2(&tcph->check, skb, htons(o), |
4b048d6d9 net: Change pseud... |
77 |
htons(n), false); |
338e8a792 [NETFILTER]: x_ta... |
78 79 80 81 82 83 84 85 |
} memset(opt + i, TCPOPT_NOP, optl); } return XT_CONTINUE; } static unsigned int |
4b560b447 netfilter: xtable... |
86 |
tcpoptstrip_tg4(struct sk_buff *skb, const struct xt_action_param *par) |
338e8a792 [NETFILTER]: x_ta... |
87 |
{ |
fb2eb1c13 netfilter: tcpmss... |
88 |
return tcpoptstrip_mangle_packet(skb, par, ip_hdrlen(skb)); |
338e8a792 [NETFILTER]: x_ta... |
89 |
} |
c0cd11566 net:netfilter: us... |
90 |
#if IS_ENABLED(CONFIG_IP6_NF_MANGLE) |
338e8a792 [NETFILTER]: x_ta... |
91 |
static unsigned int |
4b560b447 netfilter: xtable... |
92 |
tcpoptstrip_tg6(struct sk_buff *skb, const struct xt_action_param *par) |
338e8a792 [NETFILTER]: x_ta... |
93 94 |
{ struct ipv6hdr *ipv6h = ipv6_hdr(skb); |
be8d0d790 netfilter: xt_TCP... |
95 |
int tcphoff; |
338e8a792 [NETFILTER]: x_ta... |
96 |
u_int8_t nexthdr; |
75f2811c6 ipv6: Add fragmen... |
97 |
__be16 frag_off; |
338e8a792 [NETFILTER]: x_ta... |
98 99 |
nexthdr = ipv6h->nexthdr; |
75f2811c6 ipv6: Add fragmen... |
100 |
tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr, &frag_off); |
338e8a792 [NETFILTER]: x_ta... |
101 102 |
if (tcphoff < 0) return NF_DROP; |
fb2eb1c13 netfilter: tcpmss... |
103 |
return tcpoptstrip_mangle_packet(skb, par, tcphoff); |
338e8a792 [NETFILTER]: x_ta... |
104 105 106 107 108 109 |
} #endif static struct xt_target tcpoptstrip_tg_reg[] __read_mostly = { { .name = "TCPOPTSTRIP", |
ee999d8b9 netfilter: x_tabl... |
110 |
.family = NFPROTO_IPV4, |
338e8a792 [NETFILTER]: x_ta... |
111 112 113 114 115 116 |
.table = "mangle", .proto = IPPROTO_TCP, .target = tcpoptstrip_tg4, .targetsize = sizeof(struct xt_tcpoptstrip_target_info), .me = THIS_MODULE, }, |
c0cd11566 net:netfilter: us... |
117 |
#if IS_ENABLED(CONFIG_IP6_NF_MANGLE) |
338e8a792 [NETFILTER]: x_ta... |
118 119 |
{ .name = "TCPOPTSTRIP", |
ee999d8b9 netfilter: x_tabl... |
120 |
.family = NFPROTO_IPV6, |
338e8a792 [NETFILTER]: x_ta... |
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
.table = "mangle", .proto = IPPROTO_TCP, .target = tcpoptstrip_tg6, .targetsize = sizeof(struct xt_tcpoptstrip_target_info), .me = THIS_MODULE, }, #endif }; static int __init tcpoptstrip_tg_init(void) { return xt_register_targets(tcpoptstrip_tg_reg, ARRAY_SIZE(tcpoptstrip_tg_reg)); } static void __exit tcpoptstrip_tg_exit(void) { xt_unregister_targets(tcpoptstrip_tg_reg, ARRAY_SIZE(tcpoptstrip_tg_reg)); } module_init(tcpoptstrip_tg_init); module_exit(tcpoptstrip_tg_exit); |
408ffaa4a netfilter: update... |
144 |
MODULE_AUTHOR("Sven Schnelle <svens@bitebene.org>, Jan Engelhardt <jengelh@medozas.de>"); |
2ae15b64e [NETFILTER]: Upda... |
145 |
MODULE_DESCRIPTION("Xtables: TCP option stripping"); |
338e8a792 [NETFILTER]: x_ta... |
146 147 148 |
MODULE_LICENSE("GPL"); MODULE_ALIAS("ipt_TCPOPTSTRIP"); MODULE_ALIAS("ip6t_TCPOPTSTRIP"); |