diff --git a/src/Makefile b/src/Makefile index ec291fa..ce0b64e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -5,7 +5,7 @@ all: $(PROG) CC = gcc OPTIMIZATION ?= -O2 -CFLAGS = -g $(OPTIMIZATION) -Wall +CFLAGS = -g $(OPTIMIZATION) -Wall -Wextra # SANITIZE=address builds the binary and the test suite under ASan/UBSan. ifdef SANITIZE diff --git a/src/hashtable.c b/src/hashtable.c index 64b8f1f..0e545a4 100644 --- a/src/hashtable.c +++ b/src/hashtable.c @@ -26,7 +26,9 @@ unsigned int hash_function(const void *key, int len) { const unsigned char *data = (const unsigned char *)key; while(len >= 4) { - uint32_t k = *(uint32_t*)data; + uint32_t k; + + memcpy(&k, data, sizeof(k)); k *= m; k ^= k >> r; @@ -90,11 +92,12 @@ void hashtable_destroy(hashtable *ht) { } void *hashtable_add(hashtable *ht, char *key, void *value) { - int bucket, key_size; + int bucket; + size_t key_size; entry *current; key_size = strlen(key); - bucket = hash_function(key, strlen(key)) % ht->nbucket; + bucket = hash_function(key, (int)key_size) % ht->nbucket; current = ht->buckets[bucket]; while (current) { if (key_size == strlen(current->key) && !strncmp(key, current->key, key_size)) { @@ -117,11 +120,12 @@ void *hashtable_add(hashtable *ht, char *key, void *value) { } void *hashtable_get(hashtable *ht, char *key) { - int bucket, key_size; + int bucket; + size_t key_size; entry *current; key_size = strlen(key); - bucket = hash_function(key, key_size) % ht->nbucket; + bucket = hash_function(key, (int)key_size) % ht->nbucket; current = ht->buckets[bucket]; while(current) { if (strlen(current->key) == key_size && !strncmp(key, current->key, key_size)) { @@ -133,10 +137,11 @@ void *hashtable_get(hashtable *ht, char *key) { } int hashtable_del(hashtable *ht, char *key) { - int bucket, key_size = strlen(key); + int bucket; + size_t key_size = strlen(key); entry *current, *prev = NULL; - bucket = hash_function(key, key_size) % ht->nbucket; + bucket = hash_function(key, (int)key_size) % ht->nbucket; current = ht->buckets[bucket]; while (current) { if (key_size == strlen(current->key) && !strncmp(key, current->key, key_size)) { diff --git a/src/sniffer.c b/src/sniffer.c index 0a35029..6a02150 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -37,6 +37,24 @@ static void free_request(void *v) { free(req); } +/* pcap_lookupdev is deprecated and returns a shared buffer; the caller owns + * the name this returns. Loopback is a last resort, not a first guess. */ +static char *first_capture_device(char *err) { + pcap_if_t *devices, *d; + char *name = NULL; + + if (pcap_findalldevs(&devices, err) == -1) return NULL; + for (d = devices; d; d = d->next) { + if (d->flags & PCAP_IF_LOOPBACK) continue; + name = strdup(d->name); + break; + } + if (!name && devices) name = strdup(devices->name); + pcap_freealldevs(devices); + if (!name) snprintf(err, MAX_ERR_BUFF_SIZE, "no capture device available"); + return name; +} + struct bpf_program *sniffer_compile(pcap_t *pcap, const char *filter, char *err) { struct bpf_program *bpf; @@ -94,11 +112,13 @@ struct sniffer *sniffer_create(struct options *opts, char *err) { pcap = sniffer_offline(opts->offline_file, err); } else { pcap = sniffer_online(opts->dev, opts->snaplen, opts->buf_size, err); - if (!strcmp(opts->dev, "any") && !pcap) { - if ((dev = pcap_lookupdev(err)) != NULL) { + if (!pcap && !strcmp(opts->dev, "any")) { + if ((dev = first_capture_device(err)) != NULL) { pcap = sniffer_online(dev, opts->snaplen, opts->buf_size, err); free(opts->dev); - opts->dev = strdup(dev); + free(sniffer->dev); + opts->dev = dev; + sniffer->dev = strdup(dev); } } } @@ -161,13 +181,8 @@ pcap_t *sniffer_offline(const char *file, char *err) { pcap_t *sniffer_online(const char *dev, int snaplen, int buf_size, char *err) { int status; pcap_t *pcap; - bpf_u_int32 net = 0, mask = 0; - const char *new_dev = dev; - if (pcap_lookupnet(dev, &net, &mask, err) == -1) { - return NULL; - } - pcap = pcap_create(new_dev, err); + pcap = pcap_create(dev, err); if (!pcap) return NULL; status = pcap_set_snaplen(pcap, snaplen); if (status < 0) goto error;