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; }