www.pudn.com > EthernetSpy.zip > EthernetSpyReader.cpp


#include  
#include  
#include  
 
#include "ntddndis.h" 
#include "packet32.h" 
#include "EthernetSpyReader.h" 
 
#define IsBroadcast(Addr) (Addr[0]&Addr[1]&Addr[2]&Addr[3]&Addr[4]&Addr[5] == 0xFF) 
#define IsMulticast(Addr) (FALSE) 
#define SWAP(p) (((p)<<8)|((p)>>8)) 
 
 
DWORD ReadingThread(LPDWORD lpdwParam) 
{ 
	EthernetSpyReader* SpyReader = (EthernetSpyReader *) lpdwParam; 
	PSTATISTICS Stats = &(SpyReader->Stats); 
 
	LPPACKET    *Packet; 
	HANDLE		hFrame; 
	PFRAMEETH   Frame; 
	PULONG      FrameLength; 
 
	USHORT FrameType; 
		 
	BOOL Error; 
	 
	UINT i; 
 
	Packet = (LPPACKET *)malloc (SpyReader->BufLen * sizeof(PVOID)); 
	 
	hFrame = GlobalAlloc (GMEM_MOVEABLE, SpyReader->BufLen * sizeof (FRAMEETH)); 
	Frame = (PFRAMEETH) GlobalLock(hFrame); 
 
	FrameLength = (PULONG) malloc (SpyReader->BufLen * sizeof(LONG)); 
		 
	Error = FALSE; 
	for (i = 0; i < SpyReader->BufLen && !Error; i++) 
	{ 
		Packet[i] = PacketAllocatePacket(); 
	 
		Error = Packet[i] == NULL; 
	 
		if (!Error)  
		{ 
			FrameLength[i] = 0; 
 
			PacketInitPacket( Packet[i],  
							  (PVOID)(&Frame[i]),  
							  sizeof(FRAMEETH)); 
 
			PacketReceivePacket( SpyReader->Adapter, 
								 Packet[i],  
								 FALSE,  
								 &(FrameLength[i])); 
		} 
	} 
 
	if (!Error)  
	{		 
		for (i = 0 ; SpyReader->KillThread == FALSE; i = (i + 1) % SpyReader->BufLen) 
		{					 
			PacketWaitPacket( SpyReader->Adapter, 
					 		  Packet[i],  
							  &(FrameLength[i]) ); 
		 
			// CALCOLO DELLE STATISTICHE 
		 
			EnterCriticalSection(&(SpyReader->CritSecCounters)); 
		    {			 
				Stats->Total++; 
 
				FrameType = (USHORT)(Frame[i].Type[0]) + (USHORT)(Frame[i].Type[1]) << 8; 
				 
				if( IsBroadcast(Frame[i].DestAddr) ) 
				{ 
					Stats->Broadcast++; 
				} 
				else if( IsMulticast(Frame[i].DestAddr) ) 
				{ 
					Stats->Multicast++; 
				} 
				else 
				{ 
					Stats->Directed++; 
				} 
 
				if( FrameType < IEEE802_3_TYPE ) 
				{ 
					Stats->IEEE802_3++; 
				} 
				else 
				{ 
					switch(FrameType) 
					{ 
						case IP_TYPE: 
							Stats->IP++; 
							break; 
	 
						case X75_TYPE: 
							Stats->X75++; 
							break; 
 
						case X25_TYPE: 
							Stats->X25++; 
							break; 
						 
						case ARP_TYPE: 
							Stats->ARP++; 
							break; 
 
						case BANYAN_TYPE: 
							Stats->Banyan++; 
							break; 
 
						case DECMOP1_TYPE: 
							Stats->DecMop1++; 
							break; 
 
						case DECMOP2_TYPE: 
							Stats->DecMop2++; 
							break; 
 
						case DECNET_TYPE: 
							Stats->DecNet++; 
							break; 
 
						case DECLAT_TYPE: 
							Stats->DecLat++; 
							break; 
 
						case DECDIAGNOSTIC_TYPE: 
							Stats->DecDiagnostic++; 
							break; 
 
						case DECLANBRIDGE_TYPE: 
							Stats->DecLanBridge++; 
							break; 
 
						case DECETHENCR_TYPE: 
							Stats->DecEthEncr++; 
							break; 
 
						case APPLETALK_TYPE: 
							Stats->AppleTalk++; 
							break; 
 
						case IBMSNA_TYPE: 
							Stats->IBMSna++; 
							break; 
 
						case NETWARE_TYPE: 
							Stats->NetWare++; 
							break; 
 
						case SNMP_TYPE: 
							Stats->SNMP++; 
							break; 
 
						default: 
							Stats->Unknown++; 
					} 
				} 
 
				Stats->Bytes += FrameLength[i]; 
				 
				SpyReader->Pkt[SpyReader->NextPkt].Num = Stats->Total; 
				SpyReader->Pkt[SpyReader->NextPkt].Time = GetTickCount(); 
				SpyReader->Pkt[SpyReader->NextPkt].Len = FrameLength[i]; 
			 
				Stats->AvgThroughPut = (double)Stats->Bytes * 8.0 / (double)( SpyReader->Pkt[SpyReader->NextPkt].Time - SpyReader->StartTime ); 
				Stats->AvgPktLen = (double)Stats->Bytes / (double)Stats->Total; 
				Stats->AvgPktPerSec = (double)Stats->Total / (double)( SpyReader->Pkt[SpyReader->NextPkt].Time - SpyReader->StartTime ) * 1000.0; 
				 
				if( SpyReader->SoftwareFilter->Match( &(Frame[i]) ) == TRUE ) 
				{ 
					memcpy(&(SpyReader->Pkt[SpyReader->NextPkt].Frame), &(Frame[i]), SpyReader->MaxFrameLen); 
					SpyReader->StoredPkt++; 
					SpyReader->NextPkt = (SpyReader->NextPkt+1) % SpyReader->MaxPkt; 
				} 
			} 
			LeaveCriticalSection(&(SpyReader->CritSecCounters)); 
 
			// FINE CALCOLO DELLE STATISTICHE 
 
			PacketReceivePacket( SpyReader->Adapter, 
								 Packet[i],  
								 FALSE,  
								 &(FrameLength[i])); 
		} 
 
		SpyReader->ResetDriver(); 
 
		 
		for (i = 0; i < SpyReader->BufLen; i++) 
			PacketFreePacket(Packet[i]); 
 
	}      
	else 
	{		 
		for ( i-- ; i > 0; i--) 
			PacketFreePacket(Packet[i - 1]); 
	} 
	 
	free(Packet); 
	GlobalFree(hFrame); 
	free(FrameLength); 
 
//   	if (SpyReader->Wnd) 
//		SpyReader->Wnd->PostMessage(WM_THREADTERMINATED, 0, 0); 
	 
	return 0; 
} 
 
 
EthernetSpyReader::EthernetSpyReader() 
{	 
	SoftwareFilter = &DefaultSoftwareFilter; 
	 
	BufLen = 10; 
	RefreshTime = 250; 
	 
	StoredPkt = 0; 
	memset(&Stats, 0, sizeof(Stats)); 
	MaxPkt = 1000; 
	MaxFrameLen = 1514; 
 
	Pkt = (PPACKET_INFO)malloc(MaxPkt*sizeof(PACKET_INFO)); 
	 
	InitializeCriticalSection(&CritSecCounters); 
	 
	ULONG NameLength=64; 
    PacketGetAdapterNames(AdapterName, &NameLength); 
     
	Adapter=PacketOpenAdapter(AdapterName); 
	 
	SetHardwareFilter (NDIS_PACKET_TYPE_PROMISCUOUS); 
	 
	PacketQueryHardwareAddress( Adapter, HardwareAddress); 
 
	IPAddress = GetHostIPAddr(); 
} 
 
