- 论坛徽章:
- 0
|
首先说明问题:
三台机器相连A--B---C,中间一台B作为A,C的默认网关。IP地址分别为:10.1.1.3----10.1.1.1 / 169.1.1.3---169.1.1.1。
利用下面的程序在B截获从A-->C的包,并对截获的包进行目的ip地址和源ip地址修改,校验和后发出。
现象:利用wireshark观察,B主机的wireshark可以截获到2个包,一个输入的一个地址转化后的,都没有错误提示。但是在C却收到的是以下信息的包:
对比B和C的wireshark发现,只有一个地方不一直:在B中是0800 但传到C就成了0004了。。。。。。。求指导!!!谢谢谢谢!!!
- #include<linux/init.h>
- #include<linux/module.h>
- #include<linux/netfilter.h>
- #include<linux/netfilter_ipv4.h>
- #include<linux/socket.h>
- #include<linux/skbuff.h>
- #include<linux/netdevice.h>
- #include<linux/inet.h>
- #include<net/ip.h>
- #include<net/tcp.h>
- #define ETHALEN 14
- #define ETH_ALEN 6
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("123");
- //#define ETH_P_803 0x0001
- #define ETH_P_IP 0x0800
- unsigned char src_mac1[6] = {0x00,0x24,0x7E,0x0E,0x0A,0x8A}; //169.1.1.3
- unsigned char dst_mac1[6] = {0xEC,0x88,0x8F,0xEA,0x4D,0xAC}; //169.1.1.1
- //unsigned char src_mac2[6] = {};
- //unsigned char dst_mac2[6] = {};
- struct nf_hook_ops nfho;
- static unsigned int checksum(
- unsigned int hooknum,
- struct sk_buff *__skb,
- const struct net_device *in,
- const struct net_device *out,
- int (*okfn)(struct sk_buff *)
- )
- {
- struct sk_buff *skb;
- struct net_device *dev;
- struct ethhdr *eth_out;
- //struct ethhdr *eth_in;
- struct iphdr *iph;
- struct tcphdr *tcph;
- int tot_len;
- int iph_len;
- int tcph_len;
- int ret;
- skb = __skb;
- if(skb == NULL)
- return NF_ACCEPT;
- iph = ip_hdr(skb);
- if(iph == NULL)
- return NF_ACCEPT;
- tot_len = ntohs(iph->tot_len);
- if(iph->daddr == in_aton("192.168.137.1")) //查看目的IP地址!对是本IP地址的包进行以下操作
- {
- iph_len = ip_hdrlen(skb); //获取ip首部长度
- skb_pull(skb,iph_len); //skb->data指针定位到传输层
- skb_reset_transport_header(skb);//重置首部长度,现在的首部长度包括了的ip首部长度??
- if(iph->protocol == IPPROTO_TCP) //TCP协议
- {
- tcph = tcp_hdr(skb);
- tcph_len = tcp_hdrlen(skb);
- if(tcph->dest==htons(8888)) //根据自己的需求来进行过滤数据包
- {
- iph->saddr = in_aton("169.1.1.3"); //修改源IP地址(本地的一个IP地址)
- iph->daddr = in_aton("169.1.1.1"); //修改目的IP地址(与本机相连的一个主机的IP地址)
- dev = dev_get_by_name(&init_net,"eth1"); //获取输出dev信息,这里eth1 对应的是169.1.1.3的..
- tcph->check = 0;
- skb->csum = csum_partial((unsigned char *)tcph,tot_len-iph_len,0);
- tcph->check = csum_tcpudp_magic(iph->saddr,iph->daddr,ntohs(iph->tot_len)-iph_len,iph->protocol,skb->csum);
- iph->check = 0;
- ip_send_check(iph);
- skb->ip_summed = CHECKSUM_NONE;
- skb->pkt_type = PACKET_OTHERHOST;
- skb->dev = dev;
- //skb->protocol = ETH_P_803;
- skb_push(skb,iph_len); //在返回之前,先将skb中的信息恢复至原始L3层状态
- //skb_reset_transport_header(skb);
- eth_out = (struct ethhdr *)skb_push(skb,ETHALEN);//将skb->data指向l2层
- eth_out->h_proto= ETH_P_IP; //设置MAC中的 类型
- memcpy(eth_out->h_dest,src_mac1,ETH_ALEN); //设置MAC中的 目的IP地址
- memcpy(eth_out->h_source,dst_mac1,ETH_ALEN); //设置MAC中的 源IP地址
- ret = dev_queue_xmit(skb); //调用...发出
- if(ret < 0 )
- {
- printk("dev_queue_xmit()error\n");
- goto out;
- }
- return NF_STOLEN;
- }
- }
- skb_push(skb,iph_len); //在返回之前,先将skb中的信息恢复至原始L3层状态
- skb_reset_transport_header(skb);
- }
- return NF_ACCEPT;
- out:
- //dev_put(dev);
- //free(skb);
- return NF_DROP;
- }
- static int __init filter_init(void)
- {
- int ret;
- nfho.hook = (nf_hookfn*)checksum;
- nfho.pf = AF_INET;
- nfho.hooknum = NF_INET_PRE_ROUTING;
- nfho.priority = NF_IP_PRI_FIRST;
- ret = nf_register_hook(&nfho);
- if(ret<0)
- {
- printk("%s\n","can't modify skb hook!");
- return ret;
- }
- return 0;
- }
- static void filter_fini(void)
- {
- nf_unregister_hook(&nfho);
- }
- module_init(filter_init);
- module_exit(filter_fini);
复制代码 |
|