用于数据包注入的 Libnet 与原始套接字

Libnet vs Raw Sockets for packet injection

本文关键字:原始 套接字 Libnet 数据包 注入 用于      更新时间:2023-10-16

我需要更有经验的网络程序员的意见/建议,关于GNU/Linux系统上的数据包注入的一些东西。我正在开发一个用于数据包注入和嗅探的开源C++库。图书馆是自由的。在页面上有几个示例来了解库的工作原理。

我有一个两难的境地,希望你能想到。目前,该库"提供"两种在网络上写入数据包的方法。首先,构造数据包:

Packet pck = IP()/UDP()/DNS();

1) 然后与 Send() 函数一起发送:

pck.Send("eth0");

2) 或者使用 RawSocketSend() 函数(这是我用于基准测试的"实验性"函数,但可供用户使用):

pck.RawSocketSend(sd);

其中 sd 是套接字描述符。如果数据包具有链路层协议(如以太网),则 sd 应该是 PACKET 套接字描述符。如果不是,则应为 RAW 套接字描述符。

发送数据包的标准和记录方法是使用 Send() 方法。目前,Send() 方法使用 libnet 将数据包写入线路。

问题是 Send() 函数比 RawSocketSend() 慢得多...我经常不得不做很多棘手和烦人的事情来适应 libcrafter 处理协议字段的方式,以正确使用 libnet_build* 函数(这会导致性能损失)。每次我实现协议时,我都必须查看libnet文档,并使开发过程非常繁琐和缓慢。所以,我想停止使用 libnet 进行数据包注入,而是直接在 Send() 函数中使用 RAW/PACKET 套接字。

Libcrafter 旨在以透明的方式为用户处理数据包制作的所有繁琐工作(校验和计算、字节排序、标头长度等)。在最流行的GNU/Linux系统(Ubuntu,Fedora,Debian)上使用RAW/PACKET套接字(RawSocketSend函数)上一切正常。

我使用 libnet 的唯一原因是可移植性问题。但是我没有知识或意图将libcrafter移植到其他系统而不是GNU/Linux系统。

我的问题是:

  1. 在 GNU/Linux 的数据包注入库上使用 RAW/PACKET 套接字是否谨慎和安全?
  2. 如果我决定停止使用 libnet,您是否知道我应该考虑的一些关于 GNU/Linux 发行版之间 RAW/PACKET 套接字的可移植性的问题?
  3. RAW/PACKET 套接字接口可能会在内核的未来版本中更改?

非常感谢:-)

开源的美妙之处在于你可以实际浏览源代码,所以我检查了:http://code.google.com/p/libcrafter/source/browse/libcrafter/crafter/Packet.cpp

并且看到 Packet::send 效率不高:它执行了太多的系统调用(每次都将设备名称与实际接口匹配)并调用 libnet 函数,我猜每次都会打开一个套接字并发送数据包。无论如何,发送数据包的开销太大了。

原始发送,我没有看到函数代码,但我想它只是使用 send().如果我是你,如果我对 sendRawPacket() 函数不满意,我会简单地使用行套接字发送它,我已经看到数据包提供了getRawBuffer()函数。

有关原始套接字的详细信息:http://www.tenouk.com/Module43a.html 并尝试谷歌。

对于您的问题:

1)我不明白你说的"安全"是什么意思? 一般答案是"是的,仔细"

2)关于可移植性,使用原始套接字是POSIX标准的一部分,因此它可以在任何Linux发行版上运行,也可能在Windows上工作。我不知道libcraft是否可以移植到Windows上,但它应该在任何Linux发行版上运行。如果没有,您可以为库做出贡献并使其可移植。

3)我无法回答有关未来的问题。同样,这是POSIX标准,多年来没有太大变化,将来可能会改变。我不是先知,但我不认为它在不久的将来会改变。

家伙