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

Вниз

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

 
SPACE   (2005-08-01 22:45) [0]

Народ помогите подсчитать контрольную сумму TCP-заголовка
вот захваченный SYN-пакет :
                        TCP - заголовок
                              \|/
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

[0]___________[7]_____________[15|_______________________________
Src Port :  2886                | Dst Port : 80
-----------------------------------------------------------------
                Sequence Number : 35214831
-----------------------------------------------------------------
                    ASK Number  : 0
-----------------------------------------------------------------
Off_Rsvd: 0x70 | Rsvd_Flag : 2  |  Window  : 8192
-----------------------------------------------------------------
CheckSum  : 0xAC96              | Urgent Pointer : 0
-----------------------------------------------------------------

Заметьте что все значение WORD и DWORD уже инвертированы.
     

                       Псевдо - заголовок
                              \|/
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

             +--------+--------+--------+--------+              
             |       SrcIP : 62.183.70.31        |
             +--------+--------+--------+--------+
             |       DstIp : 217.73.250.40       |
             +--------+--------+--------+--------+              
             |  нули  |   6    |       20        |
             +--------+--------+--------+--------+


 
Sha ©   (2005-08-02 00:38) [1]

Арифметику забыл? В чем проблема-то?


 
SPACE   (2005-08-02 10:40) [2]

Да наверное забыл :)
Sha не впадлу подсчитай чексумму этого пакета и покажи как считал, а то у меня чего-то не получается.


 
SPACE   (2005-08-02 10:48) [3]

Эх Sorry на самом деле Sequence Number : 35214381. Видно у вас веб сервер глючит :)
Вопрос не отменял.


 
tesseract ©   (2005-08-02 11:49) [4]

В обратном коде  просуммировать все слова(16 бит) данных. если количество байт нечётное - добавляются нулевые байты( не передаются а только для CRC). И имей ввиду при расчёте CRC Дополнительно рассчитывается псевдозаголовок (12 байт)- IP приёмника + IP источника + 8 нулевых бит  + протокол (8 бит) + Длина TCP 16 бит.


 
SPACE   (2005-08-02 14:57) [5]

to tesseract
Ну тыб сразуб ссылку киндал на RFC 1071 корочеб вышло,
меня интересует ваш результат расчета относительнно вышеупомянутых данных
Вот мой расчет :

2886+80+537+21999+28674+8192 = 0xF3A0//Сумма TCP

16055+17951+55625+64040+1556 = 0x25E5B // Сумма Псевдо-аголовка.
Длину TCP я указал = 20 так-как поле опций и поле данных пусты.

F3A0+25E5B =0x351FB // Общая сумма

51FB+3 = 51FE // Складываем лишний байт с Словом.
FFFF - 51FE = 0xAE01// Дополнение до FFFF.

0xAE01 Это не есть 0xAC96.


 
SPACE   (2005-08-02 15:47) [6]

Ээ sorry небольшая ошибочка в подсчете TCP пакета :

2886+80+537+21549+28674+8192 = 0xF1DE//Сумма TCP

F3A0+25E5B =0x35039 // Общая сумма

5039+3 = 503C // Складываем лишний байт с Словом.

FFFF - 503C = 0xAFC3// Дополнение до FFFF.

Может алгоритм неправильный ?


 
Sha ©   (2005-08-02 16:45) [7]

Тебе в пору присуждать приз за волю к победе. Держи и не мучайся:

//(c) Sha 2004
//CheckSum function calculates the 16-bit one"s complement sum
//for the supplied buffer. Initial value of sum may be non-zero.
function CheckSum(pBuf: pointer; Size: integer; Initial: cardinal= 0): word;
var
 p, q: pchar;
begin;
 if (pBuf<>nil) and (Size>0) then begin;
   q:=@pchar(pBuf)[Size-1];
   p:=pBuf;
   while p<q do begin;
     inc(Initial,pword(p)^);
     inc(pword(p));
     end;
   if p=q then inc(Initial,pbyte(p)^);
   end;
 Initial:=(Initial shr 16) + (Initial and $FFFF);
 Initial:=(Initial shr 16) + Initial;
 Initial:=(not Initial) and $FFFF;
 Result:=Initial;
 end;

Пример вычисления суммы TCP-заголовка:

 //Calculate the TCP checksum including the TCP pseudo-header,
 //TCP header itself and data (padded with a 0 if the data is odd length).
 //The pseudo-header consists of the 32-bit source IP address,
 //the 32-bit destination IP address, a zero byte, the 8-bit
 //IP protocol field, the 16-bit TCP length.
 with pIp^, pTcp^ do
 tcp_checksum:=checksum(pTcp, TcpTotalSize,
     //Summing pseudo-header
     ip_srcaddr shr 16 + ip_srcaddr and $FFFF
   + ip_dstaddr shr 16 + ip_dstaddr and $FFFF
   + ip_protocol shl 8 + Sha_htons(TcpTotalSize));


 
