codice:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pcap.h>
#define MAXBYTES2CAPTURE 512
#define TIMEOUTSNIFF 60
#define ESADECBASE 16
/* pack_handle(): Funzione chiamata da pcap_loop() che rappresenta i pacchetti che arrivano continuamente */
/* nella scheda di rete. Rappresenta il contenuto del pacchetto in formato esadecimale. */
/* stampa inoltre MAC sorgente e MAC destinatario. */
void pack_handle(u_char *args, const struct pcap_pkthdr *p_info, const u_char *packet)
{
int i = 0, *counter = (int *)args;
printf("Packet Count: %d\n", ++(*counter));
printf("Receveid Packet Size: %d\n", p_info->len);
// in TCP il MAC source e dest occupano i primi 12B del pacchetto
printf("MAC source: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", packet[0], packet[1], packet[2], packet[3], packet[4], packet[5]);
printf("MAC dest: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", packet[6], packet[7], packet[8], packet[9], packet[10], packet[11]);
printf("Payload:\n");
for (i = 0; i < p_info->len; i++)
{
// checks for any printable character which is not a space or an alphanumeric character
if(isprint(packet[i]))
printf("%c ", packet[i]);
else
printf(". ");
// rappresentazione dei dati in esadecimale (vado a capo ogni 16 caratteri)
if (i % ESADECBASE == 0 && i != 0 || i == p_info->len-1)
printf(" \n");
}
}
/* main(): Prepara la sessione di sniffer impostando il protocollo, la porta ed il timeout. */
int main(int argc, char** argv)
{
int promisc, count = 0;
pcap_if_t *ifc; // struttura della libpcap che identifica l'interfaccia di rete
pcap_t *sniff;
bpf_u_int32 netp;
bpf_u_int32 maskp;
char *net, *mask;
char errbuf[PCAP_ERRBUF_SIZE], *dev = NULL;
struct bpf_program filter; // memorizza la versione compilata della sessione di sniffing
struct in_addr addr;
// se l'utente passa come parametro l'interfaccia, utilizzo quest'ultima
if(argc > 1)
dev = argv[1];
// altrimenti ne cerco una adatta (il migliore dispositivo disponibile nel sistema)
else
{
dev = pcap_lookupdev(errbuf);
if (!dev)
{
fprintf(stderr, "ERROR: %s\n", errbuf);
_exit(-1);
}
}
printf("Network device found: --> %s\n", dev);
// stampo l'indirizzo associato
if (pcap_lookupnet(dev, &netp, &maskp, errbuf) == -1)
{
fprintf(stderr, "ERROR: %s\n", errbuf);
_exit(-1);
}
else
{
// rendiamo leggibile l'ip
addr.s_addr = netp;
net = inet_ntoa(addr);
if (net == NULL)
_exit(-1);
printf("IP-ADDRESS: %s\n", errbuf);
// rendiamo leggibile la subnet mask
addr.s_addr = maskp;
mask = inet_ntoa(addr);
if (mask == NULL)
_exit(-1);
printf("NETMASK: %s\n", mask);
}
// inizia la sessione di sniffing e scelgo la modalita di sniffing
printf("Opening device %s...\n", dev);
printf("Select:\n0 - for not promiscuous mode\n1 - for promiscuous mode\n");
scanf("%d", &promisc);
if (promisc)
{
// setto lo sniffer in modalita promiscua
if (!(sniff = pcap_open_live(dev, MAXBYTES2CAPTURE, 1, TIMEOUTSNIFF, errbuf)))
{
fprintf(stderr, "ERROR: %s\n", errbuf);
_exit(-1);
}
}
else
{
// setto lo sniffer in modalita locale
if (!(sniff = pcap_open_live(dev, MAXBYTES2CAPTURE, 0, TIMEOUTSNIFF, errbuf)))
{
fprintf(stderr, "ERROR: %s\n", errbuf);
_exit(-1);
}
}
// setto lo sniffer in modalita locale
if (!(sniff = pcap_open_live(dev, MAXBYTES2CAPTURE, 0, TIMEOUTSNIFF, errbuf)))
{
fprintf(stderr, "ERROR: %s\n", errbuf);
_exit(-1);
}
// imposto il traffico da filtrare
char filter_string[] = "tcp dst port 80"; // traffico http su tcp
if (pcap_compile(sniff, &filter, filter_string, 0, netp) == -1)
{
fprintf(stderr, "ERROR: %s\n", pcap_geterr(sniff));
_exit(-1);
}
// associo il filtro alla sessione di sniffing
if (pcap_setfilter(sniff, &filter) == -1)
{
fprintf(stderr, "ERROR: %s\n", pcap_geterr(sniff));
_exit(-1);
}
// inizia il ciclo di sniffing
if (pcap_loop(sniff, 0, pack_handle, (u_char *)&count) == -1)
{
fprintf(stderr, "ERROR: %s\n", pcap_geterr(sniff));
_exit(-1);
}
// chiudo sessione
pcap_close(sniff);
return(0);
}