2010-10-14 8 views
0

J'essaie de créer un renifleur capable de renifler plusieurs appareils. Dans mon code, le programme recevra une liste de périphériques qu'un utilisateur souhaite consulter. Je prends la liste d'appareil et de le stocker dans un tableau que j'utilise en boucle à travers et transmettre à une fonction qui crée la poignée de pcap_t comme la fonction ci-dessous:Comment utiliser libpcap pour renifler sur plusieurs appareils?

void *startPcapProcess(char * dev){ 
    char errbuf[PCAP_ERRBUF_SIZE];  /* error buffer */ 
    pcap_t *handle;     /* packet capture handle */ 

/* filter expression [3] */ 
char filter_exp[] = "(dst port 53) and (udp[0xa] & 0x78 = 0x28)"; 

struct bpf_program fp;  /* compiled filter program (expression) */ 
bpf_u_int32 mask;   /* subnet mask */ 
bpf_u_int32 net;   /* ip */ 

printf("%s","startPacketProcess called\n"); 
printf("Device sent to startPacketProcess: %s\n", dev); 
/* 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; 
} 

/* 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); 
} 

pcap_freecode(&fp); 

/* now we can set our callback function */ 
pcap_loop(handle, -1, process_packet, NULL); 
printf("%s","End startPacketProcess call\n"); 

} 

Cependant, quand je fais un appel à cette fonctionne dans ma boucle for, il est seulement capable de capturer sur un périphérique, car il semble être bloqué dans la fonction de rappel pcap_loop. En conséquence, j'ai essayé de faire du multi threading et la boucle for que j'utilise pour passer dans tous les périphériques à ouvrir et à capturer traverse la boucle, mais la fonction callback pcap_loop ne semble pas s'exécuter. Le code suivant montre mon utilisation du multi threading:

for (i = 0; i < numDevice; i++){ 
     printf("Device returned by getDevices call: %s\n", deviceList[i]); 
     printf("%s","Entering for loop\n"); 
     pthread_create(&tid, thAttr, startPacketProcess,(void*)deviceList[i]); 
    } 

Est-ce que quelqu'un sait ce que je fais mal et pouvez-vous me fournir des suggestions sur la façon de résoudre ce problème?

Merci, Linh

Répondre

0

Avez-vous essayé d'utiliser pcap_findalldevs() ou pcap_findalldevs_ex()

1

process_packet pourrait être le problème. Essayez d'obtenir le paquet dans le contexte du thread.

struct pcap_pkthdr *pkt_header; 
    u_char *pkt_data;   

    while ((retval = pcap_next_ex(mpPcap, &pkt_header, (const u_char **) &pkt_data)) >= 0) { 
    //Do Whatever 
    } 
Questions connexes