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


///////////////////////////////////////////////////////////////////////////////////////////// 
// 
//  EthernetSpyReader.h 
// 
//  Dichiarazioni di strutture e classi usate per leggere i pacchetti dalla rete 
// 
// 
 
#ifndef __ETHERNETSPYREADER_H__ 
#define __ETHERNETSPYREADER_H__ 
 
 
///////////////////////////////////////////////////////////////////////////////////// 
// 
//   Tipi di pacchetti ethernet: 
//     Alcuni possibili valori dei die bypte del  
//     campo Type della struttura _FRAMEETH 
 
#define IP_TYPE				0x0800 
#define X75_TYPE			0x0801 
#define X25_TYPE			0x0805 
#define ARP_TYPE			0x0806 
#define BANYAN_TYPE			0x0BAD 
#define DECMOP1_TYPE		0x6001 
#define DECMOP2_TYPE		0x6002 
#define DECNET_TYPE			0x6003 
#define DECLAT_TYPE			0x6004 
#define DECDIAGNOSTIC_TYPE	0x6005 
#define DECLANBRIDGE_TYPE	0x8038 
#define DECETHENCR_TYPE		0x803D 
#define APPLETALK_TYPE		0x809B 
#define IBMSNA_TYPE			0x80F3 
#define NETWARE_TYPE		0x8137 
#define SNMP_TYPE			0x814C 
 
#define IEEE802_3_TYPE		0x05DC  // i pacchetti di tipo IEEE 802.3 hanno 
									//     Type <= IEEE802_3_TYPE 
									// perchè questo valore indica la lunghezza  
									// del pacchetto e non il tipo. 
 
 
 
 
 
////////////////////////////////////////////////////////////////////////// 
// 
//	Generico pacchetto ethernet 
// 
 
typedef struct _FRAMEETH 
{ 
	BYTE DestAddr[6];   // Indirizzo ethernet destinazione 
	BYTE SrcAddr[6];	// Indirizzo ethernet sorgente 
 
	BYTE Type[2];		// Tipo di pacchetto (o lunghezza per IEEE 802.3) 
						// il valore deve essere letto con la relazione: 
						//      256 * Type[0] + Type[1] 
						// e non semplicemente con un cast esplicito ad  
						// uno short, altrimenti (su una macchina INTEL)  
						// i byte più e meno significativi risultano 
						// scambiati 
 
	BYTE Dati[1500];	// Dati contenuti nel pacchetto 
}  
FRAMEETH, *PFRAMEETH; 
 
 
////////////////////////////////////////////////////////////////////////// 
// 
//	Informazioni aggiuntive relative ad ogni pacchetto memorizzato 
// 
 
typedef struct _PACKET_INFO 
{ 
	ULONG		Num;	// Numero d'ordine (il primo pacchetto ha Num = 1 
						// poi, Num viene incrementato ad ogni pacchetto 
						// ricevuto indipendenete dal fatto che esso venga 
						// memorizzato ) 
 
	DWORD		Time;	// Tempo di ricezione in millesecondi 
	ULONG		Len;	// Lunghezza in byte 
	FRAMEETH	Frame;	// Contenuto del pacchetto 
} 
PACKET_INFO, *PPACKET_INFO; 
 
 
 
////////////////////////////////////////////////////////////////////////////////////////////// 
// 
//	Frame Ethernet contenente un pacchetto di tipo ARP usato per convertire 
//	indirizzi IP in indirizzi Ethernet  
// 
 
typedef struct _ARP_FRAME 
{ 
	BYTE DestAddr[6];		// Indirizzo ethernet destinazione 
	BYTE SrcAddr[6];		// Indirizzo ethernet sorgente 
 
	BYTE Type[2];			// Tipo di pacchetto (o lunghezza per IEEE 802.3) 
							// il valore deve essere letto con la relazione: 
							//      256 * Type[0] + Type[1] 
							// e non semplicemente con un cast esplicito ad  
							// uno short, altrimenti (su una macchina INTEL)  
							// i byte più e meno significativi risultano 
							// scambiati 
 
	BYTE HWType[2];			// Tipo di hardware (in questo caso Ethernet) 
	BYTE ProtocolType[2];	// Tipo di protocollo (in questo caso IP) 
	BYTE HLen;				// Lunghezza del'indirizzo hardware (in questo caso 6 byte ) 
	BYTE PLen;				// Lunghezza del'indirizzo di protocollo (in questo caso 4 Byte) 
	BYTE Operation[2];		// Operazione (ARP o RARP) ? 
	BYTE SenderHWAddr[6];	// Indirizzo hardware mittente 
	BYTE SenderIPAddr[4];	// Indirizzo IP mittente 
	BYTE TargetHWAddr[6];	// Indirizzo hardware destinazione 
	BYTE TargetIPAddr[4];	// Indirizzo IP destinazione 
 
	BYTE Unused[32];		// Byte di riempimento per superare la lunghezza minima 
} 
ARP_FRAME; 
 
 
 
