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