SPACE   (2005-08-02 18:42) [8]

Нифига не работает. Я смотрю никто этим не занимался вот код
которы я намуливал за 20 минут. Чек-сумма  неверна.
Алгоритм стандартный  я его в интенете повсюду видел ну или подобный. Внизу в закоментированом состоянии выложен еще один
алгоритм он более изящен и понятен,но помоему неправилен так-как
у автора кода была такая-же проблема как у меня. Да и сумму он
выдает отличающеся от алгоритма Sha.

В коде применяется функция htons и htonl которая находится в модуле winsock,winsock2. Вместо htons можете использовать функцию SWAP :

Function SWAP(word) //меняет байты местами
Кстате Sha а что это у тебя за  функция Sha_htons() ? :)


 
SPACE   (2005-08-02 18:42) [9]



unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs,pcap, StdCtrls,winsock2;
  const
 SNOOP_DEFAULT_SNAPLEN = 1600;
 SNOOP_MAC_SIZE = 6;

type
 TPcap = pcap_t;
 PPcap = ppcap_t;
 PCAP_PKTHDR = Pcap.pcap_pkthdr;
 PPCAP_PKTHDR = ^PCAP_PKTHDR;
 PPPCAP_PKTHDR = ^PPCAP_PKTHDR;

// ----------------------------------------------------------------------------
// Ethernet Header
// ----------------------------------------------------------------------------
const
 PROTO_IP      =          $0800;
 PROTO_ARP     =          $0806;
 PROTO_XNS     =          $0600;
 PROTO_SNMP    =          $814C;
 PROTO_OLD_IPX =          $8137;
 PROTO_NOVELL  =          $8138;
 PROTO_IPNG    =          $86DD;

type
 SNOOPMACADDRESS = array[0 .. SNOOP_MAC_SIZE - 1] of UCHAR;
 PSNOOPMACADDRESS = ^SNOOPMACADDRESS;
 PPChar = ^PChar;
type
 ETHERNET_HDR = packed record
Destination:             SNOOPMACADDRESS;
Source:                  SNOOPMACADDRESS;
Protocol:                WORD;
 end;
 PETHERNET_HDR = ^ETHERNET_HDR;

// ----------------------------------------------------------------------------
// IP Header
// ----------------------------------------------------------------------------
const
 PROTO_ICMP = 1;
 PROTO_TCP = 6;
 PROTO_UDP = 17;

type
 ip_addres = record
 byte1,  byte2,  byte3,  byte4 : byte;
 end;
type
 Psevdo_HDR = packed record
Source:                 ip_addres;
Destination:            ip_addres;
 Zero  :                 byte;
Protocol:               byte;
 TcpLength :             WORD;
 end;

 IP_HDR = packed record
VerLen:                  UCHAR;
Service:                 UCHAR;
Length:                  WORD;
Ident:                   WORD;
FlagOff:                 WORD;
TimeLive:                UCHAR;
Protocol:                UCHAR;
Checksum:                WORD;
Source:                  ip_addres;
Destination:             ip_addres;
 end;
 PIP_HDR = ^IP_HDR;
 PPIP_HDR = ^PIP_HDR;

// ----------------------------------------------------------------------------
// ARP Header
// ----------------------------------------------------------------------------
const
 ARP_REQUEST = $0001;
 ARP_REPLY = $0002;

type
 ARP_HDR = packed record
HardwareType:            WORD;
ProtocolType:            WORD;
HLen:                    UCHAR;
PLen:                    UCHAR;
Operation:               WORD;
SenderHA:                SNOOPMACADDRESS;
SenderIP:                DWORD;
TargetHA:                SNOOPMACADDRESS;
TargetIP:                DWORD;
 end;
 PARP_HDR = ^ARP_HDR;
 PPARP_HDR = ^PARP_HDR;

// ----------------------------------------------------------------------------
// ICMP Header
// ----------------------------------------------------------------------------
type
 ICMP_HDR = packed record
VerPrio:                 UCHAR;
FlowLabel:               array[0..2] of UCHAR;
Length:                  WORD;
NextHadr:                UCHAR;
HopLimit:                UCHAR;
Source:                  array[0..15] of UCHAR;
Destination:             array[0..15] of UCHAR;
 end;
 PICMP_HDR = ^ICMP_HDR;
 PPICMP_HDR = ^PICMP_HDR;

