linux内核中ip头结构体,内核模块通过修改sk_buff结构体来修改ip头的源IP

#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);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值