【问题标题】:Extract IP address from buffer in C++ (Linux sockets)从 C++ 中的缓冲区中提取 IP 地址(Linux 套接字)
【发布时间】:2016-05-02 22:11:52
【问题描述】:

是否可以在以下情况下提取目标和源 IP 地址?我能够从in_buffer 中提取以太网源地址和目标地址。如果可以的话,有什么建议吗?

sockaddr_ll sockaddr = sockaddr_ll();

sockaddr.sll_family = PF_PACKET;
sockaddr.sll_protocol = htons(ETH_P_ALL);
// is the interface index of the interface
sockaddr.sll_ifindex = if_nametoindex(argv[1]);
sockaddr.sll_hatype = 1;

boost::asio::io_service io_service;

raw_protocol_t::socket socket(io_service, raw_protocol_t(PF_PACKET, SOCK_RAW));
socket.bind(raw_endpoint_t(&sockaddr, sizeof(sockaddr)));

boost::asio::generic::raw_protocol::socket::receive_buffer_size option;
socket.get_option(option);

std::string in_buffer(option.value(), '\0');

raw_endpoint_t rep = raw_endpoint_t();

while (true)
{
   size_t len = socket.receive_from(boost::asio::buffer(&in_buffer[0], in_buffer.size()), rep);
}

【问题讨论】:

  • 抱歉,如果从您的代码中可以看出这一点,但 IP 地址是二进制还是可读形式?
  • 好吧,我不知道。我正在尝试提取它们
  • 如果您不知道,那么提取它们是不可能的。您至少必须知道地址的格式。您可以在不进行任何进一步转换的情况下将它们打印出来吗?如果是,它们是字符串,即可读。
  • 我应该使用 asio 来提取它们还是一些解决方法?

标签: c++ sockets ip


【解决方案1】:

是的,您可以从原始数据包缓冲区中读取 IP 地址。当然,前提是数据包中有 IP 地址。如果协议为IP,则in_buffer中存储的数据包含完整的数据包,包括IP头。

注意接收到的数据可能包含任何协议。它可以是 IPv4,然后您可以在那里找到 IP 地址,但它可以是 IPv6,甚至是没有 IP 地址的更晦涩的协议。

假设接收到的数据包是一个包含IPv4 数据的Ethernet-II 数据包。然后就可以轻松获取IP地址了:

  // Source addr
  printf("%d.%d.%d.%d", (unsigned char)(in_buffer[26]),
                        (unsigned char)(in_buffer[27]),
                        (unsigned char)(in_buffer[28]),
                        (unsigned char)(in_buffer[29]));
  // Destination addr
  printf("%d.%d.%d.%d", (unsigned char)(in_buffer[30]),
                        (unsigned char)(in_buffer[31]),
                        (unsigned char)(in_buffer[32]),
                        (unsigned char)(in_buffer[33]));

当然不好,你需要检查缓冲区是否包含预期的内容,但这取决于你。

26 - 32 这个幻数是什么意思?

以太网 II 标头的大小为 14 字节。前 6 个字节是目标 MAC,接下来的 6 个字节是源 MAC,最后 2 个字节是以太网类型。 Ethertype 0x0800 表示数据包含 IPv4。源 IPv4 地址位于 IP 标头中的偏移量 12 处,目标 IP 位于偏移量 16 处。所以幻数 26 表示从数据包开始的偏移量及其 14(ethernetHeaderSize) + 12(offsetInIPHeader)。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2016-04-22
  • 1970-01-01
  • 2018-10-20
  • 1970-01-01
  • 2013-06-09
  • 2012-10-07
  • 1970-01-01
  • 2010-10-03
相关资源
最近更新 更多