【发布时间】:2021-02-22 23:12:47
【问题描述】:
我通过以下代码获取地址:
pcap_addr_t* addrs_ptr = device->addresses;
std::vector<std::string> deviceAddresses;
// Collect the device addresses into a string vector
while(addrs_ptr != nullptr)
{
if(addrs_ptr->addr->sa_family == AF_INET) // IPv4
{
char address_string4[INET_ADDRSTRLEN];
struct sockaddr_in *sa_in = (struct sockaddr_in*)addrs_ptr->addr;
struct in_addr i_a = sa_in->sin_addr;
inet_ntop(AF_INET, &(i_a), address_string4, INET_ADDRSTRLEN);
deviceAddresses.push_back(address_string4);
}
else if(addrs_ptr->addr->sa_family == AF_INET6) // IPv6
{
char address_string6[INET6_ADDRSTRLEN];
struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6*)addrs_ptr->addr;
struct in6_addr i_a = sa_in6->sin6_addr;
sa_in6->sin6_flowinfo
inet_ntop(AF_INET6, &(i_a), address_string6, INET6_ADDRSTRLEN);
deviceAddresses.push_back(address_string6);
}
addrs_ptr = addrs_ptr->next;
}
对于 IPv6,我获得了两个地址,一个是全局地址,一个是本地链接地址。如何在代码中区分两者?
【问题讨论】:
-
全局寻址都在
2000::/3范围内,而链接本地寻址都在fe80::/10范围内。此外,ULA 在fc00::/7范围内,多播在ff00::/8范围内。永远不要使用字符串来尝试计算 IP 地址(IPv4 或 IPv6),因为 IP 地址是无符号整数(IPv4 为 32 位,IPv6 为 128 位)不会在文本表示上巧妙地破坏网络。网络可能会在您的文本表示中间中断。 -
@RonMaupin 该字符串用于存储和以后用于创建需要 C 字符串进行编译的 pcap 过滤器。
-
没关系,但不要尝试使用字符串来操作或比较 IP 地址,因为它很容易以非常糟糕的方式失败。
-
@RonMaupin 因此,如果我用字符串比较进行检查,我需要做的就是检查前 4 个字符是否为“fe80”?我需要关心“/10”表示的子网吗?
-
目前还没有,但将来可能。例如,全局地址当前位于
2000::/3范围内。您不能简单地比较第一个单词中的2000来查看它是否是全局地址,因为当前范围是2000::到3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff,并且可以扩展到未来。此外,并非该范围内的所有地址都是全局可转发的。除了全局、ULA、链路本地和多播(您可以将每种类型的多个地址分配给一个接口,但多播除外),其他地址通常无效,但并非全部无效。