关于网友提出的“ 网络抓包程序疑惑,不能抓到发送的数据包”问题疑问,本网通过在网上对“ 网络抓包程序疑惑,不能抓到发送的数据包”有关的相关答案进行了整理,供用户进行参考,详细问题解答如下:
问题: 网络抓包程序疑惑,不能抓到发送的数据包
描述: IOC_IN =$80000000;
IOC_VENDOR =$18000000;
IOC_out =$40000000;
SIO_RCVALL =IOC_IN or IOC_VENDOR or 1;// or IOC_out(or IOC_OUT要出错)
.....
WSAIoctl(Fsocket[i],
SIO_RCVALL,
@dwBufferInLen,
sizeof(dwBufferInLen),
@dwBufferLen,
sizeof(dwBufferLen),
@dwBytesReturned ,
nil ,
nil);
当有数据到达的时候,会得到消息,发送的时候是得不到消息的(以及被发送的数据)
怎么弄才能得到?
除HOOK API方式。
解决方案1: jf&study
解决方案2: 学习一下
解决方案3: 我试了一下keiy的程序,还不错:)
Delphi版本,GetProtocolTxt函数没有翻译完整:)
program Test;
{$APPTYPE CONSOLE}
uses
SysUtils, WinSock, Windows;
type
PTCP = ^_TCP;
_TCP = packed record
SrcPort: Word; // 源端口
DstPort: Word; // 目的端口
SeqNum: DWord; // 顺序号
AckNum: DWord; // 确认号
DataOff: Byte; // TCP头长
Flags: Byte; // 标志(URG、ACK等)
Window: Word; // 窗口大小
Chksum: Word; // 校验和
UrgPtr: Word; // 紧急指针
end;
PIP = ^_IP;
_IP = record
U1: record
case Byte of
0: (Version: Byte); // 版本
1: (HdrLen: Byte); // IHL
end;
ServiceType: Byte; // 服务类型
TotalLen: Word; // 总长
ID: Word; // 标识
U2: record
case Byte of
0: (Flags: Word); // 标志
1: (FragOff: Word); // 分段偏移
end;
TimeToLive: Byte; // 生命期
Protocol: Byte; // 协议
HdrChksum: Word; // 头校验和
SrcAddr: DWord; // 源地址
DstAddr: DWord; // 目的地址
Options: Byte; // 选项
end;
const
IP_HDRINCL = 2;
IOC_VENDOR = $18000000;
BUFFER_SIZE = 4096;
function MAKEWORD(a, b: Byte): Word;
begin
result:=Word(a or ((Word(b) shl 8)));
end;
function SIO_RCVALL: Cardinal;
begin
result:=IOC_IN or IOC_VENDOR or 1;
end;
function isprint(c: Byte): Boolean;
begin
result:=(c>$20) and (c<$7e);
end;
function GetProtocolTxt(p: Byte): string;
begin
case p of
IPPROTO_IP: result:='IPPROTO_IP';
//省略了很多:)
else
result:='UNKNOW';
end;
end;
var
wsData: WSAData;
sock: Integer;
flag: Integer = 1;
localname: array[0..100] of char;
phost: PHostEnt;
addr_in: TSockAddrIn;
dwValue: Integer;
RecvBuf: array[0..BUFFER_SIZE-1] of byte;
ret: Integer;
ip: PIP;
tcp: PTCP;
i, j: Integer;
c: byte;
s: string;
begin
WSAStartup(MAKEWORD(2, 2), wsData);
// 创建原始套接字
sock:=socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
// 设置IP头操作选项,其中flag 设置为ture,亲自对IP头进行处理
setsockopt(sock, IPPROTO_IP, IP_HDRINCL, pchar(@flag), sizeof(flag));
// 获取本机名
gethostname(@localname, sizeof(localname));
// 获取本地 IP 地址
phost:=gethostbyname(@localname);
// 填充SOCKADDR_IN结构
addr_in.sin_addr:=PInAddr(phost.h_addr_list^)^; //IP
addr_in.sin_family:=AF_INET;
addr_in.sin_port:=htons(57274);
// 把原始套接字sock 绑定到本地网卡地址上
bind(sock, addr_in, sizeof(addr_in));
// dwValue为输入输出参数,为1时执行,0时取消
dwValue:=1;
// 设置 SOCK_RAW 为SIO_RCVALL,以便接收所有的IP包。其中SIO_RCVALL
// 的定义为: #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
ioctlsocket(sock, SIO_RCVALL, dwValue);
// 前面的工作基本上都是对原始套接字进行设置,在将原始套接字设置完毕,使其能按预期目的工作时,
// 就可以通过recv()函数从网卡接收数据了,接收到的原始数据包存放在缓存RecvBuf[]中,缓冲区长度BUFFER_SIZE定义为65535。
// 然后就可以根据前面对IP数据段头、TCP数据段头的结构描述而对捕获的数据包进行分析:
while true do
begin
// 接收原始数据包信息
FillMemory(@RecvBuf, BUFFER_SIZE, 0);
ret:=recv(sock, RecvBuf, BUFFER_SIZE, 0);
if ret>0 then
begin
ip:=@RecvBuf;
tcp:=PTCP(PChar(@RecvBuf)+ip^.U1.HdrLen);
WriteLn('协议:', GetProtocolTxt(ip^.Protocol));
WriteLn('IP源地址:', inet_ntoa(PInAddr(@ip^.SrcAddr)^));
WriteLn('IP目标地址: ', inet_ntoa(PInAddr(@ip^.DstAddr)^));
WriteLn('TCP源端口号:', tcp^.SrcPort);
WriteLn('TCP目标端口号:', tcp^.DstPort);
WriteLn('数据包长度:', ntohs(ip^.TotalLen));
WriteLn('长度:', ip^.U1.HdrLen, ' ', tcp^.DataOff, ' ', sizeof(_ip), ' ', sizeof(_tcp));
WriteLn;
Write('0000:');
for i:=0 to ntohs(ip^.TotalLen)-1 do
begin
s:=Format('%02x ', [RecvBuf[i]]);
Write(s);
if (i+1) mod 16 = 0 then
begin
Write(' ');
for j:=0 to 15 do
begin
c:=RecvBuf[i-(15-j)];
if isprint(c) or (c>$a0) then
Write(char(c))
else
Write('.');
end;
WriteLn;
Write(Format('%04x:', [i+1]));
end;
end;
i:=ntohs(ip^.TotalLen) mod 16;
if i<>0 then
begin
for j:=0 to 15-i do
Write(' ');
Write(' ');
for j:=0 to i-1 do
begin
c:=RecvBuf[ntohs(ip^.TotalLen)-i+j];
if isprint(c) or (c>$a0) then
Write(char(c))
else
Write('.');
end;
end;
WriteLn;
WriteLn('------------------------------------------');
end;
end;
readln;
end.
解决方案4: 我用过VC的,你要吗?
VC console的
#include
#include
#include
#include
#ifdef _MSC_VER
#pragma comment( lib, "WS2_32.LIB")
#endif
typedef struct _TCP {
WORD SrcPort; // 源端口
WORD DstPort; // 目的端口
DWORD SeqNum; // 顺序号
DWORD AckNum; // 确认号
BYTE DataOff; // TCP头长
BYTE Flags; // 标志(URG、ACK等)
WORD Window; // 窗口大小
WORD Chksum; // 校验和
WORD UrgPtr; // 紧急指针
} TCP;
typedef TCP *LPTCP;
typedef TCP UNALIGNED * ULPTCP;
typedef struct _IP {
union {
BYTE Version; // 版本
BYTE HdrLen; // IHL
};
BYTE ServiceType; // 服务类型
WORD TotalLen; // 总长
WORD ID; // 标识
union{ WORD Flags; // 标志
WORD FragOff; // 分段偏移
};
BYTE TimeToLive; // 生命期
BYTE Protocol; // 协议
WORD HdrChksum; // 头校验和
DWORD SrcAddr; // 源地址
DWORD DstAddr; // 目的地址
BYTE Options; // 选项
} IP;
typedef IP * LPIP;
char *GetProtocolTxt(BYTE p)
{
switch (p)
{
case IPPROTO_IP:
return "IPPROTO_IP:";
case IPPROTO_ICMP:
return "IPPROTO_ICMP:";
case IPPROTO_IGMP:
return "IPPROTO_IGMP:";
case IPPROTO_GGP:
return "IPPROTO_GGP:";
case IPPROTO_TCP:
return "IPPROTO_TCP:";
case IPPROTO_PUP:
return "IPPROTO_PUP:";
case IPPROTO_UDP:
return "IPPROTO_UDP:";
case IPPROTO_IDP:
return "IPPROTO_IDP:";
// case IPPROTO_IPV6:
// return "IPPROTO_IPV6:";
case IPPROTO_ND:
return "IPPROTO_ND:";
// case IPPROTO_ICLFXBM:
// return "IPPROTO_ICLFXBM:";
case IPPROTO_RAW:
return "IPPROTO_RAW:";
case IPPROTO_MAX:
return "IPPROTO_MAX:";
case IPPORT_ECHO:
return "IPPORT_ECHO:";
case IPPORT_DISCARD:
return "IPPORT_DISCARD:";
case IPPORT_SYSTAT:
return "IPPORT_SYSTAT:";
case IPPORT_DAYTIME:
return "IPPORT_DAYTIME:";
case IPPORT_NETSTAT:
return "IPPORT_NETSTAT:";
case IPPORT_FTP:
return "IPPORT_FTP:";
case IPPORT_TELNET:
return "IPPORT_TELNET:";
case IPPORT_SMTP:
return "IPPORT_SMTP:";
case IPPORT_TIMESERVER:
return "IPPORT_TIMESERVER:";
case IPPORT_NAMESERVER:
return "IPPORT_NAMESERVER:";
case IPPORT_WHOIS:
return "IPPORT_WHOIS:";
case IPPORT_MTP:
return "IPPORT_MTP:";
case IPPORT_TFTP:
return "IPPORT_TFTP:";
case IPPORT_FINGER:
return "IPPORT_FINGER:";
case IPPORT_TTYLINK:
return "IPPORT_TTYLINK:";
case IPPORT_SUPDUP:
return "IPPORT_SUPDUP:";
case IPPORT_EXECSERVER:
return "IPPORT_EXECSERVER:";
case IPPORT_LOGINSERVER:
return "IPPORT_LOGINSERVER:";
case IPPORT_CMDSERVER:
return "IPPORT_CMDSERVER:";
case IPPORT_EFSSERVER:
return "IPPORT_EFSSERVER:";
case IPPORT_RESERVED:
return "IPPORT_RESERVED:";
case IMPLINK_IP:
return "IMPLINK_IP:";
case IMPLINK_LOWEXPER:
return "IMPLINK_LOWEXPER:";
default:
return "UNNOW";
}
}
#define TRACE printf
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
void main()
{
// 检查 Winsock 版本号,WSAData为WSADATA结构对象
WSADATA wsaData;
SOCKET sock ;
int flag=true;
char LocalName[100];
hostent *pHost;
SOCKADDR_IN addr_in;
char RecvBuf[4096];
#define BUFFER_SIZE 4096
IP ip;
TCP tcp;
WSAStartup(MAKEWORD(2, 2),&wsaData);
// 创建原始套接字
sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
// 设置IP头操作选项,其中flag 设置为ture,亲自对IP头进行处理
setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag));
// 获取本机名
gethostname((char*)LocalName, sizeof(LocalName)-1);
// 获取本地 IP 地址
pHost = gethostbyname((char*)LocalName);
// 填充SOCKADDR_IN结构
addr_in.sin_addr = *(in_addr *)pHost->h_addr_list[0]; //IP
addr_in.sin_family = AF_INET;
addr_in.sin_port = htons(57274);
// 把原始套接字sock 绑定到本地网卡地址上
bind(sock, (PSOCKADDR)&addr_in, sizeof(addr_in));
// dwValue为输入输出参数,为1时执行,0时取消
DWORD dwValue = 1;
// 设置 SOCK_RAW 为SIO_RCVALL,以便接收所有的IP包。其中SIO_RCVALL
// 的定义为: #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
ioctlsocket(sock, SIO_RCVALL, &dwValue);
// 前面的工作基本上都是对原始套接字进行设置,在将原始套接字设置完毕,使其能按预期目的工作时,就可以通过recv()函数从网卡接收数据了,接收到的原始数据包存放在缓存RecvBuf[]中,缓冲区长度BUFFER_SIZE定义为65535。然后就可以根据前面对IP数据段头、TCP数据段头的结构描述而对捕获的数据包进行分析:
int i,j;
unsigned char c;
while (true)
{
// 接收原始数据包信息
memset( RecvBuf,0x0,BUFFER_SIZE);
int ret = recv(sock, RecvBuf, BUFFER_SIZE, 0);
if (ret > 0)
{
// 对数据包进行分析,并输出分析结果
ip = *(IP*)RecvBuf;
tcp = *(TCP*)(RecvBuf + ip.HdrLen);
// if (ip.DstAddr!=0xffffffffu)
// if (ip.DstAddr!=0x7000A8C0u)
// if ((ip.SrcAddr ==0x7700A8C0u) ||(ip.DstAddr ==0x7700A8C0u) )
{
TRACE("协议: %s\n",GetProtocolTxt(ip.Protocol));
TRACE("IP源地址: %s\n",inet_ntoa(*(in_addr*)&ip.SrcAddr));
TRACE("IP目标地址: %s\n",inet_ntoa(*(in_addr*)&ip.DstAddr));
TRACE("TCP源端口号: %d\n",tcp.SrcPort);
TRACE("TCP目标端口号:%d\n",tcp.DstPort);
TRACE("数据包长度: %d\n",ntohs(ip.TotalLen));
TRACE("长度:%x %x %x %x\n",ip.HdrLen,tcp.DataOff,sizeof(ip),sizeof(tcp));
TRACE("长度:%d %d %d %d\n\n",ip.HdrLen,tcp.DataOff,sizeof(ip),sizeof(tcp));
printf("0000:");
for(i=0;i<>
{
printf("%02x ", (unsigned char )RecvBuf[i]);
if ((i+1)%16==0)
{
putchar(' ');
for(j=0;j<16;j++)
{
c= RecvBuf[i-(15-j)];
if ((isprint(c)) || (c>0xa0))
putchar(c);
else
putchar('.');
}
printf("\n%04x:",i+1);
}
}
if (((i=ntohs(ip.TotalLen)%16))!=0)
{
for(j=0;j<16-i;j++)
printf(" ");
putchar(' ');
for(j=0;j<>
{
c= RecvBuf[ntohs(ip.TotalLen)-i+j];
if ((isprint(c)) || (c>0xa0))
putchar(c);
else
putchar('.');
}
}
printf("\n");
}
}
}
getchar();
}
解决方案5: 不说了,接分......
解决方案6: 关注
以上介绍了“ 网络抓包程序疑惑,不能抓到发送的数据包”的问题解答,希望对有需要的网友有所帮助。
本文网址链接:http://www.codes51.com/itwd/3677567.html