EthernetSpyReader::~EthernetSpyReader() 
{ 
	PacketCloseAdapter(Adapter); 
 
	free(Pkt); 
} 
 
void EthernetSpyReader::StartReading() 
{ 
	DWORD dwThreadId; 
 
	StartTime = GetTickCount(); 
	 
	memset (&Stats, 0, sizeof(Stats)); 
 
	NextPkt = 0; 
	StoredPkt = 0; 
 
	KillThread = FALSE; 
	hReadingThread = CreateThread(  
						NULL,		                         /* no security attributes        */  
						0,					                 /* use default stack size        */  
						(LPTHREAD_START_ROUTINE)ReadingThread, /* thread function       */  
						(LPDWORD) this,				         /* argument to thread function   */  
						0,									 /* use default creation flags    */  
						&dwThreadId);						 /* returns the thread identifier */  
 
} 
 
void EthernetSpyReader::StopReading( BOOL Blocking ) 
{ 
	DWORD ExitCode; 
	 
	KillThread = TRUE; 
 
	ResumeThread( hReadingThread ); 
 
	if (Blocking) 
	{ 
		do 
		{ 
			GetExitCodeThread( hReadingThread, &ExitCode ); 
			Sleep(10); 
		}  
		while( ExitCode== STILL_ACTIVE ); 
	} 
} 
 
