在 C 中查找主机地址范围
Finding host address range in C
我编写了一个简单的 C 程序,用于打印网络中所有可用的主机地址。
输入
我们提供我们网络的IP address
和subnet mask
。
输出
我们打印所有对应网络的可用ip地址。
例子
如果我们给出 Ip 192.168.3.0
和子网 255.255.255.0
(/24
在 CIDR),我们得到以下输出:
192.168.3.1
192.168.3.2
192.168.3.3
192.168.3.4
...etc until 254
问题
我没有得到正确的结果。
假设我们提供 192.168.3.0
和 255.255.255.0
。我目前使用 pcap
库中的 bpf_u_int32
类型来保存 ip
和 subnet mask
变量。
如果我运行下面的代码,这就是我得到的输出:
0.3.168.193
0.3.168.194
0.3.168.195
0.3.168.196
0.3.168.197
0.3.168.198
0.3.168.199
0.3.168.200
0.3.168.201
0.3.168.202
0.3.168.203
0.3.168.204
0.3.168.205
0.3.168.206
0.3.168.207
0.3.168.208
0.3.168.209
0.3.168.210
0.3.168.211
0.3.168.212
0.3.168.213
0.3.168.214
0.3.168.215
0.3.168.216
0.3.168.217
0.3.168.218
0.3.168.219
0.3.168.220
0.3.168.221
0.3.168.222
0.3.168.223
0.3.168.224
0.3.168.225
0.3.168.226
0.3.168.227
0.3.168.228
0.3.168.229
0.3.168.230
...etc
实际代码
// suppose we have declare ip and subnet mask variables and passed values to it.
// bpf_u_int32 subnet_mask;
// bpf_u_int32 ip_address;
bpf_u_int32 x = subnet_mask;
int numbits; // get the CIDR Prefix
for (numbits = 0; x != 0; x >>= 1) {
if (x & 0x01) {
numbits++;
}
}
// determine maximum and minimum host values.
// we exclude the host and the broadcast (should we?)
unsigned long hoststart;
unsigned long hostend;
hoststart = 1;
hostend = (1 << (32 - numbits)) - 1;
// mask off the network
uint32_t network = ip_address & subnet_mask;
// Calculate all host addresses in the range
for (unsigned i = hoststart; i <= hostend; i++) {
uint32_t hostip;
int b1, b2, b3, b4;
char ipstr[16];
hostip = network + i;
b1 = (hostip & 0xff000000) >> 24;
b2 = (hostip & 0x00ff0000) >> 16;
b3 = (hostip & 0x0000ff00) >> 8;
b4 = (hostip & 0x000000ff);
snprintf(ipstr, sizeof(ipstr), "%d.%d.%d.%d", b1, b2, b3, b4);
printf("%s\n", ipstr);
}
看起来像是字节顺序问题。
IP 地址和子网掩码以小端格式存储,这意味着最低有效字节在前。您需要使用 htonl
.
交换字节
uint32_t network = htonl(ip_address & subnet_mask);
那么字节的顺序就会正确。
我编写了一个简单的 C 程序,用于打印网络中所有可用的主机地址。
输入
我们提供我们网络的IP address
和subnet mask
。
输出
我们打印所有对应网络的可用ip地址。
例子
如果我们给出 Ip 192.168.3.0
和子网 255.255.255.0
(/24
在 CIDR),我们得到以下输出:
192.168.3.1
192.168.3.2
192.168.3.3
192.168.3.4
...etc until 254
问题
我没有得到正确的结果。
假设我们提供 192.168.3.0
和 255.255.255.0
。我目前使用 pcap
库中的 bpf_u_int32
类型来保存 ip
和 subnet mask
变量。
如果我运行下面的代码,这就是我得到的输出:
0.3.168.193
0.3.168.194
0.3.168.195
0.3.168.196
0.3.168.197
0.3.168.198
0.3.168.199
0.3.168.200
0.3.168.201
0.3.168.202
0.3.168.203
0.3.168.204
0.3.168.205
0.3.168.206
0.3.168.207
0.3.168.208
0.3.168.209
0.3.168.210
0.3.168.211
0.3.168.212
0.3.168.213
0.3.168.214
0.3.168.215
0.3.168.216
0.3.168.217
0.3.168.218
0.3.168.219
0.3.168.220
0.3.168.221
0.3.168.222
0.3.168.223
0.3.168.224
0.3.168.225
0.3.168.226
0.3.168.227
0.3.168.228
0.3.168.229
0.3.168.230
...etc
实际代码
// suppose we have declare ip and subnet mask variables and passed values to it.
// bpf_u_int32 subnet_mask;
// bpf_u_int32 ip_address;
bpf_u_int32 x = subnet_mask;
int numbits; // get the CIDR Prefix
for (numbits = 0; x != 0; x >>= 1) {
if (x & 0x01) {
numbits++;
}
}
// determine maximum and minimum host values.
// we exclude the host and the broadcast (should we?)
unsigned long hoststart;
unsigned long hostend;
hoststart = 1;
hostend = (1 << (32 - numbits)) - 1;
// mask off the network
uint32_t network = ip_address & subnet_mask;
// Calculate all host addresses in the range
for (unsigned i = hoststart; i <= hostend; i++) {
uint32_t hostip;
int b1, b2, b3, b4;
char ipstr[16];
hostip = network + i;
b1 = (hostip & 0xff000000) >> 24;
b2 = (hostip & 0x00ff0000) >> 16;
b3 = (hostip & 0x0000ff00) >> 8;
b4 = (hostip & 0x000000ff);
snprintf(ipstr, sizeof(ipstr), "%d.%d.%d.%d", b1, b2, b3, b4);
printf("%s\n", ipstr);
}
看起来像是字节顺序问题。
IP 地址和子网掩码以小端格式存储,这意味着最低有效字节在前。您需要使用 htonl
.
uint32_t network = htonl(ip_address & subnet_mask);
那么字节的顺序就会正确。