/////////////////////////////////////////////////////////////////////////////////// 
// 
//  Statistiche relative ai pacchetti ricevuti 
// 
 
typedef struct _STATISTICS 
{ 
	ULONG Directed;			// N° pacchketti diretti alla propria macchina 
	ULONG Multicast;		// N° pacchketti multicast 
	ULONG Broadcast;		// N° pacchketti broadcast 
 
	ULONG Total;			// N° pacchketti complessivo 
	 
	ULONG Bytes;			// Bytes ricevuti complessivamente 
 
	ULONG IP;				// N° pacchketti IP 
	ULONG X75;				// N° pacchketti X75 
	ULONG X25;				// N° pacchketti X25 
	ULONG ARP;				// N° pacchketti ARP 
	ULONG Banyan;			// N° pacchketti Banyan 
	ULONG DecMop1;			// N° pacchketti DecMop1 
	ULONG DecMop2;			// N° pacchketti DecMop2 
	ULONG DecNet;			// N° pacchketti DecNet 
	ULONG DecLat;			// N° pacchketti DecLat 
	ULONG DecDiagnostic;	// N° pacchketti DecDiagnostic 
	ULONG DecLanBridge;		// N° pacchketti DecLanBridge 
	ULONG DecEthEncr;		// N° pacchketti DecEthEncr 
	ULONG AppleTalk;		// N° pacchketti AppleTalk 
	ULONG IBMSna;			// N° pacchketti IBMSna	 
	ULONG NetWare;			// N° pacchketti NetWare 
	ULONG SNMP;				// N° pacchketti SNMP 
	ULONG IEEE802_3;		// N° pacchketti IEEE 802.3 
 
	ULONG Unknown;			// N° pacchketti di altro tipo 
	 
	double AvgThroughPut;	// Throughput medio della rete (bit / s) 
	double AvgPktLen;		// Lunghezza media dei pacchetti 
	double AvgPktPerSec;	 
}  
STATISTICS, *PSTATISTICS; 
 
 
//////////////////////////////////////////////////////////////////////////////// 
//			   /////////////////////////////////////////////////////////////////	 
//  SpyFilter  ///////////////////////////////////////////////////////////////// 
//             ///////////////////////////////////////////////////////////////// 
// 
//  Filtro software per i pacchetti ricevuti, usato per scegliere qali 
//  pacchetti debbano essere memorizzati: 
// 
//		Questo filtro non ha alcuna funzionalità, è usato come filtro  
//		di default e lascia passare tutti i pacchetti ricevuti. 
//		 
//		La classe SpyFilter deve essere ereditata da ogni eventuale altro 
//		filtro che debba essere implementato EthernetSpyReader. Per creare  
//		un nuovo filtro è sufficiente scrivere una classe derivata da SpyFilter,  
//		il cui metodo: 
// 
//			BOOL Match(PFRAMEETH Pkt)  
// 
//		restituisca TRUE se il paccketto Pkt soddisfa i criteri di filtraggio 
//		e FALSE altrimenti. 
//		(per un esempio vedere i file 'filter.h' e 'filter.cpp') 
// 
 
class SpyFilter 
{ 
 
public: 
	virtual BOOL Match ( PFRAMEETH ) 
	{ 
		return TRUE; 
	} 
}; 
 
 
 
 
///////////////////////////////////////////////////////////////////////////////////// 
//                     ////////////////////////////////////////////////////////////// 
//  EthernetSpyReader  ////////////////////////////////////////////////////////////// 
//                     ////////////////////////////////////////////////////////////// 
// 
//	Provvede alla lettura e alla memorizzazione dei pacchetti che transitano sulla  
//  rete.  
// 
 
class EthernetSpyReader 
{ 
private:	
	HANDLE				hReadingThread;			// Handle del thread usato per la  
												// lettura dei pacchetti 
 
	LPADAPTER			Adapter;				// Dati relativi alla scheda di rete 
												// usati per comunicare col driver 
		 
	BOOL				KillThread;				// Variabile booleana che se impostata 
												// a TRUE chiede al thread di lettura  
												// di terminare la propria esecuzione 
 
	//CWnd*				Wnd;					// Finestra alla quale viene inviato  
												// il messaggio di notifica della  
												// avvenuta terminazione del thread 
												// di lettura 
	 
	SpyFilter*			SoftwareFilter;			// Filtro software per la memorizzazione 
												// dei pacchetti 
 
	SpyFilter			DefaultSoftwareFilter;	// Filtro software usato quando non ne  
												// viene spacificato uno diverso 
												// (tutti i pacchetti vengono memorizzati) 
 
	 
public: 
 
