Я разрабатываю анализатор пакетов на основе сокета Windows Raw на Windows 7. Программа захватывает пакет с IP-уровня.Проблема, с которой я сталкиваюсь, заключается в том, что программа перехватывает все пакеты, но некоторые из них перехватываются, например, в неправильном порядке.для фазы установления соединения tcp вместо получения пакетов в SYN, SYN-ACK, порядке ACK я получаю его как SYN, ACK, SYN-ACK.Вместо захвата ACK после SYN-ACK (с удаленного компьютера) pgm получает ACK перед пакетом SYN-ACK.То же самое происходит и на этапе передачи данных.Программа захватывает пакет ACK пакета данных перед фактическим пакетом данных.Если я запускаю wireshark параллельно, он отображается правильно.Я использую Visual Studio 2005 в качестве IDE.
#include "stdio.h"
#include "winsock2.h"
#include "ws2tcpip.h"
#include "pcap.h"
#include "MSTcpIP.h"
int main(int argc, char **argv)
{
struct in_addr addr;
int in, optval=1;
struct hostent *local;
WSADATA wsa;
char *Buffer;
//Initialise Winsock
if (WSAStartup(MAKEWORD(2,2), &wsa) != 0)
{
printf("WSAStartup() failed.\n");
return 1;
}
//Create a RAW Socket
sniffer = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if (sniffer == INVALID_SOCKET)
{
printf("Failed to create raw socket.\n");
return 1;
}
memset(&dest, 0, sizeof(dest));
memcpy(&dest.sin_addr.s_addr,argv[1], sizeof(argv[1]));
dest.sin_family = AF_INET;
dest.sin_port = 0;
printf("\nBinding socket to local system and port 0 ...");
if (bind(sniffer,(struct sockaddr *)&dest,sizeof(dest)) == SOCKET_ERROR)
{
printf("bind(%s) failed.\n", inet_ntoa(addr));
return 1;
}
printf("Binding successful");
//Enable this socket with the power to sniff : SIO_RCVALL is the key Receive ALL ;)
j=1;
printf("\nSetting socket to sniff...");
if (WSAIoctl(sniffer, SIO_RCVALL, &j, sizeof(j), 0, 0, (LPDWORD) &in , 0 , 0) == SOCKET_ERROR)
{
printf("WSAIoctl() failed.\n");
wprintf(L"IOCTL failed with error %d\n", WSAGetLastError());
if (WSAIoctl(sniffer, SIO_RCVALL, &j, sizeof(j), 0, 0, (LPDWORD) &in , 0 , 0) == SOCKET_ERROR) {
printf("Failed again\n");
wprintf(L"IOCTL failed again with error %d\n", WSAGetLastError());
return 1;
}
}
printf("Socket set.");
if(setsockopt(sniffer, IPPROTO_IP, IP_HDRINCL, (char *)&optval, sizeof(optval))==SOCKET_ERROR)
{
printf("failed to set socket in raw mode.");
return 0;
}
char *Buffer = (char *)malloc(65536); //Its Big!65536
do
{
mangobyte = recvfrom(sniffer , Buffer , 2000 , 0 , 0 , 0); //Eat as much as u can
if(mangobyte > 0)
{
writeCaptofile(Buffer, mangobyte); //write the captured packet to file in pcap format
}
else
{
printf( "recvfrom() failed.\n");
}
}
while ((mangobyte > 0) && (!StopSniffing));
free(Buffer);
closesocket(sniffer);
WSACleanup();
return 0;
}