📄 ipt_tcpmss.c
字号:
/* * This is a module which is used for setting the MSS option in TCP packets. * * Copyright (c) 2000 Marc Boucher */#include <linux/module.h>#include <linux/skbuff.h>#include <linux/ip.h>#include <net/tcp.h>#include <linux/netfilter_ipv4/ip_tables.h>#include <linux/netfilter_ipv4/ipt_TCPMSS.h>#if 0#define DEBUGP printk#else#define DEBUGP(format, args...)#endifstatic u_int16_tcheat_check(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck){ u_int32_t diffs[] = { oldvalinv, newval }; return csum_fold(csum_partial((char *)diffs, sizeof(diffs), oldcheck^0xFFFF));}static inline unsigned intoptlen(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 intipt_tcpmss_target(struct sk_buff **pskb, unsigned int hooknum, const struct net_device *in, const struct net_device *out, const void *targinfo, void *userinfo){ const struct ipt_tcpmss_info *tcpmssinfo = targinfo; struct tcphdr *tcph; struct iphdr *iph; u_int16_t tcplen, newtotlen, oldval, newmss; unsigned int i; u_int8_t *opt; /* raw socket (tcpdump) may have clone of incoming skb: don't disturb it --RR */ if (skb_cloned(*pskb) && !(*pskb)->sk) { struct sk_buff *nskb = skb_copy(*pskb, GFP_ATOMIC); if (!nskb) return NF_DROP; kfree_skb(*pskb); *pskb = nskb; } iph = (*pskb)->nh.iph; tcplen = (*pskb)->len - iph->ihl*4; tcph = (void *)iph + iph->ihl*4; /* Since it passed flags test in tcp match, we know it is is not a fragment, and has data >= tcp header length. SYN packets should not contain data: if they did, then we risk running over MTU, sending Frag Needed and breaking things badly. --RR */ if (tcplen != tcph->doff*4) { if (net_ratelimit()) printk(KERN_ERR "ipt_tcpmss_target: bad length (%d bytes)\n", (*pskb)->len); return NF_DROP; } if(tcpmssinfo->mss == IPT_TCPMSS_CLAMP_PMTU) { if(!(*pskb)->dst) { if (net_ratelimit()) printk(KERN_ERR "ipt_tcpmss_target: no dst?! can't determine path-MTU\n"); return NF_DROP; /* or IPT_CONTINUE ?? */ } if((*pskb)->dst->pmtu <= (sizeof(struct iphdr) + sizeof(struct tcphdr))) { if (net_ratelimit()) printk(KERN_ERR "ipt_tcpmss_target: unknown or invalid path-MTU (%d)\n", (*pskb)->dst->pmtu); return NF_DROP; /* or IPT_CONTINUE ?? */ } newmss =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -