size_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen)
In what byte order is the src_addr
argument written? Network or host? I couldn't find this in the recvfrom
man page or a search through google and SO.
Assuming the socket is an IPv4 or IPv6 socket, the host and port stored in src_addr
will be in network byte order.
This is documented in the man page for IPv4 (man 7 ip
) as follows:
Address format
An IP socket address is defined as a combination of an IP interface address and a 16-bit port number. The basic IP protocol does not supply port numbers, they are implemented by higher level protocols
like udp(7) and tcp(7). On raw sockets sin_port is set to the IP protocol.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 */ }; /* Internet address. */ struct in_addr { uint32_t s_addr; /* address in network byte order */ };
sin_family
is always set toAF_INET
. This is required; in Linux 2.2 most networking functions returnEINVAL
when this setting is missing.sin_port
contains the port in network byte order. The port numbers below 1024 are called privileged ports (or sometimes: reserved ports). Only a privileged process (on Linux: a process that has the CAP_NET_BIND_SERVICE capability in the user namespace governing its network namespace) may bind(2) to these sockets. Note that the raw IPv4 protocol as such has no concept of a port, they are implemented only by higher protocols like tcp(7) and udp(7).
sin_addr
is the IP host address. Thes_addr
member of structin_addr
contains the host interface address in network byte order.in_addr
should be assigned one of theINADDR_*
values (e.g.,INADDR_LOOPBACK
) using htonl(3) or set using the inet_aton(3), inet_addr(3), inet_makeaddr(3) library functions or directly with the name resolver (see gethostbyname(3)).
The ipv6 man page has similar wording.
So when reading the port number, use ntohs
to extract it. When reading the address, use inet_ntop
to convert it to text form.