In the following code addr_min
and addr_max
are 32-bit unsigned values representing IPv4 address, and they're in network-byte order, i.e. big-endian format:
uint32_t addr;
for (addr = addr_min; addr <= addr_max; addr = addr + htonl(1)) {
...
}
So assuming I want to iterate over address 1.2.0.0
and gradually increment the third and fourth octets, thus yielding 65534 addresses in total (addr_max
when printed shows feff0201). I expected the above code would work, instead it only changes the 4th octet to value 0xfe and never touches the third one.
What am I possibly doing wrong?
You aren't intended to do any arithmetic with values already encoded in network byte order. In this case, you're likely only adding to the highest-order byte.
The quick answer is that:
uint32_t val_n = htonl(init_val);
val_n += htonl(1);
is not equivalent to
uint32_t val = init_val;
val += 1;
uint32_t val_n = htonl(val);
Where val
and init_val
are regular host-order values, and val_n
is network-order encoded.
The network-order values are not useful for arithmetic directly. You don't know what value htonl(1)
will add to your value, and you don't know that adding it will cause the next byte to roll over after you've gotten to 255 on the lowest byte. Don't consider network-order values to be numbers, think of them as opaque values with meaning.
Keep everything that you work with in host order, as actual numbers:
uint32_t addr;
for (addr = addr_min; addr <= addr_max; addr += 1) {
uint32_t addr_net_order = htonl(addr);
...
}
where addr
, addr_min
, and addr_max
are all host order i.e. if addr_min
should be 1.2.0.0
, addr_min = 0x01020000
.