c++sockets

Why does sendto reverse my IP address when using network byte order?


I'm trying to send a multicast UDP packet to the IP address 239.255.0.1. I have a ConnectionAttributes class that stores IP addresses and can return them in either network byte order (NBO) or host byte order (HBO).

Here are the values for the IP 239.255.0.1 in both formats:

IP: 239.255.0.1
NBO: 4026466305 (0xEFFF0001)
HBO: 16842735 (0x0100FFEF)

This is the C++ snippet I’m using to send the data over a socket:

Error UDPConnectionHandler::send(const void *data, size_t dataSize) {

    auto nbo = 4026466305; // 239.255.0.1 in network byte order
    auto hbo = 16842735; // 239.255.0.1 in host byte order

    sockaddr_in destAddr = {};
    destAddr.sin_family = AF_INET;
    destAddr.sin_port = 59420;
    destAddr.sin_addr.s_addr = nbo;
    ssize_t bytesSent;

    bytesSent = sendto(connAttr.getSocket(), data, dataSize, 0, (struct sockaddr *)&destAddr, sizeof(destAddr));

    if (bytesSent == -1)
          return Error(ERROR_ERRNO, errno);

    return Error(ERR_SUCCESS);
}

I use inet_pton(AF_INET, ip, &addr) to get the network byte order from an IP given as a const char*. To convert this address into host network order, I am using ntohl. I am on a Little Endian system.

But, if I provide the IP in host byte order (16842735), the packet is correctly sent with the IP address 239.255.0.1.

My understanding is that sendto should take network byte order. Why is it reversing the IP address when I provide it in network byte order? What am I missing here?


Solution

  • You are confusing the external representation with the internal representation. Your CPU is little-endian, so your "NBO" 0xEFFF0001 is actually stored as the following sequence of bytes:

    01 00 FF EF
    

    htonl(0xEFFF0001) is the proper way to compute the network byte order. It will byteswap on little-endian systems and do nothing on big-endian systems (but those are rare anyway).

    As a general rule, you should only work with IP addresses in host order and swap to/from network order when you send/receive.