RFC: 3022
Оригинал: Traditional IP Network Address Translator (Traditional NAT)
Предыдущие версии: RFC 1631
Категория: Информационный
Дата публикации:
Авторы: ,
Перевод: Николай Малых

4.2. Корректировка контрольной суммы

Преобразования NAT выполняются для каждого пакета и могут приводить к значительным расходам вычислительных ресурсов при необходимости корректировки одной или нескольких контрольных сумм в дополнение к простой замене полей. К счастью существует приведенный ниже алгоритм, делающий корректировку контрольных сумм заголовков IP, TCP, UDP и ICMP очень простой и эффективной. Поскольку все эти заголовки используют арифметику дополнения до 1, достаточно рассчитать разность между адресами до и после трансляции и добавить полученное значение к контрольной сумме. Приведенный ниже алгоритм применим только для случаев четного смещения (т. е., поле optr должно начинаться с четного октета от начала заголовка) и четной длины (т. е., поля olen и nlen должны иметь четные значения). Ниже приведен вариант реализации алгоритма на языке C.

void checksumadjust(unsigned char *chksum, unsigned char *optr,
int olen, unsigned char *nptr, int nlen)

/* Допущения: unsigned char имеет размер 8 битов, long - 32 бита.
  - chksum указывает контрольную сумму пакета
  - optr указывает старые данные в пакете
  - nptr указывает новые данные в пакете
*/
{
  long x, old, new;
  x=chksum[0]*256+chksum[1];
  x=~x & 0xFFFF;
  while (olen)
  {
      old=optr[0]*256+optr[1]; optr+=2;
      x-=old & 0xffff;
      if (x<=0) { x--; x&=0xffff; }
      olen-=2;
  }
  while (nlen)
  {
      new=nptr[0]*256+nptr[1]; nptr+=2;
      x+=new & 0xffff;
      if (x & 0x10000) { x++; x&=0xffff; }
      nlen-=2;
  }
  x=~x & 0xFFFF;
  chksum[0]=x/256; chksum[1]=x & 0xff;
}
2007 - 2017 © Русские переводы RFC, IETF, ISOC.