分享
 
 
 

改tcp/ip协议栈屏蔽nat的尝试

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

在开发H323设备时,发现有一个公网ip地址实在不错,因为H245协议中的TransportAddress包含了ip地址的信息,有时候可能portforward后也搞不定(至少理论上是这样)。可惜用adsl上网,一般都是使用私有地址,没办法,试试看改内核。

使LAN中的一台PC(或其它设备以下称A)和某些internet网IP的PC(或其它设备以下称B)通信时,和拨号服务器(以下称C)一样,拥有外网IP地址。

基本思路:

从PPPOE(严格地说是PPP)来的数据数据包,避开NAT,直接转发到内网;反之亦然。我把截获数据包的点选在ip_rcv中。

当然,原来的拨号网关还有一个代理arp的功能,在arp_rcv中截下A发出的arp包,特别应答一下(conv.c)。

具体过程如下:

1.在arp.c和ip_input.c中各埋下一个钩子(函数指针),实际的处理把它放到外面的模块中实现,这样便于调试和修改,内核只需要改一次。

2.在模块程序中实现实际的ip数据包的转发:如果ip包来自某个地址,则给这个包加上MAC帧头,然后从把这个包通过dev_queue_xmit()转发到内部局域网。跳过路由,NAT,防火墙等功能模块;在反方向,从A收到的MAC包(通过IP辨认),直接去头转发给ppp设备。

3.收到A的arp请求(通过 A的MAC地址确认)直接应答。然后丢弃这个arp请求包。

4.应用程序中读取ppp0的ip地址(就是拨号得到的动态ip),交给模块。

说明:

1.new_ip_rcv中返回0,表示这个数据包经过了短路处理,内核对这个包不做进一步处理。

返回1;此包有问题要系统丢弃它;其它,一般数据包,内核应该继续正常处理。

2.new_arp_rcv中返回0,表示是一般arp包,系统继续正常处理,返回1,系统对此包不作进一步处理。

3.程序中有许多hardcode的地方,如ppp0,eth0。还有拨号服务器判断数据包是否是A发出的时,用的是IP,可能用MAC地址更合理。

[code]

内核(2.2.20)的修改:

1. arp.c

加入:

int (*arp_rcv_hook)(struct sk_buff *skb, struct device *dev, struct packet_type *pt) = 0;

改:

…….

int arp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)

{

…..

/*

* Check for bad requests for 127.x.x.x and requests for multicast

* and in the case of requests for us we add the requester to the arp

* cache.

*/

/* Special case: IPv4 duplicate address detection packet (RFC2131) */

if(arp_rcv_hook && arp_rcv_hook(skb,dev,pt)) /* 大约689行*/

goto out;

if (sip == 0) {

…..

}

2. ip_input.c

加入:

int (*ip_rcv_hook)(struct skb_buff *) = 0;

改:

int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)

{

……

if(ip_rcv_hook) /* 大约第464行*/

{

int retval;

retval = (*ip_rcv_hook)(skb);

if(retval == 0)

return 0;

else if(retval == 1)

goto drop;

}

#ifdef CONFIG_FIREWALL

……

}

3. netsyms.c

加入:

extern int (*arp_rcv_hook)(struct sk_buff*,struct device *,struct packet_type*);

EXPORT_SYMBOL_NOVERS(arp_rcv_hook);

extern int (*ip_rcv_hook)(struct sk_buff*);

EXPORT_SYMBOL_NOVERS(ip_rcv_hook);

应用程序:

/*conv.c shortcut between adsl and lan device

* email: jundai20@hotmail.com

*/

#include

#include

#include

#include

#include

#include

#include "conv.h"

int ppp_ipaddr;

MODULE_PARM(ppp_ipaddr,"i");

/* This our_memcpy it is runs in kernel,

* so the des, src is equ to phy address

*/

void our_memcpy(unsigned char* des,unsigned char* src,unsigned int len)

