亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? ip_nat_helper.c

?? 優龍2410linux2.6.8內核源代碼
?? C
字號:
/* ip_nat_helper.c - generic support functions for NAT helpers  * * (C) 2000-2002 Harald Welte <laforge@netfilter.org> * (C) 2003-2004 Netfilter Core Team <coreteam@netfilter.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * 	14 Jan 2002 Harald Welte <laforge@gnumonks.org>: *		- add support for SACK adjustment  *	14 Mar 2002 Harald Welte <laforge@gnumonks.org>: *		- merge SACK support into newnat API *	16 Aug 2002 Brian J. Murrell <netfilter@interlinx.bc.ca>: *		- make ip_nat_resize_packet more generic (TCP and UDP) *		- add ip_nat_mangle_udp_packet */#include <linux/config.h>#include <linux/module.h>#include <linux/kmod.h>#include <linux/types.h>#include <linux/timer.h>#include <linux/skbuff.h>#include <linux/netfilter_ipv4.h>#include <net/checksum.h>#include <net/icmp.h>#include <net/ip.h>#include <net/tcp.h>#include <net/udp.h>#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock)#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock)#include <linux/netfilter_ipv4/ip_conntrack.h>#include <linux/netfilter_ipv4/ip_conntrack_helper.h>#include <linux/netfilter_ipv4/ip_nat.h>#include <linux/netfilter_ipv4/ip_nat_protocol.h>#include <linux/netfilter_ipv4/ip_nat_core.h>#include <linux/netfilter_ipv4/ip_nat_helper.h>#include <linux/netfilter_ipv4/listhelp.h>#if 0#define DEBUGP printk#define DUMP_OFFSET(x)	printk("offset_before=%d, offset_after=%d, correction_pos=%u\n", x->offset_before, x->offset_after, x->correction_pos);#else#define DEBUGP(format, args...)#define DUMP_OFFSET(x)#endifDECLARE_LOCK(ip_nat_seqofs_lock);/* Setup TCP sequence correction given this change at this sequence */static inline void adjust_tcp_sequence(u32 seq,		    int sizediff,		    struct ip_conntrack *ct, 		    enum ip_conntrack_info ctinfo){	int dir;	struct ip_nat_seq *this_way, *other_way;	DEBUGP("ip_nat_resize_packet: old_size = %u, new_size = %u\n",		(*skb)->len, new_size);	dir = CTINFO2DIR(ctinfo);	this_way = &ct->nat.info.seq[dir];	other_way = &ct->nat.info.seq[!dir];	DEBUGP("ip_nat_resize_packet: Seq_offset before: ");	DUMP_OFFSET(this_way);	LOCK_BH(&ip_nat_seqofs_lock);	/* SYN adjust. If it's uninitialized, of this is after last	 * correction, record it: we don't handle more than one	 * adjustment in the window, but do deal with common case of a	 * retransmit */	if (this_way->offset_before == this_way->offset_after	    || before(this_way->correction_pos, seq)) {		    this_way->correction_pos = seq;		    this_way->offset_before = this_way->offset_after;		    this_way->offset_after += sizediff;	}	UNLOCK_BH(&ip_nat_seqofs_lock);	DEBUGP("ip_nat_resize_packet: Seq_offset after: ");	DUMP_OFFSET(this_way);}/* Frobs data inside this packet, which is linear. */static void mangle_contents(struct sk_buff *skb,			    unsigned int dataoff,			    unsigned int match_offset,			    unsigned int match_len,			    const char *rep_buffer,			    unsigned int rep_len){	unsigned char *data;	BUG_ON(skb_is_nonlinear(skb));	data = (unsigned char *)skb->nh.iph + dataoff;	/* move post-replacement */	memmove(data + match_offset + rep_len,		data + match_offset + match_len,		skb->tail - (data + match_offset + match_len));	/* insert data from buffer */	memcpy(data + match_offset, rep_buffer, rep_len);	/* update skb info */	if (rep_len > match_len) {		DEBUGP("ip_nat_mangle_packet: Extending packet by "			"%u from %u bytes\n", rep_len - match_len,		       skb->len);		skb_put(skb, rep_len - match_len);	} else {		DEBUGP("ip_nat_mangle_packet: Shrinking packet from "			"%u from %u bytes\n", match_len - rep_len,		       skb->len);		__skb_trim(skb, skb->len + rep_len - match_len);	}	/* fix IP hdr checksum information */	skb->nh.iph->tot_len = htons(skb->len);	ip_send_check(skb->nh.iph);}/* Unusual, but possible case. */static int enlarge_skb(struct sk_buff **pskb, unsigned int extra){	struct sk_buff *nskb;	if ((*pskb)->len + extra > 65535)		return 0;	nskb = skb_copy_expand(*pskb, skb_headroom(*pskb), extra, GFP_ATOMIC);	if (!nskb)		return 0;	/* Transfer socket to new skb. */	if ((*pskb)->sk)		skb_set_owner_w(nskb, (*pskb)->sk);#ifdef CONFIG_NETFILTER_DEBUG	nskb->nf_debug = (*pskb)->nf_debug;#endif	kfree_skb(*pskb);	*pskb = nskb;	return 1;}/* Generic function for mangling variable-length address changes inside * NATed TCP connections (like the PORT XXX,XXX,XXX,XXX,XXX,XXX * command in FTP). * * Takes care about all the nasty sequence number changes, checksumming, * skb enlargement, ... * * */int ip_nat_mangle_tcp_packet(struct sk_buff **pskb,			 struct ip_conntrack *ct,			 enum ip_conntrack_info ctinfo,			 unsigned int match_offset,			 unsigned int match_len,			 const char *rep_buffer,			 unsigned int rep_len){	struct iphdr *iph;	struct tcphdr *tcph;	int datalen;	if (!skb_ip_make_writable(pskb, (*pskb)->len))		return 0;	if (rep_len > match_len	    && rep_len - match_len > skb_tailroom(*pskb)	    && !enlarge_skb(pskb, rep_len - match_len))		return 0;	SKB_LINEAR_ASSERT(*pskb);	iph = (*pskb)->nh.iph;	tcph = (void *)iph + iph->ihl*4;	mangle_contents(*pskb, iph->ihl*4 + tcph->doff*4,			match_offset, match_len, rep_buffer, rep_len);	datalen = (*pskb)->len - iph->ihl*4;	tcph->check = 0;	tcph->check = tcp_v4_check(tcph, datalen, iph->saddr, iph->daddr,				   csum_partial((char *)tcph, datalen, 0));	adjust_tcp_sequence(ntohl(tcph->seq),			    (int)rep_len - (int)match_len,			    ct, ctinfo);	return 1;}			/* Generic function for mangling variable-length address changes inside * NATed UDP connections (like the CONNECT DATA XXXXX MESG XXXXX INDEX XXXXX * command in the Amanda protocol) * * Takes care about all the nasty sequence number changes, checksumming, * skb enlargement, ... * * XXX - This function could be merged with ip_nat_mangle_tcp_packet which *       should be fairly easy to do. */int ip_nat_mangle_udp_packet(struct sk_buff **pskb,			 struct ip_conntrack *ct,			 enum ip_conntrack_info ctinfo,			 unsigned int match_offset,			 unsigned int match_len,			 const char *rep_buffer,			 unsigned int rep_len){	struct iphdr *iph;	struct udphdr *udph;	/* UDP helpers might accidentally mangle the wrong packet */	iph = (*pskb)->nh.iph;	if ((*pskb)->len < iph->ihl*4 + sizeof(*udph) + 	                       match_offset + match_len)		return 0;	if (!skb_ip_make_writable(pskb, (*pskb)->len))		return 0;	if (rep_len > match_len	    && rep_len - match_len > skb_tailroom(*pskb)	    && !enlarge_skb(pskb, rep_len - match_len))		return 0;	iph = (*pskb)->nh.iph;	udph = (void *)iph + iph->ihl*4;	mangle_contents(*pskb, iph->ihl*4 + sizeof(*udph),			match_offset, match_len, rep_buffer, rep_len);	/* update the length of the UDP packet */	udph->len = htons((*pskb)->len - iph->ihl*4);	/* fix udp checksum if udp checksum was previously calculated */	if (udph->check) {		int datalen = (*pskb)->len - iph->ihl * 4;		udph->check = 0;		udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr,		                                datalen, IPPROTO_UDP,		                                csum_partial((char *)udph,		                                             datalen, 0));	}	return 1;}/* Adjust one found SACK option including checksum correction */static voidsack_adjust(struct sk_buff *skb,	    struct tcphdr *tcph, 	    unsigned int sackoff,	    unsigned int sackend,	    struct ip_nat_seq *natseq){	while (sackoff < sackend) {		struct tcp_sack_block *sack;		u_int32_t new_start_seq, new_end_seq;		sack = (void *)skb->data + sackoff;		if (after(ntohl(sack->start_seq) - natseq->offset_before,			  natseq->correction_pos))			new_start_seq = ntohl(sack->start_seq) 					- natseq->offset_after;		else			new_start_seq = ntohl(sack->start_seq) 					- natseq->offset_before;		new_start_seq = htonl(new_start_seq);		if (after(ntohl(sack->end_seq) - natseq->offset_before,			  natseq->correction_pos))			new_end_seq = ntohl(sack->end_seq)				      - natseq->offset_after;		else			new_end_seq = ntohl(sack->end_seq)				      - natseq->offset_before;		new_end_seq = htonl(new_end_seq);		DEBUGP("sack_adjust: start_seq: %d->%d, end_seq: %d->%d\n",			ntohl(sack->start_seq), new_start_seq,			ntohl(sack->end_seq), new_end_seq);		tcph->check = 			ip_nat_cheat_check(~sack->start_seq, new_start_seq,					   ip_nat_cheat_check(~sack->end_seq, 						   	      new_end_seq,							      tcph->check));		sack->start_seq = new_start_seq;		sack->end_seq = new_end_seq;		sackoff += sizeof(*sack);	}}/* TCP SACK sequence number adjustment */static inline unsigned intip_nat_sack_adjust(struct sk_buff **pskb,		   struct tcphdr *tcph,		   struct ip_conntrack *ct,		   enum ip_conntrack_info ctinfo){	unsigned int dir, optoff, optend;	optoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct tcphdr);	optend = (*pskb)->nh.iph->ihl*4 + tcph->doff*4;	if (!skb_ip_make_writable(pskb, optend))		return 0;	dir = CTINFO2DIR(ctinfo);	while (optoff < optend) {		/* Usually: option, length. */		unsigned char *op = (*pskb)->data + optoff;		switch (op[0]) {		case TCPOPT_EOL:			return 1;		case TCPOPT_NOP:			optoff++;			continue;		default:			/* no partial options */			if (optoff + 1 == optend			    || optoff + op[1] > optend			    || op[1] < 2)				return 0;			if (op[0] == TCPOPT_SACK			    && op[1] >= 2+TCPOLEN_SACK_PERBLOCK			    && ((op[1] - 2) % TCPOLEN_SACK_PERBLOCK) == 0)				sack_adjust(*pskb, tcph, optoff+2,					    optoff+op[1],					    &ct->nat.info.seq[!dir]);			optoff += op[1];		}	}	return 1;}/* TCP sequence number adjustment.  Returns true or false.  */intip_nat_seq_adjust(struct sk_buff **pskb, 		  struct ip_conntrack *ct, 		  enum ip_conntrack_info ctinfo){	struct tcphdr *tcph;	int dir, newseq, newack;	struct ip_nat_seq *this_way, *other_way;		dir = CTINFO2DIR(ctinfo);	this_way = &ct->nat.info.seq[dir];	other_way = &ct->nat.info.seq[!dir];	/* No adjustments to make?  Very common case. */	if (!this_way->offset_before && !this_way->offset_after	    && !other_way->offset_before && !other_way->offset_after)		return 1;	if (!skb_ip_make_writable(pskb, (*pskb)->nh.iph->ihl*4+sizeof(*tcph)))		return 0;	tcph = (void *)(*pskb)->data + (*pskb)->nh.iph->ihl*4;	if (after(ntohl(tcph->seq), this_way->correction_pos))		newseq = ntohl(tcph->seq) + this_way->offset_after;	else		newseq = ntohl(tcph->seq) + this_way->offset_before;	newseq = htonl(newseq);	if (after(ntohl(tcph->ack_seq) - other_way->offset_before,		  other_way->correction_pos))		newack = ntohl(tcph->ack_seq) - other_way->offset_after;	else		newack = ntohl(tcph->ack_seq) - other_way->offset_before;	newack = htonl(newack);	tcph->check = ip_nat_cheat_check(~tcph->seq, newseq,					 ip_nat_cheat_check(~tcph->ack_seq, 					 		    newack, 							    tcph->check));	DEBUGP("Adjusting sequence number from %u->%u, ack from %u->%u\n",		ntohl(tcph->seq), ntohl(newseq), ntohl(tcph->ack_seq),		ntohl(newack));	tcph->seq = newseq;	tcph->ack_seq = newack;	return ip_nat_sack_adjust(pskb, tcph, ct, ctinfo);}static inline inthelper_cmp(const struct ip_nat_helper *helper,	   const struct ip_conntrack_tuple *tuple){	return ip_ct_tuple_mask_cmp(tuple, &helper->tuple, &helper->mask);}int ip_nat_helper_register(struct ip_nat_helper *me){	int ret = 0;	WRITE_LOCK(&ip_nat_lock);	if (LIST_FIND(&helpers, helper_cmp, struct ip_nat_helper *,&me->tuple))		ret = -EBUSY;	else		list_prepend(&helpers, me);	WRITE_UNLOCK(&ip_nat_lock);	return ret;}static intkill_helper(const struct ip_conntrack *i, void *helper){	int ret;	READ_LOCK(&ip_nat_lock);	ret = (i->nat.info.helper == helper);	READ_UNLOCK(&ip_nat_lock);	return ret;}void ip_nat_helper_unregister(struct ip_nat_helper *me){	WRITE_LOCK(&ip_nat_lock);	/* Autoloading conntrack helper might have failed */	if (LIST_FIND(&helpers, helper_cmp, struct ip_nat_helper *,&me->tuple)) {		LIST_DELETE(&helpers, me);	}	WRITE_UNLOCK(&ip_nat_lock);	/* Someone could be still looking at the helper in a bh. */	synchronize_net();	/* Find anything using it, and umm, kill them.  We can't turn	   them into normal connections: if we've adjusted SYNs, then	   they'll ackstorm.  So we just drop it.  We used to just	   bump module count when a connection existed, but that	   forces admins to gen fake RSTs or bounce box, either of	   which is just a long-winded way of making things	   worse. --RR */	ip_ct_selective_cleanup(kill_helper, me);}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲123区在线观看| 26uuu久久综合| 欧美精品久久天天躁| 久久综合色婷婷| 亚洲一区二区在线视频| 高清成人在线观看| 中文字幕av资源一区| 蜜臀a∨国产成人精品| 91美女在线看| 精品国产乱码久久久久久图片 | 91免费视频网| 久久久亚洲精品一区二区三区| 亚洲一区二区中文在线| 色综合天天综合网国产成人综合天 | 一区二区欧美精品| 国产成人夜色高潮福利影视| 日韩欧美资源站| 亚洲va韩国va欧美va精品| 99久久国产综合精品麻豆| 久久久精品综合| 日韩电影免费一区| 欧美老人xxxx18| 亚洲综合偷拍欧美一区色| 高清beeg欧美| 久久久久久一二三区| 日本成人中文字幕| 中文av字幕一区| 国产伦精品一区二区三区视频青涩| 欧美一区二区观看视频| 日韩国产高清在线| 在线不卡一区二区| 日韩精品1区2区3区| 欧美群妇大交群中文字幕| 天天综合日日夜夜精品| 91精品国产免费久久综合| 日韩1区2区3区| 欧美zozozo| 国产成人免费在线视频| 国产精品入口麻豆原神| 99久久综合99久久综合网站| 一色桃子久久精品亚洲| 色婷婷综合久久久| 亚洲美女视频在线| 欧美撒尿777hd撒尿| 日韩中文字幕麻豆| 久久综合成人精品亚洲另类欧美| 国内成+人亚洲+欧美+综合在线| 亚洲精品在线观看网站| 国产成人在线视频网站| 成人欧美一区二区三区| 欧美亚洲一区二区三区四区| 蜜臀av一级做a爰片久久| 日韩久久精品一区| 岛国一区二区三区| 一区二区久久久| 欧美一区二区在线免费观看| 国产成人在线看| 亚洲欧美另类图片小说| 91精品欧美久久久久久动漫 | 蜜臀精品久久久久久蜜臀| 欧美日本在线播放| 日韩av在线发布| 日本一区二区三区电影| 91蜜桃免费观看视频| 日韩不卡一区二区| 中文字幕精品—区二区四季| 在线免费一区三区| 精一区二区三区| 亚洲精品视频观看| 精品国产免费视频| 欧美综合一区二区| 国产另类ts人妖一区二区| 亚洲小少妇裸体bbw| 欧美va亚洲va| 色屁屁一区二区| 黄色成人免费在线| 亚洲福利视频导航| 国产欧美精品一区aⅴ影院| 欧美网站一区二区| 日韩欧美成人一区| 狠狠色丁香婷婷综合久久片| 中文字幕一区二区三| 精品国产一区二区三区久久久蜜月| 不卡视频一二三四| 九九九精品视频| 亚洲精品久久嫩草网站秘色| 日韩美女主播在线视频一区二区三区| 国产高清精品久久久久| 三级影片在线观看欧美日韩一区二区| 亚洲国产精品成人综合色在线婷婷| 91国偷自产一区二区使用方法| 国产精品中文欧美| 日韩精品欧美成人高清一区二区| 国产精品麻豆视频| 久久久久久一二三区| 欧美成人一级视频| 亚洲午夜精品在线| 经典一区二区三区| 夜夜夜精品看看| 国产精品乱码一区二区三区软件| 欧美剧情电影在线观看完整版免费励志电影 | 欧美猛男男办公室激情| 色综合咪咪久久| 丁香桃色午夜亚洲一区二区三区| 捆绑调教一区二区三区| 亚洲福利一二三区| 亚洲日本在线天堂| 亚洲三级在线观看| 国产精品久久久久久久岛一牛影视 | 亚洲视频一区二区免费在线观看| 久久久久久影视| 久久精品视频免费观看| 久久蜜桃一区二区| 久久久久综合网| 久久精品一区二区三区不卡| 26uuu国产电影一区二区| 欧美激情综合在线| 亚洲精品国产一区二区三区四区在线| 日韩欧美一二三区| 欧美一二区视频| 制服.丝袜.亚洲.另类.中文| 欧美日韩小视频| 制服.丝袜.亚洲.中文.综合| 日韩美女主播在线视频一区二区三区| 日韩免费电影一区| 日韩精品在线网站| 国产视频亚洲色图| 亚洲视频综合在线| 午夜影院久久久| 日韩1区2区3区| 精品一区二区三区蜜桃| 国产一区亚洲一区| va亚洲va日韩不卡在线观看| 一本色道久久加勒比精品| 国产三级精品视频| 国产精品伦理在线| 亚洲国产成人av网| 99久久99久久精品免费观看 | 久久亚区不卡日本| 国产亚洲自拍一区| 国产精品国产三级国产普通话三级| 国产日韩欧美高清| 一区二区三区在线观看视频| 午夜精品久久久久久久久久 | 国产精品日韩成人| 伊人色综合久久天天人手人婷| 午夜视频在线观看一区| 国产原创一区二区| 91福利视频久久久久| 日韩一级欧美一级| 国产精品家庭影院| 美女视频网站黄色亚洲| 成人亚洲精品久久久久软件| 欧美日韩aaa| 国产精品国产三级国产| 午夜视频在线观看一区二区三区| 亚洲影视在线播放| 久久午夜电影网| 亚洲欧美偷拍三级| 日韩精品亚洲一区| 丁香婷婷综合网| 在线播放亚洲一区| 亚洲色图.com| 国产精品99久久久久久久女警| 99精品热视频| 久久综合视频网| 日韩精品乱码免费| 日本精品一区二区三区高清| 2020国产精品久久精品美国| 亚洲国产aⅴ成人精品无吗| 国产精品自拍毛片| 精品免费日韩av| 天堂午夜影视日韩欧美一区二区| 不卡在线视频中文字幕| 精品国产乱码久久久久久久久 | 五月天丁香久久| 99久久综合国产精品| 久久午夜羞羞影院免费观看| 日韩黄色免费网站| 欧美日韩成人高清| 亚洲午夜在线视频| 91在线一区二区三区| 国产精品女同互慰在线看| 亚洲免费观看高清| 国产精品综合一区二区| 亚洲欧洲性图库| 国产精品一区二区你懂的| 日韩你懂的在线观看| 午夜精品在线看| 欧美在线999| 亚洲在线免费播放| 色综合久久久久久久久久久| 国产精品久久久爽爽爽麻豆色哟哟| 国产高清一区日本| 久久精品一区蜜桃臀影院| 精品无码三级在线观看视频| 精品福利av导航| 国产大片一区二区| 日本一区二区三区dvd视频在线| 国产一区二区三区免费播放|