[c/winpcap]sniffer tcp(analyseur de trames) pour windows

Soyez le premier à donner votre avis sur cette source.

Vue 41 418 fois - Téléchargée 2 273 fois

Description

Bonjour voila un sniffer minimaliste pour windows qui utilise la librairie winpcap vous devez donc la télécharger et l'intaller pour faire tourner mon programme. => http://www.winpcap.org/<=
Pour le développer j'ai utiliser codeblocks, voila un tutorial que j'ai fait pour ceux qui voudrait tester et recompiler mon code:
http://psyphi.zeblog.com/54921-configurer-winpcap-pour-codeblocks/
Sinon que dire de plus, le sniffer affiche les entêtes ethernet, ip et tcp ainsi que le reste des données contenues dans le paquet.

README:

Compiled and tested with Code::Blocks and Mingw under Windows XP SP2.
You need to install winPcap and configure Code::Blocks to compile this source.

Links:
------
Project:
http://bores.fr/psyphi/dev/c/network/sniffer_winpcap/
winPcap:
http://www.winpcap.org/
Code::Blocks
http://www.codeblocks.org/
How to configure Code::Blocks for winPcap (french):
http://psyphi.zeblog.com/54921-configurer-winpcap-pour-codeblocks/

Source / Exemple :


/*

  • sniffer_winPcap *
  • Last version at http://psyphi.bores.fr/dev/c/network/sniffer_winpcap *
  • Copyright (C) 2006 psyphi psyphi(_at_)gmail(_dot_)com *
  • *
  • sniffer_winPcap program is free software; you can redistribute it and/or *
  • modify it under the terms of the GNU General Public License *
  • as published by the Free Software Foundation; either version 2 *
  • of the License, or (at your option) any later version. *
  • *
  • sniffer_winPcap program is distributed in the hope that it will be useful, *
  • but WITHOUT ANY WARRANTY; without even the implied warranty of *
  • MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  • GNU General Public License for more details. *
  • *
  • You should have received a copy of the GNU General Public License *
  • along with this program; if not, write to the Free Software *
  • Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
  • /
#include <stdio.h> #include <stdlib.h> #include <winsock2.h> #pragma comment(lib,"wpcap.lib") #pragma comment(lib,"ws2_32.lib") #define HAVE_REMOTE #define WPCAP #define PACKET_SIZE 65536 #include <pcap.h> // must be writing after the defines /*
  • Structures
  • /
struct ethhdr // Ethernet header { unsigned char h_dest[6]; // Destination host address unsigned char h_source[6]; // Source host address unsigned short h_proto; // Packet type ID field (IP, ARP ...) }; struct iphdr // structure IP Header { //Pour processeur de type little-endian unsigned char ihl:4; // IP header length unsigned char version:4; unsigned char tos; // Type of service unsigned short tot_len; // Total length unsigned short id; // Identification unsigned short frag_off; // Fragment Offset + Flags unsigned char ttl; // Time to life unsigned char protocol; unsigned short check; // Checksum unsigned int saddr; // Source address unsigned int daddr; // Destination address }; struct tcphdr // structure TCP Header { //Pour processeur de type little-endian unsigned short source; // port source unsigned short dest; // port de destination unsigned int seq; // Sequence number unsigned int ack_seq; // acknowledge sequence unsigned short res1:4, // Reserved 1 : 4 bits doff:4, // Data Offset fin:1, // Flag FINISH syn:1, // Flag SYNCHRONIZE rst:1, // Flag RESET psh:1, // Flag PUSH ack:1, // Flag ACKNOLEDGE urg:1, // Flag URGENT res2:2; // Reserved 2 : 2 bits (res1 + res2 = 6 bits reserved) unsigned short window; unsigned short check; // checksum unsigned short urg_ptr; // urgent }; /*
  • Functions
  • /
void print_eth_header(struct ethhdr * eth){ fprintf(stdout,"-------------------[ETH HEADER]-----------\r\n"); fprintf(stdout,"| %.2X:%.2X:%.2X:%.2X:%.2X:%.2X -> ",eth->h_source[0],eth->h_source[1], eth->h_source[2],eth->h_source[3],eth->h_source[4],eth->h_source[5]); fprintf(stdout,"%.2X:%.2X:%.2X:%.2X:%.2X:%.2X |\r\n",eth->h_dest[0],eth->h_dest[1], eth->h_dest[2],eth->h_dest[3],eth->h_dest[4],eth->h_dest[5]); fprintf(stdout,"------------------------------------------\r\n"); fprintf(stdout,"Protocol: 0x%.4X\r\n", htons(eth->h_proto)); } void print_ip_header(struct iphdr * ip){ unsigned char * src = (unsigned char *)&(ip->saddr); unsigned char * dest = (unsigned char *)&(ip->daddr); fprintf(stdout,"[ IP : %d.%d.%d.%d -> ",src[0],src[1],src[2],src[3]); fprintf(stdout,"%d.%d.%d.%d ]\r\n",dest[0],dest[1],dest[2],dest[3]); fprintf(stdout,"--------------------[IP HEADER]----------------------\r\n"); fprintf(stdout,"| IP header length : %d * 32 bits = %d bytes |\r\n",ip->ihl, ip->ihl * 4); fprintf(stdout,"| IP version : %.5d | ",ip->version); fprintf(stdout,"Type of service : %.5d |\r\n",ip->tos); fprintf(stdout,"| Total length : %.5d | ",htons(ip->tot_len)); fprintf(stdout,"Identification : %.5d |\r\n",htons(ip->id)); fprintf(stdout,"| Time to live : %.5d | ",ip->ttl); fprintf(stdout,"Protocol : %.5d |\r\n",ip->protocol); fprintf(stdout,"| Checksum : %.5d |\r\n",ip->check); fprintf(stdout,"-----------------------------------------------------\r\n"); } void print_tcp_header(struct tcphdr * tcp){ fprintf(stdout,"[ Port : %.5d -> %.5d ]\n", ntohs(tcp->source), ntohs(tcp->dest) ); fprintf(stdout,"--------------------[TCP HEADER]---------------------\r\n"); fprintf(stdout,"| TCP Header length : %d * 32 bits = %d bytes |\r\n",tcp->doff, tcp->doff * 4); fprintf(stdout,"| URG (URGENT) = %d | ",tcp->urg); fprintf(stdout,"ACK (ACKNOWLEDGE) = %d |\r\n",tcp->ack); fprintf(stdout,"| PSH (PUSH) = %d | ",tcp->psh); fprintf(stdout,"RST (RESET) = %d |\r\n",tcp->rst); fprintf(stdout,"| SYN (SYNCHRONIZE) = %d | ",tcp->syn); fprintf(stdout,"FIN (FINISH) = %d |\r\n",tcp->fin); fprintf(stdout,"-----------------------------------------------------\r\n"); } void print_data(unsigned char * data, unsigned int size){ int j = 0, k = 0; for( j = 0; j < size; j++) { if( k == 16) { j -= 16; fprintf(stdout," "); for(k = 0 ; k < 16 ; k++, j++) { if(data[j] < 127 && data[j] > 31) fprintf(stdout, "%c", data[j]); else fprintf(stdout, "."); } j--; k = 0; fprintf(stdout,"\r\n"); } else { fprintf(stdout,"%.2x ",data[j]); k++; } } j -= k; while(k!=0) { if(data[j] < 127 && data[j] > 31) fprintf(stdout, "%c", data[j]); else fprintf(stdout, "."); k--; j++; } fprintf(stdout,"\r\n"); } void print_packet(const u_char * packetData){ struct iphdr * ip; struct tcphdr * tcp; ip = (struct iphdr *)(packetData+sizeof(struct ethhdr)); print_ip_header(ip); switch(ip->protocol){ case 1 : printf("Internet Control Message Protocol (ICMP)\r\n"); break; case 6 : printf("Transmission Control Protocol (TCP)\r\n"); tcp = (struct tcphdr *)(packetData+sizeof(struct ethhdr)+sizeof(struct iphdr)); print_tcp_header(tcp); /* Data */ unsigned char * data = (unsigned char *)(packetData+sizeof(struct ethhdr)+sizeof(struct iphdr)+sizeof(struct tcphdr)); print_data(data, htons(ip->tot_len)-(ip->ihl * 4)-(tcp->doff * 4)); break; case 17 : printf("User Datagram Protocol (UDP)\r\n"); break; default : printf("Unknow\r\n"); break; } } int main(void){ // Interfaces pcap_if_t * alldevs; pcap_if_t * d; int ifNum; int i=0; pcap_t * captureHandle; // Packet struct pcap_pkthdr* packetHeader; const u_char * packetData; struct ethhdr * eth; int res; char errbuf[PCAP_ERRBUF_SIZE]; /* Retrieve the device list from the local machine */ if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) { fprintf(stderr,"Error in pcap_findalldevs_ex: %s\r\n", errbuf); return EXIT_FAILURE; } /* Print the list */ for(d= alldevs; d != NULL; d= d->next) { printf("%d.\r\nName:\r\n\t%s\r\n", ++i, d->name); if (d->description) printf("Descriptions:\r\n\t%s\r\n\r\n", d->description); else printf(" (No description available)\r\n"); } if (i == 0) { printf("\r\nNo interfaces found! Make sure WinPcap is installed.\r\n"); return EXIT_FAILURE; }else{ printf("Enter the interface number (1-%d):",i); scanf("%d", &ifNum); } if(ifNum < 1 || ifNum > i) { printf("\nInterface number out of range.\r\n"); /* Free the device list */ pcap_freealldevs(alldevs); return -1; } /* Jump to the selected adapter */ for(d=alldevs, i=0; i< ifNum-1 ;d=d->next, i++); captureHandle = pcap_open(d->name, PACKET_SIZE, 0, 1000, NULL, errbuf); if( captureHandle == NULL){ fprintf(stderr, "pcap_open(): %s\r\n", errbuf); pcap_freealldevs(alldevs); return EXIT_FAILURE; } /* We don't need any more the device list. Free it */ pcap_freealldevs(alldevs); /* start the capture */ while( (res = pcap_next_ex(captureHandle, &packetHeader, &packetData)) >= 0){ if(res == 0) /* Timeout elapsed */ continue; printf("\r\n\r\nPacket length: %d\r\n", packetHeader->len); printf("Received at ..... %s\r\n",ctime((const time_t*)&packetHeader->ts.tv_sec)); eth = (struct ethhdr *) packetData; print_eth_header(eth); // Analyse ethernet type switch(htons(eth->h_proto)){ case 0x0800 : fprintf(stdout,"Internet Protocol, Version 4 (IPv4)\r\n"); print_packet(packetData); break; case 0x0806 : fprintf(stdout,"Address Resolution Protocol (ARP)\r\n"); break; case 0x8035 : fprintf(stdout,"Reverse Address Resolution Protocol (RARP)\r\n"); break; case 0x809B : fprintf(stdout,"AppleTalk (Ethertalk)\r\n"); break; case 0x80F3 : fprintf(stdout,"AppleTalk Address Resolution Protocol (AARP)\r\n"); break; case 0x8100 : fprintf(stdout,"IEEE 802.1Q-tagged frame\r\n"); break; case 0x8137 : fprintf(stdout,"Novell IPX (alt)\r\n"); break; case 0x8138 : fprintf(stdout,"Novell\r\n"); break; case 0x86DD : fprintf(stdout,"Internet Protocol, Version 6 (IPv6)\r\n"); print_packet(packetData); break; case 0x8847 : fprintf(stdout,"MPLS unicast\r\n"); break; case 0x8848 : fprintf(stdout,"MPLS multicast\r\n"); break; case 0x8863 : fprintf(stdout,"PPPoE Discovery Stage\r\n"); break; case 0x8864 : fprintf(stdout,"PPPoE Session Stage\r\n"); break; case 0x88A2 : fprintf(stdout,"ATA over Ethernet\r\n"); break; default : fprintf(stdout,"Unknow packet\r\n"); break; } } if(res == -1){ printf("Error reading the packets: %s\r\n", pcap_geterr(captureHandle)); return EXIT_FAILURE; } pcap_close(captureHandle); return EXIT_SUCCESS; }

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

RadTCP
Messages postés
3
Date d'inscription
vendredi 20 mai 2011
Statut
Membre
Dernière intervention
20 mai 2011
-
Salut !
Actuellement, je vais développer un proxy TCP qui intercepte les paquets TCP provenant de la couche Transport et les mets dans un cache pour les retransmettre par la suite en cas de perte ou altération. Pour le faire, je me demande est ce que je pourrais utiliser ce code pour le cas de mon programme car je ne sais vraiment pas par ou commencer? est ce que quelqu'un peut me diriger sur ça SVP?
cs_Chancie007
Messages postés
9
Date d'inscription
vendredi 29 avril 2011
Statut
Membre
Dernière intervention
20 février 2014
-
ok, je vois! Mais sauf que je ne sais pas le faire. J'ai trouver un truc sur le net qui me montre comment ajouter un biblio sur code::blocks. Mais quand je le fais, dans les dossiers include et bin de winpcap, je ne trouve pas les fichiers nécessaires... (exemple les fichiers.a)
Alors comment je fais?!!! J'ai aucune idée.
Peux-tu m'aider stp?
zebulon88
Messages postés
32
Date d'inscription
jeudi 5 juin 2008
Statut
Membre
Dernière intervention
4 mai 2011
-
par déclaration je voulais dire que tu dois dire à ton compilateur où aller chercher les librairies et les fichiers include, notameent ceux de cap.
cs_Chancie007
Messages postés
9
Date d'inscription
vendredi 29 avril 2011
Statut
Membre
Dernière intervention
20 février 2014
-
Salut Zebulon,

Mis à part la déclaration des fichiers.h à l'entête du programme actuellement défini et installation du Winpcap, je n'ai effectué aucune déclaration ailleurs.
j'ai trouvé un fichier "pcap.h" sur le net que j'ai joins au projet. Mais, ça ne marche toujours pas. :(
zebulon88
Messages postés
32
Date d'inscription
jeudi 5 juin 2008
Statut
Membre
Dernière intervention
4 mai 2011
-
Pour Chancie,
as tu déclarer la position des librairies et include ?

Questions à tous : ce programme n'est il pas sujet à des fuites de mémoire ?
En le faisant tourner longtemps le RAM occupée augmente indéfiniment.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.