// ----------------------------------------------------------------------------
// TCP Header
// ----------------------------------------------------------------------------
const
 TCP_FLAG_FIN =          $01;
 TCP_FLAG_SYN =          $02;
 TCP_FLAG_RST =          $04;
 TCP_FLAG_PSH =          $08;
 TCP_FLAG_ACK =          $10;
 TCP_FLAG_URG =          $20;

type
 TCP_HDR = packed record
Source:                  WORD;
Destination:             WORD;
Seq:                     DWORD;
Ack:                     DWORD;
Off_Rsvd:                UCHAR;
Rsvd_Flags:              UCHAR;
Window:                  WORD;
Checksum:                WORD;
UrgPoint:                WORD;
 end;
 PTCP_HDR = ^TCP_HDR;
 PPTCP_HDR = ^PTCP_HDR;

// ----------------------------------------------------------------------------
// UDP Header
// ----------------------------------------------------------------------------
type
 UDP_HDR = packed record
Source:                  WORD;
Destination:             WORD;
Length:                  WORD;
Checksum:                WORD;
 end;
 PUDP_HDR = ^UDP_HDR;
 PPUDP_HDR = ^PUDP_HDR;

type
 TForm1 = class(TForm)
   Edit1: TEdit;
   procedure FormCreate(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;
//function CheckSum(Var Buffer; Size : integer) : Word;
function CheckSum(pBuf: pointer; Size: integer; Initial: cardinal= 0): word;
var
 Form1: TForm1;
 buf : array [0..31] of char;
 ptr : pointer;
implementation

{$R *.dfm}
procedure IncPtr(Value : Integer);
 begin
   ptr := pointer(integer(ptr) + Value);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
tcpHdr : TCP_HDR;
psehdr : Psevdo_HDR;
begin
psehdr.Source.byte1 :=62;
psehdr.Source.byte2 :=183;
psehdr.Source.byte3 :=70;
psehdr.Source.byte4 :=31;
psehdr.Destination.byte1 :=217;
psehdr.Destination.byte2 :=73;
psehdr.Destination.byte3 :=250;
psehdr.Destination.byte4 :=40;
psehdr.Zero := 00;
psehdr.Protocol := 6;
psehdr.TcpLength := htons(sizeof(tcpHdr));

tcphdr.Source :=  htons(2886);
tcphdr.Destination := htons(80);
tcphdr.Seq := htonl(35214381) ;
tcphdr.Ack := 0;
tcphdr.Off_Rsvd := $70;
tcphdr.Rsvd_Flags :=2;
tcpHdr.Window := htons(8192);
tcpHdr.Checksum := 0;
tcpHdr.UrgPoint := 0;

FillChar(Buf, SizeOf(Buf), 0);
Ptr := @Buf[0];
Move(psehdr, ptr^, sizeof(psehdr));
IncPtr(sizeof(psehdr));
Move(tcpHdr, ptr^, sizeof(tcphdr));
IncPtr(sizeof(tcphdr));

edit1.Text := IntToStr(checksum(@buf[0],sizeof(tcphdr) + sizeof(psehdr)));

end;

function CheckSum(pBuf: pointer; Size: integer; Initial: cardinal= 0): word;
var
p, q: pchar;
begin;
if (pBuf<>nil) and (Size>0) then begin;
  q:=@pchar(pBuf)[Size-1];
  p:=pBuf;
  while p<q do begin;
    inc(Initial,pword(p)^);
    inc(pword(p));
    end;
  if p=q then inc(Initial,pbyte(p)^);
  end;
Initial:=(Initial shr 16) + (Initial and $FFFF);
Initial:=(Initial shr 16) + Initial;
Initial:=(not Initial) and $FFFF;
Result:=Initial;
end;

{function CheckSum(Var Buffer; Size : integer) : Word;
type
 TWordArray = Array[0..1] of Word;
var
 ChkSum : LongWord;
 i      : Integer;
begin
 ChkSum := 0;
 i := 0;
 While Size > 1 do begin
   ChkSum := ChkSum + TWordArray(Buffer)[i];
   inc(i);
   Size := Size - SizeOf(Word);
 end;

 if Size=1 then ChkSum := ChkSum + Byte(TWordArray(Buffer)[i]);

 ChkSum := (ChkSum shr 16) + (ChkSum and $FFFF);
 ChkSum := ChkSum + (Chksum shr 16);

 Result := Word(ChkSum);
end;}

end.


 
Sha ©   (2005-08-02 20:52) [10]

> SPACE   (02.08.05 18:42) [8]
> Нифига не работает. Я смотрю никто этим не занимался вот код
> которы я намуливал за 20 минут. Чек-сумма  неверна.

Значит, сделал что-то не так. Сам виноват.

> Алгоритм стандартный  я его в интенете повсюду видел ну или
> подобный. Внизу в закоментированом состоянии выложен еще один
> алгоритм он более изящен и понятен,но помоему неправилен так-как
> у автора кода была такая-же проблема как у меня.

Ну, таких намуливателей в инете много :)
Надо в RFC смотреть, а не помойкам рыться.

