I am trying to convert dotted IP to integer using htonl(inet_addr(IP_str))
.
The problem is the function returns negative results for IP address of class B and C.
here is some of my code (simplified):
int main() {
const char IP1[] = "10.0.0.0"; //Class A
const char IP2[] = "20.0.0.0"; //Class A
const char IP3[] = "126.0.0.0"; //Class A
const char IP4[] = "128.0.0.0"; //Class B
const char IP5[] = "160.0.0.0"; //Class B
const char IP6[] = "190.0.0.0"; //Class B
const char IP7[] = "193.0.0.0"; //Class C
const char IP8[] = "200.0.0.0"; //Class C
uint32_t integer_ip;
integer_ip = htonl(inet_addr(IP1));
printf("IP1: %s ------> Integer: %d\n",IP1,integer_ip);
integer_ip = htonl(inet_addr(IP2));
printf("IP2: %s ------> Integer: %d\n",IP2,integer_ip);
integer_ip = htonl(inet_addr(IP3));
printf("IP3: %s ------> Integer: %d\n",IP3,integer_ip);
integer_ip = htonl(inet_addr(IP4));
printf("IP4: %s ------> Integer: %d\n",IP4,integer_ip);
integer_ip = htonl(inet_addr(IP5));
printf("IP5: %s ------> Integer: %d\n",IP5,integer_ip);
integer_ip = htonl(inet_addr(IP6));
printf("IP6: %s ------> Integer: %d\n",IP6,integer_ip);
integer_ip = htonl(inet_addr(IP7));
printf("IP7: %s ------> Integer: %d\n",IP7,integer_ip);
integer_ip = htonl(inet_addr(IP8));
printf("IP8: %s ------> Integer: %d\n",IP8,integer_ip);
return 0;
}
and The resuls:
IP1: 10.0.0.0 ------> Integer: 167772160
IP2: 20.0.0.0 ------> Integer: 335544320
IP3: 126.0.0.0 ------> Integer: 2113929216
IP4: 128.0.0.0 ------> Integer: -2147483648
IP5: 160.0.0.0 ------> Integer: -1610612736
IP6: 190.0.0.0 ------> Integer: -1107296256
IP7: 193.0.0.0 ------> Integer: -1056964608
IP8: 200.0.0.0 ------> Integer: -939524096
I tested The results on some online tools like this one.
Consider this line of output :
IP5: 160.0.0.0 ------> Integer: -1610612736
-1610612736
is equal to 160.0.0.0
whiles 1610612736
is equal to 96.0.0.0.
The most important requirement for me is speed. I don't want to check each IP if it is in class A or not.
How do i resolve this problem?
Thanks?
Your code invokes undefined behaviour for printing an unsigned integer as a signed.
To print the stdint.h
types, see inttypes.h
. Use the PRIu32
macro to print a uint32_t
:
uint32_t u = 42;
printf("Value: %" PRIu32 "\n", u);
The standard %u
conversion type specificer is not guaranteed to be correct, if uint32_t
is not typedef unsigned int uint32_t;
. For example with 32 bit long
and int
, it could be typedef
ed to unsigned
of either.
For hex, use PRIx32
or PRIX32
.
The Macros map to a string literal with the conversion specifier appropriate for your platform, which can be "u"
. Notice the %
must be given in the peceeding part. The standard C feature of concatenating adjscent string literals will generate the final format-string. There will be no run-time overhead.