void EthernetSpyReader::SuspendReading(void) 
{ 
	SuspendThread( hReadingThread ); 
} 
 
void EthernetSpyReader::ResumeReading( void ) 
{ 
	ResumeThread( hReadingThread ); 
} 
 
void EthernetSpyReader::SetReadingPriority(int Priority) 
{ 
	SetThreadPriority (hReadingThread, Priority); 
} 
 
void EthernetSpyReader::ClearGlobalStats() 
{ 
	EnterCriticalSection(&CritSecCounters); 
	{ 
		Stats.Total = 0; 
		Stats.Broadcast = 0; 
		Stats.Multicast = 0; 
		Stats.Bytes = 0; 
		 
		StartTime = GetTickCount(); 
	} 
	LeaveCriticalSection(&CritSecCounters); 
} 
 
void EthernetSpyReader::ClearTypeStats( ) 
{ 
	EnterCriticalSection(&CritSecCounters); 
	{ 
		Stats.IP = 0; 
		Stats.X75 = 0; 
		Stats.X25 = 0; 
		Stats.ARP = 0; 
		Stats.Banyan = 0; 
		Stats.DecMop1 = 0; 
		Stats.DecMop2 = 0; 
		Stats.DecNet = 0; 
		Stats.DecLat = 0; 
		Stats.DecDiagnostic = 0; 
		Stats.DecLanBridge = 0; 
		Stats.DecEthEncr = 0; 
		Stats.AppleTalk = 0; 
		Stats.IBMSna = 0; 
		Stats.NetWare = 0; 
		Stats.SNMP = 0; 
		Stats.IEEE802_3 = 0; 
		Stats.Unknown = 0; 
	} 
	LeaveCriticalSection(&CritSecCounters);	 
} 
/* 
void EthernetSpyReader::InitializeNetData(CWnd* _Wnd) 
{ 
	Wnd = _Wnd; 
	 
	StartTime = GetTickCount(); 
	 
	memset (&Stats, 0, sizeof(Stats)); 
 
	NextPkt = 0; 
	StoredPkt = 0; 
} 
*/ 
 
void EthernetSpyReader::ResetDriver () 
{ 
	PacketCloseAdapter (Adapter); 
	 
	Adapter = PacketOpenAdapter (AdapterName); 
 
	SetHardwareFilter (HardwareFilter); 
} 
 
 
BOOL EthernetSpyReader::SetHardwareFilter(ULONG Filter) 
{ 
	HardwareFilter = Filter; 
 
	return PacketSetFilter(Adapter, Filter); 
} 

void EthernetSpyReader::SetSoftwareFilter (SpyFilter* _Filter)
{
	if (_Filter) 
		SoftwareFilter = _Filter; 
	else 
		SoftwareFilter = &DefaultSoftwareFilter;
} 
 
#define MAXHOSTNAME 255 
 