> Да и сумму он выдает отличающеся от алгоритма Sha.

Значит, в нем ошибка.

> Кстате Sha а что это у тебя за  функция Sha_htons() ? :)

//Fast version htons
function Sha_htons(Value: cardinal): cardinal;
asm
 and eax,$FFFF
 xchg al,ah
 end;

//Fast version ntohs
function Sha_ntohs(Value: cardinal): cardinal;
asm
 and eax,$FFFF
 xchg al,ah
 end;

//Fast version htonl
function Sha_htonl(Value: cardinal): cardinal;
asm
 bswap eax
 end;

//Fast version ntohl
function Sha_ntohl(Value: cardinal): cardinal;
asm
 bswap eax
 end;


 
SPACE   (2005-08-02 23:18) [11]

>Надо в RFC смотреть, а не помойкам рыться

Помойки потому что разъясняют хреново. Много слов мало действий.

Цита из одной статьи :
http://ava.org.ua/topics/printable/?read=155

С контрольной суммой в сетях TCP/IP имеется некоторая путаница.
Алгоритм ее подсчета, претендующий быть определением, изложен в RFC про IP. Если написать программу по этому алгоритму - она будет  считать все, что угодно, но не ту контрольную сумму, которую считают Ваши соседи на сети.
Есть даже отдельный RFC про контрольную сумму, RFC1071, но вопрос
все равно остается мутным.

Блин Sha я уже задолбался с этой контрольной суммой , ты я смотрю Пакетики та подделовал :) Удели часок поклоцай по калькулятору ...


 
Sha ©   (2005-08-02 23:35) [12]

> SPACE   (02.08.05 23:18) [11]
> Удели часок поклоцай по калькулятору.

Не царское это дело :)
Чем тебе функция [7] не нравится?
Хочешь найти ошибку у себя - ищи отличия своего алгоритма от [7].


 
SPACE   (2005-08-03 01:58) [13]

>Чем тебе функция [7] не нравится?
>Хочешь найти ошибку у себя - ищи отличия своего алгоритма от [7]
Sha ты мне квесты тут не устраивай давай выкладывай ... :)


 
DVladimir   (2005-08-03 04:49) [14]

Проще реальный алгоритм взять из реально работающих программ.
Как пример - программа ping.
Вот функция, вычисляющая контрольную сумму IPv4 (точно такой же алгоритм и для ICMPv4, IGMPv4, ICMPv6, UDP применяется).

Приношу свои извинения что на Сях и с оригинальными комментариями. Но, надеюсь, поможет.

u_short in_cksum(addr, len)
       u_short *addr;
       int len;
{
       int nleft, sum;
       u_short *w;
       union {
               u_short us;
               u_char  uc[2];
       } last;
       u_short answer;

       nleft = len;
       sum = 0;
       w = addr;

       /*
        * Our algorithm is simple, using a 32 bit accumulator (sum), we add
        * sequential 16 bit words to it, and at the end, fold back all the
        * carry bits from the top 16 bits into the lower 16 bits.
        */
       while (nleft > 1)  {
               sum += *w++;
               nleft -= 2;
       }

       /* mop up an odd byte, if necessary */
       if (nleft == 1) {
               last.uc[0] = *(u_char *)w;
               last.uc[1] = 0;
               sum += last.us;
       }

       /* add back carry outs from top 16 bits to low 16 bits */
       sum = (sum >> 16) + (sum & 0xffff);     /* add hi 16 to low 16 */
       sum += (sum >> 16);                     /* add carry */
       answer = ~sum;                          /* truncate to 16 bits */
       return(answer);
}

Если нужны более производительные алгоритмы - есть книга  Стивенсона и Райта "TCP/IP Illustrated. Vol. 2 - The Implementation", 1995 г.


 
Sha ©   (2005-08-03 08:50) [15]

> SPACE   (03.08.05 01:58) [13]
> Sha ты мне квесты тут не устраивай давай выкладывай ... :)

Все уже выложено.

> DVladimir   (03.08.05 04:49) [14]
> Проще реальный алгоритм взять из реально работающих программ.

Ну, я так и сделал :)

