As the title states that data I am getting back from gethostbyname
seems to have a mangled first bit.
Here is a short example:
struct hostent* host= gethostbyname("indiana.cs.rit.edu");
if (!host)
exit(-1);
printf("%d.%d.%d.%d\n", (host->h_addr_list[0][0]),
(host->h_addr_list[0][1]),
(host->h_addr_list[0][2]),
(host->h_addr_list[0][3]));
printf("%d.%d.%d.%d\n",UP(host->h_addr_list[0][0]),
UP(host->h_addr_list[0][1]),
UP(host->h_addr_list[0][2]),
UP(host->h_addr_list[0][3]));
Where UP is defined as
#define UP(X) (((int)X) & 0XFF)
The output of the above code is:
-127.21.37.10
and 129.21.37.10
.
Now I know I should be using inet_ntoa
to get my char* version of the IP address. However, does anyone know why my first byte is mangled? Since I am getting back a char** from host->h_addr_list
my first []
should deference to the first address where the second []
should dereference to the actual char. given that the char is 1byte, why do I have to perform an bitwise operator to clear out the mangled bit?
Adding to the layer of confusion is why I am getting -127 or 129.
For example, in binary my 129 for one byte should look like..
1000 0001
However, based on the value of -127 it suggest that my underlying binary value is.
1111 1111
Now, where I am really confused is how the bitwise operator of 0XFF (1111 1111) is returning 129 since what I am seeing it should return 255 for unsigned or -127 for signed. Where is the extra data coming from?
Thanks for the help in advance.
host->h_addr_list[0][0]
is getting sign extended into a signed int when you use %d with it.
If you were to do:
printf("%d.%d.%d.%d\n", (unsigned char)(host->h_addr_list[0][0]),
(unsigned char)(host->h_addr_list[0][1]),
(unsigned char)(host->h_addr_list[0][2]),
(unsigned char)(host->h_addr_list[0][3]));
Then you wouldn't have the problem.
In two's complement (8 bit) 129 and -127 have the same bit pattern and your analysis is wrong.
11111111 is -1 in 8 bit signed two's complement (not -127) and the range of a signed 8 bit number is -128 to 127.
1000000 = -128 (128 unsigned)
1000001 = -127 (129 unsigned)
1000010 = -126 (130 unsigned) (etc)