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



在以下代码中,addr_minaddr_max是表示IPv4地址的32位无符号值,它们按网络字节顺序排列,即big-endian格式:

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

因此,假设我想迭代地址1.2.0.0,并逐渐增加第三个和第四个八位字节,从而总共产生65534个地址(打印时的addr_max显示feff0201(。我原以为上面的代码会起作用,但它只将第四个八位字节更改为值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.0addr_min = 0x01020000

最新更新