c++ - 从 C++ 缓冲区中提取 IP 地址(Linux 套接字)

标签 c++ sockets ip

在下面的情况下是否可以提取目标和源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 地址。当然前提是数据包中有IP地址。如果协议(protocol)是IP,则in_buffer 中存储的数据包含完整的数据包,包括IP header 。

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

假设接收到的数据包是一个包含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 这个魔数(Magic Number)是什么意思?

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

关于c++ - 从 C++ 缓冲区中提取 IP 地址(Linux 套接字),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35012295/

相关文章:

ip - 如何通过控制端口获取 Tor 导出节点 IP 地址?

c# - 如何在 Windows 应用商店应用程序中获取本地主机 IP 地址?

c++ - 如何将 sort() 的比较参数与模板和自定义数据结构一起使用

c++ - IMMDevice::Activate 缺少接口(interface)的返回代码

c++ - 从 YUY2 到 RGB24 的快速转换

java - 关闭ServerSocket的正确方法

sql - 有效地查找子网内可用 IP 地址的列表/范围

c++ - 从基类成员函数返回派生类的实例

Java 小程序 java.security.AccessControlException

java - 使用java发送电子邮件而不使用JavaMail