#include <stdio.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <libnet.h>
#include <pcap.h>
/********************************
PARAMETRES
********************************/
// Formule de filtrage.
char filtreString[255] = "arp && ether dst 00:10:a7:15:e8:18";
// Adresse MAC de eth0.
u_char enet_src[6] = { 0x00, 0x10, 0xa7, 0x15, 0xe8, 0x18 };
// Adresse IP de eth0.
u_char ip_src[4] = { 192, 168, 0, 10 };
/********************************
FONCTIONS
********************************/
/****
Decode un paquet ARP.
Affiche seulement l’adresse IP source et l’adresse MAC source.
- packet_p : un pointeur vers le premier octet du paquet.
- packet_size : taille totale du paquet.
****/
void decodeARP( const u_char *packet_p, int packet_size ) {
const u_char * ptr;
// On cherche l'adresse IP source
fprintf( stdout, "IP=" );
for( ptr=packet_p+28; ptr<packet_p+32; ptr++ ) {
fprintf( stdout, ptr==packet_p+31 ? "%d" : "%d.", *ptr );
}
// On cherche l'adresse MAC source
fprintf( stdout, " - MAC=" );
for( ptr=packet_p+6; ptr<packet_p+12; ptr++ ) {
fprintf( stdout, ptr==packet_p+11 ? "%.2x" : "%.2x:", *ptr );
}
fprintf( stdout, "\n" );
}
/****
Handler de pcap_loop.
Traite les paquets recus.
- param : paramètres supplémentaires.
- hdr : header pcap du paquet.
- paquet : le paquet recu, contenant les données.
****/
void traiterPaquet( u_char *param, const struct pcap_pkthdr * hdr, const u_char *paquet ) {
struct ether_header * eptr = (struct ether_header *) paquet;
switch( ntohs( eptr->ether_type ) ) {
case ETHERTYPE_IP :
break;
case ETHERTYPE_ARP :
decodeARP( paquet, hdr->len );
break;
default :
fprintf( stdout, "Protocole inconnu est ??? hex:0x%x\n", ntohs( eptr->ether_type ) );
}
}
/********************************
MAIN
********************************/
int main( int argc, char ** argv ) {
char * device;
int i;
// Libnet
libnet_t * contexte;
libnet_ptag_t id_paquetARP;
libnet_ptag_t id_paquetETH;
u_int8_t * payload = NULL;
u_short payload_s = 0;
// Libpcap
struct bpf_program filtre;
pcap_t * capture;
bpf_u_int32 reseau, masque;
// Adresse IP Destination
u_char ip_dst[4] = { 192, 168, 0, 1 };
// adresses MAC Destination : Broadcast
u_char enet_dst[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
// Contiendra les erreurs
char errlibnet[LIBNET_ERRBUF_SIZE];
char errpcap[PCAP_ERRBUF_SIZE];
if( argc!=1 ) {
fprintf( stdout, "\tUsage : %s\n", argv[0] );
exit( EXIT_FAILURE );
}
/* Initialisation */
// Recherche d'un device valide (eth0).
if( ( device = pcap_lookupdev( errpcap ) )==NULL ) {
fprintf( stderr, “pcap_lookupdev() : %s\n”, errpcap );
exit( EXIT_FAILURE );
// Recherche de l’adresse de réseau et son masque
} else if( pcap_lookupnet( device, &reseau, &masque, errpcap )==-1 ) {
fprintf( stderr, “pcap_lookupdev() : %s\n”, errpcap );
exit( EXIT_FAILURE );
// Initialisation du contexte Libnet pour construire la trame Ethernet.
} else if( ( contexte = libnet_init( LIBNET_LINK, device, errlibnet ) )==NULL ) {
fprintf( stderr, “libnet_init() : %s\n”, errlibnet );
exit( EXIT_FAILURE );
// Démarrage de la capture.
} else if( ( capture = pcap_open_live( device, BUFSIZ, 1, 2000, errpcap ) )==NULL ) {
fprintf( stderr, “pcap_open_live() : %s\n”, errpcap );
exit( EXIT_FAILURE );
// Compilation du filtre : le filtre est-il correct ?
} else if( pcap_compile( capture, &filtre, filtreString, 0, reseau )==-1 ) {
fprintf( stderr, “pcap_compile()\n”);
exit( EXIT_FAILURE );
// Mise en place du filtre.
} else if( pcap_setfilter( capture, &filtre )==-1 ) {
fprintf( stderr, “pcap_setfilter()\n”);
exit( EXIT_FAILURE );
}
/* Construction des trames Ethernet */
for( i=0; i<255; i++ ) {
// Construction du paquet ARP.
id_paquetARP = LIBNET_PTAG_INITIALIZER;
id_paquetARP = libnet_build_arp(
ARPHRD_ETHER, // hardware address format
ETHERTYPE_IP, // protocol address format
ETHER_ADDR_LEN, // hardware address length : 6 octets
0x4, // protocol address length : 4 octets
ARPOP_REQUEST, // ARP operation type
enet_src,
&ip_src, // adresse source identique
enet_dst,
&ip_dst, // adresse destination est changée à chaque fois
payload,
payload_s,
contexte,
id_paquetARP
);
// Construction du paquet ethernet.
id_paquetETH = LIBNET_PTAG_INITIALIZER;
id_paquetETH = libnet_build_ethernet(
enet_dst, // ethernet destination
enet_src, // ethernet source
ETHERTYPE_ARP, // protocole embarqué
payload, // payload
payload_s, // payload size
contexte, // contexte libnet = trame
id_paquetETH
);
// Injection.
libnet_write( contexte );
// On modifie l’adresse de destination.
( ip_dst[3] )++;
}
/* Traitement de la capture */
if( pcap_loop( capture, -1, traiterPaquet, NULL) < 0 ) {
fprintf( stderr, "pcap_loop() : %s\n", pcap_geterr( capture ) );
exit( EXIT_FAILURE );
}
/* Destruction du contexte et arrêt de la capture */
pcap_close( capture );
libnet_destroy( contexte );
return( EXIT_SUCCESS );
}