![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Подсчитать контрольную сумму TCP заголовка [D6, D7, Win2k, WinXP]
Leha © (2005-07-01 18:21:00)Приветсвую всех!
Трубуется собрать пакет. Собрал.
Но не получается высчитать правильную контрольную сумму заголовка TCP... :( IP считает на правильно.
Все взял сдесь http://ntkernel.com/forum/viewtopic.php?t=114
Описание заголовков:
type
TIPHeaderPtr = ^TIPHeader;
TIPHeader = packed record
VerLen: Byte;
TOS: Byte;
TotalLen: Word;
Identifer: Word;
FragOffsets: Word;
TTL: Byte;
Protocol: Byte;
CheckSum: Word;
SourceIp: DWORD;
DestIp: DWORD;
Options: DWORD;
end;
TTCPHeaderPtr = ^TTCPHeader;
TTCPHeader = packed record
SourcePort:Word;
DestPort:Word;
SequenceNumber:DWord;
AcknowledgementNumber:DWord;
Offset:Byte; //only left 4 bits. Header length in 32-bit segments
Flags:Byte;
Window:Word;
Checksum:Word; //includes speudo header instead of TCP header.
UrgentPointer:Word;
end;
Описание переменных:
pIPHeader : TIPHeaderPtr;
pTCPHeader : TTCPHeaderPtr;
pData: PChar;
Функция для подсчета:
function Checksum(p: PWORD; Size: word): WORD;
var i: Integer;
Sum: DWORD;
begin
Sum := 0;
for i := 0 to Size - 1 do
begin
Sum := Sum + ntohs(p^);
inc(p);
end;
while (Sum shr 16) > 0 do
Sum := (Sum and $FFFF) + (Sum shr 16);
Sum := not Sum;
Result := Sum;
end;
Использую:
PData := Pointer(integer(pTCPHeader) + 20);
// IP считает правильно
pIPHeader.CheckSum := 00;
pIPHeader.CheckSum :=
htons(Checksum(Pword(pIPHeader), 20 div 2));
// TCP неправильно
pTCPHeader.CheckSum := 00;
pTCPHeader.Checksum :=
htons(Checksum(Pword(pTCPHeader), (20 + length(pData)) div 2));
Не подскажите, может функция для TCP не так выглядит?
Заранее благодарен.
С уважением Алексей.
Sha (2005-07-03 10:26:00) [1]Совсем сегодня расслабился, выражаюсь так, что хрен поймешь :)
Должно быть понятно, что в предыдущем посте имелось ввиду,
что нет небходимости в оператореSum := not Sum;
при подсчете суммы псевдозаголовка, т.е. имелась ввиду
как раз инвертированнаясумма, которую возвращает
функция Checksum.
Sha (2005-07-03 10:11:00) [2]И еще есть одна опечатка - пропуск слова неинвертированной
в предложении:
Оно должно быть равно неинвертированнойконтрольной сумме псевдозаголовка.
Sha (2005-07-03 10:05:00) [3]Там у меня опечатка вкралась:
> Начальное значение суммы для TCP и UDP не равно 0, как
> например, для UDP.
Надо читать:
Начальное значение суммы для TCP и UDP не равно 0, как
например, для ICMP.
Sha (2005-07-03 09:44:00) [4]И еще одно.
Длина TCP заголовка не является константой.
Sha (2005-07-03 09:39:00) [5]Да, еще одно.
Обычно не пишут цикл while в программе подсчета контрольной
суммы, т.к. переполнение там может возникнуть только два раза.
Достаточно дважды выполнить
Sum := (Sum and $FFFF) + (Sum shr 16);
Sha (2005-07-03 09:33:00) [6]2 ошибкм:
1. Для нечетной длины данных надо добавлять в сумму значение
последнего байта, а ты его игнорируешь.
2. Начальное значение суммы для TCP и UDP не равно 0, как
например, для UDP. Оно должно быть равно контрольной сумме
псевдозаголовка.
А уж если ты установил его равным нулю, то должен строить
псевдопакет и подсчитывать его сумму. Читай доки, в общем.