子网(C)中的所有IP [英] All IP's in a subnet (C)

查看:148
本文介绍了子网(C)中的所有IP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人能很好地说明我如何使用带有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 包装为 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