大家看看ARP包哪里构造错了 ( 积分: 100 )

  • 主题发起人 linuxping
  • 开始时间
L

linuxping

Unregistered / Unconfirmed
GUEST, unregistred user!
//以太网MAC地址
TEtherHardAddr=array[0..5]of Byte;

//开始定义ARP数据包结构。
//首先构造"以太网首部"
TEtherHeader=packed record
Ether_Dest:TEtherHardAddr;
//以太网目的地址
Ether_Src:TEtherHardAddr;
//以太网源地址
Frame_Type:Word;
//帧类型
end;
TARPHeader=TEtherHeader;
//构造”28字节的ARP请求/应答“
TRequestResponse=packed record
HardAddrType:Word;
//硬件类型
ProtoAddrType:Word;
//协议类型
HardAddr_Len:Byte;
//硬件地址长度
ProtoAddr_Len:Byte;
//协议地址长度
Operation:Word;
//操作. ARP/RARP.
Sender_Hard_Addr:TEtherHardAddr;
//发送端以太网地址
Sender_IP:LongWord;
//发送端IP
Dest_Hard_Addr:TEtherHardAddr;
//目的以太网地址
Dest_IP:LongWord;
//目的IP
end;
TARPData=TRequestResponse;
PARPData=^TARPData;

//构造ARP包
PARPPacket=^TARPPacket;
TARPPacket=packed record
Header:TARPHeader;
RequestResponse:TARPData;
Padding:array[0..17]of byte;
//填充. 因为以太网每帧至少60 Byte。
end;

//==========================================================
TMIBIfArray = array of TMIBIFRow;

//==========================================================

//定义ARP包的操作字段。
TARPOperation=(aoArpRequest,aoARPResponse,aoRARPRequest,aoRARPResponse);


//-----------------------------------------------
// 该类用来构造一以太网帧
//使用方法:
// 1, Create
// 2, 设置目标IP和MAC(DestIP,DestMAC),源IP和MAC(SrcIP,SrcMAC)
// 3, 设置IsRequest属性表示是请求包还是回复包 .
// 4 调用BuildPacket方法。
// 5, ARPPacket属性即是构造的以太网帧。
// 6, free.
//-----------------------------------------------
TBuildARPFrame=class(TPersistent)
private
FARPPacket:WideString;
public
DestIP,SrcIP:string;
DestMAC,SrcMAC:string;
IsRequest:Boolean;
constructor Create;
procedure BuildPacket;
property ARPPacket:WideString read FARPPacket;
end;


//=======================================================
{ TBuildARPFrame }
function GetRemoteMacAdress(var address: String): Boolean;
var
dwRemoteIP: Cardinal;
PhyAddrLen: Longword;
pMacAddr : array [0..1] of Longword;
temp: array [0..5] of byte;
I: Byte;
begin
Result := false;
dwremoteIP := inet_addr (@address[1]);
if dwremoteIP <> 0 then
begin
PhyAddrLen := 6;
if SendARP (dwremoteIP, 0, @pMacAddr, PhyAddrLen) = NO_ERROR then
begin
if (PhyAddrLen <> 0) and (pMacAddr[0] <> 0) then
begin
Move (pMacAddr, temp, 6);
address := '';
For I := 0 to 5do
address := address + inttohex (temp, 2)+'-';
Delete (address, Length (address), 1);
Result := true;
end;
end;
end;
end;