> Как пример - программа ping.
> Вот функция, вычисляющая контрольную сумму IPv4
> (точно такой же алгоритм и для ICMPv4, IGMPv4, ICMPv6, UDP применяется).

Например, для UDP (также как и для TCP) - не точно такой :)
а такой:

 with pIp^, pUdp^ do
 udp_checksum:=checksum(pUdp, UdpTotalSize,
     //Summing pseudo-header
     ip_srcaddr shr 16 + ip_srcaddr and $FFFF
   + ip_dstaddr shr 16 + ip_dstaddr and $FFFF
   + ip_protocol shl 8 + udp_total);

хотя, конечно:
 
pIcmp.icmp_checksum:=checksum(pIcmp, IcmpTotalSize, 0);


 
Verg ©   (2005-08-03 09:26) [16]

А при чем тут КС заголовка?

Checksum (контрольная сумма)  16 бит
  Поле контрольной суммы - это 16-битное дополненение суммы всех 16-
  битных слов заголовка и текста.
Если сегмент содержит в заголовке
  и тексте нечетное количество октетов, подлежащих учету в контоль-
  ной сумме, последний октет будет дополнен нулями справа с тем,
  чтобы образовать для предоставления контрольной сумме 16-битное
  слово. Возникший при таком выравнивании октет не передается вместе
  с сегментом по сети. Перед вычислением контрольной суммы поле этой
  суммы заполняется нулями.
     Контрольная сумма, помимо всего прочего, учитывает 96 бит псев-
  дозаголовка, который для внутреннего употребления ставится перед
  TCP заголовком. Этот псевдозаголовок содержит адрес отправителя,
  адрес получателя, протокол и длину TCP сегмента. Такой подход
  обеспечивает защиту протокола TCP от ошибшихся в маршруте сегмен-
  тов. Эту информацию обрабатывает Internet протокол. Она передается
  через интерфейс протокол TCP/локальная сеть в качестве аргументов
  или результатов запросов от протокола TCP к протоколу IP.
                 +--------+--------+--------+--------+              
                 |         Адрес отправителя         |
                 +--------+--------+--------+--------+
                 |         Адрес получателя          |
                 +--------+--------+--------+--------+              
                 |  нули  |  PTCL  |    длина TCP    |
                 +--------+--------+--------+--------+              
     Длина TCP сегмента - это длина TCP заголовка и поля данных, из-
  меренная в октетах. Это не является точным указанием количества
  передаваемых по сети октетов, она не учитывает 12 октетов псевдо-
  заголовка, но тем не менее расчет этого параметра все же произво-
  дится.


 
wal ©   (2005-08-03 10:17) [17]


> [10] Sha ©   (02.08.05 20:52)
Вопрос не по теме. Какой глубокий смысл в команде and eax,$FFFF, и зачем на входе-выходе тип Cardinal в htons (и наоборот)?

C уважением.


 
Sha ©   (2005-08-03 11:18) [18]

> wal ©   (03.08.05 10:17) [17]
> Какой глубокий смысл в команде and eax,$FFFF,
> и зачем на входе-выходе тип Cardinal в htons (и наоборот)?

Понятно, что на скорость полета пули ни то, ни другое не влияет.

В целом, так сделано:
- для единообразия исходников,
- для единообразия поведения при любом компиляторе,
- потому, что сам люблю приводить типы,
- для удобства отладки.


 
Sha ©   (2005-08-03 11:50) [19]

> wal ©   (03.08.05 10:17) [17]

Сравни:

function Sha_htons(Value: cardinal): cardinal;
asm
 and eax,$FFFF
 xchg al,ah
 end;

function Sha_htons2(Value: word): word;
asm
 xchg al,ah
 end;

procedure TForm1.Button1Click(Sender: TObject);
var
 i, Port, Port2: integer;
begin
 i:=$44332211;
 Port:=Sha_htons(i);
 Port2:=Sha_htons2(i);
 ShowMessage(Format("%8x %8x",[Port,Port2]));
end;

Видно, что если сделать иначе, то после каждого вызова htons
компилятор вынужден вставлять movzx eax,ax

00457760 8BC3             mov eax,ebx
00457762 E8CDFFFFFF       call Sha_htons

00457769 8BC3             mov eax,ebx
0045776B E8CCFFFFFF       call Sha_htons2
00457770 0FB7C0           movzx eax,ax


 
Sha ©   (2005-08-03 12:26) [20]

> wal ©   (03.08.05 10:17) [17]

Спасибо за вопрос.
В принципе, надо бы и объявление CheckSum изменить на

function CheckSum(pBuf: pointer; Size: integer; Initial: cardinal= 0): cardinal;

