我刚刚看过你的程序, 你对TCP的定义确实有问题。 我刚刚弄好以下code, 估计应该可以
解决你的问题。 我的程序需要保存每一个packet. so i can analysis them later on.
I declare a generic structure to hold these packets.
//use variant type record depends on different kinds of packet
//no contineous memo being allocated for pre-defined packet struc.
//good for filter purpose. can discard packet without write them into disk
type
Packet_struc = record
// PacketID: WORD;
DestMac: string[17];
SrcMac: string[17];
case Frame_protocol: WORD of
80: //ip packet
(
Verlen: String[2];
Service: String[2]; // TOS
TLength: string[10];
Ident: string[4];
Flagoff: string[2]; //3bit flag - 13 bit offset
TimeLive: WORD;
Checksum: String[4];
SrcIP: string[16];
DestIP: string[16];
case IP_protocol:WORD of
6: //TCP 0x06
(
// SrcPort : String[4];
SrcPort : String[4];
DestPort : string[4];
SequenceNr : String[8];
AckNumber : String[8];
LenResvFlags: String[4]; //length(4bits) rsvd(6bits) flags(6bits)
WindowSize : String[4];
CRC : String[4];
UrgentPtr : String[4];
// Data : array[0..0] of UCHAR;
);
1: //ICMP 0x01
();
17: //UDP 0x11
();
);
86: //arp packet
();
90: //loopback packet
(); //x9000
end;
以下code 拆数据包, 并复制给上面data structure
procedure TCaptureThread.Capturing(Data
ointer;recvbytes:Word);
var
IP : PIP_RHDR;
TCP : PTCP_RHDR;
s:string;
pack : ^packet_struc;
begin
{analysis routine, should handle the receiving data.
Possible solution:
1: analysis data packet in real time
2: dump data to a file send it to central controller
3: ...
}
// case protocolStr(@PETHERNET_HDR(data).protocol) of
GetMem(Pack,SizeOf(packet_struc));
IP := @PETHERNET_HDR(data).data; //retrive
pack^.DestMac:= MACtoStr(@PETHERNET_HDR(data).Destination[0]);
pack^.SrcMac:= MACtoStr(@PETHERNET_HDR(data).Source[0]);
s := format('%d%d',[PETHERNET_HDR(data).protocol[0],PETHERNET_HDR(data).protocol[1]]);
case StrToInt(s) of
80: begin //ip
with pack^ do
begin
Frame_protocol :=80;
verlen :=format('%x',[integer(IP.verlen)]);
Service :=format('%x',[integer(IP.Service)]);
TLength :=format('%d%d',[IP.Length[0],IP.Length[1]]); //if packet len is small, using int represent packet len is ok. if it is too big
Ident :=format('%.2x%.2x',[IP.Ident[0],IP.Ident[1]]); //that must be wrong!!! not sure the threadhold for length
Flagoff :=format('%x%x',[IP.Flagoff[0],IP.Flagoff[1]]);
IP_protocol :=IP.Protocol;
TimeLive :=IP.TimeLive;
Checksum :=format('%.2x%.2x',[IP.Checksum[0],IP.Checksum[1]]);
SrcIP :=IPtoStr(@ip.srcIP[0]);
DestIP :=IPtoStr(@ip.destIP[0]);
end;
end;
86: begin //arp
pack^.Frame_protocol:=86;
end;
90: begin //loopback
pack^.Frame_protocol:=90;
end;
end;
TCP :=@IP.data;
case IP.Protocol of
6: begin //TCP
with pack^ do
begin
SrcPort :=format('%.2x%.2x',[TCP.SrcPort[0],TCP.SrcPort[1]]);
DestPort :=format('%.2x%.2x',[TCP.DestPort[0],TCP.DestPort[1]]);
SequenceNr :=format('%.2x%.2x%.2x%.2x',[TCP.SequenceNr[0],TCP.SequenceNr[1],TCP.SequenceNr[2],TCP.SequenceNr[3]]);//??
AckNumber :=format('%.2x%.2x%.2x%.2x',[TCP.AckNumber[0],TCP.AckNumber[1],TCP.AckNumber[2],TCP.AckNumber[3]]); //??
LenResvFlags :=format('%.2x%.2x',[TCP.LenResvFlags[0],TCP.LenResvFlags[1]]);
WindowSize :=format('%.2x%.2x',[TCP.WindowSize[0],TCP.WindowSize[1]]);
CRC :=format('%.2x%.2x',[TCP.CheckSum[0],TCP.CheckSum[1]]);
UrgentPtr :=format('%.2x%.2x',[TCP.UrgentPtr[0],TCP.UrgentPtr[1]]);
end;
end;
17: begin //UDP
end;
end;
packetlist.add(pack);
freeMem(pack);
end;
function ProtocolStr(protocol: byte): string;
begin
case protocol of
1 : result := 'ICMP';
6 : result := 'TCP';
17: result := 'UDP'; //should be 11;
80: result := 'ISO IP';
else result:= inttostr(protocol);
end;
end;
function IPtoStr;
type
PIP = ^TIP;
TIP = array[0..3] of byte;
begin
result := format('%d.%d.%d.%d',[PIP(IP)[0],
PIP(IP)[1],
PIP(IP)[2],
PIP(IP)[3]]);
end;
你要做到:
“从TCP的包头信息中知道,
这外封包是那一组的,同组的封包的排列顺序。
再就是最后一个包是那一个包”。
通过检查identification field你应该可以分清数据包属于哪一组,
同组的封包的排列顺序可通过查序列号(sequence number)
你“从得到的序列号中无法看出同包的顺序有关。
完全是一个杂乱无章的东西”是因为你定义TCP structure 错误。
行了, 你应该可以交差了。