17.5.2. Адресация IPv4
17.5.2. Адресация IPv4
Соединения IPv4 представляют собой кортеж из 4-х элементов (локальный хост, локальный порт, удаленный хост, удаленный порт). До установки соединения необходимо определить каждую его часть. Элементы локальный хост и удаленный хост являются IPv4-адресами. IPv4-адреса — это 32-битные (4-байтовые) числа, уникальные для всей установленной сети. Как правило, они записываются в виде aaa.bbb.ccc.ddd, где каждый элемент адреса является десятичным представлением одного из байтов адреса машины. Первое слева число в адресе соответствует самому значимому байту в адресе. Такой формат для IPv4-адресов известен как десятичное представление с разделителями-точками.
В связи с тем, что большинство компьютеров вынуждено поддерживать работу нескольких параллельных TCP/IP приложений, IP-номер не обеспечивает уникальную идентификацию для соединения на одной машине. Номера портов — это 16-битные числа, которые позволяют однозначно распознавать одну из сторон соединения на данном хосте. Объединение IPv4-адреса и номера порта обеспечивает идентификацию стороны соединения где-либо в пределах одной сети TCP/IP (например, Internet является единой TCP/IP сетью). Две конечные точки соединения образуют полное TCP-соединение, таким образом, две пары, состоящие из IP-номера и номера порта, однозначно определяют TCP/IP соединение в сети.
Распределение номеров портов для различных протоколов производится на основе раздела стандартов Internet, известного как официальные номера портов, который утверждается Агентством по выделению имен и уникальных параметров протоколов Internet (Internet Assigned Numbers Authority, LANA)[128]. Общие протоколы Internet, такие как ftp, telnet и http, имеют свои номера портов. Большинство серверов предусматривают данные службы на присвоенных номерах, что позволяет их легко найти. Некоторые сервера запускаются на альтернативных номерах портов, как правило, для поддержки нескольких служб на одной машине[129]. Поскольку официальные номера портов не изменяются, система Linux просто находит соответствие между именами протоколов (обычно называемых службами) и номерами портов с помощью файла /etc/services.
Все номера портов попадают в диапазон от 0 до 65 535; в системе Linux они разделяются на два класса. Зарезервированные порты с номерами от 0 до 1 024 могут использоваться только процессами, работающими как root. Это позволяет клиентским программам иметь гарантию того, что программа, запущенная на сервере, не является троянским конем, активизированным каким-то пользователем[130].
IPv4-адреса хранятся в структуре struct sockaddr_in, которая определяется следующим образом.
#include <sys/socket.h>
#include <netinet/in.h>
struct sockaddr_in {
short int sin_family; /* AF_INET */
unsigned short int sin_port; /* номер порта */
struct in_addr sin_addr; /* IP-адрес */
}
Первым членом должен быть AF_INET, указывающий, что это IP-адрес. Следующий член — это номер порта в сетевом порядке байтов. Последний элемент — это IP-номер машины для данного TCP адреса. IP-номер, хранящийся в sin_addr, должен трактоваться как непрозрачный тип и не иметь возможности прямого доступа.
Если хотя бы одна из переменных sin_port или sin_addr заполнена байтами (обычно функцией memset()), то это указывает на условие "пренебречь". Серверные процессы, как правило, не беспокоятся о том, какой IP-адрес используется для локального соединения. Другими словами, они согласны принимать соединения с любым адресом, имеющимся на данной машине. Если в приложении требуется принимать соединения только на одном интерфейсе, то при этом нужно обязательно указать адрес. Такой адрес иногда называется неустановленным, поскольку он не представляет собой полное определение адреса соединения (для него требуется еще IP-адрес)[131].