Назад | Перейти на главную страницу

Фрагментация и размер пакета с использованием tcpdump

я пытаюсь понять концепцию фрагментации:

У меня есть две виртуальные машины с общедоступным IP-адресом, подключенными к коммутатору.

tracepath показывает, что пакет не проходит через шлюз

от vm1: Попытка отправить icmp с 65507 байтами на vm2.

ping -M want -s 65507 vm2 

но в выводе tcpdump на vm2: он показывает

tcpdump -evvv icmp

12:48:44.635551 42:43:30:b4:89:0c (oui Unknown) > b6:7a:6b:7d:54:32 (oui Unknown), ethertype IPv4 (0x0800), length 1514: (tos 0x0, ttl 64, id 10843, offset 1480, flags [+], proto ICMP (1), length 1500)
VM1 > VM2: icmp
12:48:44.635568 42:43:30:b4:89:0c (oui Unknown) > b6:7a:6b:7d:54:32 (oui Unknown), ethertype IPv4 (0x0800), length 1514: (tos 0x0, ttl 64, id 10843, offset 2960, flags [+], proto ICMP (1), length 1500)
VM1 > Vm2: icmp
12:48:44.635572 42:43:30:b4:89:0c (oui Unknown) > b6:7a:6b:7d:54:32 (oui Unknown), ethertype IPv4 (0x0800), length 1514: (tos 0x0, ttl 64, id 10843, offset 4440, flags [+], proto ICMP (1), length 1500)
VM1>VM2 icmp
12:48:44.635575 42:43:30:b4:89:0c (oui Unknown) > b6:7a:6b:7d:54:32 (oui Unknown), ethertype IPv4 (0x0800), length 1514: (tos 0x0, ttl 64, id 10843, offset 5920, flags [+], proto ICMP (1), length 1500)
VM1>VM2: icmp
12:48:44.635578 42:43:30:b4:89:0c (oui Unknown) > b6:7a:6b:7d:54:32 (oui Unknown), ethertype IPv4 (0x0800), length 1514: (tos 0x0, ttl 64, id 10843, offset 7400, flags [+], proto ICMP (1), length 1500)
**Vm1 > VM2**: icmp
12:48:44.635581 42:43:30:b4:89:0c (oui Unknown) > b6:7a:6b:7d:54:32 (oui Unknown), ethertype IPv4 (0x0800), length 1514: (tos 0x0, ttl 64, id 10843, offset 8880, flags [+], proto ICMP (1), length 1500)

Это повторяется 31 раз, пока не будет получен полностью. полная паста: http://pastebin.com/cnQhn8dK

Итак, почему похоже, что все полученные данные 1500 * 31 = 46500 байт и что случилось с 65507-46500 = 19007 байт.

Кто-нибудь, пожалуйста, проясните это.

Просто чтобы добавить Gnouc's ответ.

Вы отправляете 65507 байты данных. Это не включает заголовки ICMP, которые составляют 8 байтов.

Наиболее распространенный размер MTU - 1500 . Этот размер соответствует размеру уровня 3, поэтому вы видите ethertype IPv4 (0x0800), length 1514: это означает, что общий размер кадра составляет 1514 байт. Эти 14 байтов составляют заголовок Ethernet. 12 байтов на MAC-адрес + 2 для типа.

Минимальный и очень распространенный размер IP-заголовка - это его минимальный размер 20 байтов (максимум - 60 байтов).

Итак, у нас есть

1514 bytes - Ethernet header = 1500 bytes
1500 - IP header = 1480 bytes
1480 - ICMP header = 1472 bytes

Вы можете отправить не более 1472 байтов без фрагментации.

НО способ, которым IP фрагментирует пакеты, не требует отправки заголовка для каждого пакета, а только для первого пакета.

С фрагментацией максимальное количество байтов, которое вы можете отправить при MTU, равном 1500, составляет 1480 байтов.

Мы знаем общий размер ваших данных и максимальный размер, который вы можете отправить.

Так что потребуется как минимум 65507 / 1480 ~= 44.2 packets . Т.е. 44 пакета из 1514, а затем последний пакет размером менее половины.

Что случилось с остальными пакетами?

Но почему 31 пакет? Ну, все дело в размере буфера, который вы захватываете. В конце вашего tcpdump вы должны увидеть

31 packets captured 
57 packets received by filter
14 packets dropped by kernel

Если вы добавите захваченные пакеты + пакеты, отброшенные ядром, вы получите правильный ответ, и вот что -s он изменяет длину защелки.

Из руководство по tcpdump

-s Snarf snaplen байтов данных из каждого пакета вместо 65535 байтов по умолчанию. Пакеты, усеченные из-за ограниченного моментального снимка, указываются в выходных данных с помощью «[| proto]», где proto - это имя уровня протокола, на котором произошло усечение. Обратите внимание, что создание снимков большего размера увеличивает время, необходимое для обработки пакетов, и, по сути, уменьшает объем буферизации пакетов. Это может привести к потере пакетов. Вы должны ограничить snaplen наименьшим числом, которое будет захватывать интересующую вас информацию о протоколе. Установка snaplen в 0 устанавливает его по умолчанию 65535, для обратной совместимости с последними более старыми версиями tcpdump.

Почему ядро ​​вообще отбрасывает пакеты?

Снова из справочной страницы tcpdump

пакетов, отброшенных ядром (это количество пакетов, которые были отброшены из-за нехватки буферного пространства механизмом захвата пакетов в ОС, на которой запущен tcpdump, если ОС сообщает эту информацию приложениям; если нет, то будет отображаться как 0).

Да, используя tcpdump с параметром -s, результат правильный. По вашему результату мы насчитываем 45 пакетов. 44 пакета по 1500 байт, 1 пакет 415 байт.

44 * 1500 + 415 = 66415

66415–65507 = 908

908/45 = 20 плюс 8

Как видите, каждый пакет добавляет 20 байт для заголовка ip + 8 байт заголовка icmp для первого пакета.