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.22 115 lines 2.7 kB view raw
1/* Kernel module to match TCP MSS values. */ 2 3/* Copyright (C) 2000 Marc Boucher <marc@mbsi.ca> 4 * Portions (C) 2005 by Harald Welte <laforge@netfilter.org> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 */ 10 11#include <linux/module.h> 12#include <linux/skbuff.h> 13#include <net/tcp.h> 14 15#include <linux/netfilter/xt_tcpmss.h> 16#include <linux/netfilter/x_tables.h> 17 18#include <linux/netfilter_ipv4/ip_tables.h> 19#include <linux/netfilter_ipv6/ip6_tables.h> 20 21MODULE_LICENSE("GPL"); 22MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 23MODULE_DESCRIPTION("iptables TCP MSS match module"); 24MODULE_ALIAS("ipt_tcpmss"); 25 26static int 27match(const struct sk_buff *skb, 28 const struct net_device *in, 29 const struct net_device *out, 30 const struct xt_match *match, 31 const void *matchinfo, 32 int offset, 33 unsigned int protoff, 34 int *hotdrop) 35{ 36 const struct xt_tcpmss_match_info *info = matchinfo; 37 struct tcphdr _tcph, *th; 38 /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ 39 u8 _opt[15 * 4 - sizeof(_tcph)], *op; 40 unsigned int i, optlen; 41 42 /* If we don't have the whole header, drop packet. */ 43 th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph); 44 if (th == NULL) 45 goto dropit; 46 47 /* Malformed. */ 48 if (th->doff*4 < sizeof(*th)) 49 goto dropit; 50 51 optlen = th->doff*4 - sizeof(*th); 52 if (!optlen) 53 goto out; 54 55 /* Truncated options. */ 56 op = skb_header_pointer(skb, protoff + sizeof(*th), optlen, _opt); 57 if (op == NULL) 58 goto dropit; 59 60 for (i = 0; i < optlen; ) { 61 if (op[i] == TCPOPT_MSS 62 && (optlen - i) >= TCPOLEN_MSS 63 && op[i+1] == TCPOLEN_MSS) { 64 u_int16_t mssval; 65 66 mssval = (op[i+2] << 8) | op[i+3]; 67 68 return (mssval >= info->mss_min && 69 mssval <= info->mss_max) ^ info->invert; 70 } 71 if (op[i] < 2) 72 i++; 73 else 74 i += op[i+1] ? : 1; 75 } 76out: 77 return info->invert; 78 79dropit: 80 *hotdrop = 1; 81 return 0; 82} 83 84static struct xt_match xt_tcpmss_match[] = { 85 { 86 .name = "tcpmss", 87 .family = AF_INET, 88 .match = match, 89 .matchsize = sizeof(struct xt_tcpmss_match_info), 90 .proto = IPPROTO_TCP, 91 .me = THIS_MODULE, 92 }, 93 { 94 .name = "tcpmss", 95 .family = AF_INET6, 96 .match = match, 97 .matchsize = sizeof(struct xt_tcpmss_match_info), 98 .proto = IPPROTO_TCP, 99 .me = THIS_MODULE, 100 }, 101}; 102 103static int __init xt_tcpmss_init(void) 104{ 105 return xt_register_matches(xt_tcpmss_match, 106 ARRAY_SIZE(xt_tcpmss_match)); 107} 108 109static void __exit xt_tcpmss_fini(void) 110{ 111 xt_unregister_matches(xt_tcpmss_match, ARRAY_SIZE(xt_tcpmss_match)); 112} 113 114module_init(xt_tcpmss_init); 115module_exit(xt_tcpmss_fini);