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

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.25-rc5 147 lines 4.0 kB view raw
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 23static 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 32static unsigned int 33tcpoptstrip_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 77static unsigned int 78tcpoptstrip_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) 87static unsigned int 88tcpoptstrip_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 106static 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 129static int __init tcpoptstrip_tg_init(void) 130{ 131 return xt_register_targets(tcpoptstrip_tg_reg, 132 ARRAY_SIZE(tcpoptstrip_tg_reg)); 133} 134 135static void __exit tcpoptstrip_tg_exit(void) 136{ 137 xt_unregister_targets(tcpoptstrip_tg_reg, 138 ARRAY_SIZE(tcpoptstrip_tg_reg)); 139} 140 141module_init(tcpoptstrip_tg_init); 142module_exit(tcpoptstrip_tg_exit); 143MODULE_AUTHOR("Sven Schnelle <svens@bitebene.org>, Jan Engelhardt <jengelh@computergmbh.de>"); 144MODULE_DESCRIPTION("Xtables: TCP option stripping"); 145MODULE_LICENSE("GPL"); 146MODULE_ALIAS("ipt_TCPOPTSTRIP"); 147MODULE_ALIAS("ip6t_TCPOPTSTRIP");