提升 asio 原始套接字

Posted

技术标签:

【中文标题】提升 asio 原始套接字【英文标题】:Boost asio raw sockets 【发布时间】:2011-11-05 18:53:04 【问题描述】:

我正在尝试用 asio 编写一个简单的数据包制作器。而且我需要通过不同的协议发送原始数据。

我正在尝试更改 asio 文档中的 ping 示例。在这个例子中 icpm-packet 是通过 socket_.send_to 方法发送的。该方法将icmp-packet封装成ip-packet。

但我需要发送 ip 标头,然后是 icmp 标头,然后是数据包主体,无需任何封装!我正在尝试使用 socket.send 方法来做到这一点。但它会引发异常。

这是代码。 在我的课堂上,我有:

boost::asio::basic_raw_socket<raw> socket_;

当 'raw' 是原始数据协议的类时。这个类就像来自 asio 的 'icmp' 类,protocol_ 等于 IPPROTO_RAW。

然后我发送数据:

     IPV4header ip_header;
 //fill ip_header

 ICMPHeader echo_request;
 //fill icmp-header

 std::string body("---");

 // Encode the request packet.
 boost::asio::streambuf request_buffer;
 std::ostream os(&request_buffer);
 os << ip_header << echo_request << body;

 socket_.send(request_buffer.data(), request_buffer.size());

【问题讨论】:

【参考方案1】:

使用 setsockopt 将值 IPPROTO_IP IP_HDRINCL 设置为 0。它应该会有所帮助

【讨论】:

【参考方案2】:

我不相信您可以使用 Asio 原始套接字或一般的 Asio 库发送这样的 IP 标头。您还需要指定目标端点,如果您尝试通过套接字发送而不首先连接,则需要使用 send_to() 方法而不是 send() 方法。

我创建了一个 github 存储库,其中包含如何使用带有自定义传输层标头的 Asio 原始套接字的示例:https://github.com/kevincon/asio-rawsockets-example

如果您希望发送自己的 IP 标头,可以查看 libpnet6 的数据包注入功能:http://pnet6.sourceforge.net/

【讨论】:

【参考方案3】:

“使用 setsockopt 将值 IPPROTO_IP IP_HDRINCL 设置为 0。应该有帮助”,

IPPROTO_IP IP_HDRINCL 如果需要发送不经过任何封装的 ip 头,则应设置为 1

【讨论】:

以上是关于提升 asio 原始套接字的主要内容,如果未能解决你的问题,请参考以下文章

从套接字和 STDIN 提升 Asio 多线程

如何接受boost :: asio :: ssl :: stream 作为boost :: asio :: ip :: tcp :: socket类型的参数

提升asio断网处理

提升 asio 取消读取而不取消写入

提升 Asio 单线程性能

原始套接字的问题