winapi - gethostbyname and endianness - how are the bytes returned? -
on (intel) x86 machine, i've noticed if printf
results of gethostbyname
localhost
, 100007f
, though msdn documentation states should return ip in network byte order, aka big endian. searched bit , found this topic. based on answers there, i've deduced sequence of bytes same no matter endianness, so, localhost
, i'd have in memory on both intel , amd chips:
7f|00|00|01
thus, reading memory intel chip results in 'reversed' result, while on amd cpu, i'd 0x7f000001. assumption correct? seems possible explanation, want make sure.
this code i'm using:
#define win32_lean_and_mean #include <winsock2.h> #include <ws2tcpip.h> #include <stdio.h> // need link ws2_32.lib #pragma comment(lib, "ws2_32.lib") int main(int argc, char **argv) { //----------------------------------------- // declare , initialize variables wsadata wsadata; int iresult; dword dwerror; int = 0; struct hostent *remotehost; char *host_name; struct in_addr addr; char **palias; // initialize winsock iresult = wsastartup(makeword(2, 2), &wsadata); if (iresult != 0) { printf("wsastartup failed: %d\n", iresult); return 1; } host_name = "localhost"; // if user input alpha name host, use gethostbyname() // if not, host addr (assume ipv4) if (isalpha(host_name[0])) { /* host address name */ printf("calling gethostbyname %s\n", host_name); remotehost = gethostbyname(host_name); } else { printf("calling gethostbyaddr %s\n", host_name); addr.s_addr = inet_addr(host_name); if (addr.s_addr == inaddr_none) { printf("the ipv4 address entered must legal address\n"); return 1; } else remotehost = gethostbyaddr((char *)&addr, 4, af_inet); } if (remotehost == null) { dwerror = wsagetlasterror(); if (dwerror != 0) { if (dwerror == wsahost_not_found) { printf("host not found\n"); return 1; } else if (dwerror == wsano_data) { printf("no data record found\n"); return 1; } else { printf("function failed error: %ld\n", dwerror); return 1; } } } else { printf("function returned:\n"); printf("\tofficial name: %s\n", remotehost->h_name); (palias = remotehost->h_aliases; *palias != 0; palias++) { printf("\talternate name #%d: %s\n", ++i, *palias); } printf("\taddress type: "); switch (remotehost->h_addrtype) { case af_inet: printf("af_inet\n"); break; case af_inet6: printf("af_inet6\n"); break; case af_netbios: printf("af_netbios\n"); break; default: printf(" %d\n", remotehost->h_addrtype); break; } printf("\taddress length: %d\n", remotehost->h_length); if (remotehost->h_addrtype == af_inet) { while (remotehost->h_addr_list[i] != 0) { addr.s_addr = *(u_long *)remotehost->h_addr_list[i++]; printf("\tipv4 address #%d: %x %s\n", i, addr.s_addr, inet_ntoa(addr)); } } else if (remotehost->h_addrtype == af_inet6) printf("\tremotehost ipv6 address\n"); } getchar(); return 0; }
the output:
note: i've had friend run on amd cpu, , surprisingly, apparently it's 100007f
him well. previous assumption wrong, or friend drunk?
the addresses contained in hostent
structure in network byte order.
if have code suggests otherwise misinterpreting code , reaching wrong conclusion.
in network byte order, on little endian host, 127.0.0.1
0x0100007f
. see how works, remember on little endian host, least significant byte stored first. that's 0x7f
. bytes appear in order in memory, 0x7f
, 0x00
, 0x00
, 0x01
. , therefore represents 127.0.0.1
.
now, same bytes on big endian host represent different 32 bit value. on big endian host, first byte if significant, , 0x7f
, 0x00
, 0x00
, 0x01
represent value 0x7f000001
.
Comments
Post a Comment