rendered paste body
#include <iostream>
#include "C_Sniffer.h"
std::queue<C_Sniffer::S_WinPcapPacket> C_Sniffer::m_Packets;
CRITICAL_SECTION C_Sniffer::m_PacketsSection;
C_Sniffer::C_Sniffer(void) : m_ThreadCapturingRunning(false), m_ThreadProcessingRunning(false)
{
InitializeCriticalSection(&m_PacketsSection);
}
C_Sniffer::~C_Sniffer(void)
{
DeleteCriticalSection(&m_PacketsSection);
}
bool C_Sniffer::IsRunning()
{
return m_ThreadCapturingRunning;
}
bool C_Sniffer::Start()
{
pcap_if_t *alldevs;
pcap_if_t *d;
int inum;
int i=0;
char errbuf[PCAP_ERRBUF_SIZE];
if(m_ThreadCapturingRunning == true)
{
return false;
}
// Retrieve the device list
if(pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}
// Print the list
for(d=alldevs; d; d=d->next)
{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else
printf(" (No description available)\n");
}
if(i==0)
{
printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
return false;
}
printf("Enter the interface number (1-%d):",i);
scanf("%d", &inum);
if(inum < 1 || inum > i)
{
printf("\nInterface number out of range.\n");
// Free the device list
pcap_freealldevs(alldevs);
return false;
}
// Jump to the selected adapter
for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
// Open the device
// Open the adapter
if ((m_CapturingArgs.m_Handle = pcap_open_live(d->name, // name of the device
65536, // portion of the packet to capture.
// 65536 grants that the whole packet will be captured on all the MACs.
1, // promiscuous mode (nonzero means promiscuous)
1000, // read timeout
errbuf // error buffer
)) == NULL)
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
// Free the device list
pcap_freealldevs(alldevs);
return false;
}
printf("\nlistening on %s...\n", d->description);
// At this point, we don't need any more the device list. Free it
pcap_freealldevs(alldevs);
m_ThreadProcessingId = 0;
m_ProcessingArgs.m_Instance = this;
m_ProcessingArgs.m_Running = true;
m_ThreadProcessingRunning = true;
m_ThreadProcessing = CreateThread(
NULL, // default security attributes
0, // use default stack size
ThreadProcessingProc, // thread function
&m_ProcessingArgs, // argument to thread function
0, // use default creation flags
&m_ThreadProcessingId); // returns the thread identi
// start the capture
if(m_ThreadProcessing == NULL)
{
m_ThreadProcessingRunning = false;
return false;
}
m_ThreadCapturingId = 0;
m_CapturingArgs.m_Instance = this;
m_CapturingArgs.m_Running = true;
m_ThreadCapturingRunning = true;
m_ThreadCapturing = CreateThread(
NULL, // default security attributes
0, // use default stack size
ThreadCapturingProc, // thread function
&m_CapturingArgs, // argument to thread function
0, // use default creation flags
&m_ThreadCapturingId); // returns the thread identi
// start the capture
if(m_ThreadCapturing == NULL)
{
m_ThreadCapturingRunning = false;
return false;
}
return true;
}
bool C_Sniffer::Stop()
{
if(m_ThreadCapturingRunning == false)
{
return false;
}
m_CapturingArgs.m_Running = false; // Ukoncime vlakno
Sleep(250);
SuspendThread(m_ThreadCapturing);
CloseHandle(m_ThreadCapturing);
pcap_close(m_CapturingArgs.m_Handle);
m_ProcessingArgs.m_Running = false; // Ukoncime vlakno
Sleep(250);
SuspendThread(m_ThreadProcessing);
CloseHandle(m_ThreadProcessing);
return true;
}
DWORD WINAPI C_Sniffer::ThreadCapturingProc( LPVOID lpParam )
{
S_ThreadArgs* args = (S_ThreadArgs*)lpParam;
pcap_loop(args->m_Handle, 0, Callback, NULL);
return EXIT_SUCCESS;
}
DWORD WINAPI C_Sniffer::ThreadProcessingProc( LPVOID lpParam )
{
S_ThreadArgs* args = (S_ThreadArgs*)lpParam;
static bool inside = false;
struct tm *ltime;
char timestr[16];
ip_header *ih;
udp_header *uh;
u_int ip_len;
u_short sport,dport;
time_t local_tv_sec;
while(args->m_Running)
{
if(m_Packets.size() <= 0)
{
continue;
}
EnterCriticalSection(&m_PacketsSection);
S_WinPcapPacket packet = m_Packets.front();
m_Packets.pop();
LeaveCriticalSection(&m_PacketsSection);
/* convert the timestamp to readable format */
local_tv_sec = packet.header.ts.tv_sec;
ltime=localtime(&local_tv_sec);
/* retireve the position of the ip header */
ih = (ip_header *) (packet.data +14); //length of ethernet headers
/* retireve the position of the udp header */
ip_len = (ih->ver_ihl & 0xf) * 4;
uh = (udp_header *) ((u_char*)ih + ip_len);
/* convert from network byte order to host byte order */
sport = ntohs( uh->sport );
dport = ntohs( uh->dport );
char hostname_source[255];
char hostname_destination[255];
struct hostent* host;
T_ResolveMap::iterator it;
it = args->m_Instance->m_IpResolver.find(*(long*)&ih->saddr);
if(it != args->m_Instance->m_IpResolver.end())
{
strncpy(hostname_source,it->second.c_str(), sizeof(hostname_source)/sizeof(hostname_source[0]));
}
else
{
host = gethostbyaddr((char *) &ih->saddr, 4, AF_INET);
hostname_source[0] = '\0';
if(host)
{
strncpy(hostname_source, host->h_name, sizeof(hostname_source)/sizeof(hostname_source[0]));
args->m_Instance->m_IpResolver.insert(T_ResolvePair(*(long*)&ih->saddr, host->h_name));
}
else
{
strcpy(hostname_source,"N/A");
args->m_Instance->m_IpResolver.insert(T_ResolvePair(*(long*)&ih->saddr, "N/A"));
}
}
it = args->m_Instance->m_IpResolver.find(*(long*)&ih->daddr);
if(it != args->m_Instance->m_IpResolver.end())
{
strncpy(hostname_destination, it->second.c_str(), sizeof(hostname_destination)/sizeof(hostname_destination[0]));
}
else
{
host = gethostbyaddr((char *) &ih->daddr, 4, AF_INET);
hostname_destination[0] = '\0';
if(host)
{
strncpy(hostname_destination, host->h_name, sizeof(hostname_destination)/sizeof(hostname_destination[0]));
args->m_Instance->m_IpResolver.insert(T_ResolvePair(*(long*)&ih->saddr, host->h_name));
}
else
{
strcpy(hostname_destination,"N/A");
args->m_Instance->m_IpResolver.insert(T_ResolvePair(*(long*)&ih->saddr, "N/A"));
}
}
if(ltime)
{
strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);
}
else
{
timestr[0] = '\0';
}
/* print ip addresses and udp ports */
// /*
printf("%s,%.6d len:%d %d.%d.%d.%d:%d (%s) -> %d.%d.%d.%d:%d (%s)\n",
timestr, packet.header.ts.tv_usec, packet.header.len,
ih->saddr.byte1, ih->saddr.byte2, ih->saddr.byte3, ih->saddr.byte4, sport, hostname_source,
ih->daddr.byte1, ih->daddr.byte2, ih->daddr.byte3, ih->daddr.byte4, dport, hostname_destination
);
// */
/*
std::cout << timestr ", " << packet.header->ts.tv_usec << " len:" << packet.header->len
<< ih->saddr.byte1 << "." << ih->saddr.byte2 << "." << ih->saddr.byte3 << "." ih->saddr.byte4 << ":" <<sport, hostname_source,
<< ih->daddr.byte1, ih->daddr.byte2, ih->daddr.byte3, ih->daddr.byte4, dport, hostname_destination
// */
}
return EXIT_SUCCESS;
}
void C_Sniffer::Callback(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
S_WinPcapPacket packet(header,pkt_data);
EnterCriticalSection(&m_PacketsSection);
m_Packets.push(packet);
LeaveCriticalSection(&m_PacketsSection);
return;
}