	UINT				BufLen;					// Dimensione del buffer circolare (in pacchetti) 
												// nel quale il driver TDI scrive i pacchetti  
												// ricevuti dalla rete 
	 
	ULONG				HardwareFilter;			// Filtro hardware correntemente impostato 
												// sulla scheda ethernet 
 
	TCHAR				AdapterName[64];		// Nome della scheda di rete 
 
	BYTE				HardwareAddress[6];		// Indirizzo hardware della scheda ethernet 
 
	ULONG				IPAddress;				// Indirizzo IP della macchina 
 
	UINT				RefreshTime;			// Periodo (in millisecondi)  
												// dell'aggiornamento delle finestre 
 
	STATISTICS			Stats;					// Dati relativi ai pacchetti ricevuti 
 
	CRITICAL_SECTION	CritSecCounters;		// Critical section usata per sincronizzare 
												// l'accesso ai dati contenuti in 'Stats' e 
												// 'Pkt' 
 
	PPACKET_INFO		Pkt;					// Vettore nel quale vengono memorizzati  
												// i pacchetti che passano il filtro software 
												// Questo vettore viene usato come un buffer  
												// circolare (quando è pieno si inizia a scrivere  
												// sui pacchetti ricavuti per primi 
 
	DWORD				StartTime;				// Istante di inizio della raccolta delle  
												// informazioni contenute in 'Stats' (espresso 
												// in millisecondi a partire dall'accensione 
												// della macchina 
 
	ULONG				MaxPkt;					// Dimensione (in numero di pacchetti)  
												// del vettore 'Pkt' 
 
	ULONG				NextPkt;				// Posizione nel buffer 'Pkt' nella quale  
												// verrà memorizzato il prossimo pacchetto 
												// che oltrepassa il filtro software 
 
	ULONG				MaxFrameLen;			// Numero massimo di byte di ogni pacchetto 
												// che vengono memorizzati nel buffer 'Pkt' 
 
	ULONG				StoredPkt;				// Numero di pacchetti che hanno superato  
												// il filtro software. 
												// Se 'StoredPkt < MaxPkt' concide anche con 
												// il numero di pacchetti memorizzati nel 
												// buffer 
			 
 
public: 
	EthernetSpyReader();		// Costruttore 
								 
	~EthernetSpyReader();		// Distruttore 
	 
	void StartReading();		// Fa partire il thread di lettura dei pacchetti 
 
	void StopReading( BOOL Blocking);	// Termina il thread di lettura dei pacchetti: 
										// 
										//	  Blocking = TRUE   attende la terminazione  
										//						del thread 
										// 
										//    Blocking = FALSE	esce immediatamente 
										//						senza attandere la effettiva 
										//						terminazione 
										// 
										// L'attesa della effettiva terminazione del thread 
										// si rende necessaria quando si intenda deallocare 
										// il buffer circolare 'Pkt' per evitare che esso  
										// tenti di accedervi dopo che la memoria è stata  
										// rilasciata 
										 
	void SuspendReading();		// Sospende l'esecuzione del thread di lettura dei pacchetti 
 
	void ResumeReading();		// Riprende l'esecuzione del thread di lettura dei  
								// pacchetti precedentemente interrotto con SuspendReading()		 
 
	void SetReadingPriority(int Priority);	// Imposta la priorità del thread di lettura  
											// dei pacchetti 
 
	void ClearGlobalStats();	// Azzera le statistiche generiche relative ai pacchetti 
								// riceviti 
 
	void ClearTypeStats();		// Azzera le statistiche relative ai tipi di pacchetti 
								// riceviti 
	 
	//void InitializeNetData(CWnd* Wnd = NULL); 
 
	void ResetDriver ();		// Reinizializza il driver annullando tutte le richieste 
								// di lettura pendenti 
 
	BOOL SetHardwareFilter (ULONG Filter);	// Imposta il filtro hardware 
 
	void SetSoftwareFilter (SpyFilter*);	// Imposta il filtro software 
 
	ULONG GetHostIPAddr ();		// Restituisce l'indirizzo IP della propria macchina 
 
	BOOL IPAddrToEthernetAddr (ULONG IPAddr, PBYTE EthAddr);	// converte un indirizzo IP  
																// in un indirizzo ethernet 
																// mediante il protocollo  
																// ARP 
 
	BOOL ConvertAddress (CString S, PBYTE EthAddr);		// converte un indirizzo dato sotto  
														// forma di stringa contenete  
														// l'indirizzo hardware in esadecimale 
														// oppure l'indirizzo IP, oppure  
														// il nome di una macchina, in indirizzo 
														// hardware 
 
	friend DWORD ReadingThread(LPDWORD lpdwParam);		// Thread di lettura dei pacchetti 
}; 
 
//#define WM_THREADTERMINATED (WM_USER+10) 
 
 
#endif