ULONG EthernetSpyReader::GetHostIPAddr () 
{ 
/*----------------------------------------------------------- 
 * Function: GetHostID() 
 * 
 * Description:  
 *  Get the Local IP address using the following algorithm: 
 *    - get local hostname with gethostname() 
 *    - attempt to resolve local hostname with gethostbyname() 
 *    if that fails: 
 *    - get a UDP socket 
 *    - connect UDP socket to arbitrary address and port 
 *    - use getsockname() to get local address 
 */ 
 
    char szLclHost [MAXHOSTNAME]; 
    LPHOSTENT lpstHostent; 
    SOCKADDR_IN stLclAddr; 
    SOCKADDR_IN stRmtAddr; 
    int nAddrSize = sizeof(SOCKADDR); 
    SOCKET hSock; 
    int nRet; 
     
    /* Init local address (to zero) */ 
    stLclAddr.sin_addr.s_addr = INADDR_ANY; 
     
    /* Get the local hostname */ 
    nRet = gethostname(szLclHost, MAXHOSTNAME);  
    if (nRet != SOCKET_ERROR) { 
      /* Resolve hostname for local address */ 
      lpstHostent = gethostbyname((LPSTR)szLclHost); 
      if (lpstHostent) 
        stLclAddr.sin_addr.s_addr = *((u_long FAR*) (lpstHostent->h_addr)); 
    }  
     
    /* If still not resolved, then try second strategy */ 
    if (stLclAddr.sin_addr.s_addr == INADDR_ANY) { 
      /* Get a UDP socket */ 
      hSock = socket(AF_INET, SOCK_DGRAM, 0); 
      if (hSock != INVALID_SOCKET)  { 
        /* Connect to arbitrary port and address (NOT loopback) */ 
        stRmtAddr.sin_family = AF_INET; 
        stRmtAddr.sin_port   = htons(IPPORT_ECHO); 
        stRmtAddr.sin_addr.s_addr = inet_addr("128.127.50.1"); 
        nRet = connect(hSock, 
                       (LPSOCKADDR)&stRmtAddr, 
                       sizeof(SOCKADDR)); 
        if (nRet != SOCKET_ERROR) { 
          /* Get local address */ 
          getsockname(hSock,  
                      (LPSOCKADDR)&stLclAddr,  
                      (int FAR*)&nAddrSize); 
        } 
        closesocket(hSock);   /* we're done with the socket */ 
      } 
    } 
    return (stLclAddr.sin_addr.s_addr); 
} 

 
/* 
BOOL EthernetSpyReader::IPAddrToEthernetAddr (ULONG IPAddr, PBYTE EthAddr) 
{ 
	ARP_FRAME SendFrame; 
	ARP_FRAME RcvFrame; 
 
	LPPACKET SendPacket; 
	LPPACKET RcvPacket; 
 
	ULONG Len; 
 
	memset (SendFrame.DestAddr, 0xFF, 6); 
	memcpy (SendFrame.SrcAddr, HardwareAddress, 6); 
	 
	SendFrame.Type[0] = 0x08; 
	SendFrame.Type[1] = 0x06; 
 
	SendFrame.HWType[0] = 0; 
	SendFrame.HWType[1] = 1; 
 
	SendFrame.ProtocolType[0] = 0x08; 
	SendFrame.ProtocolType[1] = 0x00; 
 
	SendFrame.HLen = 6; 
	SendFrame.PLen = 4; 
 
	SendFrame.Operation[0] = 0; 
	SendFrame.Operation[1] = 1; 
 
	memcpy (SendFrame.SenderHWAddr, HardwareAddress, 6); 
	memcpy (SendFrame.SenderIPAddr, &IPAddress, 4); 
	memset (SendFrame.TargetHWAddr, 0, 6); 
	memcpy (SendFrame.TargetIPAddr, &IPAddr, 4); 
 
	memset (SendFrame.Unused, 0, 32); 
 
	PacketSetFilter(Adapter, NDIS_PACKET_TYPE_DIRECTED); 
 
	SendPacket = PacketAllocatePacket (); 
	PacketInitPacket (SendPacket, &SendFrame, sizeof (SendFrame)); 
 
	memset (&RcvFrame, 0, sizeof(RcvFrame)); 
	RcvPacket = PacketAllocatePacket (); 
	PacketInitPacket (RcvPacket, &RcvFrame, sizeof (SendFrame)); 
 
 
	while ( RcvFrame.Type[0] != 0x08 || RcvFrame.Type[1] != 0x06 ||  
			RcvFrame.Operation[0] != 0 || RcvFrame.Operation[1] != 2 || 
		    memcmp(RcvFrame.SenderIPAddr, &IPAddr, 4) ) 
	{ 
	//	PacketSendPacket (Adapter, SendPacket, FALSE); 
	//	PacketSendPacket (Adapter, SendPacket, FALSE); 
	 
		PacketReceivePacket (Adapter, RcvPacket, FALSE, &Len); 
		PacketSendPacket (Adapter, SendPacket, FALSE); 
		PacketWaitPacket (Adapter, RcvPacket, &Len);		 
	} 
	 
 
	memcpy (EthAddr, RcvFrame.SenderHWAddr, 6); 
 
	PacketFreePacket (SendPacket); 
	PacketFreePacket (RcvPacket); 
 
	PacketSetFilter(Adapter, HardwareFilter); 
	 
	return TRUE; 
} 
 
*/ 
 
