例子是通过netfilter的hook来实现修改源IP,对应的内核版本是2.6.21以后
tcp端口:9877
本地ip: 192.168.3.88
伪IP:192.168.7.88
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
MODULE_AUTHOR("st");
#ifdef MODULE_LICENSE
MODULE_LICENSE("Dual BSD/GPL");
#endif /* MODULE_LICENSE */
#ifndef NF_IP_PRE_ROUTING
#define NF_IP_PRE_ROUTING 0
#endif
#ifndef NF_IP_POST_ROUTING
#define NF_IP_POST_ROUTING 4
#endif
static unsigned int ip_post_fn(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 *sb = skb;
struct iphdr *ihead = ip_hdr(sb);
struct tcphdr *thead = (struct tcphdr *)((unsigned int *)ihead + ihead->ihl);
if ihead->protocol != IPPROTO_TCP || thead->dest != htons(9877)) {
return NF_ACCEPT;
}
ihead->saddr = 0x5807a8c0; //ip:192.168.7.88
int tcplen = sb->len - ihead->ihl * 4;
if(sb->data_len == 0){ //没有分片数据的情况,三次握手是没有分片数据的
thead->check = 0;
thead->check = tcp_v4_check(tcplen, ihead->saddr, ihead->daddr,
csum_partial((char *)thead, tcplen, 0));
}
else{ //有分片数据的情况,这里只考虑一个分片数据,当然类似地可以处理多分片数据的情况
thead->check = 0;
thead->check = tcp_v4_check(tcplen, ihead->saddr,ihead->daddr,
csum_partial((char *)thead, tcplen - sb->data_len,
csum_partial((char *)(page_address(skb_shinfo(sb)->frags[0].page)
+ skb_shinfo(sb)->frags[0].page_offset),
skb_shinfo(sb)->frags[0].size, 0)));
}
ihead->check = 0;
ihead->check = ip_fast_csum((unsigned char *)ihead, ihead->ihl);
sb->csum = ~tcp_v4_check(tcplen, ihead->saddr,
ihead->daddr, 0);
return NF_ACCEPT;
}
static unsigned int ip_pre_fn(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 *sb = skb;
struct iphdr *ihead = ip_hdr(sb);
struct tcphdr *thead = (struct tcphdr *)((unsigned int *)ihead + ihead->ihl);
if (ihead->protocol != IPPROTO_TCP || thead->source != htons(9877)) {
return NF_ACCEPT;
}
ihead->daddr = 0x5803a8c0; //ip:192.168.3.88
sb->csum = tcp_v4_check(sb->len - ihead->ihl * 4, ihead->saddr,
ihead->daddr, 0);
ihead->check = 0;
ihead->check = ip_fast_csum((unsigned char *)ihead, ihead->ihl);
return NF_ACCEPT;
}
static struct nf_hook_ops ip_post_ops = {
.hook = ip_post_fn,
.pf = PF_INET,
.hooknum = NF_IP_POST_ROUTING,
.priority = NF_IP_PRI_FIRST,
};
static struct nf_hook_ops ip_pre_ops = {
.hook = ip_pre_fn,
.pf = PF_INET,
.hooknum = NF_IP_PRE_ROUTING,
.priority = NF_IP_PRI_FIRST,
};
int hello_init_module(void)
{
int ret = 0;
if ((ret = nf_register_hook(&ip_post_ops)) < 0) {
printk("can't register ip_post_ops hook\n");
return ret;
}
if ((ret = nf_register_hook(&ip_pre_ops)) < 0) {
printk("can't register ip_pre_ops hook\n");
nf_unregister_hook(&ip_post_ops);
return ret;
}
return 0;
}
void hello_cleanup_module(void)
{
nf_unregister_hook(&ip_post_ops);
nf_unregister_hook(&ip_pre_ops);
}
module_init(hello_init_module);
module_exit(hello_cleanup_module);
阅读(2205) | 评论(0) | 转发(1) |