int err;
WSADATA wsaData;
if ( WSAStartup(MAKEWORD(2,2), &wsaData)!=0)
{
err=WSAGetLastError();
CString Error;
Error.Format("sock init failed, Error code: %d",err);
MessageBox(Error);
return;
}
SOCKADDR_IN addr_in;
m_socket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (m_socket==SOCKET_ERROR)
{
err=WSAGetLastError();
CString Error;
Error.Format("sock create failed, Error code: %d",err);
MessageBox(Error);
return;
}////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
在这里程序会报错"sock create failed, Error code: 10013",我查了下资料说
1 参数protocol用来指明所要接收的协议包,如果是象IPPROTO_TCP(6)这种非0、非255的协议,刚操作系统内核碰到ip头中protocol域和创建socket所使用参数protocol相同的IP包,就会交给这个raw socket来处理,因此,一般来说,要想接收什么样的数据包,就应该在参数protocol里来指定相应的协议。当内核向此raw socket交付数据包的时候,是包括整个IP头的,并且已经是重组好的IP包。
2 如果protocol是IPPROTO_RAW(255),这时候,这个socket只能用来发送IP包,而不能接收任何的数据。发送的数据需要自己填充IP包头,并且自己计算校验和。
3 对于protocol为0(IPPROTO_IP)的raw socket。用于接收任何的IP数据包。其中的校验和和协议分析由程序自己完成。
我这里用的是m_socket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
肯定是看这里错了,我该怎么做呢,我想捕获到所有经过本地网卡的数据包,谢谢,下面是后面得代码:
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
char flag[100];
// 设置IP头操作选项,其中flag 设置为ture,亲自对IP头进行处理
setsockopt(m_socket,IPPROTO_IP,IP_HDRINCL,(char*)&flag,sizeof(flag));
char szhn[256];
int nStatus = gethostname(szhn, sizeof(szhn)); // 获取本机名
if (nStatus == SOCKET_ERROR )
{
err=WSAGetLastError();
CString Error;
Error.Format("gethostname failed, Error code: %d",err);
MessageBox(Error);
return;
}
HOSTENT *host = gethostbyname(szhn); // 获取本地 IP 地址
addr_in.sin_addr = *(in_addr *)host->h_addr_list[0]; // 填充SOCKADDR_IN结构
addr_in.sin_family = AF_INET;
addr_in.sin_port = htons(57274);
if (bind(m_socket, (PSOCKADDR)&addr_in, sizeof(addr_in))==SOCKET_ERROR) // 把原始套接字sock 绑定到本地网卡地址上 {
err=WSAGetLastError();
CString Error;
Error.Format("bind failed, Error code: %d",err);
MessageBox(Error);
return;
} DWORD dwValue = 1; // dwValue为输入输出参数,为1时执行,0时取消
ioctlsocket(m_socket, SIO_RCVALL, &dwValue); // 设置 SOCK_RAW 为SIO_RCVALL,以便接收所有的IP包。其中SIO_RCVALL
char RecvBuf[BUFFER_SIZE]; // 的定义为: #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
CString Protcol,SrcAddr,DstAddr,SrcPort,DstPort,TotalLen;
for( int j=0;j<100; j++ )
{
int ret = recv(m_socket, RecvBuf, BUFFER_SIZE, 0); // 接收原始数据包信息
if (ret > 0) // 对数据包进行分析,并输出分析结果
{
ip = *(IP*)RecvBuf;
tcp = *(TCP*)(RecvBuf + ip.HdrLen);
Protcol.Format("s%",GetProtocolTxt(ip.Protocol));
SrcAddr.Format("%s",inet_ntoa(*(in_addr*)&ip.SrcAddr));
DstAddr.Format("%s",inet_ntoa(*(in_addr*)&ip.DstAddr));
SrcPort.Format("%d",tcp.SrcPort);
DstPort.Format("%d",tcp.DstPort);
TotalLen.Format("%d",ntohs(ip.TotalLen));
m_Grid.InsertItem(j,"");
m_Grid.SetItemText(j,0,Protcol);
m_Grid.SetItemText(j,1,SrcAddr);
m_Grid.SetItemText(j,2,DstAddr);
m_Grid.SetItemText(j,3,SrcPort);
m_Grid.SetItemText(j,4,DstPort);
m_Grid.SetItemText(j,5,TotalLen);
}
WSACleanup();
WSADATA wsaData;
if ( WSAStartup(MAKEWORD(2,2), &wsaData)!=0)
{
err=WSAGetLastError();
CString Error;
Error.Format("sock init failed, Error code: %d",err);
MessageBox(Error);
return;
}
SOCKADDR_IN addr_in;
m_socket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (m_socket==SOCKET_ERROR)
{
err=WSAGetLastError();
CString Error;
Error.Format("sock create failed, Error code: %d",err);
MessageBox(Error);
return;
}////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
在这里程序会报错"sock create failed, Error code: 10013",我查了下资料说
1 参数protocol用来指明所要接收的协议包,如果是象IPPROTO_TCP(6)这种非0、非255的协议,刚操作系统内核碰到ip头中protocol域和创建socket所使用参数protocol相同的IP包,就会交给这个raw socket来处理,因此,一般来说,要想接收什么样的数据包,就应该在参数protocol里来指定相应的协议。当内核向此raw socket交付数据包的时候,是包括整个IP头的,并且已经是重组好的IP包。
2 如果protocol是IPPROTO_RAW(255),这时候,这个socket只能用来发送IP包,而不能接收任何的数据。发送的数据需要自己填充IP包头,并且自己计算校验和。
3 对于protocol为0(IPPROTO_IP)的raw socket。用于接收任何的IP数据包。其中的校验和和协议分析由程序自己完成。
我这里用的是m_socket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
肯定是看这里错了,我该怎么做呢,我想捕获到所有经过本地网卡的数据包,谢谢,下面是后面得代码:
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
char flag[100];
// 设置IP头操作选项,其中flag 设置为ture,亲自对IP头进行处理
setsockopt(m_socket,IPPROTO_IP,IP_HDRINCL,(char*)&flag,sizeof(flag));
char szhn[256];
int nStatus = gethostname(szhn, sizeof(szhn)); // 获取本机名
if (nStatus == SOCKET_ERROR )
{
err=WSAGetLastError();
CString Error;
Error.Format("gethostname failed, Error code: %d",err);
MessageBox(Error);
return;
}
HOSTENT *host = gethostbyname(szhn); // 获取本地 IP 地址
addr_in.sin_addr = *(in_addr *)host->h_addr_list[0]; // 填充SOCKADDR_IN结构
addr_in.sin_family = AF_INET;
addr_in.sin_port = htons(57274);
if (bind(m_socket, (PSOCKADDR)&addr_in, sizeof(addr_in))==SOCKET_ERROR) // 把原始套接字sock 绑定到本地网卡地址上 {
err=WSAGetLastError();
CString Error;
Error.Format("bind failed, Error code: %d",err);
MessageBox(Error);
return;
} DWORD dwValue = 1; // dwValue为输入输出参数,为1时执行,0时取消
ioctlsocket(m_socket, SIO_RCVALL, &dwValue); // 设置 SOCK_RAW 为SIO_RCVALL,以便接收所有的IP包。其中SIO_RCVALL
char RecvBuf[BUFFER_SIZE]; // 的定义为: #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
CString Protcol,SrcAddr,DstAddr,SrcPort,DstPort,TotalLen;
for( int j=0;j<100; j++ )
{
int ret = recv(m_socket, RecvBuf, BUFFER_SIZE, 0); // 接收原始数据包信息
if (ret > 0) // 对数据包进行分析,并输出分析结果
{
ip = *(IP*)RecvBuf;
tcp = *(TCP*)(RecvBuf + ip.HdrLen);
Protcol.Format("s%",GetProtocolTxt(ip.Protocol));
SrcAddr.Format("%s",inet_ntoa(*(in_addr*)&ip.SrcAddr));
DstAddr.Format("%s",inet_ntoa(*(in_addr*)&ip.DstAddr));
SrcPort.Format("%d",tcp.SrcPort);
DstPort.Format("%d",tcp.DstPort);
TotalLen.Format("%d",ntohs(ip.TotalLen));
m_Grid.InsertItem(j,"");
m_Grid.SetItemText(j,0,Protcol);
m_Grid.SetItemText(j,1,SrcAddr);
m_Grid.SetItemText(j,2,DstAddr);
m_Grid.SetItemText(j,3,SrcPort);
m_Grid.SetItemText(j,4,DstPort);
m_Grid.SetItemText(j,5,TotalLen);
}
WSACleanup();
而且操作系统必须支持RAW_SOCKET才行。
http://msdn.microsoft.com/en-us/library/ms740548(VS.85).aspx
而且操作系统必须支持RAW_SOCKET才行。
http://msdn.microsoft.com/en-us/library/ms740548(VS.85).aspx