Вопрос относительно кода ip контрольной суммы
unsigned short /* this function generates header checksums */
csum (unsigned short *buf, int nwords)
{
unsigned long sum;
for (sum = 0; nwords > 0; nwords--) // add words(16bits) together
{
sum += *buf++;
}
sum = (sum >> 16) + (sum & 0xffff); //add carry over
sum += (sum >> 16); //MY question: what exactly does this step do??? add possible left-over
//byte? But hasn't it already been added in the loop (if
//any)?
return ((unsigned short) ~sum);
}
- Я предполагаю nwords в количестве 16-битного слова, а не 8-битного байта (если есть нечетный байт, nword округляется до следующего большого), это правильно? Скажем, у ip_hdr всего 27 байтов, тогда nword будет 14 вместо 13, верно?
- Строка sum = (sum >> 16) + (sum & 0xffff) должна добавить перенос, чтобы сделать 16-битное дополнение
- сумма += (сумма >> 16); Какова цель этого шага? Добавить оставшийся байт? Но оставшийся байт уже был добавлен в цикл?
Спасибо!
1 ответ
Ты прав. Шаг 3 объединяет 32-битную сумму в 16-битную беззнаковую длину, которая является длиной контрольной суммы. Это сделано для повышения производительности, позволяя вычислить контрольную сумму без отслеживания переполнения до конца. Он делает это как на шаге 2, так и на шаге 3, потому что он мог переполниться с шага 2. Затем он возвращает только инвертированные младшие 16 битов суммы.
Это немного понятнее: http://www.sysnet.ucsd.edu/~cfleizac/iptcphdr.html