Перейти к содержанию

Контрольная сумма UDP

В заголовке UDP всего четыре поля, и одно из них — 16-битная контрольная сумма. В IPv4 её разрешено не считать, в IPv6 без неё датаграмму отбросят. Разбираем, что именно суммируется и почему в сумму попадают адреса из заголовка IP.

Обновлено Редакция GAW

Контрольная сумма UDP (UDP checksum) — 16-битное поле в заголовке UDP, по RFC 768 равное дополнению до единицы суммы по дополнению до единицы трёх частей: псевдозаголовка из полей заголовка IP, самого заголовка UDP и данных. Если длина нечётная, в конец на время расчёта добавляется нулевой октет. Процедура та же, что в TCP, и это тот же Internet checksum, что описан в статье о контрольных суммах.

Что входит в сумму

Псевдозаголовок никуда не передаётся: его строят только для расчёта. По RFC 768 для IPv4 он содержит адрес источника, адрес назначения, нулевой байт, номер протокола (17 для UDP) и длину UDP. Благодаря этому сумма защищает не только содержимое, но и адреса: датаграмма, доставленная не тому узлу из-за испорченного заголовка IP, не пройдёт проверку.

ЧастьIPv4 (RFC 768)IPv6 (RFC 8200, разд. 8.1)
Адреса в псевдозаголовке32-битные источника и назначения128-битные источника и назначения
Длина в псевдозаголовкедлина UDPдлина UDP (из заголовка UDP)
Протокол17Next Header = 17
Сумма отсутствуетдопустимо, поле = 0запрещено, приёмник отбрасывает датаграмму
Вычисленная сумма равна 0передаётся 0xFFFFпередаётся 0xFFFF

Нулевая сумма

У кода 0 в этом поле особое значение. В IPv4 нулевое поле означает «отправитель сумму не считал», и приёмник её не проверяет — RFC 768 допускает это для отладки и для протоколов, которым защита не нужна. Чтобы честно вычисленный ноль не спутали с «суммы нет», его передают как 0xFFFF: в арифметике с дополнением до единицы это тот же ноль.

В IPv6 правило строже. По RFC 8200 (разд. 8.1) узел обязан вычислить сумму UDP всегда, заменить нулевой результат на 0xFFFF, а приёмник обязан отбросить датаграмму с нулевым полем и должен бы записать ошибку в журнал. Исключение сделано только для туннелей поверх UDP, которые включают режим нулевой суммы на отдельных портах по правилам RFC 6936. Причина в том, что заголовок IPv6, в отличие от IPv4, не имеет собственной контрольной суммы, и адреса защищены только суммой транспортного уровня. По той же причине ICMPv6 включает псевдозаголовок (с Next Header 58) в свою сумму, а ICMP для IPv4 — нет; подробнее — в термине «ICMP Echo».

На микроконтроллере

Стек TCP/IP на контроллере считает сумму программно над каждой датаграммой; чем больше трафик, тем заметнее эта нагрузка. Модули с аппаратным стеком, описанные в статье «Ethernet для микроконтроллеров», берут расчёт на себя. При собственной реализации протокола поверх UDP не забывайте, что сумма зависит от адресов IP: если устройство подменяет адрес в заголовке, сумму нужно пересчитать. Отличие такой суммы от CRC и способы проверки целостности на прикладном уровне разобраны в статье «Реализация протоколов».

Частые вопросы

Что такое псевдозаголовок UDP и зачем он нужен?

Это блок полей заголовка IP, который мысленно приписывают перед заголовком UDP только на время расчёта суммы, в сеть он не уходит. По RFC 768 он содержит адрес источника, адрес назначения, номер протокола и длину UDP. Так сумма защищает не только данные, но и адреса: датаграмма, доставленная не тому узлу, не пройдёт проверку. В IPv6 (RFC 8200, разд. 8.1) псевдозаголовок строится из 128-битных адресов, длины верхнего уровня и поля Next Header.

Можно ли передать UDP с нулевой контрольной суммой?

В IPv4 — да: по RFC 768 поле из всех нулей означает, что отправитель сумму не считал. Если же сумма вычислена и получилась нулевой, отправитель передаёт все единицы (0xFFFF), чтобы её не приняли за «сумма отсутствует». В IPv6 нулевое поле запрещено: RFC 8200 требует считать сумму всегда, а приёмник обязан отбросить датаграмму с нулём. Единственное исключение — режим нулевой суммы для туннелей по RFC 6936.

Чем контрольная сумма UDP отличается от CRC кадра Ethernet?

Сумма UDP — это дополнение до единицы 16-битных слов, её легко считать на любом процессоре, но она пропускает некоторые ошибки, например перестановку слов. CRC кадра Ethernet — полиномиальный код, который ловит гораздо больше искажений, но проверяется только на одном участке между двумя сетевыми картами. Сумма UDP работает из конца в конец, через все маршрутизаторы, и к тому же покрывает адреса из псевдозаголовка.

Источники

  1. IETF. RFC 768 User Datagram Protocol. J. Postel, 28 August 1980 — разд. Fields: Checksum — 16-битное дополнение до единицы суммы по дополнению до единицы псевдозаголовка из полей IP, заголовка UDP и данных, дополненных нулевыми октетами до чётного числа; псевдозаголовок содержит адрес источника, адрес назначения, протокол и длину UDP и защищает от неверно доставленных датаграмм; процедура та же, что в TCP; если вычисленная сумма равна нулю, передаётся поле из всех единиц; переданное поле из всех нулей означает, что отправитель сумму не считал; разд. Protocol Number: протокол 17
  2. IETF. RFC 8200 Internet Protocol, Version 6 (IPv6) Specification. S. Deering, R. Hinden, July 2017 — разд. 8.1: псевдозаголовок IPv6 для TCP и UDP — 128-битные адреса источника и назначения, Upper-Layer Packet Length, нули, Next Header (6 для TCP, 17 для UDP); для UDP в псевдозаголовке используется длина из заголовка UDP; в отличие от IPv4 сумма UDP в IPv6 обязательна: узел должен вычислить её, а нулевой результат заменить на 0xFFFF; приёмник должен отбросить датаграмму с нулевой суммой и должен бы записать ошибку в журнал; исключение — режим нулевой суммы для туннелей по RFC 6936; ICMPv6 включает псевдозаголовок в свою сумму с Next Header 58, ICMP для IPv4 — нет
Страница помогла?

Нашли ошибку? ·