Мы начнем изучение сетевого уровня интернета с формата IPv4-дейтаграмм. Такая дейтаграмма состоит из заголовка и основной части (пользовательских данных). Заголовок содержит фиксированную 20-байтную часть, а также необязательную часть, длина которой варьируется. Формат заголовка показан на илл. 5.47. Биты передаются слева направо и сверху вниз, то есть старший бит поля Version (Версия) идет первым. (Такой порядок байтов называется «от старшего к младшему» («big-endian»). На компьютерах с порядком «от младшего к старшему» («little-endian»), например Intel x86, требуется программное преобразование, как при передаче, так и при приеме.) Сегодня уже совершенно ясно, что для IP лучше было использовать порядок «от младшего к старшему», но на момент создания протокола это было не столь очевидно.
Поле Version содержит версию протокола, к которому принадлежит дейтаграмма. Сейчас в интернете доминирует версия 4, поэтому с нее мы и начали обсуждение IP. Указание версии в начале каждой дейтаграммы позволяет переходить от одной версии к другой в течение долгого времени. На самом деле протокол IPv6 (следующая версия IP) разработан более десяти лет назад, но применять его начинают только сегодня. О нем мы поговорим позже в этом разделе. Широкое распространение протокол IPv6 получит, когда у каждого из почти 231 жителей Китая будет настольный ПК, ноутбук и IP-телефон. Что касается нумерации, то ничего странного в ней нет: в свое время существовал малоизвестный экспериментальный потоковый протокол реального времени IPv5.
Илл. 5.47. Заголовок IPv4
Поскольку длина заголовка является переменной величиной, она указывается в поле IHL и выражается в 32-разрядных словах. Минимальное значение длины — при отсутствии поля Options (Опции) — равно 5. Максимальное значение этого 4-битного поля равно 15, что соответствует заголовку длиной 60 байт; таким образом, максимальный размер поля Options равен 40 байтам. Для некоторых функций, например для записи маршрута, пройденного пакетом, 40 байт недостаточно, и дополнительное поле оказывается бесполезным.
Поле Differentiated services (Дифференцированное обслуживание) — одно из немногих полей, смысл которых с годами слегка изменился. Изначально оно называлось Type of service (Тип службы). Его задача (была и остается) — определять различные классы обслуживания. Возможны разные комбинации надежности и скорости. Для цифрового голосового сигнала скорость доставки важнее точности. При передаче файла, наоборот, отсутствие ошибок важнее быстрой доставки. В поле Type of service 3 бита обозначали приоритет, еще 3 бита показывали, что беспокоит хост больше всего: задержка, пропускная способность или надежность. Никто не знал, что делать со всеми этими битами на маршрутизаторах, поэтому они не использовались в течение многих лет. Когда появилось дифференцированное обслуживание, IETF сдался и нашел этому полю другое применение. Теперь первые 6 бит задают класс обслуживания; о срочном и гарантированном обслуживании мы уже говорили ранее в этой главе. В последние два бита помещаются явные уведомления о перегрузке, которые обсуждались в разделе 5.3.
Поле Total length (Полная длина) содержит длину всей дейтаграммы: заголовок и данные. Максимальная длина дейтаграммы — 65 535 байт. В настоящий момент этого достаточно, однако для будущих сетей могут понадобиться дейтаграммы большего размера.
Поле Identification (Идентификация) позволяет хосту-получателю определить, какому пакету принадлежат принятые им фрагменты. Все фрагменты одного пакета содержат одно и то же значение идентификатора.
Далее идет неиспользуемый бит, что достаточно странно, так как место в IP-заголовке крайне ограниченно. В качестве первоапрельской шутки Белловин (Bellovin, 2003) предложил использовать его для обнаружения вредоносного трафика. Это значительно упростило бы защиту сети: пакеты с таким битом можно было бы просто удалять, зная, что они отправлены злоумышленниками. К сожалению, сетевую безопасность невозможно обеспечить столь простым способом, как бы заманчиво идея ни выглядела.
Затем следуют два однобитных поля, относящиеся к фрагментации. Бит DF означает «Don’t Fragment» («Не фрагментировать»); он запрещает маршрутизатору фрагментировать пакет. Изначально предполагалось, что это поле будет помогать хостам, которые не могут восстановить пакет из фрагментов. Сейчас оно используется при определении путевого значения MTU, которое равно максимальному размеру пакета, передаваемого по пути без фрагментации. Пометив дейтаграмму битом DF, отправитель гарантирует, что либо дейтаграмма дойдет единым блоком, либо отправитель получит сообщение об ошибке.
Бит MF означает «More Fragments» («Дополнительные фрагменты»). Он устанавливается во всех фрагментах, кроме последнего. По этому биту получатель узнает о прибытии последнего фрагмента дейтаграммы.