提升 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 原始套接字的主要内容,如果未能解决你的问题,请参考以下文章
如何接受boost :: asio :: ssl :: stream 作为boost :: asio :: ip :: tcp :: socket类型的参数