Ведь в коде уже есть приведение к word"у.


 
SPACE   (2005-08-03 18:01) [21]

Я поправил второй алгоритм теперь он считает также как и алгоритм Sha, проверял на подсчете Check-суммы IP заголовка работает но там у меня и на калькуляторе все сходилась. TCP-ж сумма не сходится не на калькуляторе не с помощью этих алгоритмов.  

function CheckSum(Var Buffer; Size : integer) : Word;
type
 TWordArray = Array[0..1] of Word;
var
 ChkSum : LongWord;
 i      : Integer;
 w : word;
begin
 ChkSum := 0;
 i := 0;
 While Size > 1 do begin
   W := TWordArray(Buffer)[i];
   ChkSum := ChkSum + W;
   inc(i);
   Size := Size - SizeOf(Word);
 end;

 if Size=1 then ChkSum := ChkSum + Byte(TWordArray(Buffer)[i]);

 ChkSum := (ChkSum shr 16) + (ChkSum and $FFFF);
 ChkSum := ChkSum + (Chksum shr 16);
 ChkSum:=(not ChkSum) and $FFFF;
 Result := Word(ChkSum);
end;

Интересно еще и то что у меня некак не получается отправить
SYN запрос. Тоесть я перехвачеваю пакет делаю копию этого
пакета, включаю снифер проверяю все значение верны ошибок
точно нет, но никаких ответов на мой запрос не приходит.
Пробовал также менять предоставленное мне снифером значение Check-суммы TCP на результат вышеупомянутого алгоритма - глухо.
Кстате если Check-сумма  не верна каковы действия
хоста ? Пакет просто отбрасывается ?


 
Sha ©   (2005-08-03 23:02) [22]

> SPACE   (03.08.05 18:01) [21]
> Я поправил второй алгоритм теперь он считает также как и
> алгоритм Sha, проверял на подсчете Check-суммы IP заголовка
> работает но там у меня и на калькуляторе все сходилась.

Ну вот. Можешь, если хочешь.
Кстати, последнюю строчку можно заменить на Result := (ChkSum);
Осталось сделать еще один шаг, чтобы не требовалось формировать
в памяти псевдозаголовок. Попробуй сделать нечто подобное моей функции.

> TCP-ж сумма не сходится не на калькуляторе не с помощью этих
> алгоритмов.

У меня все сходится. Выкладывай свой код.
Если успею, посмотрю. Завтра в 9 поезд.

> Интересно еще и то что у меня некак не получается отправить
SYN запрос.

Жаль, что и там у тебя ошибка.

> Кстате если Check-сумма  не верна каковы действия
хоста ?
> Пакет просто отбрасывается ?

А что ты сам обычно делаешь с кривыми данными?


 
SPACE   (2005-08-04 01:51) [23]

>Жаль, что и там у тебя ошибка

Ну-ну все ошибки которые я допускал находились мной довольно быстро здесь же какойто бред.

Значение ident ip заголовка может быть любым ?


Народ есть ли у кого код посылающий SYN пакет желательно
на Дельфях.
 
>У меня все сходится. Выкладывай свой код
Вот мой код отправляющий SYN пакет :
Он использует библиотеку WINPCAP.
Константы и объявление структур смотрите выше.
Единственное изменена структура ETHERNET заголовка :

type
 mac_addres = packed record
 byte1,  byte2,  byte3,  byte4, byte5, byte6 : byte;
 end;
type
 ETHERNET_HDR = packed record
Destination:             mac_addres;
Source:                  mac_addres;
Protocol:                WORD;
 end;


 
SPACE   (2005-08-04 01:52) [24]

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  Dialogs,pcap,winsock, StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Edit1: TEdit;
   procedure FormCreate(Sender: TObject);
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;
 hDevice : ppcap_t;
 buf : array [0..575] of char;
 ptr : pointer;

procedure IncPtr(Value : Integer);
function CheckSum(Var Buffer; Size : integer) : Word;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
pErorr,p : pchar;
begin
// Если у вас сетевая карта то здесь надо править.
p := pchar("PPPMAC");

hDevice := pcap_open_live(p,576,1,20,pErorr);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
etherhdr : ETHERNET_HDR;
iphdr : IP_HDR;
tcpHdr : TCP_HDR;
psehdr : Psevdo_HDR;
begin
//Это пакет был мной перехвачен и скопирован.

                {Ethernet Заголовок}