{

unsigned int i;

for(i=0;i *(des+i) = *(src+i);

}

struct sk_buff* ppp2eth(struct sk_buff* skb)

{

unsigned char ethhdr[14] ={0x00,0x06,0x4e,0x00,0x04,0x94,0x00,0xe0,0x4c,0xe0,0xf8,0x35,0x08,0x00};/* change the mac addr pls*/

struct sk_buff* skb2;

unsigned int size;

size = skb-len + 14;

skb2 = alloc_skb(size,GFP_ATOMIC);

our_memcpy(skb2-data,ethhdr,14);

our_memcpy(skb2-data+14,skb-data,skb-len);

skb2-tail += size;

skb2-len = size;

__kfree_skb(skb);

return skb2;

}

struct sk_buff* eth2ppp(struct sk_buff* skb)

{

return skb;

}

int new_ip_rcv(struct sk_buff *skb)

{

struct device* lan_eth,*ppp_h;

struct sk_buff* skb_new;

lan_eth = dev_get("eth1");

ppp_h = dev_get("ppp0");

if(lan_eth == NULL || ppp_h == NULL)

return 0;

if(skb-dev-name[0] == 'p')

{

if(skb-nh.iph-saddr != 0x12345678)/* change to the ip addr as you wish*/

return 3;

skb_new = ppp2eth(skb);

skb_new-dev = lan_eth;

dev_queue_xmit(skb_new);

return 0;

}

else if (skb-dev-name[0] == 'e' && skb-dev-name[3] == '1')

{

if(skb-nh.iph-saddr != ppp_ipaddr)

return 3;

skb_new = eth2ppp(skb);

skb_new-dev = ppp_h;

dev_queue_xmit(skb_new);

}

// if we return 1 , we will free skb

return 0;

}

int new_arp_rcv(struct sk_buff* skb,struct device* dev,struct packet_type* pt)

{

struct arphdr *arp = skb-nh.arph;

unsigned char *arp_ptr= (unsigned char *)(arp+1);

unsigned long sip,tip;

unsigned char* sha;

sha=arp_ptr;

arp_ptr += dev-addr_len;

our_memcpy((unsigned char*)(&sip),arp_ptr,4);

arp_ptr += 4;

arp_ptr += dev-addr_len;

our_memcpy((unsigned char*)(&tip),arp_ptr,4);

if(*sha== 0x00 && *(sha+1) == 0x06 && *(sha+2) == 0x4e && *(sha+3) == 0x00 && *(sha+4) == 0x04 && *(sha+5) == 0x94 && arp-ar_op == __constant_htons(ARPOP_REQUEST))

{

arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev-dev_addr,sha);

return 1;

}

else

return 0;

}

int init_module()

{

EXPORT_NO_SYMBOLS;

arp_rcv_hook = new_arp_rcv;

ip_rcv_hook = new_ip_rcv;

printk("now enter ipnat : %x...\n",ppp_ipaddr);

return 0;

}

void cleanup_module()

{

arp_rcv_hook = 0;

ip_rcv_hook = 0;

printk("now net_hook will quit.\n");

}

/* conv.h: head file for conv.c

* email:jundai20@hotmail.com

*/

extern int (*ip_rcv_hook)(struct sk_buff *);

extern int (*arp_rcv_hook)(struct sk_buff *,struct device* dev,struct packet_type* pt);

extern void arp_send(int type, int ptype, u32 dest_ip,

struct device *dev, u32 src_ip,

unsigned char *dest_hw, unsigned char *src_hw, unsigned char *th);

extern struct device* dev_get(const char* name);

extern struct sk_buff * skb_realloc_headroom(struct sk_buff *skb, int newheadroom);

extern void __kfree_skb(struct sk_buff*);

#ifndef ARPOP_REPLY

#define ARPOP_REPLY 2

#endif

#ifndef ETH_P_ARP

#define ETH_P_ARP 0x0806

#endif

#ifndef GFP_ATOMIC

#define GFP_ATOMIC 0x08

#endif

/* passnat.c : user interface for use conv

* email: jundai20@hotmail.com

*/

#include

#include

#include

#include

#include

#include

int main()

{

struct ifreq ifr;

struct sockaddr_in *skt;

int eth_s;

unsigned long ip_addr_rtrn;

unsigned char command[256]={0};

if((eth_s = socket(AF_INET, SOCK_DGRAM, 0))

{

perror("socket");

exit(0);

}

strcpy(ifr.ifr_name, "ppp0");

if(ioctl(eth_s, SIOCGIFADDR, &ifr)

skt = (struct sockaddr_in*)&ifr.i

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有