I was updating a wrapper 32 bit windows DLL on an old winsock utilities library, to allow for the case where I need to specifically bind() my sockets to one or another IP addresses, on a multi homed system. I'm working with Visual studio 2008, on XP pro if it matters.

Anyway, previously I just would not bother doing a bind, just allowing winsock to choose an appropriate IP. But now I was doing something like the below. (Assume dwMyIP is a ULONG containing a known good IP, in host order.)


Code:
struct sockaddr_in sock_bind_addr;
 
sock_bind_addr.sin_family = AF_INET;  
sock_bind_addr.sin_addr.S_un.S_addr = htonl(dwMyIp); 
sock_bind_addr.sin_port = 0;   // 0 allows winsock to pick a port.
   
if (bind(*pSockToStartWith, (struct sockaddr *)(&sock_bind_addr), sizeof(struct sockaddr_in)) == SOCKET_ERROR) {

... (Houston, we have a problem)'
 return -1;
}
So anyway, the bind would fail, and on a whim I decided to
remove the htonl() call, and store the 32 bit address in host order in the sockaddr_in structure. It WORKED!

Now I know everyone will jump to tell me that obviously I was missing something, and that my address was already in network order. Well consider this... the network IP in question was "192.168.0.190" Single step debugging though the code reveals that at this point in the program, dwMyIp = 0xBE00A8C0, which as an IP address is nothing like mine (makes sense... since I'm on an intel/windows machine). If, however I run my dwMyIP through htonl(), I get 0xC0A800BE, which indeed equates to 192.168.0.190. But that won't work, and I get an error (error 10049).

Further, after completing the bind the "wrong" way (with my host order IP), I can connect to a test application on another machine, which does indeed report the incoming connection from 192.168.0.190. Now I repeated this test with the ULONG equivalent of every available IP IP I'm set up on my system and the result is the same. I can bind to any valid address as long as I store it in host order, not network order.

OK...getting something to work the WRONG way and ignoring the problem is a prescription for a disaster sooner or later. So I'm about to make a hidden configuration variable for this to take care of both cases. But can anyone tell me why this is happening? Is there a known problem with the winsock (winsock 2 if it matters) bind() function? I can tell you from using the TCP/IP server variation, where I DO have to specify a port to connect to, that the expected behavior there is correct (meaning, if I want a client to connect to me at port 1234, I *DO* have to bind my listening socket to htons(1234).

As far as my server goes, its currently bound to IP_ANY, which in windows equates to 0. I have not yet tested to to see how it responds to a host format (little endian) IP, and I'll do that next. But I thought it was a good stopping point and a good time to ask.

Thanks for any help!