etherhdr.Destination.byte1 :=32;
etherhdr.Destination.byte2 :=83;
etherhdr.Destination.byte3 :=82;
etherhdr.Destination.byte4 :=67;
etherhdr.Destination.byte5 :=0;
etherhdr.Destination.byte6 :=0;
etherhdr.Source.byte1 :=68;
etherhdr.Source.byte2 :=69;
etherhdr.Source.byte3 :=83;
etherhdr.Source.byte4 :=84;
etherhdr.Source.byte5 :=0;
etherhdr.Source.byte6 :=0;
etherhdr.Protocol := 8;

                      {iphdr}
iphdr.VerLen := 69;
iphdr.Service := 0;
iphdr.Length := 12288;
iphdr.Ident :=  167;
iphdr.FlagOff := 0;
iphdr.TimeLive := 64;
iphdr.Protocol  := 6;
iphdr.Checksum := 0;
iphdr.Source.byte1 := 192;
iphdr.Source.byte2 := 168;
iphdr.Source.byte3 := 1;
iphdr.Source.byte4 := 1;
iphdr.Destination.byte1 := 81;
iphdr.Destination.byte2 := 201;
iphdr.Destination.byte3  := 66;
iphdr.Destination.byte4  := 7;

FillChar(Buf, SizeOf(Buf), 0);
Ptr := @Buf[0];
Move(ipHDr, ptr^, sizeof(ipHDr));
iphdr.Checksum := checksum(buf,sizeof(iphdr));

                    {tcphdr+psehdr}
psehdr.Source.byte1 :=192;
psehdr.Source.byte2 :=168;
psehdr.Source.byte3 :=1;
psehdr.Source.byte4 :=1;
psehdr.Destination.byte1 :=81;
psehdr.Destination.byte2 :=201;
psehdr.Destination.byte3 :=66;
psehdr.Destination.byte4 :=7;
psehdr.Zero := 0;
psehdr.Protocol := 6;
psehdr.TcpLength := htons(sizeof(tcpHdr));

tcphdr.Source :=  htons(1077);
tcphdr.Destination := htons(80);
tcphdr.Seq := htonl(15889439) ;
tcphdr.Ack := 0;
tcphdr.Off_Rsvd := $70;
tcphdr.Rsvd_Flags :=2;
tcpHdr.Window := htons(8192);
tcpHdr.Checksum := 0;
tcpHdr.UrgPoint := 0;

// Высчитываем Чек-сумму TCP, а вопще в снифере было так $97ab.

FillChar(Buf, SizeOf(Buf), 0);
Ptr := @Buf[0];
Move(tcpHdr, ptr^, sizeof(tcphdr));
IncPtr(sizeof(tcphdr));
Move(psehdr, ptr^, sizeof(psehdr));
tcpHdr.Checksum :=checksum(buf,sizeof(tcphdr)+sizeof(psehdr));

//собираем все воединно в переменую Buf.

FillChar(Buf, SizeOf(Buf), 0);
Ptr := @Buf[0];
Move(etherhdr, ptr^, sizeof(etherhdr));
IncPtr(sizeof(etherhdr));
Move(ipHDr, ptr^, sizeof(ipHDr));
IncPtr(sizeof(ipHDr));
Move(tcpHdr, ptr^, sizeof(tcphdr));
IncPtr(sizeof(tcphdr));

//Отправка пакета с помощью WINPCAP функции pcap_sendpacket(Открытая сесия; Буфер; Размер отправляемых данных).

pcap_sendpacket(hDevice,buf,sizeof(tcphdr)+sizeof(ipHDr)+sizeof(etherhdr));
end;

procedure IncPtr(Value : Integer);
 begin
   ptr := pointer(integer(ptr) + Value);
end;


 
SPACE   (2005-08-04 01:54) [25]

Что здесь неправилино ?


 
Sha ©   (2005-08-04 06:19) [26]

> SPACE   (04.08.05 01:51) [23]
> Ну-ну все ошибки которые я допускал находились мной довольно быстро здесь же какойто бред.

Это точно.

> Значение ident ip заголовка может быть любым?

При отсылке через PCap - любое,
через сырые сокеты - не 0, иначе БГ егл заполнит и пересчитат КС.

> Народ есть ли у кого код посылающий SYN пакет желательно
на Дельфях.

Зачем? Мы привыкли по помойкам, так интереснее :)
Ты уже где-то нарыл код, но это не помогло. Сам.

Не забудь подсчитать КС IP-заголовка,
но сначала разбермсь с этим бредом:
tcphdr.Off_Rsvd := $70;

Успехов, и никому не вреди. Пока.


 
SPACE   (2005-08-13 02:47) [27]

Решил я поднять это тему так-как я решил эту проблему...

>но сначала разбермсь с этим бредом:
>tcphdr.Off_Rsvd := $70;

