В каком порядке байтов recvfrom () сохраняет src_addr как? - PullRequest
3 голосов
/ 10 марта 2019

size_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen)

В каком порядке байтов записан аргумент src_addr? Сеть или хост? Я не смог найти это на справочной странице recvfrom или в поиске через Google и SO.

1 Ответ

5 голосов
/ 10 марта 2019

Предполагая, что сокет является сокетом IPv4 или IPv6, хост и порт, сохраненные в src_addr, будут иметь сетевой порядок байтов.

Это описано в справочной странице для IPv4 (man 7 ip) следующим образом:

Формат адреса

IP-адрес сокета определяется как комбинация IP-интерфейса. адрес и 16-битный номер порта. Базовый протокол IP не номера портов питания, они реализованы протоколами более высокого уровня
как udp (7) и tcp (7). На сырых сокетах sin_port установлен на IP протокол.

   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 всегда установлен на AF_INET. Это обязательно; в линуксе 2.2 большинство сетевых функций возвращают EINVAL, если этот параметр отсутствует. sin_port содержит порт в сетевом порядке байтов. номера портов ниже 1024 называются привилегированными портами (или иногда: зарезервированные порты). Только привилегированный процесс (в Linux: процесс который имеет возможность CAP_NET_BIND_SERVICE в пространстве имен пользователя управляющий его сетевым пространством имен) может связать (2) с этими сокетами. Обратите внимание, что протокол IPv4 как таковой не имеет понятия порта, они реализуются только более высокими протоколами, такими как tcp (7) и UDP (7). * * тысячу двадцать-два

sin_addr - IP-адрес хоста. s_addr член структуры in_addr содержит адрес интерфейса хоста в сетевом порядке байтов. in_addr должно быть присвоено одно из INADDR_* значений (например, INADDR_LOOPBACK) с помощью htonl (3) или с помощью inet_aton (3), inet_addr (3), inet_makeaddr (3) библиотечные функции или непосредственно с распознаватель имен (см. gethostbyname (3)).

Страница man ipv6 имеет похожую формулировку.

Поэтому, читая номер порта, используйте ntohs, чтобы извлечь его. При чтении адреса используйте inet_ntop, чтобы преобразовать его в текстовую форму.

...