All pastes #574327 Raw Edit

C_Sniffer.cpp

public text v1 · immutable
·published 2007-06-18 14:58 UTC
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;
	
}