Capturer des paquets sans socket?

jonathan100 Messages postés 39 Date d'inscription jeudi 23 janvier 2003 Statut Membre Dernière intervention 3 juin 2003 - 3 févr. 2003 à 14:25
jonathan100 Messages postés 39 Date d'inscription jeudi 23 janvier 2003 Statut Membre Dernière intervention 3 juin 2003 - 21 avril 2003 à 15:58
Bonjour a tous,

Voila je developpe une application de type sniffer en java. Or apparemment il n'est pas possible de capturer des paquets sans passer par un socket. Je ne sais d'ailleurs meme pas si c'est possible tout court.
Cela peut se faire en c++. Je suis a la recherche d'un algo me permettant de lire un paquet sur un reseau ethernet, mais sans y toucher. Le but de cela est de pouvoir les compter afin de faire des statistiques sur le reseau (est-il sature, qui genere l'information ... ).

Si en plus par hasard quelqu'un avait cet algo en java, ou alors si quelqu'un connait assez le JNI pour m'aiguiller, c'est vraiment le bienvenu!

En tout cas merci par avance de votre aide. :)

2 réponses

djo81 Messages postés 1 Date d'inscription samedi 5 avril 2003 Statut Membre Dernière intervention 5 avril 2003
5 avril 2003 à 10:57
-------------------------------
Réponse au message :
-------------------------------

> Bonjour a tous,
>
> Moi aussi je développe un analyseur de trames WLAN pour cela il me faut un algo pour accèder a la carte réseau, j'est fait des recherches et j'est trouver qu'il y a deux méthodes soit en utilisant les sockets en RAW soit en utilisant la bibliothèque libpcap et tout les deux sous l'environnement LINUX voici les deux alog :

Avant de commencer par l'algo je veut vous rappeler que Libpcap est téléchargeable à www.tcpdump.org (tcpdump est aussi un très bon
sniffeur, une fois que l'on sait s'en servir). Pour l'installer, lisez le
INSTALL ou le README avec lequel libpcap est fournit. (RTFM !#@!)

Une fois cela fait, une seule commande est à faire:

virginie:/usr/www/htdocs/mags$ man pcap

(et oui, vous aurez l'aide.)

En lisant la doc, donc, j'ai remarqué (on peut dire trouvé) les deux fonctions
nécessaire pour la réalisation de notre programme:

pcap_t *pcap_open_live(char *device, int snaplen,
int promisc, int to_ms, char *ebuf)

u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)

La première, pcap_open_live, permet:
'pcap_open_live() is used to obtain a packet capture descriptor to look
at packet on the network'.
Elle est utilisée pour obtenir un descripteur de capture de paquets pour
surveiller les datagrammes sur le réseau. Ca va renvoyer, une fois les
paramètres bien choisis, une variable, de type 'pcap_t', qui va permettre
d'agir sur ce genre d'interface virtuel qui joue sur la capture.
Les paramètres sont : 'char *device', chaine de caractères devant comporter
le nom de l'interface réseau, 'int snaplen', entier qui doit spécifier le
nombre maximum d'octets à capturer, 'int promisc', qui doit soit contenir 0,
soit un autre nombre (faux, vrai), pour dire si l'interface doit se situer
en mode promiscious (pour ecouter tout les paquets, meme ceux qui ne sont pas
déstinés à nous), 'int to_ms', le timeout en lecture, 'char *ebuf', le buffer
de sortie d'erreur. (utilisé quand pcap_open_live ne marche pas, ce qui lui
fait retourner une erreur).

Pour pcap_next:
Une fois le descripteur ouvert, on va recevoir des paquets dans les buffers.
pcap_next permet de les lire, un par un, a chaque appel de cette fonction, en
renvoyant l'adresse du prochain paquet.

Qu'est ce que ca donne en programmant ?

# -- test 1 -- #

#include <stdio.h>
// pour les entrées sorties (printf ...)

