从子网生成子网掩码和地址前缀长度

时间:2015-12-03 17:20:15

标签: c subnet

我有一个文件可以在一行上存储一些子网信息:

123.123.0.0/16 123.123.123.123 

第一部分是子网和地址前缀长度,后面是数据包的节点的ip地址。

我正在尝试确定给定的IP是否是子网的一部分,我理解这个过程在大多数情况下应该如何工作。但我不知道如何从上面的信息生成子网掩码。

我考虑过的选项:

我已经在网上找到了一些地址前缀长度为1-32的表格,所以我可以将其中一个表格转换成一个switch语句并将其称为一天,但这看起来很糟糕。

地址前缀长度给出了从左边开始的掩码中的'1'。因此,32 - 地址前缀长度给出从右边开始的'0'的数字。我可以将2 ^地址前缀长度的2的幂加到2 ^ 32,并将结果用作子网掩码。我有点担心这个想法,我有一种感觉,如果我试图这样做,常规的int会溢出,所以我应该使用uint32_t吗?我不确定。

选项2会起作用吗?我应该选择1吗?有没有更好的办法?

我在C中这样做。

3 个答案:

答案 0 :(得分:2)

您可以使用~0形成所有视频的掩码。您需要将其向左移32-n位,以使n低位为空:

#include <stdint.h>

uint32_t subnet_mask(int prefix_len)
{
    return prefix_len ? ~0 << (32 - prefix_len) : 0;
}

/* Unit tests */
int main()
{
    return 0xFFFFFF00u != subnet_mask(24)
        +  0x00000000u != subnet_mask(0)
        +  0xFFFFFFFFu != subnet_mask(32);
}

特殊情况(由单元测试找到)很容易被遗漏 - uint32左移32位被视为完全没有移位。注意极端情况!

答案 1 :(得分:0)

这适用于1到32范围内的prefix0xFFFFFFFFU & -(1U << (32 - prefix))

答案 2 :(得分:0)

以下(未经测试的)宏应该适用于值0到31.它会生成一个掩码,该掩码可以与IPv4地址进行AND运算以生成地址的子网部分。 n是IPv4地址的子网部分中的位数。

#define SUBNET_MASK(n) ((1u << (n)) - 1)

以下(也是未经测试的宏)生成子网的网络地址部分。 n是IPv4地址的子网部分中的位数。

#define NETWORK_MASK(n) (~SUBNET_MASK(n))