linux内核态发送tcp包,Linux内核发送构造数据包的方式

本文介绍了在Linux内核态下如何构造TCP数据包,包括直接用alloc_skb创建新数据包或在原有数据包上修改,以及通过Netfilter框架或dev_queue_xmit函数发送构造好的数据包。详细讲解了send_reset函数的实现过程,讨论了不同发送方法中路由、校验和的处理,以及钩子函数的返回值问题。
摘要由CSDN通过智能技术生成

本文欢迎自由转载,但请标明出处,并保证本文的完整性。

作者:Godbach

日期:2009/09/01

一、构造数据包简析

这里并不详细介绍如何在内核中构造数据包,下文如有需要会在适当的位置进行分析。这里简单的分析讲一下内核态基于Netfilter框架构造数据包的方式。

内核中可以用到的构造数据包的方式,个人认为可以分为两种。

其一,我们直接用alloc_skb申请一个skb结构体,然后根据实际的应用填充不同的成员,或者基于当前数据包的skb,调用skb_copy_expand()函数等新申请一个nskb,并且拷贝skb的内容。

其二,也是个人比较常用的,就是直接在先前接收到的数据包skb上作修改,主要有源IP、目IP,如果是TCP/UDP协议的话,还有源端口目的端口号。总之,就是根据自己的需求去调整数据包的相关成员即可。

通常,这两种方式最终可能都要涉及到重新计算各个部分的校验和,这也是必须的。

二、如何发送构造的数据包

承接上文,数据包已经构造完毕,下一步关键就是如何发送数据包了。个人这里总结的有两种方法。

方法一,就是让数据包接着按照Netfilter的流程进行传输。因为数据包的一些内容已经被更改,尤其是当源IP和目的IP被更改,主要是交换的情况下,是需要确保有路由可查的。

NF框架中查路由的位置一是在PREROUTING之后,而是在LOCALOUT之后。又由于这里是需要将数据包从本地发送出去。因此,可以考虑让修改后的数据包从LOCALOUT点发出。

内核代码中有这种方式的典型体现。本文涉及的相关内核代码的版本都是2.6.18.3。源文件为ipt_REJECT.c,函数send_reset用于往当前接收到数据包的源IP上发送RST包,整个函数涉及了数据包的构造和发送,这里一起做个简单分析。

/* Send RST reply */

static void send_reset(struct sk_buff *oldskb, int hook)

{

struct sk_buff *nskb;

struct iphdr *iph = oldskb->nh.iph;

struct tcphdr _otcph, *oth, *tcph;

struct rtable *rt;

u_int16_t tmp_port;

u_int32_t tmp_addr;

int needs_ack;

int hh_len;

/* 判断是否是分片包*/

if (oldskb->nh.iph->frag_off & htons(IP_OFFSET))

return;

/*得到TCP头部指针*/

oth = skb_header_pointer(oldskb, oldskb->nh.iph->ihl * 4,

sizeof(_otcph), &

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值