#include
// pour utiliser libpcap

int main(void)
{
int i;
// on va en avoir besoin pour notre boucle :)

pcap_t *desc = NULL;
// desc = notre descripteur

struct pcap_pkthdr usefull;
// usefull est une structure pcap_pkthdr (header de paquet), type de pcap
// dans notre programme, on doit la définir pour utiliser pcap_next, mais
// on l'utilise pas.

u_char *packet;
// pointeur sur nos paquets captés

if ((desc = pcap_open_live("xl0", 1500, 0, 1000, NULL))==NULL)
{
perror("pcap_open_live()");
exit(1);
}
// on ouvre le device xl0 (BSD: 3com vortex/boomerang), on lit 1500 octets
// par paquets, on ne met pas le périphérique en mode prosmisc, avec un
// timeout de 1000 secondes, et sans buffer d'erreur.

// Si pcap_open_live se passe mal, alors le if s'executera, et on aura le
// droit à l'erreur, et le programme quitera (perror, exit)

printf("A partir de maintenant, je surveille le traffic sur xl0\n");
// Si tout se passe bien

while (1)
// boucle sans fin
// on attend de recevoir pleins de paquets, et donc on doit les recevoir
// pendant cette boucle. Il lira le réseau sans arret.
{
packet = (u_char *) pcap_next(desc, &usefull);
// on lit le prochain paquet. Si il n'y a pas de paquets en attente, alors
// la fonction renvoit NULL (et au bout d'une seconde, 1000 ms (notre timeout)
// sinon, elle renvoit l'adresse du paquet recu, et on le traite après:
if (packet != NULL)
{
// si le paquet n'est pas NULL

for (i=0; i<26;i++)
{
printf("%.2x ",*packet);
// on va faire afficher les 26 premiers caractères, et on les affiche à
// l'écran
packet++;
// prochain paquet.
}
printf("\n");
// fin du paquet, retour à la ligne
}
}
}

> # -- sniffeur en raw -- #

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
// les fichiers d'entete (pour socket(), recvfrom(), les types différents

int main(void)
{
int i;
int sock, bytes_recieved, fromlen;
char buffer[65535];
struct sockaddr_in from;
// variables

sock = socket(AF_INET,SOCK_RAW,0);
// ouverture de la socket elle méme

while (1)
{
bytes_recieved = recvfrom(sock, buffer, sizeof buffer, 0,
(struct sockaddr *)&from, &fromlen);
// reception des données
if (bytes_recieved > 0)
{
for (i=0; i<26;i++)
printf("%.2x ",buffer[i]);
printf("\n");
}
else
perror("recvfrom()");
}
}

Personnelement je travaille sur les sockets et j'aime bien trouver un algo qui marche sur le java, alors si vous avez d'autre information j'aime bien que tu m'envoi un email sur djo0181@yahoo.fr et enfin je vous souhaite une bonne chance et merci :)
0
jonathan100 Messages postés 39 Date d'inscription jeudi 23 janvier 2003 Statut Membre Dernière intervention 3 juin 2003
21 avril 2003 à 15:58
Bonjour,

Désolé pour le retard de ma réponse.
Non malheureursement je n'ai toujours rien trouvé pour cela en Java. Visiblement pour le Java, le socket fonctionne juste entre deux machines. Or nous cherchons ici autre chose car il faut capturer tous les paquets transitant sur le réseau. Pour cela la carte doit être configurée en mode promiscuous, ce que permet le C, mais je ne suis pas arrivé a cela en Java.

La meilleure solution je pense est de capturer les paquets en C, et d'utiliser le JNI (Java Native Interface) pour appliquer les données capturées a l'application Java. je ne me suis pas encore penché sur la question.
Mais êtres-vous sur que cela fonctionne avec un socket? Un socket fonctionne au niveau middleware de la couche OSI, alors que la capture s'opère au niveau 1 (matériel).

Merci de me tenir informer. ++
0
Rejoignez-nous