PDA

Visualizza la versione completa : [C] sniffer con libpcap


shazo
23-04-2010, 17:29
Buonasera a tutti.
Sto cercando di realizzare un semplice sniffer di rete che cattura il traffico TCP su porta 80.
Il mio problema e' che nel main ad un certo punto faccio stampare ip e subnet mask della scheda di rete su cui faccio sniffing, la stampa della subnet mask e' corretta quella dell'ip no.
Stampa 192.168.255.0 ma in realta l'ip e' 192.168.255.55.
Qualcuno puo' aiutarmi per favore?

Posto il 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);
}

Loading