Chinaunix
标题:
netfilter修改IP以后一直发不出包
[打印本页]
作者:
tinysniper
时间:
2014-05-29 01:06
标题:
netfilter修改IP以后一直发不出包
下面是hook的代码
麻烦各位帮忙看下,怎么做
static unsigned int hook_func_postrouting(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct iphdr *iph;
struct tcphdr *tcph;
struct rtable *rt;
int dest_port;
int orig_ip;
int datalen;
if (!skb) {
return NF_ACCEPT;
} else {
rt = skb_rtable(skb);
iph = ip_hdr(skb);
if (!iph) {
return NF_ACCEPT;
} else {
if ( skb_linearize(skb) != 0 ) {
printk(KERN_INFO "skb not liner\n");
return NF_ACCEPT;
}
if ( iph->protocol == IPPROTO_TCP ) {
tcph = (struct tcphdr*) (((char*) iph) + iph->ihl * 4);
if ( !tcph ) {
return NF_ACCEPT;
}
dest_port = ntohs(tcph->dest);
// printk(KERN_INFO "[FILTER]: from %pI4:%d to %pI4:%d\n", &iph->saddr, ntohs(tcph->source), &iph->daddr, ntohs(tcph->dest));
if ( dest_port == 80 ) {
orig_ip = iph->daddr;
iph->daddr = in_aton("192.168.2.116");
// printk(KERN_INFO "[FILTER]: modify dest ip from %pI4:%d to %pI4:%d\n", &orig_ip, dest_port, &iph->daddr, 80);
iph->check = 0;
ip_send_check(iph);
datalen = skb->len - iph->ihl * 4;
tcph->check = 0;
tcph->check = tcp_v4_check(datalen, iph->saddr, iph->daddr, csum_partial(tcph, datalen, 0));
}
}
return NF_ACCEPT;
}
}
}
作者:
黎明748
时间:
2014-05-29 01:18
。。。。怎么都返回NF_ACCEPT。。还是不明白你说什么。。。
作者:
tinysniper
时间:
2014-05-29 10:26
我只是拿来做下测试,修改了ip头的目的ip以后,包就发不出去了,感觉是tcp校验和的问题
作者:
bfdhczw
时间:
2014-05-29 10:45
我是这么算的,你试试看。
static void update_chksum(struct sk_buff *skb, struct iphdr *iph, struct tcphdr *tcp)
{
//ip
iph->check = 0;
iph->check = ip_fast_csum(iph,iph->ihl);
//tcp
tcp->check = 0;
tcp->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
ntohs(iph->tot_len)-iph->ihl*4, IPPROTO_TCP,
csum_partial(tcp, ntohs(iph->tot_len)-iph->ihl*4, 0));
}
复制代码
作者:
tinysniper
时间:
2014-05-29 11:25
回复
4#
bfdhczw
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/inet.h>
#include <linux/skbuff.h>
#include <linux/tcp.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <net/tcp.h>
#include <net/ip.h>
static struct nf_hook_ops nfho_postrouting;
static void update_checksum(struct sk_buff *skb, struct iphdr *iph, struct tcphdr *tcp)
{
iph->check = 0;
iph->check = ip_fast_csum(iph, iph->ihl);
tcp->check = 0;
tcp->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
ntohs(iph->tot_len) - iph->ihl * 4, IPPROTO_TCP,
csum_partial(tcp, ntohs(iph->tot_len) - iph->ihl * 4, 0));
}
static unsigned int hook_func_postrouting(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct iphdr *iph;
struct tcphdr *tcph;
struct rtable *rt;
int dest_port;
int orig_ip;
int datalen;
if (!skb) {
return NF_ACCEPT;
} else {
rt = skb_rtable(skb);
iph = ip_hdr(skb);
if (!iph) {
return NF_ACCEPT;
} else {
if ( skb_linearize(skb) != 0 ) {
printk(KERN_INFO "skb not liner\n");
return NF_ACCEPT;
}
if ( iph->protocol == IPPROTO_TCP ) {
tcph = (struct tcphdr*) (((char*) iph) + iph->ihl * 4);
if ( !tcph ) {
return NF_ACCEPT;
}
dest_port = ntohs(tcph->dest);
if ( dest_port == 80 ) {
orig_ip = iph->daddr;
// 直接浏览器打开http://192.168.2.1,只要挂上重新算了checksum就失败
iph->daddr = in_aton("192.168.2.1");
update_checksum(skb, iph, tcph);
}
}
return NF_ACCEPT;
}
}
}
static int __init init_main(void)
{
nfho_postrouting.hook = hook_func_postrouting;
nfho_postrouting.hooknum = NF_INET_POST_ROUTING;
nfho_postrouting.pf = PF_INET;
nfho_postrouting.priority = NF_IP_PRI_FIRST;
nf_register_hook(&nfho_postrouting);
return 0;
}
static void __exit cleanup_main(void)
{
nf_unregister_hook(&nfho_postrouting);
}
module_init(init_main);
module_exit(cleanup_main);
MODULE_LICENSE("GPL");
复制代码
依旧有问题
我直接wget
http://192.168.2.1
,等于是,我压根没有修改ip,只是重新计算了一次checksum
直接就发不出包了
但是,不计算checksum的话,就完全没问题了
另外,我的内核版本有点高,我现在的内核是3.11.0
作者:
tinysniper
时间:
2014-05-29 12:09
回复
4#
bfdhczw
又抓包确认了下,还是tcp的校验和求错了
ip层的校验和没问题
作者:
tinysniper
时间:
2014-05-29 13:18
谢谢各位,搞定了
skb->ip_summed忘记处理了
作者:
天外来的飞猪
时间:
2014-10-15 16:30
你好,请问你是怎么解决的,ip_summed设置成了什么
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2