Witam
Ostatnio próbuję napisać sobie prostego sniffera przy użyciu rawsocket i napisałem sobie klasę o nazwie cinque oto jej kod:
#include <winsock2.h>
#define MAX_PACKET_SIZE 65535
#ifndef SIO_RCVALL
# define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
#endif
typedef struct _IP_HEADER_
{
BYTE ver_ihl; // Version (4 bits) and Internet Header Length (4 bits)
BYTE type; // Type of Service (8 bits)
WORD length; // Total size of packet (header + data)(16 bits)
WORD packet_id; // (16 bits)
WORD flags_foff; // Flags (3 bits) and Fragment Offset (13 bits)
BYTE time_to_live; // (8 bits)
BYTE protocol; // (8 bits)
WORD hdr_chksum; // Header check sum (16 bits)
DWORD source_ip; // Source Address (32 bits)
DWORD destination_ip; // Destination Address (32 bits)
} IPHEADER;
class cinque
{
private:
WSADATA wsaData;
SOCKET s_socket;
SOCKADDR_IN sockaddr;
SOCKADDR sockaddr_from;
char ip[20];
char packet[MAX_PACKET_SIZE];
//char source_ip[20];
char destination_ip[20];
IPHEADER *ip_header;
public:
unsigned int error;
cinque();
~cinque();
void Recv(char *source_ip);
};
cinque::cinque()
{
error = 0;
if ( WSAStartup( MAKEWORD(2,2), &wsaData ) !=0 )
{
error = 1;
}
s_socket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if(s_socket == INVALID_SOCKET)
{
error = 2;
}
char hostname[128];
PHOSTENT phostent;
gethostname(hostname, sizeof(hostname));
phostent = gethostbyname(hostname);
memcpy((char FAR *)&(sockaddr.sin_addr),phostent->h_addr,phostent->h_length);
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons(0);
if(bind(s_socket, (PSOCKADDR)&sockaddr, sizeof(SOCKADDR_IN)) != SOCKET_ERROR)
{
error = 3;
}
int optval = 1;
DWORD dwLen = 0;
if ( WSAIoctl( s_socket, SIO_RCVALL, &optval, sizeof(optval), NULL, 0, &dwLen, NULL, NULL ) == SOCKET_ERROR )
{
error = 4;
}
}
cinque::~cinque()
{
closesocket(s_socket);
WSACleanup();
}
void cinque::Recv(char *source)
{
if(recv(s_socket, packet, MAX_PACKET_SIZE, 0) > 0)
{
ip_header = (IPHEADER *) packet;
in_addr in;
in.S_un.S_addr = ip_header->source_ip;
strcpy(source, inet_ntoa(in));
}
}
Później napisałem program który miał sprawdzić działanie tego programu i niestety nie działa. Oto jego kod:
#include <cinque.h>
#include <iostream>
int main()
{
cinque snif;
char ip[20];
while(1)
{
std::cout<<"Listenig...";
snif.Recv(ip);
std::cout<<ip;
}
}
Proszę o jakieś wskazówki lub uwagi dlaczego to nie działa. Myślę że jest to spowodowane tym że rawsocket'y mają wprowadzone jakieś ograniczenia w systemach windows xp i wyższych. Jeśli to jest przyczyną to proszę o podanie linków do jakichś bibliotek lub sposobu aby uzyskać takie uprawnienia.
z góry dziękuję
pozdro