Home > Net >  Does bind actually require conversion to network byte order?
Does bind actually require conversion to network byte order?

Time:12-07

In every top google result for "C Linux Socket Tutorial" (1, 2, 3, 4, 5 ) they convert the port (and sometimes the address) to network byte order:

address.sin_family = AF_INET;
address.sin_addr.s_addr = htonl(INADDR_ANY);
address.sin_port = htons(PORT);

bind(socket_fd, (struct sockaddr*)&address, sizeof(address)); 

Is this correct? Or does it just so happen to work since port is typically 0 and INADDR_ANY is also 0, and therefore the conversion to network byte order does nothing.

Testing on my own linux machine, it seems that bind(...) expects host byte order as demonstrated in the following code.

address.sin_family = AF_INET;
address.sin_addr.s_addr = htonl(INADDR_ANY);
address.sin_port = htons(1);

int status = bind(socket_fd, (struct sockaddr\*)&address, sizeof(address));
if (status == -1)
{
    perror("bind");
    return 1;
}

I expect this to produce a permission error due to requesting a privileged port, however the program runs without error. And when I change htons(1) to just 1, then the program fails with a permission error. Which seems to imply that bind(...) expects host byte order.

Am I misunderstanding something or are the majority of tutorials incorrect? Does bind(...) require host byte order or network byte order for the sockaddr_in struct?

CodePudding user response:

bind requires a sockaddr. For IPv4 this means sockaddr_in. From the documentation:

Address format
...
       struct sockaddr_in {
           sa_family_t    sin_family; /* address family: AF_INET */
           in_port_t      sin_port;   /* port in network byte order */
           struct in_addr sin_addr;   /* internet address */
       };

So, it clearly says network byte order for sin_port.

And when I change htons(1) to just 1, then the program fails with a permission error.

Since this is about a short (16 bit) a 1 in the wrong byte order just means 256. This is still below 1024 and thus requires root privileges to bind. Thus, no matter if you use htons(1) or 1 it should still fail with the same reason. I have no idea what exactly you did so it does not fail with htons(1) for you (for me it does).

  • Related