1*662a7eb4Sotto /* $OpenBSD: pcap.c,v 1.6 2016/09/21 06:02:03 otto Exp $ */
244609ad6Smarc /*
344609ad6Smarc * Placed in the PUBLIC DOMAIN
444609ad6Smarc */
544609ad6Smarc
644609ad6Smarc #include <pcap.h>
744609ad6Smarc #include <stdlib.h>
844609ad6Smarc #include <stdio.h>
944609ad6Smarc #include <unistd.h>
10*662a7eb4Sotto #include <sys/ioctl.h>
1144609ad6Smarc
1244609ad6Smarc #include "test.h"
1344609ad6Smarc
1444609ad6Smarc #define LOOPBACK_IF "lo0"
1544609ad6Smarc #define SNAPLEN 96
1644609ad6Smarc #define NO_PROMISC 0
1744609ad6Smarc #define PKTCNT 3
1844609ad6Smarc
1944609ad6Smarc volatile int packet_count = 0;
20bf306b9fSmarc pthread_mutex_t dummy;
21bf306b9fSmarc pthread_cond_t syncer;
2244609ad6Smarc
23db3296cfSderaadt static void
packet_ignore(u_char * tag,const struct pcap_pkthdr * hdr,const u_char * data)2444609ad6Smarc packet_ignore(u_char *tag, const struct pcap_pkthdr *hdr, const u_char *data)
2544609ad6Smarc {
2644609ad6Smarc packet_count += 1;
2744609ad6Smarc }
2844609ad6Smarc
29db3296cfSderaadt static void *
pcap_thread(void * arg)3044609ad6Smarc pcap_thread(void *arg)
3144609ad6Smarc {
3244609ad6Smarc char errbuf[PCAP_ERRBUF_SIZE];
3344609ad6Smarc pcap_t *handle;
34*662a7eb4Sotto int on = 1;
3544609ad6Smarc
3644609ad6Smarc SET_NAME("pcap_thread");
37bf306b9fSmarc CHECKr(pthread_mutex_lock(&dummy));
3844609ad6Smarc handle = pcap_open_live(LOOPBACK_IF, SNAPLEN, NO_PROMISC, 0, errbuf);
3944609ad6Smarc if (!handle)
4044609ad6Smarc PANIC("You may need to run this test as UID 0 (root)");
41*662a7eb4Sotto ASSERT(ioctl(pcap_fileno(handle), BIOCIMMEDIATE, &on) != -1);
42bf306b9fSmarc CHECKr(pthread_mutex_unlock(&dummy));
43bf306b9fSmarc CHECKr(pthread_cond_signal(&syncer));
4444609ad6Smarc ASSERT(pcap_loop(handle, PKTCNT, packet_ignore, 0) != -1);
4544609ad6Smarc return 0;
4644609ad6Smarc }
4744609ad6Smarc
48db3296cfSderaadt static void *
ping_thread(void * arg)4944609ad6Smarc ping_thread(void *arg)
5044609ad6Smarc {
5144609ad6Smarc SET_NAME("ping_thread");
52bf306b9fSmarc CHECKr(pthread_mutex_lock(&dummy));
5344609ad6Smarc ASSERT(system("ping -c 3 127.0.0.1") == 0);
54bf306b9fSmarc CHECKr(pthread_mutex_unlock(&dummy));
55bf306b9fSmarc CHECKr(pthread_cond_signal(&syncer));
56bf306b9fSmarc return 0;
5744609ad6Smarc }
5844609ad6Smarc
5944609ad6Smarc int
main(int argc,char ** argv)6044609ad6Smarc main(int argc, char **argv)
6144609ad6Smarc {
6244609ad6Smarc pthread_t pcap;
6344609ad6Smarc pthread_t ping;
6444609ad6Smarc
65bf306b9fSmarc CHECKr(pthread_mutex_init(&dummy, NULL));
66bf306b9fSmarc CHECKr(pthread_cond_init(&syncer, NULL));
67bf306b9fSmarc CHECKr(pthread_mutex_lock(&dummy));
6844609ad6Smarc CHECKr(pthread_create(&pcap, NULL, pcap_thread, NULL));
69bf306b9fSmarc CHECKr(pthread_cond_wait(&syncer, &dummy));
7044609ad6Smarc CHECKr(pthread_create(&ping, NULL, ping_thread, NULL));
71bf306b9fSmarc CHECKr(pthread_cond_wait(&syncer, &dummy));
72bf306b9fSmarc CHECKr(pthread_mutex_unlock(&dummy));
73bf306b9fSmarc ASSERT(packet_count == 3);
74bf306b9fSmarc SUCCEED;
7544609ad6Smarc }
76