Skip to content

Latest commit

 

History

History
101 lines (54 loc) · 12.3 KB

lecture.adoc

File metadata and controls

101 lines (54 loc) · 12.3 KB

IP протокол

На сетевом уровне работает протокол IP (Internet protocol), который описан в RFC 791. IP протокол был придуман в далеком 1981 году, является частью стека протоколов TCP/IP и ответственный за доставку данных от одного хоста к другому. А IP адреса это только часть протокола. На рисунке ниже можно увидеть заголовок IP пакета. Source Address и Destination Address - это IP адреса.

Заголовок IP пакета из RFC 791 (https://datatracker.ietf.org/doc/html/rfc791).
Figure 1. Заголовок IP пакета из RFC 791 (https://datatracker.ietf.org/doc/html/rfc791).

Разберем некоторые поля из IP заголовка.

Версия IP протокола

Самое первое поле в IP заголовке называется Version. Оно указывает на текущую версию протокола. Сейчас используется 4 версия протокола, поэтому иногда можно встретить вот такую запись IPv4.

Есть еще 6-я версия протокола (IPv6). Основное отличие IPv4 от IPv6 - размер IP адреса. В IPv4 размер IP адреса 4 байта (32 бита), а в IPv6 целых 16 байт (128 бит).

Это поле указывает на версию IP протокола. Когда внутри Ethernet пакета передается IPv4, то в поле тип/длина указывается 0x0800, как на рисунке ниже.

Внутри Ethernet кадра передается IPv4.
Figure 2. Внутри Ethernet кадра передается IPv4.

А если бы мы передавали IPv6, то в поле тип/длина было бы 0x08DD. Таким образом, еще в заголовке Ethernet кадра мы можем понять, какой тип IP протокола лежит внутри и смотреть на поле Version в заголовке IP нет особого смысла.

Время жизни пакета (Time To Live - TTL)

Поле Time To Live (TTL) определяет время жизни пакета в сети. Как видно из заголовка, это поле размером 1 байт (8 бит). Измеряется оно в хопах. Хоп - это переход пакета через маршрутизатор. Т.е. каждый раз, когда маршрутизатор пересылает пакет, он уменьшает это поле на 1. Если поле TTL становится 0, то маршрутизатор отбрасывает такой пакет и генерирует для отправителя этого пакета специальное ICMP сообщение “time to live exceeded in transit”. Таким образом, отправитель будет знать по какой причине и какой маршрутизатор отбросил этот пакет. Это защита от вечно зацикленного пакета.

Сделаем сеть как показано на рисунке ниже.

Кольцо из 3-х маршрутизаторов. (https://miminet.ru/web_network?guid=7509b963-d190-4aad-8d90-9be42f302bbb)
Figure 3. Кольцо из 3-х маршрутизаторов. (https://miminet.ru/web_network?guid=7509b963-d190-4aad-8d90-9be42f302bbb)

Нам понадобится 1 хост и 3 маршрутизатора:

  • Хост 1 и маршрутизатор будут в IP сети 10.0.0.0/24. В качестве маршрутизатора по умолчанию для хоста 1 будем использовать маршрутизатор 1.

  • Маршрутизатор 1 и 2 будут в сети 172.16.12.0/24. В качестве маршрутизатора по умолчанию для маршрутизатора 1 будет маршрутизатор 2.

  • Маршрутизатор 2 и 3 будут в сети 192.168.1.0/24. В качестве маршрутизатора по умолчанию для маршрутизатора 2 будет маршрутизатор 3.

  • А сеть между маршрутизаторами 3 и 1 будет 169.254.1.0/24. В качестве маршрутизатора по умолчанию для маршрутизатора 3 будет маршрутизатор 1.

По умолчанию маршрутизатор 1 будет отправлять пакет на маршрутизатор 2, тот на маршрутизатор 3, а тот в свою очередь на маршрутизатор 1. Т.е. пакет будет летать по кругу.

Теперь на хосте 1 выполним команду ping -c 1 -t 5 12.34.45.67 и посмотрим за работой сети. Флаг -t для команды пинг означает установить поле TTL в IP пакете. В данном случае я установил это поле в 5. Это означает, что через 5 маршрутизаторов поле TTL станет 0 и пакет будет отброшен.

В качестве IP адреса получателя в команде ping я выбрал 12.34.45.67, чтобы все маршрутизаторы отправляли этот пакет на маршрутизатор по умолчанию.

Запустим анимацию сети мы увидим, что пакет прошел по кругу и, когда он оказался второй раз на маршрутизаторе 2, он был отброшен. Вместо ICMP-запроса с маршрутизатора 2 вышел ICMP- time to live exceeded, который в итоге был доставлен хосту 1.

Таким образом, поле TTL в IP протоколе защищает сеть от вечно циркулирующих IP пакетов.

Фрагментация

В заголовке IP пакета есть поле Total Length (длина). Это поле сообщает длину IP пакета в байтах. Длина поля 2 байта (16 бит). Это означает, что максимальная длина одного IP пакета может быть 65 536 байт.

С другой стороны, есть ограничения физического уровня на передачу максимального размера кадра. В Ethernet это 1500 байт.

И как передать пакет длиной в 65535 байт, если максимальный размер пакета 1500 байт? Ответ - фрагментация пакета. Т.е. перед отправкой пакет разбивается на фрагменты, так, чтобы помещаться в пакет более низкого уровня и отправляются в сеть.

Чтобы принимающий хост смог все эти фрагменты правильно собрать используются следующие поля:

  • Identification (идентификатор)

  • Flags (флаги)

  • Fragment Offset (смещение фрагмента)

Фрагментация выглядит как на рисунке ниже.

Фрагментация IP пакета.
Figure 4. Фрагментация IP пакета.

Алгоритм следующий:

  1. Берем данные для передачи, и нарезаем их на порции, которые смогут поместиться в один пакет. Напомню, что в Ethernet мы можем передать до 1500 байт данных. Размер заголовка IP 20 байт, соответственно, 1500 - 20 = 1480, в одном пакете мы можем передать до 1480 байт данных.

  2. Для каждой такой порции формируем IP пакет, в котором указываем:

    1. Идентификатор пакета, например, 12. Он нам нужен для идентификации пакета. Представим ситуацию, на хост приходит два фрагмента IP пакета. Как понять, что это два фрагмента от одного IP пакета, а не от разных? Именно для этого и используется поле идентификатор. Значение этого поля будет одинаковым для всех фрагментов нашего пакета.

    2. Флаг More Fragments (MF). Если это не последний фрагмент, то флаг выставляется в 1. Если это последний фрагмент, то флаг выставляется в 0. Этот флаг нужен, чтобы сообщить принимающему хосту, что все, фрагменты закончились, можешь обрабатывать пакет.

    3. Offset (смещение). Указывает на смещение в байтах относительно начала данных. У первого фрагмента это будет 0.

  3. Передаем в сеть.

Получив все эти фрагменты удаленный хост может собрать все обратно и отдать на дальнейшую обработку.

Всех этих данных достаточно, чтобы собрать пакет, даже если фрагменты придут в неправильном порядке.

Note
Если внимательно посмотреть на IP заголовок, то можно заметить, что поле Fragment Offset имеет размер 13 бит. Максимальное число, которое мы сможем записать с помощью 13 бит - это 8191. А максимальный размер IP пакет 65 5236 байт. Как тогда с помощью Fragment Offset указать на смещение 12000 или 30000 байт? Все дело в том, что поле Fragment Offset указывает на количество 8 битных слов (64 бита). Т.е. значение поля Fragment Offset в 1 указывает на смещение на 8 байт, а значение Fragment Offset в 100 будет указывать на смещение в 800 байт.

IHL

IHL (Internet Header Length) - длина IP заголовка. Если посмотреть на формат IP заголовка, то можно увидеть в конце поле Options (опции). Они могут быть, а могут и не быть, от этого длина заголовка будет разной. Чтобы при обработке пакета понять, сколько байт занимает длина IP заголовка используется поле IHL. IP заголовок всегда должен быть кратен 4 байтам (32 бита), поэтому поле IHL указывает количество 32-битных слов в заголовке. Если опций нет, то поле IHL равно 5 (5 * 4 = 20 байт).

Type Of Service

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

Header Checksum

Контрольная сумма заголовка, считается как CRC32.