BOOL EthernetSpyReader::IPAddrToEthernetAddr (ULONG IPAddr, PBYTE EthAddr) 
{ 
	ARP_FRAME SendFrame; 
	LPPACKET SendPacket; 
 
	ARP_FRAME* RcvFrame; 
 
	ULONG i, j, LastRead, NumRead; 
 
	BOOL Result; 
 
	SpyFilter* OldFilter = SoftwareFilter; 
 
	SoftwareFilter = &DefaultSoftwareFilter; 
 
	memset (SendFrame.DestAddr, 0xFF, 6); 
	memcpy (SendFrame.SrcAddr, HardwareAddress, 6); 
	 
	SendFrame.Type[0] = 0x08; 
	SendFrame.Type[1] = 0x06; 
 
	SendFrame.HWType[0] = 0; 
	SendFrame.HWType[1] = 1; 
 
	SendFrame.ProtocolType[0] = 0x08; 
	SendFrame.ProtocolType[1] = 0x00; 
 
	SendFrame.HLen = 6; 
	SendFrame.PLen = 4; 
 
	SendFrame.Operation[0] = 0; 
	SendFrame.Operation[1] = 1; 
 
	memcpy (SendFrame.SenderHWAddr, HardwareAddress, 6); 
	memcpy (SendFrame.SenderIPAddr, &IPAddress, 4); 
	memset (SendFrame.TargetHWAddr, 0, 6); 
	memcpy (SendFrame.TargetIPAddr, &IPAddr, 4); 
 
	memset (SendFrame.Unused, 0, 32); 
 
	PacketSetFilter(Adapter, NDIS_PACKET_TYPE_DIRECTED); 
 
	SendPacket = PacketAllocatePacket (); 
	PacketInitPacket (SendPacket, &SendFrame, sizeof (SendFrame)); 
 
	Result = FALSE; 
 
	for (j = 0; j < 5 && !Result; j++) 
	{ 
		LastRead = NextPkt; 
		 
		PacketSendPacket (Adapter, SendPacket, FALSE); 
 
		Sleep (1000); 
 
		NumRead = NextPkt - LastRead; 
 
		for (i = 0; i < NumRead; i++) 
		{ 
			RcvFrame = (ARP_FRAME *)(&Pkt[(LastRead+i) % MaxPkt].Frame); 
		 
			if ( RcvFrame->Type[0] == 0x08 && RcvFrame->Type[1] == 0x06 &&  
				 RcvFrame->Operation[0] == 0 && RcvFrame->Operation[1] == 2 && 
				 memcmp(RcvFrame->SenderIPAddr, &IPAddr, 4) == 0 ) 
			{ 
				Result = TRUE; 
				break; 
			} 
		} 
	}	 
 
	if (Result) 
		memcpy (EthAddr, RcvFrame->SenderHWAddr, 6); 
	else 
		memset (EthAddr, 0, 6); 
 
	SoftwareFilter = OldFilter; 
 
	PacketFreePacket (SendPacket); 
	PacketSetFilter(Adapter, HardwareFilter); 
	 
	return Result; 
} 
 
 
 
 
 
 
 
#define ASCII_TO_EXE(c) (c >= 'A' ? c-'A'+10 : c-'0')  
 
BOOL EthernetSpyReader::ConvertAddress (CString S, PBYTE EthAddr) 
{ 
	hostent* Host; 
 
	ULONG IPAddr; 
 
	if (S != "") 
	{ 
		if ((Host = gethostbyname (S)) != NULL) 
		{ 
			memcpy (&IPAddr, Host->h_addr, 4); 
		 
			return IPAddrToEthernetAddr (IPAddr, EthAddr);		 
		} 
		else 
		{ 
			S.MakeUpper (); 
 
			memset (EthAddr, 0, 6); 
 
			for(int i = 0; i < min(12, S.GetLength()) / 2; i++) 
			{ 
				EthAddr[i] = ASCII_TO_EXE( S[2*i] ) * 16 + ASCII_TO_EXE( S[2*i+1] ); 
			}	 
					 
			return TRUE; 
		}	 
	} 
 
	memset (EthAddr, 0, 6); 
 
	return FALSE; 
}