Значение $70 здесь верное яж говорил что все значение взяты из перехваченого пакета и говорит оно о том что в пакете tcp 7
32-битных сегментов, а это значит что в TCP заголовке присутсвует
поля Опций которое начинатся с 6 сегмента именно это я и неучел.
Снифер которым я пользовался не показывал поля Опций в пакете да
и я чего-то решил что поля Опций в Syn пакете должно отсутсвовать.

Хочу также всем посоветовать вот этот снифер CommView v 5.0
довольно удобный показывает все данные и что самое главное
пишет верна ли чексумма.
Качал с офицального сайта программы помоему www.tamos.com хотя может и нетак.
Удачи.
Ах да код выше использующий функцую pcap_sendpacket у меня
почемуто не работает.. тоесть работает но ответы на мои syn запросы не приходят я думаю эта проблема с Winpcapом и моими 98  
окнами или же с Diul-up соеденением.


 
Dim_kr ©   (2005-11-03 20:01) [28]

Народ! я тут помучался вечер другой и нашел один рабочий способ:

пакет строим так:
   iTcpChecksumSize := 0;

   ptr := @buf[0];
   FillChar(Buf, SizeOf(Buf), 0);

   Move(ipHdr.ip_totallength, ptr^, SizeOf(ipHdr.ip_totallength));
   IncPtr(SizeOf(ipHdr.ip_totallength));
   iTcpChecksumSize := iTcpChecksumSize + sizeof(ipHdr.ip_totallength);

   Move(ipHdr.ip_srcaddr, ptr^, SizeOf(ipHdr.ip_srcaddr));
   IncPtr(SizeOf(ipHdr.ip_srcaddr));
   iTcpChecksumSize := iTcpChecksumSize + sizeof(ipHdr.ip_srcaddr);

   Move(ipHdr.ip_destaddr, ptr^, SizeOf(ipHdr.ip_destaddr));
   IncPtr(SizeOf(ipHdr.ip_destaddr));
   iTcpChecksumSize := iTcpChecksumSize + sizeof(ipHdr.ip_destaddr);

   IncPtr(1);
   Inc(iTcpChecksumSize);

   Move(ipHdr.ip_protocol, ptr^, sizeof(ipHdr.ip_protocol));
   IncPtr(sizeof(ipHdr.ip_protocol));
   iTcpChecksumSize := iTcpChecksumSize + sizeof(ipHdr.ip_protocol);
{
   Move(tcpHdr.tcp_length, ptr^, sizeof(tcpHdr.tcp_length));
   IncPtr(sizeof(tcpHdr.tcp_length));
   iTcpChecksumSize := iTcpChecksumSize + sizeof(tcpHdr.tcp_length);
}
   move(tcpHdr, ptr^, sizeof(tcpHdr));
   IncPtr(sizeof(tcpHdr));
   iTcpChecksumSize := iTcpCheckSumSize + sizeof(tcpHdr);

   Move(StrMessage[1], ptr^, Length(strMessage));
   IncPtr(Length(StrMessage));
   iTcpChecksumSize := iTcpChecksumSize + length(strMessage);

   cksum := checksum(buf, iTcpChecksumSize);
   tcpHdr.tcp_checksum := cksum;

function CheckSum(Var Buffer; Size : integer) : Word;
type
TWordArray = Array[0..1] of Word;
var
ChkSum : LongWord;
i      : Integer;
begin
ChkSum := 0;
i := 0;
While Size > 1 do
   begin
   ChkSum := ChkSum + htons(TWordArray(Buffer)[i]);
   inc(i);
   Size := Size - SizeOf(Word);
   end;

if Size=1 then ChkSum := ChkSum + htons(Byte(TWordArray(Buffer)[i]));
ChkSum := (ChkSum shr 16) + (ChkSum and $FFFF);
ChkSum := ChkSum + (Chksum shr 16);

ChkSum := $10013 - Chksum;
//ChkSum := 0;
Result := Word(htons(ChkSum));
end;

(если будет глючить - сообщите =)



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

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

Наверх





Память: 0.6 MB
Время: 0.054 c
15-1137654352
WondeRu
2006-01-19 10:05
2006.02.12
Составление 3D-карты из двух аэро(космо)фотоснимков.


4-1132648371
salexn
2005-11-22 11:32
2006.02.12
Определение версии установленного Office


2-1138183216
aviseral
2006-01-25 13:00
2006.02.12
Из Excel в DBGrid


11-1099944747
ALex13
2004-11-08 23:12
2006.02.12
Вопрос по TKOLListBox


6-1129105959
Дмитрий_05
2005-10-12 12:32
2006.02.12
Прервать выполнение функции RasDial





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский