Структура протокола IP
Формат заголовка протокола IP состоит из определённого набора полей, которые описаны в RFC 791. Разбор данных полей важен для понимания процесса маршрутизации. Ниже я опишу данные поля и постараюсь показать их в реальности, используя Wireshark.
Version - 4-битное поле, определяющее версию используемого протокола. В настоящее время используется две версии протокола - 4 (0100
) версия и 6 (0110
) версия.
Header Length - 4-битное поле, которое показывает какова длина IP-заголовка в 32-битных словах.
Заметка: Минимальный размер IP-заголовка - 20 байт (сумма всех полей заголовка при пустом поле Options). Так как максимально в поле из 4 бит можно записать значение 15 (1111
), то максимальный размер IP-заголовка составляет 15 * 4 байта = 60 байт
Type of Service - 8-битное поле, может быть использовано для определения обработки пакета. В настоящее время данное поле переопределено как часть фреймворка Differentiated Services.
Данный фреймворк позволяет более гибко обрабатывать IP-пакеты. Фреймворк DiffServe определяет классы обслуживания (service classes
) на маршрутизаторах, а затем позволяет производить сортировку согласно данным классам. Маршрутизатор может ставить в очередь и производить пересылку пакетов с различными уровнями приоритета в зависимости от их классификации. Каждая процедура постановки в очередь и пересылки называется PHB - Per-Hop Behaviour
В современном мире 6 бит поля Type of Service определено как поле DSCP - DiffServe Code Point. Используя эти 6 бит, произвольно либо в соответствии с предопределенными в архитектуре DiffServe классами обслуживания, администратор может определить до 64 классов обслуживания, которые затем могут быть отсортированы в PHB.
Оставшиеся 2 бита используется для поля ECN - Explicit Congestion Notification - явное уведомление о перегрузках (RFC 3168). Если маршрутизатор поддерживает данный параметр, то поле примет значение 11
в случае сигнализации о перегрузке.
Total Length - 16-битное поле, определяет общую длину пакета, включая заголовок, в байтах. Вычитая длину заголовка можно получить размер данных. 16 бит может содержать максимальное значение в 65535, учитывая это получаем максимально возможное значение IP пакета - 65535 байт.
16-битное поле Identifier совместно с полями Flags и Fragment Offset используются для того чтобы показать был ли фрагментирован пакет или нет.
Пакет будет фрагментирован на более мелкие пакеты в случае когда его размер превышает Maximimum Transmition Unit (MTU) канальной среды через которую данный пакет будет передаваться.
Например, в случае когда MTU канальной среды равен 1500 байт и по ней передаётся пакет размером 5000 байт, то максимальный размер пакета может содержать только 1500 байт информации. Маршрутизатор должен маркировать каждый фрагмент с тем же значением в поле Identifier для того чтобы получающая сторона могла определить, что фрагменты относятся к одному и тому же пакету.
Заметка: фрагментированный пакет не собирается с каждой стороны канальной среды. Пакет остается фрагментированным до тех пор пока он не достигнет финальной точки назначения.
Flags - 3-битное поле, первый бит в котором не используется. Второй бит - бит DF (Don't Fragment
). Когда данный бит установлен в 1
, то маршрутизатор не может фрагментировать пакет.
Если пакет не может быть отправлен без фрагментации, маршрутизатор отбросит пакет и отправит источнику сообщение об ошибке пересылки. Данный функционал позволяет протестировать MTU в сети.
Рассмотрим простую схему между двумя маршрутизаторами:
С помощью расширенной утилиты ping на маршрутизаторах Cisco можно найти максимальный MTU между устройствами.
Ниже представлен пример выполнения данной команды:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Router#
Router# ping
Protocol [ip]:
Target IP address: 192.168.1.1
Repeat count [5]: 1
Datagram size [100]:
Timeout in seconds [2]:
Extended commands [n]: y
Ingress ping [n]:
Source address or interface: 192.168.1.1
Type of service [0]:
Set DF bit in IP header? [no]: y
Validate reply data? [no]:
Data pattern [0x0000ABCD]:
Loose, Strict, Record, Timestamp, Verbose[none]:
Sweep range of sizes [n]: y
Sweep min size [36]: 1451
Sweep max size [18024]: 1550
Sweep interval [1]: 1
Type escape sequence to abort.
Sending 100, [1451..1550]-byte ICMP Echos to 192.168.1.1, timeout is 2 seconds:
Packet sent with a source address of 192.168.1.1
Packet sent with the DF bit set
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!....................
..............................
Success rate is 50 percent (50/100), round-trip min/avg/max = 1/1/1 ms
Router#
Из вывода видно, что максимальный MTU равен 1500 байт. Существуют и другие способы как с помощью данной команды найти максимальный MTU между целой группой сетевых устройств.
Например, возьмем следующую схему *:
В данной схеме на всех интерфейсах за исключением одного установлен MTU равный 1500 байт. Для того чтобы найти данный интерфейс мы также можем воспользоваться расширенной утилитой:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
Router# ping
Protocol [ip]:
Target IP address: 163.19.203.170
Repeat count [5]: 1
Datagram size [100]:
Timeout in seconds [2]:
Extended commands [n]: y
Ingress ping [n]:
Source address or interface:
Type of service [0]:
Set DF bit in IP header? [no]: y
Validate reply data? [no]:
Data pattern [0x0000ABCD]:
Loose, Strict, Record, Timestamp, Verbose[none]: r
Number of hops [ 9 ]:
Loose, Strict, Record, Timestamp, Verbose[RV]:
Sweep range of sizes [n]: y
Sweep min size [76]: 500
Sweep max size [18024]: 1500
Sweep interval [1]: 500
Type escape sequence to abort.
Sending 3, [500..1500]-byte ICMP Echos to 163.19.203.170, timeout is 2 seconds:
Packet sent with the DF bit set
Packet has IP options: Total option bytes= 39, padded length=40
Record route: <*>
(0.0.0.0)
(0.0.0.0)
(0.0.0.0)
(0.0.0.0)
(0.0.0.0)
(0.0.0.0)
(0.0.0.0)
(0.0.0.0)
(0.0.0.0)
Reply to request 0 (3 ms) (size 500). Received packet has options
Total option bytes= 40, padded length=40
Record route:
(192.168.172.50)
(163.19.203.180)
(163.19.203.170)
(163.19.203.170)
(192.168.172.60)
(192.168.172.50) <*>
(0.0.0.0)
(0.0.0.0)
(0.0.0.0)
End of list
Reply to request 1 (3 ms) (size 1000). Received packet has options
Total option bytes= 40, padded length=40
Record route:
(192.168.172.50)
(163.19.203.180)
(163.19.203.170)
(163.19.203.170)
(192.168.172.60)
(192.168.172.50) <*>
(0.0.0.0)
(0.0.0.0)
(0.0.0.0)
End of list
Unreachable from 192.168.172.60, maximum MTU 1200 (size 1500). Received packet has options
Total option bytes= 39, padded length=40
Record route: <*>
(0.0.0.0)
(0.0.0.0)
(0.0.0.0)
(0.0.0.0)
(0.0.0.0)
(0.0.0.0)
(0.0.0.0)
(0.0.0.0)
(0.0.0.0)
Success rate is 66 percent (2/3), round-trip min/avg/max = 3/3/3 ms
Router#
Из вывода видно, что максимальный MTU в данной схеме равен 1200 байт.
Третий бит в поле Flags - More Fragment
. Когда маршрутизатор фрагментирует пакет, он записывает значение равное 1
в данный бит, за исключением последнего фрагмента. Этот бит необходим принимающей стороне для того чтобы определить где заканчивается фрагментированный пакет.
Fragment Offset - 13-битное поле, определяющее смещение от начала заголовка до начала фрагмента. Так как фрагменты не всегда могут приходить в правильном порядке, то данное поле позволяет принимающей стороне собрать фрагментированный пакет в правильном порядке.
Важно: в случае если в процессе передачи фрагментированного пакета теряется хотя бы один пакет, то весь пакет будет переслан заново. Таким образом, это может привести к непропорциональным задержкам в сети.
Time to Live или просто TTL - 8-битное поле, в которое записывается некоторое число в момент создания пакета.
По мере передачи пакета от одного маршрутизатора до другого, каждый из них будет уменьшать данное число. Если значение данного поля станет равным нулю, пакет будет отброшен и источнику пакета будет отправлено сообщение об ошибке пересылки. Данный механизм позволяет предотвратить бесконечное блуждание пакета по сети.
Современные маршрутизаторы в независимости от задержки уменьшают значение TTL на единицу. Рекомендуемое значение по умолчанию 64. Однако, встречаются и другие реализации в зависимости от операционной системы.
Некоторые утилиты для трасировки маршрута используют значение поля TTL. Пример выполнения трассировки приведён ниже:
Protocol - 8-битное поле, определяющее номер вышестоящего протокола, которому предназначена передаваемая информация в пакете.
Ниже в таблице представлены одни из наиболее часто используемых протоколов, но данный список далеко не полный, каким может казаться на первый взгляд.
Номер протокола | Название протокола |
---|---|
1 |
Internet Control Message Protocol - ICMP |
2 |
Internet Group Management Protocol - IGMP |
4 |
IP in IP (encapsulation) |
6 |
Transmission Control Protocol - TCP |
17 |
User Datagram Protocol - UDP |
47 |
Generic Routing Encapsulation - GRE |
89 |
Open Shortest Path First - OSPF |
Header Checksum - поле, определяющее ошибки в заголовке IP. Чексумма не вычисляется для содержимого IP пакета. Практически каждый вышестоящий протокол (будь то TCP, UDP, ICMP, etc.) имеет свои механизмы вычисления ошибок.
Данное поле представляет собой 16-битное значение, вычисляемое отправителем пакета. Принимающая сторона снова вычисляет данное значение и если значения сходятся, то считается, что чексумма не битая.
Важно: стоит помнить, что каждый маршрутизатор уменьшает значение поля TTL, поэтому значение чексуммы должно рассчитывается на каждом маршрутизаторе! RFC 1624 более подробно описывает процесс вычисления чексуммы в протоколе IP.
Source and Destination Addresses - 32-битный адреса источника и назначения пакета. Формат адресов представляет собой 4 десятичных числа от 0
до 255
, разделенных точкой.
Options - поле переменной длины, как следует из описания используется для дополнительных опций.
Данное поле используется в основном для тестирования. Наиболее часто используемые опции:
- Loose source routing - используется список IP-адресов, через которые должен пройти пакет, однако, на этом пути могут быть и другие адреса через которые не запрещено проходить
- Strict source routing - в отличие от предыдущего варианта, пакет должен пройти через строго отведенные адреса. В случае если следующий адрес не находится в списке адресов, то возникает ошибка.
- Record route - как и в случае трассировки маршрута, обеспечивает аналогичную функцию, за тем лишь исключением, что отображаются исходящие интерфейсы как на пути к месту назначения, так и на обратном пути. Данный механизм был показан ранее при выявлении максимального MTU в сети из нескольких устройств
- Timestamp - отличается от Record route тем, что отслеживает не только где проходил пакет, но и когда.
Padding - используется для наполнения заголовка нулями (после поля Options), гарантируя, что граница конца заголовка проходит по 32 биту.
Для подробного анализа трафика можно скачать файл с дампом трафика, открыть его с помощью анализатора трафика Wireshark и пройтись по тем полям, которые были описаны выше в данной статье.
Также прикладываю файл топологий Eve-Ng, которые я использовал для тестирования прохождения трафика в данной статье (это лишь файл топологии, конфигурацию экспортировать нет возможности, т.к. у меня нет pro-версии Eve-Ng, но всегда можно обратиться ко мне напрямую и я поделюсь копипастом конфига. Образы устройств можно найти на просторах необъятного, а также использовать лицензионные образы устройств).
P.S. вся информация представленная здесь используется исключительно в образовательных целях. Все совпадения с реальными объектами, адресами, именами и т.д. случайна и не несёт цели получить от этого выгоду или причинить кому-либо вред.
Back to top ↑
Leave a comment