Network Working Group T. Mallory Request for Comments: 1141 A. Kullberg Obsoletes: RFC 1071 BBN Communications January 1990
Incremental Updating of the Internet Checksum
Инкрементальное обновление контрольных сумм Internet
Статус документа
В этом документе корректно описана процедура инкрементального обновления для использования со стандартными контрольными суммами Internet. Документ предназначен для замены описания инкрементального обновления (Incremental Update) в RFC 1071. Это не стандарт, а метод реализации. Распространение документа не ограничено.
Описание
На стр. 4 и 5 в RFC 1071 приведено описание метода обновления контрольной суммы IP в заголовке IP без полного расчета контрольной суммы. В частности, рекомендуется использовать приведенное ниже уравнения для расчета обновленной контрольной суммы C’ на основании исходной суммы C и старого и нового значения байта m.
C' = C + (-m) + m' = C + (m' - m)
Хотя приведенное выше уравнение корректно, оно бесполезно для инкрементального обновления, поскольку обновляется контрольная сумма C, а не дополнение контрольной суммы до 1 (~C), которое содержится в поле заголовка. Кроме того, нотация не указывает четко, что вся используемая арифметика, включая унарное изменение знака (unary negation), должна использовать «обратный код» (one’s complement), поэтому его сложно использовать при создании рабочего кода. Полезная для машин с «дополнительным кодом» (2’s complement) форма имеет вид
~C' = ~(C + (-m) + m') = ~C + (m - m') = ~C + m + ~m'
В часто встречающемся случае обновления поля IP TTL вычитание 1 из TTL означает прибавление 1 или 256 в зависимости от поля контрольной суммы в пакете с использованием сложения в обратном коде (one’s complement). Одна из не переносимых реализаций C в формате big-endian имеет вид
unsigned long sum;
ipptr->ttl--; /* уменьшение ttl */
sum = ipptr->Checksum + 0x100; /* увеличение старшего байта контрольной суммы */
ipptr->Checksum = (sum + (sum>>16)) /* добавление переноса */
Этот особый случай можно оптимизировать разными способами. Например, можно связать обновление и проверку ttl, от чего может меняться эффективность компиляции. Ниже представлен более общий и, возможно, более полезный пример обновления ttl на n секунд
UpdateTTL(iph,n) struct ip_hdr *ipptr; unsigned char n; { unsigned long sum; unsigned short old; old = ntohs(*(unsigned short *)&ipptr->ttl); ipptr->ttl -= n; sum = old + (~ntohs(*(unsigned short *)&ipptr->ttl) & 0xffff); sum += ntohs(ipptr->Checksum); sum = (sum & 0xffff) + (sum>>16); ipptr->Checksum = htons(sum + (sum>>16)); }
Вопросы безопасности
Вопросы безопасности не рассматриваются в этом документе.
Адреса авторов
Tracy Mallory
BBN Communications Corporation
50 Moulton Street
Cambridge, MA 02238
Phone: (617) 873-3193
EMail: tmallory@CCV.BBN.COM
A. Kullberg
BBN Communications Corporation
50 Moulton Street
Cambridge, MA 02238
Phone: (617) 873-4000
EMail: akullberg@BBN.COM
Перевод на русский язык
Николай Малых