Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2005.10.23;
Скачать: [xml.tar.bz2];

Вниз

Подсчитать контрольную сумму TCP заголовка   Найти похожие ветки 

 
Leha   (2005-07-01 18:21) [0]

Приветсвую всех!

Трубуется собрать пакет. Собрал.
Но не получается высчитать правильную контрольную сумму заголовка 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 09:33) [1]

2 ошибкм:

1. Для нечетной длины данных надо добавлять в сумму значение
последнего байта, а ты его игнорируешь.

2. Начальное значение суммы для TCP и UDP не равно 0, как
например, для UDP. Оно должно быть равно контрольной сумме
псевдозаголовка.
А уж если ты установил его равным нулю, то должен строить
псевдопакет и подсчитывать его сумму. Читай доки, в общем.


 
Sha ©   (2005-07-03 09:39) [2]

Да, еще одно.

Обычно не пишут цикл while в программе подсчета контрольной
суммы, т.к. переполнение там может возникнуть только два раза.
Достаточно дважды выполнить
Sum := (Sum and $FFFF) + (Sum shr 16);


 
Sha ©   (2005-07-03 09:44) [3]

И еще одно.
Длина TCP заголовка не является константой.


 
Sha ©   (2005-07-03 10:05) [4]

Там у меня опечатка вкралась:

> Начальное значение суммы для TCP и UDP не равно 0, как
> например, для UDP.

Надо читать:

Начальное значение суммы для TCP и UDP не равно 0, как
например, для ICMP.


 
Sha ©   (2005-07-03 10:11) [5]

И еще есть одна опечатка - пропуск слова неинвертированной
в предложении:

Оно должно быть равно неинвертированной контрольной сумме псевдозаголовка.


 
Sha ©   (2005-07-03 10:26) [6]

Совсем сегодня расслабился, выражаюсь так, что хрен поймешь :)

Должно быть понятно, что в предыдущем посте имелось ввиду,
что нет небходимости в операторе Sum := not Sum;
при подсчете суммы псевдозаголовка, т.е. имелась ввиду
как раз инвертированная сумма, которую возвращает
функция Checksum.



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2005.10.23;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.46 MB
Время: 0.035 c
2-1127455271
Гость22
2005-09-23 10:01
2005.10.23
Как узнать, что запущено сторонее приложение?


14-1127416528
Piter
2005-09-22 23:15
2005.10.23
Возможно, кому-то поднимет настроение :)


6-1120196627
Dust
2005-07-01 09:43
2005.10.23
Сколько данных читать из неблокирующего сокета?


14-1128433357
Trigun
2005-10-04 17:42
2005.10.23
Проведение выделенки. Есть ли подводные камни в быстром потоке?


1-1127907595
Knight
2005-09-28 15:39
2005.10.23
Цифровая подпись...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский