Старина IPv4… В сетевом мире он распространён так же, как и воздух на Земле. Однако несмотря на то, что миллионы людей используют этот протокол в повседневной жизни, у IPv4 всё ещё есть пара сюрпризов в рукаве. Сегодня мы рассмотрим один из них.
Очень простая схема из 4 маршрутизаторов, выстроенных в цепь:
На каждом устройстве настроена базовая адресация и включён EIGRP на всех интерфейсах:
R2#show run | section router|interface FastEthernet
interface FastEthernet0/0
ip address 192.168.12.2 255.255.255.0
interface FastEthernet0/1
ip address 192.168.23.2 255.255.255.0
router eigrp 1
network 0.0.0.0
По умолчанию, IP MTU на каждом интерфейсе равен 1500. Это означает, что допустимый размер пакета, включая заголовки и полезную нагрузку, не превышает 1500 байтов; если же пакет больше, то его следует фрагментировать. Предположим, что MTU на интерфейсах R2-R3 равен 1400 с обеих сторон:
R2#show run interface fastEthernet0/1
interface FastEthernet0/1
ip address 192.168.23.2 255.255.255.0
ip mtu 1400
На сколько фрагментов будет разделён пакет размером 1500 байтов?
R1#ping 4.4.4.4 source 1.1.1.1 size 1500 repeat 1
Type escape sequence to abort.
Sending 1, 1500-byte ICMP Echos to 4.4.4.4, timeout is 2 seconds:
Packet sent with a source address of 1.1.1.1
!
Success rate is 100 percent (1/1), round-trip min/avg/max = 68/68/68 ms
Согласно учению начальной школы, такой пакет превратится в 2 фрагмента. Неожиданно то, что ответ на пинг тоже оказывается фрагментирован. Однако странным это кажется только на первый взгляд: ICMP echo reply обязан нести на себе ту же полезную нагрузку, что и изначальный пакет.
Уменьшим MTU до 700 байтов на обоих интерфейсах и проверим, можно ли пропихнуть ровно 2 фрагмента по 700 байтов через них. IP-заголовок занимает 20 байтов, поэтому данных в первоначальном пакете должно быть 680*2 + 20 = 1380 байтов (значение IP MTU включает в себя и длину заголовков).
R1#ping 4.4.4.4 source 1.1.1.1 size 1380 repeat 1
Type escape sequence to abort.
Sending 1, 1380-byte ICMP Echos to 4.4.4.4, timeout is 2 seconds:
Packet sent with a source address of 1.1.1.1
!
Success rate is 100 percent (1/1), round-trip min/avg/max = 48/48/48 ms
А теперь к гвоздю сегодняшней программы: волшебному значению MTU в 725 байтов.
R1#ping 4.4.4.4 source 1.1.1.1 size 1430 repeat 1
Type escape sequence to abort.
Sending 1, 1430-byte ICMP Echos to 4.4.4.4, timeout is 2 seconds:
Packet sent with a source address of 1.1.1.1
!
Success rate is 100 percent (1/1), round-trip min/avg/max = 48/48/48 ms
И так, 20 байтов заголовка и 1410 байтов данных превращаются… в 3 фрагмента? С каких пор 705 + 20 ≠ 725?
По правде говоря, в числе 725 не больше волшебства, чем в любом другом числе, не кратном 8. Засада прячется в поле Fragment Offset, которое содержит сдвиг данных фрагмента относительно данных первоначального пакета.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| IHL |Type of Service| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time to Live | Protocol | Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Этот сдвиг измеряется в хитрых единицах – по 8 байтов. Поскольку 705 на 8 не делится, маршрутизатор выбирает ближайшее к 705 кратное – 704.
Алгоритм, по которому нужно выбирать размер фрагментов, не фиксирован в RFC. В нашем случае R2 предпочёл отправить 8 байтов со вторым фрагментом, а остальные данные оставить последнему.
Вообще, конечные устройства всячески стараются избежать фрагментации с помощью разных механизмов, например, PMTUD, TCP MSS. Такое поведение сводит на нет шансы наступить на грабли, связанные с неожиданным количеством фрагментов от одного пакета. Впрочем, иногда же надо как-то обосновать требование разобраться с заголовками используемых протоколов?..
За рецензию большое спасибо Анастасии Куралёвой.
AlexGluck
Больше веселья начинается когда в гетерогенной сетевой среде L1 media MTU (аппаратный размер кадра) различается между оборудованием различных вендоров. https://ru.wikipedia.org/wiki/Maximum_transmission_unit