首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >IP cidr匹配功能

IP cidr匹配功能
EN

Stack Overflow用户
提问于 2011-08-27 18:37:03
回答 4查看 6.5K关注 0票数 3

我要找出来,ip是不是属于ip掩码。例如:

ip = 192.168.0.1掩码= 192.168.0.1/24。

我找到了将ip转换为掩码的函数:

代码语言:javascript
运行
复制
inet_cidrtoaddr(int cidr, struct in_addr *addr)
{
        int ocets;

        if (cidr < 0 || cidr > 32) {
                errno = EINVAL;
                return -1;
        }
        ocets = (cidr + 7) / 8;

        addr->s_addr = 0;
        if (ocets > 0) {
                memset(&addr->s_addr, 255, (size_t)ocets - 1);
                memset((unsigned char *)&addr->s_addr + (ocets - 1),
                       (256 - (1 << (32 - cidr) % 8)), 1);
        }

        return 0;
}

如何比较ip和cidr范围?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-08-27 19:20:12

如果您有IP地址、网络地址和网络掩码,则可以使用如下函数:

代码语言:javascript
运行
复制
bool
is_in_net (
        const struct in_addr*   addr,     /* host byte order */
        const struct in_addr*   netaddr,
        const struct in_addr*   netmask
        )
{
   if ((addr->s_addr & netmask->s_addr) == (netaddr->s_addr & netmask->s_addr))
      return true;
   return false;
}
票数 2
EN

Stack Overflow用户

发布于 2014-08-13 23:58:19

因此,将Olis的答案放在代码中:

代码语言:javascript
运行
复制
// Check if 192.168.0.1 is inside 192.168.0.0/24
in_addr ip, net, netmask;
inet_aton("192.168.0.1", &ip);
inet_aton("192.168.0.0", &net);

他说:

代码语言:javascript
运行
复制
inet_cidrtoaddr(24, &netmask);
bool is_inside = ((ip.s_addr & netmask.s_addr) == (net.s_addr & netmask.s_addr));

不过,我更喜欢addr4_match方法:

代码语言:javascript
运行
复制
bool cidr_match(const in_addr &addr, const in_addr &net, uint8_t bits) {
  if (bits == 0) {
    // C99 6.5.7 (3): u32 << 32 is undefined behaviour
    return true;
  }
  return !((addr.s_addr ^ net.s_addr) & htonl(0xFFFFFFFFu << (32 - bits)));
}
bool is_inside = cidr_match(ip, net, 24);

我尝试了一堆不同的输入:https://gist.github.com/duedal/b83303b4988a4afb2a75

如果有人发现它也想要一个IPv6解决方案:

代码语言:javascript
运行
复制
bool cidr6_match(const in6_addr &address, const in6_addr &network, uint8_t bits) {
#ifdef LINUX
  const uint32_t *a = address.s6_addr32;
  const uint32_t *n = network.s6_addr32;
#else
  const uint32_t *a = address.__u6_addr.__u6_addr32;
  const uint32_t *n = network.__u6_addr.__u6_addr32;
#endif
  int bits_whole, bits_incomplete;
  bits_whole = bits >> 5;         // number of whole u32
  bits_incomplete = bits & 0x1F;  // number of bits in incomplete u32
  if (bits_whole) {
    if (memcmp(a, n, bits_whole << 2)) {
      return false;
    }
  }
  if (bits_incomplete) {
    uint32_t mask = htonl((0xFFFFFFFFu) << (32 - bits_incomplete));
    if ((a[bits_whole] ^ n[bits_whole]) & mask) {
      return false;
    }
  }
  return true;
}

检查2001:db8::ff00:42:8329是否存在于2001:db8/32中。注意inet_net_pton非常挑剔,它是2001:db8/32而不是2001:db8::/32。但是2001:db8::/48是完全有效的(也称为2001:db8:0/48)。

代码语言:javascript
运行
复制
in6_addr ip6, net6, net6_48;
memset(&net6, 0, sizeof(net6));
memset(&net6_48, 0, sizeof(net6_48)); 
assert(inet_pton(AF_INET6, "2001:db8::ff00:42:8329", &ip6));

int bits = inet_net_pton(AF_INET6, "2001:db8/32", &net6, sizeof(net6));
assert((bits != -1));  // assert that inet_net_pton understood us
bool is_inside6 = cidr6_match(ip6, net6, bits);

int bits_48 = inet_net_pton(AF_INET6, "2001:db8::/48", &net6_48, sizeof(net6_48));
assert((bits_48 == 48));
bool is_inside6_48 = cidr6_match(ip6, net6_48, bits_48);
票数 9
EN

Stack Overflow用户

发布于 2011-08-27 19:06:00

此函数计算网络掩码(例如,形式为255.255.255.128的内容)。因此,要检查指定的IP地址是否属于指定的子网,只需将掩码应用于CIDR地址和IP地址(使用bitwise AND即可完成此操作)。如果结果相同,则IP地址有效。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7213995

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档