我有一个文件可以在一行上存储一些子网信息:
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中这样做。
答案 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范围内的prefix
:0xFFFFFFFFU & -(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))