IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Programmation d'un Sniffer en C


Sujet :

C

  1. #1
    Membre à l'essai
    Inscrit en
    Mars 2007
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 7
    Par défaut Programmation d'un Sniffer en C
    Bonjour, je suis encore novice en programmation en C et je souhaite créer un sniffer en C. J'ai récupéré le code source d'un sniffer très simple qui utilise la fonction pcap_next pour afficher la taille des paquets capturer. Je voudrais remplacer cette fonction par une fonction de type pcap_loop faisant appel à une fonction de callback appelée got_packet. Cette focntion à pour but également d'afficher la taille du paquet capturé mais aussi d'associer la taille des paquets (ce sont des paquets de taille spécifique) à des lettre avec je pense un switch case.

    Je bloque sur la focntion void got_packet (u_char *args, const struct pcap_pkthdr *header, const u_char *packet) en fait j'arrive pas à faire afficher la taille du paquet capturer avec cette fonction.

    Pourriez vous m'aider ??

  2. #2
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Ces fonctions me sont inconnues. N'hésites pas à poser des questions précises et à poster les morceaux de code qui te posent problème..

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  3. #3
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Aenarion3
    Bonjour, je suis encore novice en programmation en C et je souhaite créer un sniffer en C.
    Il peut être instructif de réinventer la roue, mais je rappelle l'existence de l'excellent et gratuit Ethereal

  4. #4
    Membre à l'essai
    Inscrit en
    Mars 2007
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 7
    Par défaut
    Je connais ethereal mais il ne se prête pas à ce que je veux faire.
    En fait but précis est d'envoyer dans un canal chiffré IPSec des trames ICMP dont la taille varie en focntion de la lettre taper au clavier. En gros quand j'appuie sur une lettre ça encoie une trame ICMP chiffrée en ESP d'une taille spécifique pour la lettre.
    Mon sniffeur est censé écouter le traffic et lorsqu'il tombe sur une trame ESP avec une longueur spécifique il m'affiche la lettre.

    J'ai réussi à afficher la longueur grâce à la libraire pcap.h et à une fonction :
    void print_length (const u_char *packet)
    {
    int pkt_size;
    struct pcap_pkthdr header; //structure contenue dans pcap.h
    pkt_size = header.len;
    printf("Taille totale: %i\n", pkt_size);
    }

    Cette fonction est appelé par ma fonction de callback
    void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
    {
    static int count = 1;
    printf("Paquet numero %i\n", count);
    print_length (packet); //affiche la longueur du paquet actuellement sniffer
    count ++;
    }

    Dans le main j'y fait appel par:
    pcap_loop (handle, num_packet, got_packet, NULL)
    le prototype de cette fonction se trouve également dans pcap.h

    Mon problème est que lorsqu'un paquet est reçu sa taille n'est afficher que lorsque le paquet suivant arrive ce qui provoque un décalage de 1 paquet à chaque fois et je ne vois pas d'ou vient le problème.

    Je suis désolé je ne peut pas vous poster le code source entier maintenant je ne dispose que d'un ordinateur sur internet avec accès restreint et interdit en lecture donc impossible d'ouvrir même un fichier text .
    J'essaierais de vous le poster ce soir de chez moi pour que ce que je dis soit plus clair .

  5. #5
    Membre très actif Avatar de Goundy
    Profil pro
    Étudiant
    Inscrit en
    Avril 2005
    Messages
    605
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2005
    Messages : 605
    Compil your life guy!
    The Aures Project

  6. #6
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Aenarion3
    En fait but précis est d'envoyer dans un canal chiffré IPSec des trames ICMP dont la taille varie en focntion de la lettre taper au clavier. En gros quand j'appuie sur une lettre ça encoie une trame ICMP chiffrée en ESP d'une taille spécifique pour la lettre.
    Mon sniffeur est censé écouter le traffic et lorsqu'il tombe sur une trame ESP avec une longueur spécifique il m'affiche la lettre.
    Est-ce bien légal tout ça ?

  7. #7
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 349
    Par défaut
    Quand je regarde le code:

    void print_length (const u_char *packet)
    {
    int pkt_size;
    struct pcap_pkthdr header; //structure contenue dans pcap.h
    pkt_size = header.len;
    printf("Taille totale: %i\n", pkt_size);
    }
    je me demande ce que tu cherches à faire. Tu n'utilises pas le paramètre packet et au lieu de cela, tu affiches un champ de la structure non initialisée header. C'est censé faire quoi ?

  8. #8
    Membre à l'essai
    Inscrit en
    Mars 2007
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 7
    Par défaut
    Je développe ce programme dans le cadre de mon stage de fin d'étude afin de tester la sécurité IPSec dans l'entreprise dans laquelle je suis et voir la fiabilité de différents algorithme de chiffrement.
    Ceci est donc tout à fait légal.

    Quand je regarde le code:


    Citation:
    void print_length (const u_char *packet)
    {
    int pkt_size;
    struct pcap_pkthdr header; //structure contenue dans pcap.h
    pkt_size = header.len;
    printf("Taille totale: %i\n", pkt_size);
    }



    je me demande ce que tu cherches à faire. Tu n'utilises pas le paramètre packet et au lieu de cela, tu affiches un champ de la structure non initialisée header. C'est censé faire quoi ?
    Cette fonction à pour but de renvoyer la taille du paquet actuellement sniffer.
    const u_char * packet est le paquet en cours de capture qui sera passer en paramètre.
    pcap_pkthdr header est la structure de l'entête de ce paquet qui contient la variable len contenant la taille totale de la trame en octets.

    Pour mon problème de décalage je pense que ça viens de la façon dont j'ai défini la boucle de "sniffage" (got_packet et pcap_loop) mais j'arrive pas à trouver comment y remédier.

  9. #9
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 349
    Par défaut
    Désolé d'insister, mais la structure header que tu donnes dans ton code n'est en rien rattachée au paramètre packet. Il s'agit d'une variable locale non initialisée.

    Soit ce code est erroné, soit tu t'es trompé en le retranscrivant.

  10. #10
    Membre à l'essai
    Inscrit en
    Mars 2007
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 7
    Par défaut
    Voici donc le source de mon programme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    /*Ce programme Ã* pour le décodage et l'affichage de messages grâce aux paquets envoyés
      par le script Alphaping*/
     
    #define APP_NAME		"AlphaSniffeur"
    #define APP_DESC		"Sniffer example using libpcap"
    #define APP_COPYRIGHT	"Autheur Guillaume DELAUNAY"
    #define APP_DISCLAIMER	"Ce programme Ã* été développé dans le cadre de mon stage Ã* l'ESAT"
     
    #include <pcap.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
     
    /* default snap length (maximum bytes per packet to capture) */
    #define SNAP_LEN 1518
     
    // Prototype des différentes fonctions utilisées dans ce programme
    void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);
    void print_app_banner(void);
    void print_app_usage(void);
    char message (int pkt_size);
     
    // Fonction d'affichage des messages
    char message (int pkt_size)
    {	
    	switch (pkt_size) {
    		case 102: return '\t';
    		case 110: return '\n';		
    		case 254: return ' '; 		// Liste des caractères a affiché en fonction	
    		case 262: return '!';		// de la taille du paquet 	
    		case 270: return '\"';
    		case 286: return '#';
    		case 294: return '$';
    		case 302: return '%';
    		case 310: return '&';
    		case 318: return '\'';
    		case 326: return '(';
    		case 334: return ')';
    		case 350: return '*';
    		case 358: return '+';
    		case 366: return ',';
    		case 374: return '-';
    		case 390: return '.';
    		case 398: return '/';
    		case 406: return '0';
    		case 422: return '1';
    		case 430: return '2';
    		case 438: return '3';
    		case 446: return '4';
    		case 462: return '5';
    		case 470: return '6';
    		case 486: return '7';
    		case 494: return '8';
    		case 502: return '9';
    		case 518: return ':';
    		case 526: return ';';
    		case 542: return '<';
    		case 550: return '=';
    		case 566: return '>';
    		case 574: return '?';
    		case 590: return '@';
    		case 598: return 'A';
    		case 614: return 'B';
    		case 622: return 'C';
    		case 638: return 'D';
    		case 646: return 'E';
    		case 662: return 'F';
    		case 670: return 'G';
    		case 686: return 'H';
    		case 702: return 'I';
    		case 710: return 'J';
    		case 726: return 'K';
    		case 734: return 'L';
    	 	case 750: return 'M';
    		case 766: return 'N';
    		case 774: return 'O';
    		case 790: return 'P';
    		case 806: return 'Q';
    		case 814: return 'R';
    		case 830: return 'S';
    		case 846: return 'T';
    		case 862: return 'U';
    		case 870: return 'V';
    		case 886: return 'W';
    		case 902: return 'X';
    		case 918: return 'Y';
    		case 926: return 'Z';
    		case 942: return '[';
    		case 958: return '\\';
    		case 974: return ']';
    		case 990: return '^';
    		case 998: return '_';
    		case 1014: return '`';
    		case 1030: return 'a';			
    		case 1046: return 'b';
    		case 1062: return 'c';
    		case 1078: return 'd';
    		case 1094: return 'e';
    		case 1102: return 'f';
    		case 1118: return 'g';
    		case 1134: return 'h';
    		case 1150: return 'i';
    		case 1166: return 'j';
    		case 1182: return 'k';
    		case 1198: return 'l';
    		case 1214: return 'm';
    		case 1230: return 'n';
    		case 1246: return 'o';
    		case 1262: return 'p';
    		case 1278: return 'q';
    		case 1294: return 'r';
    		case 1310: return 's';
    	 	case 1326: return 't';
    		case 1342: return 'u';
    		case 1358: return 'v';
    		case 1374: return 'w';
    		case 1390: return 'x';
    		case 1406: return 'y';
    		case 1422: return 'z';
    		case 1438: return '{';
    		case 1454: return '|';
    		case 1470: return '}';
    		case 1486: return '~';
    		default: break;
    	}
    }				
     
    // Affiche de la bannière avec les champs définit au début de programme
    void print_app_banner(void)
    {
    	printf("%s - %s\n", APP_NAME, APP_DESC);
    	printf("%s\n", APP_COPYRIGHT);
    	printf("%s\n", APP_DISCLAIMER);
    	printf("\n");
    return;
    }
     
    // Affichage de l'aide
    void
    print_app_usage(void)
    {
     
    	printf("Usage: %s [interface]\n", APP_NAME);
    	printf("\n");
    	printf("Options:\n");
    	printf("    interface    Listen on <interface> for packets.\n");
    	printf("\n");
     
    return;
    }
     
    // Fonction de callback permettant d'effectuer un traitement sur chaque paquet
    void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
    {	
    	int pkt_size;
                 pkt_size=header->len;
                 printf("%c", message(pkt_size);
                 fflush(stdout);
    }							
     
    int main(int argc, char **argv)
    {
    	char *dev = NULL;			/* capture device name */
    	char errbuf[PCAP_ERRBUF_SIZE];		/* error buffer */
    	pcap_t *handle;				/* packet capture handle */
    	char filter_exp[] = "esp and src host 10.0.0.3 and greater 102 and less 1518";// Filtre
    	struct bpf_program fp;			/* compiled filter program (expression) */
    	bpf_u_int32 mask;			/* subnet mask */
    	bpf_u_int32 net;			/* ip */
    	int num_packets = -1;			// Nombre de paquet Ã* capturer ici -1 signifie 
    						// que la boucle est infinie
    	print_app_banner();
     
    	/* check for capture device name on command-line */
    	if (argc == 2) {
    		dev = argv[1];
    	}
    	else if (argc > 2) {
    		fprintf(stderr, "error: unrecognized command-line options\n\n");
    		print_app_usage();
    		exit(EXIT_FAILURE);
    	}
    	else {
    		/* find a capture device if not specified on command-line */
    		dev = pcap_lookupdev(errbuf);
    		if (dev == NULL) {
    			fprintf(stderr, "Couldn't find default device: %s\n",
    			    errbuf);
    			exit(EXIT_FAILURE);
    		}
    	}
     
    	/* get network number and mask associated with capture device */
    	if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
    		fprintf(stderr, "Couldn't get netmask for device %s: %s\n",
    		    dev, errbuf);
    		net = 0;
    		mask = 0;
    	}
     
    	/* print capture info */
    	printf("Device: %s\n", dev);
    	printf("Number of packets: %d\n", num_packets);
    	printf("Filter expression: %s\n", filter_exp);
     
    	printf("\nMessage:");
     
    	/* open capture device */
    	handle = pcap_open_live(dev, SNAP_LEN, 1, 1000, errbuf);
    	if (handle == NULL) {
    		fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
    		exit(EXIT_FAILURE);
    	}
     
    	/* make sure we're capturing on an Ethernet device [2] */
    	if (pcap_datalink(handle) != DLT_EN10MB) {
    		fprintf(stderr, "%s is not an Ethernet\n", dev);
    		exit(EXIT_FAILURE);
    	}
     
    	/* compile the filter expression */
    	if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
    		fprintf(stderr, "Couldn't parse filter %s: %s\n",
    		    filter_exp, pcap_geterr(handle));
    		exit(EXIT_FAILURE);
    	}
     
    	/* apply the compiled filter */
    	if (pcap_setfilter(handle, &fp) == -1) {
    		fprintf(stderr, "Couldn't install filter %s: %s\n",
    		    filter_exp, pcap_geterr(handle));
    		exit(EXIT_FAILURE);
    	}
    	printf("\nMessage: ");
    	/* now we can set our callback function */
    	pcap_loop(handle, num_packets, got_packet, NULL);
     
    	/* cleanup */
    	pcap_freecode(&fp);
    	pcap_close(handle);
     
    	printf("\nCapture complete.\n");
     
    return 0;
    }
    En tout cas il compile et marche à peut prêt hormsi le problème de décalage.

    Edit: le programme à été éditer avec les modifs faite depuis et il marche.

  11. #11
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 349
    Par défaut
    Tu dis que ton code ne fonctionne pas vraiment et qu'il affiche la taille du paquet précédent.

    Je maintiens donc l'idée de dire que ta structure pcap_pkthdr est non initialisée (et tout programmeur en C pourrait te le confirmer !), et que ce que tu affiches est ce qui traine sur la pile à ce moment là.

    Pour résoudre ton problème, vois comment tu peux rattacher ta structure pcap_pkthdr à ton paquet (variable packet).

    Je ne connais pas la structure de tes paquets. Mais si le paquet contient systématiquement un header de type pcap_pkthdr au début, il te suffit de faire:

    struct pcap_pkthdr *header;
    header = (struct pcap_pkthdr *) packet;
    switch(header->len)
    {
    ...

  12. #12
    Membre à l'essai
    Inscrit en
    Mars 2007
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 7
    Par défaut
    Mea coulpa .
    Je me suis rendu compte effectivement, que lorsque j'enlevais le paramètre de la fonction message ça faisait la même chose.
    Je vais donc essayer le code de Josse95.

    Encore merci

  13. #13
    Membre à l'essai
    Inscrit en
    Mars 2007
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 7
    Par défaut
    char message (const u_char *packet);
    En fait le const u_char *packet be servait à rien dans cette fonction.
    J'ai réussi à résoudre mon problème de décalage en vidant le buffer en faite qui attendait d'être rempli avant de se vider.

    j'ai donc rajouter fflush(stdout); dans ma fonction got_packet et cela fonctionnne.

    Encore merci pour votre aide

  14. #14
    Membre confirmé
    Inscrit en
    Juillet 2002
    Messages
    168
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 168
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Il peut être instructif de réinventer la roue, mais je rappelle l'existence de l'excellent et gratuit Ethereal
    Bonjour,

    +1

    turbo_chess

  15. #15
    Membre à l'essai
    Inscrit en
    Mars 2007
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 7
    Par défaut
    Maintenant que mon problème est résolu, je voudrais rajouter un test de validation de paquet qui regarde si 5 paquet reçu à la suite sont identiques (même longueur) et dans ce cas on peut afficher la lettre correspondante.
    Je vois pas trop comment faire. Pourriez-vous m'aider ???

    PS: j'ai éditer le source de mon programme avec les modifs apportées.

Discussions similaires

  1. Programme sniffer en c
    Par f9o0S dans le forum Réseau
    Réponses: 0
    Dernier message: 18/11/2011, 19h40
  2. Réponses: 8
    Dernier message: 26/04/2010, 15h55
  3. [Kylix] Probleme d'execution de programmes...
    Par yopziggy dans le forum EDI
    Réponses: 19
    Dernier message: 03/05/2002, 14h50
  4. [Kylix] icone associée à un programme
    Par Anonymous dans le forum EDI
    Réponses: 1
    Dernier message: 22/03/2002, 09h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo