【问题标题】:How to compare an IPv6 is greater/less than in C如何比较 IPv6 大于/小于 C
【发布时间】:2014-07-13 14:00:40
【问题描述】:

inet_pton 转换一个IPv4 来比较它是否在IPv4 的范围内是相当简单的。但是,我不确定如何使用 inet_ptonin6_addr 并查看它是否小于/大于另一个 IP。这就是我的想法:

#include <arpa/inet.h>

  ...

const char *ip6str = "0:0:0:0:0:ffff:c0a8:3";
const char *first = "0:0:0:0:0:ffff:c0a8:1";
const char *last = "0:0:0:0:0:ffff:c0a8:5";

struct in6_addr result, resfirst, restlast;
uint8_t ipv6[16]; // perhaps to hold the result?

inet_pton(AF_INET6, first, &resfirst);
inet_pton(AF_INET6, last, &reslast);
inet_pton(AF_INET6, ip6str, &result);

//assuming inet_pton succeed
if(result.s6_addr >= resfirst.s6_addr && result.s6_addr <= reslast.s6_addr)
    //within range

【问题讨论】:

  • 大概你的意思是前两个inet_pton分别使用firstlast,而不是ip6str
  • @JoachimPileborg,测试地址是否在 OP 中的代码所做的预定义范围内是一种情况。另一个可能是在地图中存储 IP 地址。
  • @ooga 已更新。谢谢

标签: c comparison ipv6


【解决方案1】:

您可以为此使用memcmp,因为它们以网络字节顺序(又名大端序)存储。

if (memcmp(&result, &resfirst, sizeof(result)) > 0 && memcmp(&result, &reslast, sizeof(result)) < 0)

我想你可能指的是&gt;=,也可能是&lt;=

事实上,对于 IPv4,您也必须这样做,至少在小端机器上是这样。

【讨论】:

  • 正是我需要的。谢谢!
【解决方案2】:

is_in_network_v6() 基于伟大的文档http://grothoff.org/christian/rmv608.pdf

#include <arpa/inet.h>
#include <stdio.h>

int is_in_network_v6(const struct in6_addr *network,
                       const struct in6_addr *mask,
                       const struct in6_addr *ip)
{
    unsigned int i;
    for (i = 0; i < sizeof(struct in6_addr) / sizeof(int); i++) {
        if ( ((((int *) ip )[i] & ((int *) mask)[i])) != (((int *) network)[i]
            & ((int *) mask)[i]))
            return 0;
    }
    return 1;
}

int main(int argc, char *argv[]) 
{
    char *ipStr = "2001:db8:8714:3a90::12";
    char *netmaskStr = "ffff:ffff:ffff:ffff::";
    char *networkStr = "2001:db8:8714:3a90::";

    struct sockaddr_in6 ip, netmask, network;
    inet_pton(AF_INET6, ipStr, &(ip.sin6_addr));
    inet_pton(AF_INET6, netmaskStr, &(netmask.sin6_addr));
    inet_pton(AF_INET6, networkStr, &(network.sin6_addr));

    printf("ip: '%s', netmask: '%s', network: '%s': %d\n",
           ipStr, netmaskStr, networkStr,
           is_in_network_v6(&(network.sin6_addr), &(netmask.sin6_addr),
                            &(ip.sin6_addr)));

    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-06
    • 1970-01-01
    • 2020-04-22
    • 2016-06-21
    • 2013-05-16
    • 2021-02-11
    • 1970-01-01
    相关资源
    最近更新 更多