gpt4 book ai didi

C CIDR 到地址列表

转载 作者:行者123 更新时间:2023-12-04 10:32:26 25 4
gpt4 key购买 nike

我正在编写一个程序,我需要遍历从给定 cidr 的用户派生的地址列表(例如 75.24.64.0/24 )。

我看了一些code ,但这似乎过于复杂。

最后我决定使用一个看起来像这样的结构:

struct ip_iterator {
unsigned int netmask;
int bitcount;
long long num_total;
long long num_left;
int current_ip[4];
};

然后我可以定义 ip_iterator_init ip_iterator_next , 和 ip_iterator_is_finished职能。但是,我被困在如何从 cidr 获得第一个 IP 的问题上。不久前我学习了网络数学,但自从我获得认证以来,我一直在使用在线计算器。

最佳答案

假设你有一个字符串中的 CIDR,这样的事情可能会为你做。

首先,一个将 CIDR 转换为 IP 和掩码的函数:

int cidr_to_ip_and_mask(const char *cidr, uint32_t *ip, uint32_t *mask)
{
uint8_t a, b, c, d, bits;
if (sscanf(cidr, "%hhu.%hhu.%hhu.%hhu/%hhu", a, b, c, d, bits) < 5) {
return -1; /* didn't convert enough of CIDR */
}
if (bits > 32) {
return -1; /* Invalid bit count */
}
*ip =
(a << 24UL) |
(b << 16UL) |
(c << 8UL) |
(d);
*mask = (0xFFFFFFFFUL << (32 - bits)) & 0xFFFFFFFFUL;
}

接下来,获取第一个 IP 的片段:
uint32_t ip;
uint32_t mask;
uint32_t first_ip;
if (cidr_to_ip_and_mask(cidr, &ip, &mask) < 0) {
/* return some failure */
}
first_ip = ip & mask;

首先,我假设 C99 或 stdint.h 可用的环境,这样我就可以使用显式位宽数据类型(最大可移植性,因为您没有指定架构)。我还假设 IPv4,因为那是您的示例字符串。

接下来我使用 sscanf 将字符串转换为地址的组成部分。将字节组合成完整的 32 位值应该很简单。我将我的文字标记为 unsigned long 以确保结果在分配之前不会被截断,如果我们在一个小位宽机器上。

设置表达式背后的想法 mask是因为 CIDR 中的位数指定了表示网络的最高有效位的数量,所以如果我们从 32 中减去它,那就是我们需要上移一整套位以获得该掩码(截断后)的数量。例如,掩码 32 将是所有位,而 32-32 = 0 所以我们根本不会移位,给出所有 32 位。比特数为 24(如您的示例)将给出 32-24=8,并且 0xFFFFFFFF << 8 是截断后的 0xFFFFFF00(或十进制表示法中的 255.255.255.0)

最后,为了获得初始 IP,我只需使用按位 AND 将掩码应用于 IP 地址。简单的!

由于您的标题问题讨论了整个列表,您可以通过将掩码的补码与基数进行 ORing 来获得最终地址:
uint32_t finalIP = first_ip | ~mask;

这也应该等于广播地址。然后,您可以按顺序从 firstIP 迭代到 finalIP,包括或排除 finalIP 取决于您是否需要广播地址(如果您需要网络地址,则包括或排除 firstIP)。

关于C CIDR 到地址列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28532688/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com