Расчет контрольных сумм для IP и TCP

Delphist 28.05.2004 - 02:58 | Что-то не понимаю с контрольными суммами. Конкретно: Есть программа-сниффер (отсюда, с RSDN). Нюхает все замечательно. Пытаюсь разобраться как самому считать контрольную сумму, проверяя полученный пакет и расчитывая сумму самостоятельно. Нашел функцию для расчета суммы: WORD net_checksum( void *data, size_t len) { DWORD sum = 0; WORD *dp = (WORD *) data; WORD sum_s; size_t words = len >> 1; while( words -- ) sum += *dp ++; if( len & 1 ) sum += *(char *) dp; sum = (WORD) sum + (sum >> 16) & 0xffff; sum_s = (WORD) sum + (WORD)(sum >> 16); return sum_s != 0xffff ? ~sum_s : sum_s; } Считаю для IP-заголовка - все ОК. Для TCP - проблемы. Как считаю: typedef struct _IPHeader { unsigned char verlen; // версия и длина заголовка unsigned char tos; // тип сервиса unsigned char length[2]; // длина всего пакета unsigned short id; // Id unsigned short offset; // флаги и смещения unsigned char ttl; // время жизни unsigned char protocol; // протокол unsigned short xsum; // контрольная сумма unsigned char src[4]; // IP-адрес отправителя unsigned char dest[4]; // IP-адрес назначения } IPHeader; typedef struct _TCPHeader { BYTE SrcPort[2]; BYTE DestPort[2]; BYTE Seq[4]; BYTE Ack[4]; BYTE DataOffset; BYTE Flags; BYTE Window[2]; BYTE xSum[2]; BYTE Urgent[2]; } TCPHeader; Собственно расчет: IPHeader* hdr = (IPHeader*) &Buffer; iIpHeaderSize = (hdr->verlen & 0xF) << 2; TCPHeader* tcp = (TCPHeader*) &Buffer[iIpHeaderSize]; iTcpHeaderSize = (tcp->DataOffset >> 2); szTcpData = &Buffer[iIpHeaderSize + iTcpHeaderSize]; WORD OldSum = hdr->xsum; hdr->xsum = 0; //зануляем старую сумму, чтобы не мешала hdr->xsum = net_checksum(&Buffer, iIpHeaderSize); // тут все в порядке, OldSum == hdr->xsum OldSum = MAKEWORD(tcp->xSum[1], tcp->xSum[0]); tcp->xSum[0] = 0; tcp->xSum[1] = 0; WORD TcpLength = MAKEWORD(hdr->length[1], hdr->length[0]); // зануляем старую сумму, чтобы не мешала // формируем псевдозаголовок перед TCP-заголовком Buffer[iIpHeaderSize - 12] = hdr->src[0]; Buffer[iIpHeaderSize - 11] = hdr->src[1]; Buffer[iIpHeaderSize - 10] = hdr->src[2]; Buffer[iIpHeaderSize - 9] = hdr->src[3]; Buffer[iIpHeaderSize - 8] = hdr->dest[0]; Buffer[iIpHeaderSize - 7] = hdr->dest[1]; Buffer[iIpHeaderSize - 6] = hdr->dest[2]; Buffer[iIpHeaderSize - 5] = hdr->dest[3]; Buffer[iIpHeaderSize - 4] = 0; Buffer[iIpHeaderSize - 3] = hdr->protocol; Buffer[iIpHeaderSize - 2] = hdr->length[0]; Buffer[iIpHeaderSize - 1] = hdr->length[1]; WORD NewSum = net_checksum(&Buffer[iIpHeaderSize - 12], TcpLength - iIpHeaderSize + 12); // а вот тут результат абсолютно никакой В чем лыжи, кто знает? P.S. Buffer - это массив char (не указатель), содержащий все байты IP-заголовка, TCP-заголовка и TCP-данных

>>