procedure TBuildARPFrame.BuildPacket;
var
p:pPcap;
EtherHaeder:TEtherHeader;
ARPData:TARPData;
ARPPack:TARPPacket;
IPHeader:THdrIP;
PPack:ppacket;
begin
if (DestIP='') or (DestMAC='') then
Exit;
//-------------------------------------
{构造一个ARP包}
//以太网头部
EtherHaeder.Ether_Dest:=TMacAddrOperation.Str2MacAddr(DestMac);
EtherHaeder.Ether_Src:=TMacAddrOperation.Str2MacAddr(SrcMac);
EtherHaeder.Frame_Type:=htons(FrameType);
//以太网数据域
ARPData.Sender_Hard_Addr:=TMacAddrOperation.Str2MacAddr(SrcMac);
ARPData.Sender_IP:=inet_addr(PChar(SrcIP));
// htonl ???????????????????
ARPData.Dest_Hard_Addr:=TMacAddrOperation.Str2MacAddr(DestMac);
ARPData.Dest_IP:=inet_addr(PChar(DestIP));
// htons ???????????????????
ARPData.HardAddrType:=htons(HardWareType_Ether);
ARPData.ProtoAddrType:=htons(ProtoType_IP);
ARPData.HardAddr_Len:=6;
ARPData.ProtoAddr_Len:=4;
if IsRequest then
ARPData.Operation:=htons(Op_ARP_Request)
else
ARPData.Operation:=htons(Op_ARP_Response);
ARPPack.Header:=EtherHaeder;
ARPPack.RequestResponse:=ARPData;
FillChar(ARPPack.Padding,18,0);
//------------------------------------------
SetLength(FARPPacket,SizeOf(ARPPack));
CopyMemory(@FARPPacket[1],@ARPPack,SizeOf(ARPPack));
end;

constructor TBuildARPFrame.Create;
var
IpWatch: TIdIPWatch;
begin
IpWatch:=TIdIPWatch.Create(nil);
IpWatch.HistoryEnabled:=False;
SrcIP:=IpWatch.LocalIP;
//默认源IP为本机IP
IpWatch.Free;
SrcMAC:=SrcIP;
GetRemoteMacAdress(SrcMac);
//默认源MAC为本机MAC
IsRequest:=True;
// 默认发送请求包
FARPPacket:='';
end;
 
L

linuxping

Unregistered / Unconfirmed
GUEST, unregistred user!
TMacAddrOperation=class
public
class function Str2MacAddr(StrMac:string):TEtherHardAddr;
class function MacAddr2Str(Addr:TEtherHardAddr):string;
class function GetLocaleMAC:TEtherHardAddr;
end;

{ TMacAddrOperation }
class function TMacAddrOperation.GetLocaleMAC: TEtherHardAddr;
var
MibArr : TMIBIfArray;
I:Integer;
begin
Get_IfTableMIB( MibArr );
// get current MIB data
if (Length(MibArr) > 0) then
{$R-}
for I:=0 to MibArr[0].dwPhysAddrLen-1do
Result:= MIBArr[0].bPhysAddr
{$R+}
else
FillChar(Result[0],Length(Result),0);
end;

class function TMacAddrOperation.MacAddr2Str(Addr: TEtherHardAddr): string;
var
I:Integer;
begin
Result:='';
for I:=Low(Addr) to High(Addr)do
Result:=Result+InttoHex(ADDR,2)+'-';
Delete(Result,Length(Result),1);
end;

class function TMacAddrOperation.Str2MacAddr(
StrMac: string): TEtherHardAddr;
var
I:Integer;
Section:string;
begin
StrMac:=StrPas(StrUpper(PAnsiChar(StrMac)));
StrMac:=Trim(StrMac);
for I:=0 to 4do
begin
Section:=Fetch(StrMac,'-');
Result:=Byte(StrToInt('$'+Section));
end;
Result[5]:=Byte(StrToInt('$'+StrMac));
end;
 
Q

QSmile

Unregistered / Unconfirmed
GUEST, unregistred user!
ARP 協議是個很簡單的協議,自已看 RFC 就可以了。
也就一個以太網層,一個 ARP 層
把數據輸出來看哪裡錯了
 
W

wql

Unregistered / Unconfirmed
GUEST, unregistred user!
警告:
SendARP 有时候不一定正确返回MAC地址!
因为遇到过!
 
L

linuxping

Unregistered / Unconfirmed
GUEST, unregistred user!
多谢你看了程序~~~
多谢提醒sendarp错误!
其实下面已经写了另一个函数TMacAddrOperation.GetLocaleMAC

问题还没有解决哦
 
W

wql

Unregistered / Unconfirmed
GUEST, unregistred user!
倒Google上找利用WinPCap的伪 ARP!
关键字: WinPCap ARP 攻击
 
L

linuxping

Unregistered / Unconfirmed
GUEST, unregistred user!
^_^ 我可不是搞ARP攻击
多谢了
 
顶部