子网(C)中的所有IP [英] All IP's in a subnet (C)
问题描述
有人能很好地说明我如何使用带有CIDR的IP地址(例如 192.168.1.1/24
)并返回其中的所有IP地址范围例如 192.168.1.1、192.168.1.2、192.168.1.3 ...
Does someone have a good example of a way I could take a IP address with a CIDR such as 192.168.1.1/24
and return all the ip addresses inside of that range such as 192.168.1.1, 192.168.1.2, 192.168.1.3 ...
我很好它以 unsigned long
, char
或类似
/* Pseudocode */
while(currnetip <= finalip) {
print(currnetip);
currnetip++;
}
只要我能理解就可以了。
As long as I can understand it its fine.
如果您认为它可以帮助我,请随意评论帖子的链接。
Feel free to comment a link to a post if you think it could help me.
编辑:可能值得一提,我已经找到了我只是不确定如何将所有这些功能链接在一起。
Probably worth mentioning I've found lots of stuff that calculated the broadcast address ect I'm just not sure how to link all those functions together.
推荐答案
首先,将您的IPv4地址打包到 uint32_t
(在< stdint.h>
中定义)中,将最左边的八位字节加点-将十进制表示法转换为最高有效位。例如,
First, pack your IPv4 address into an uint32_t
(defined in <stdint.h>
), putting the leftmost octet in dotted-decimal notation into the most significat bits. For example,
uint32_t ipv4_pack(const uint8_t octet1,
const uint8_t octet2,
const uint8_t octet3,
const uint8_t octet4)
{
return (((uint32_t)octet1) << 24)
| (((uint32_t)octet2) << 16)
| (((uint32_t)octet3) << 8)
| ((uint32_t)octet4);
}
及其反函数,
unsigned char *ipv4_unpack(unsigned char *addr, const uint32_t packed)
{
addr[3] = (uint8_t)(packed);
addr[2] = (uint8_t)(packed >> 8);
addr[1] = (uint8_t)(packed >> 16);
addr[0] = (uint8_t)(packed >> 24);
return addr;
}
128.64.32.16 $ c之类的地址$ c>包装为
0x80402010
(128 == 80 16 ,64 == 40 16 ,32 == 20 16 ,和16 == 10 16 )。
An address like 128.64.32.16
is packed into 0x80402010
(128 == 8016, 64 == 4016, 32 == 2016, and 16 == 1016).
您还需要将 CIDR 前缀大小(1到32)转换为二进制设置的那个最高位的掩码:
You need to also convert the CIDR prefix size (1 to 32) into a binary mask of that many highest bits set:
uint32_t ipv4_mask(const int prefix_size)
{
if (prefix_size > 31)
return (uint32_t)0xFFFFFFFFU;
else
if (prefix_size > 0)
return ((uint32_t)0xFFFFFFFFU) << (32 - prefix_size);
else
return (uint32_t)0U;
}
前缀24对应于二进制掩码11111111111111111111111100000000,十六进制为0xFFFFFF00。
Prefix 24 corresponds to a mask of 11111111111111111111111100000000 in binary, and 0xFFFFFF00 in hexadecimal.
前缀28对应掩码为11111111111111111111111111111110000的掩码,十六进制为0xFFFFFFF0。
Prefix 28 corresponds to a mask of 11111111111111111111111111110000 in binary, and 0xFFFFFFF0 in hexadecimal.
对于地址 addr1.addr2.addr3.addr4 / prefix
,范围中的第一个地址(通常是该范围的网关地址)是
For address addr1.addr2.addr3.addr4/prefix
, the first address in a range (typically the gateway address for said range) is
uint32_t first = ipv4_pack(addr1, addr2, addr3, addr4) & ipv4_mask(prefix);
最后一个地址(通常是该范围的广播地址)是
and the last address (typically the broadcast address for said range) is
uint32_t last = ipv4_pack(addr1, addr2, addr3, addr4) | (~ipv4_mask(prefix));
在所有情况下, first< = last
,然后从 first
迭代到 last
(包括两端),并调用 ipv4_unpack()
将该值解压缩为点分十进制格式),将产生该范围内的所有IPv4地址。
In all cases, first <= last
, and iterating from first
to last
, inclusive, and calling ipv4_unpack()
to unpack the value into dotted-decimal notation), yields all IPv4 addresses within the range.
相同的方法适用于IPv6,但需要类似 uint128_t
类型的内容。 (当然,可以使用更小的无符号整数类型来模拟它,当然,它需要更多的指令,但是逻辑保持不变。)
The same would work for IPv6, but requires something like an uint128_t
type. (It can be emulated with smaller unsigned integer types, of course, taking a few more instructions, but the logic stays the same.)
这篇关于子网(C)中的所有IP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!