比较两个IPv6地址及其掩码(窗口)

时间:2012-07-31 00:13:08

标签: c++ ip-address equals ipv6 mask

我必须比较两个IPv6地址及其掩码,看它们是否相同。它们都是字符串,例如“xxxx:xxxx:xxxx:xxxx / xx”。我会使用memcmp逐位比较它们,但是当真实时,这可能会返回false,因为xxxx:xxxx:0000:xxxx / xx和xxxx:xxxxx :: xxxxx / xx在技术上是相同的地址。 / p>

我不想创建地址和掩码的子串,但是如果有一个比较两个IPv6地址的函数,我会这样做。有什么建议? :)

4 个答案:

答案 0 :(得分:5)

您应该使用inet_pton转换为二进制格式,然后比较二进制格式(您只能将16个字节的数据与memcmp进行比较)。

如果您需要比较屏蔽地址,那么您将需要做更多的工作。 inet_pton不会为您解析前缀长度(“/ something”),因此您必须:

  1. 找到斜杠
  2. 将斜线前的部分传递给inet_pton
  3. 使用普通的“atoi
  4. 解析斜杠后的整数
  5. 手动将128减去地址二进制形式末尾的位数
  6. 在比较之前,

    ...在每个地址上。

答案 1 :(得分:1)

像往常一样,不要重新发明轮子。优秀的libcidr库可以满足您的需求。 http://www.over-yonder.net/~fullermd/projects/libcidr

答案 2 :(得分:0)

我仍然建议使用子字符串,因为它们很容易提取。然后,你可以重载string的equals()函数,在比较“0000”和“”以及你可能遇到的任何其他角落情况时返回true。

答案 3 :(得分:0)

您还可以通过一个函数传递这两个地址,该函数会将它们转换为相同的格式。之后,您可以将它们作为字符串进行比较。

功能示例:

string Ip6(const string& data) {
    struct in6_addr ip6;
    if (inet_pton(AF_INET6, data.c_str(), &ip6) != 1)
        throw str::runtime_error("bad ivp6 address");

    char buf[INET6_ADDRSTRLEN];
    return inet_ntop(AF_INET6, &ip6, buf, sizeof(buf));
}