1 /* $OpenBSD: pcap.c,v 1.6 2016/09/21 06:02:03 otto Exp $ */ 2 /* 3 * Placed in the PUBLIC DOMAIN 4 */ 5 6 #include <pcap.h> 7 #include <stdlib.h> 8 #include <stdio.h> 9 #include <unistd.h> 10 #include <sys/ioctl.h> 11 12 #include "test.h" 13 14 #define LOOPBACK_IF "lo0" 15 #define SNAPLEN 96 16 #define NO_PROMISC 0 17 #define PKTCNT 3 18 19 volatile int packet_count = 0; 20 pthread_mutex_t dummy; 21 pthread_cond_t syncer; 22 23 static void 24 packet_ignore(u_char *tag, const struct pcap_pkthdr *hdr, const u_char *data) 25 { 26 packet_count += 1; 27 } 28 29 static void * 30 pcap_thread(void *arg) 31 { 32 char errbuf[PCAP_ERRBUF_SIZE]; 33 pcap_t *handle; 34 int on = 1; 35 36 SET_NAME("pcap_thread"); 37 CHECKr(pthread_mutex_lock(&dummy)); 38 handle = pcap_open_live(LOOPBACK_IF, SNAPLEN, NO_PROMISC, 0, errbuf); 39 if (!handle) 40 PANIC("You may need to run this test as UID 0 (root)"); 41 ASSERT(ioctl(pcap_fileno(handle), BIOCIMMEDIATE, &on) != -1); 42 CHECKr(pthread_mutex_unlock(&dummy)); 43 CHECKr(pthread_cond_signal(&syncer)); 44 ASSERT(pcap_loop(handle, PKTCNT, packet_ignore, 0) != -1); 45 return 0; 46 } 47 48 static void * 49 ping_thread(void *arg) 50 { 51 SET_NAME("ping_thread"); 52 CHECKr(pthread_mutex_lock(&dummy)); 53 ASSERT(system("ping -c 3 127.0.0.1") == 0); 54 CHECKr(pthread_mutex_unlock(&dummy)); 55 CHECKr(pthread_cond_signal(&syncer)); 56 return 0; 57 } 58 59 int 60 main(int argc, char **argv) 61 { 62 pthread_t pcap; 63 pthread_t ping; 64 65 CHECKr(pthread_mutex_init(&dummy, NULL)); 66 CHECKr(pthread_cond_init(&syncer, NULL)); 67 CHECKr(pthread_mutex_lock(&dummy)); 68 CHECKr(pthread_create(&pcap, NULL, pcap_thread, NULL)); 69 CHECKr(pthread_cond_wait(&syncer, &dummy)); 70 CHECKr(pthread_create(&ping, NULL, ping_thread, NULL)); 71 CHECKr(pthread_cond_wait(&syncer, &dummy)); 72 CHECKr(pthread_mutex_unlock(&dummy)); 73 ASSERT(packet_count == 3); 74 SUCCEED; 75 } 76