c:以网络字节顺序递增 IPv4 地址的八位字节

c: increment octets of IPv4 address in network byte order

在下面的代码中,addr_minaddr_max是表示IPv4地址的32位无符号值,它们是网络字节顺序,即大端格式:

uint32_t addr;
for (addr = addr_min; addr <= addr_max; addr = addr + htonl(1)) {
   ...
}

所以假设我想遍历地址 1.2.0.0 并逐渐增加第三个和第四个八位字节,从而总共产生 65534 个地址(addr_max 打印时显示 feff0201)。我预计上面的代码会起作用,相反它只将第 4 个八位字节更改为值 0xfe 而从不触及第三个八位字节。

我可能做错了什么?

您不打算对已按网络字节顺序编码的值进行任何算术运算。在这种情况下,您可能只添加到最高位字节。

快速回答是:

uint32_t val_n = htonl(init_val);
val_n += htonl(1);

不等于

uint32_t val = init_val;
val += 1;
uint32_t val_n = htonl(val);

其中 valinit_val 是常规主机顺序值,val_n 是网络顺序编码。

网络顺序值不能直接用于算术。您不知道什么值 htonl(1) 会添加到您的值,并且您不知道添加它会导致下一个字节在最低字节达到 255 后翻转。不要将网络顺序值视为数字,将它们视为具有含义的不透明值。

按照主机顺序保存您使用的所有内容,如实际数字:

uint32_t addr;
for (addr = addr_min; addr <= addr_max; addr += 1) {
    uint32_t addr_net_order = htonl(addr);
    ...
}

其中 addraddr_minaddr_max 都是主机顺序 如果 addr_min 应该是 1.2.0.0, addr_min = 0x01020000.