L'astrazione della java virtual machine pone il limite alla realizzazione di programmi Java in grado di interagire a basso livello con l'hardware della macchina. Tuttavia ricorrendo ai metodi nativi (JNI) e utilizzando degli espedienti opportuni, è stato possibile realizzare una libreria Java, Jpcap per l’appunto, in grado di gestire la scheda di rete in modalità promiscua ed utilizzare il sistema molto veloce di filtraggio dei pacchetti del BPF.
Jpcap è un progetto nato nel giugno del 2000 da un'idea di Keita Fujii e distribuito con licenza GNU , GENERAL PUBLIC LICENSE, durante gli ultimi anni la libreria non ha subito sostanziali cambiamenti, un suo ultimo aggiornamento risale al settembre del 2003. Esiste un altro progetto simile iniziato nel maggio del 2001 completamente Open Source sviluppato dalla NetSourceForge ed in continua evoluzione, tale progetto può vantare in più un Tool per la visualizzazione del traffico di rete e funzioni aggiuntive per la gestione del traffico catturato. Entrambe utilizzano la Libpcap. Tra le due si è deciso di utilizzare quella sviluppata da Keita Fujii che non si discosta molto dalla interfaccia delle funzioni della libreria Libpcap risultando più semplice da utilizzare, mentre nella Jpcap sviluppata dalla NetSourceForge le interfacce delle funzioni sono state completamente ridisegnate.
Il package Jpcap si avvale di una interfaccia e di una serie di classi per la cattura, l’analisi e la manipolazione di pacchetti di rete.
La classe principale è Jpcap che permette di accedere alla libreria di sistema utilizzata per catturare i pacchetti, ecco la gerarchia di ereditarietà relativa alla classe in questione:
Class Jpcap
java.lang.Object
|
+--jpcap.Jpcap
tra i metodi più importanti che mette a disposizione abbiamo:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Un’altra classe importante legata strettamente a quella precedentemente descritta è la classe Packet tale classe contiene i campi relativi ai pacchetti catturati mediante la classe Jpcap. Ecco la gerarchia di ereditarietà relativa alla classe in questione:
Class Packet
java.lang.Object
|
+--jpcap.Packet
I campi che è possibile prendere in considerazione sono:
byte[] |
data Rappresenta il campo dati del pacchetto |
DatalinkPacket |
datalink E’ il Datalink Layer |
byte[] |
header Rappresenta il campo Header |
int |
len E’ la lunghezza del pacchetto catturato |
Nella realizzazione dello Sniffer Talk gli unici pacchetti che andremo ad analizzare che non filtreremo saranno quelli provenienti dai protocolli TCP e UDP.
Il package Jpcap mette a disposizione due classi che sono ad hoc per il nostro scopo. Le classi sono:
La prima rappresenta i pacchetti TCP mentre la seconda rappresenta i pacchetti UDP. Ecco la gerarchia di ereditarietà relativa alla prima classe:
Class TCPPacket
java.lang.Object
|
+--jpcap.Packet
|
+--jpcap.IPPacket
|
+--jpcap.TCPPacket
Ed ecco alcuni dei campi che mette a disposizione la seguente classe per rappresentare i pacchetti di tipo TCP:
long |
ack_num Numero dell’ACK |
long |
sequence Numero della sequenza |
int |
dst_port Numero della porta di destinazione |
int |
src_port Numero della porta sorgente |
Ecco la gerarchia di ereditarietà relativa alla seconda classe:
Class UDPPacket
java.lang.Object
|
+--jpcap.Packet
|
+--jpcap.IPPacket
|
+--jpcap.UDPPacket
Ed ecco alcuni dei campi che mette a disposizione la seguente classe per rappresentare i pacchetti di tipo UDP:
int |
dst_port Numero della porta di destinazione |
int |
src_port Numero della porta sorgente |
int |
length Lunghezza del pacchetto |
L’unica interfaccia utilizzata nel package è la :
Inferface JpcapHandler
Questa interfaccia è utilizzata per definire un metodo per analizzare i pacchetti catturati, questa interfaccia è utilizzata in Jpcap.processPacket() e Jpcap.loopPacket(), e rappresenta l'handle per la procedura che riceve il pacchetto catturato. L’unico metodo disponibile è:
void |
handlePacket (Packet p) Analizza un pacchetto. Questo metodo è chiamato ogni volta che un pacchetto è catturato. |
Il wrapper Jpcap mette a nostra disposizione le funzionalità della libreria libpcap, ma in Java, così da utilizzare questo linguaggio come base per catturare ed analizzare i pacchetti di rete. Il ponte creato da Jpcap rappresenta una soluzione interessante perché, se da un lato fornisce un accesso alla libreria originale sotto una piattaforma di sviluppo nota e diffusa, dall’altro si interfaccia ad essa in una maniera che non ne altera la sostanza. Jpcap è una astrazione di libpcap che ci risparmia la necessità di lavorare con complesse strutture dati, puntatori, handler di funzioni, e via dicendo.
Oltre all'implementazione della libreria Jpcap da noi utilizzata, esiste un'ulteriore implementazione sviluppata come progetto open source disponibile sul sito sourceforge.net.
Sebbene le due implementazioni assolvono i medesimi compiti, risultano molto differenti per le API messe a disposizione. La nostra decisione nella scelta dell'implementazione della libreria da utilizzare è dovuta alla maggiore similarità col la libreria originale libpcap, sebbene il progetto della sourceforge.net risulti più completo e in continua evoluzione.
Nel nostro caso il multi-threading è risultato utile in quanto ha reso possibile la suddivisione logica del processo di sniffing del nostro programma. Infatti si è deciso di utilizzare due tipi di thread, un primo responsabile dello sniffing dei messaggi di controllo sul canale UDP e un secondo tipo di thread responsabile dello sniffing dei messaggi relativi ad ogni singola sessione Talk tra ogni coppia di utenti.