Coverage Report

Created: 2025-07-04 06:44

/src/libpcap/testprogs/fuzz/fuzz_both.c
Line
Count
Source (jump to first uncovered line)
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <fcntl.h>
4
#include <errno.h>
5
#include <string.h>
6
#include <unistd.h>
7
8
#include <pcap/pcap.h>
9
10
FILE * outfile = NULL;
11
12
13.8k
static int bufferToFile(const char * name, const uint8_t *Data, size_t Size) {
13
13.8k
    FILE * fd;
14
13.8k
    if (remove(name) != 0) {
15
0
        if (errno != ENOENT) {
16
0
            printf("failed remove, errno=%d\n", errno);
17
0
            return -1;
18
0
        }
19
0
    }
20
13.8k
    fd = fopen(name, "wb");
21
13.8k
    if (fd == NULL) {
22
0
        printf("failed open, errno=%d\n", errno);
23
0
        return -2;
24
0
    }
25
13.8k
    if (fwrite (Data, 1, Size, fd) != Size) {
26
0
        fclose(fd);
27
0
        return -3;
28
0
    }
29
13.8k
    fclose(fd);
30
13.8k
    return 0;
31
13.8k
}
32
33
0
void fuzz_openFile(const char * name) {
34
0
    if (outfile != NULL) {
35
0
        fclose(outfile);
36
0
    }
37
0
    outfile = fopen(name, "w");
38
0
}
39
40
13.8k
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
41
13.8k
    pcap_t * pkts;
42
13.8k
    char errbuf[PCAP_ERRBUF_SIZE];
43
13.8k
    char filename[FILENAME_MAX] = { 0 };
44
13.8k
    const u_char *pkt;
45
13.8k
    struct pcap_pkthdr *header;
46
13.8k
    int fd = -1, r;
47
13.8k
    size_t filterSize;
48
13.8k
    char * filter;
49
13.8k
    struct bpf_program bpf;
50
51
52
    //initialize output file
53
13.8k
    if (outfile == NULL) {
54
1
        outfile = fopen("/dev/null", "w");
55
1
        if (outfile == NULL) {
56
0
            return 0;
57
0
        }
58
1
    }
59
60
13.8k
    if (Size < 1) {
61
0
        return 0;
62
0
    }
63
13.8k
    filterSize = Data[0];
64
13.8k
    if (Size < 1+filterSize || filterSize == 0) {
65
15
        return 0;
66
15
    }
67
68
    //generate temporary file name
69
13.8k
    snprintf(filename, FILENAME_MAX, "/tmp/libpcap_fuzz_both.XXXXXX");
70
13.8k
    if ((fd = mkstemp(filename)) < 0) {
71
0
        return 0;
72
0
    }
73
13.8k
    close(fd);
74
75
    //rewrite buffer to a file as libpcap does not have buffer inputs
76
13.8k
    if (bufferToFile(filename, Data+1+filterSize, Size-(1+filterSize)) < 0) {
77
0
        unlink(filename);
78
0
        return 0;
79
0
    }
80
81
    //initialize structure
82
13.8k
    pkts = pcap_open_offline(filename, errbuf);
83
13.8k
    if (pkts == NULL) {
84
732
        fprintf(outfile, "Couldn't open pcap file %s\n", errbuf);
85
732
        unlink(filename);
86
732
        return 0;
87
732
    }
88
89
13.0k
    filter = malloc(filterSize);
90
13.0k
    memcpy(filter, Data+1, filterSize);
91
    //null terminate string
92
13.0k
    filter[filterSize-1] = 0;
93
94
13.0k
    if (pcap_compile(pkts, &bpf, filter, 1, PCAP_NETMASK_UNKNOWN) == 0) {
95
        //loop over packets
96
7.31k
        r = pcap_next_ex(pkts, &header, &pkt);
97
51.7k
        while (r > 0) {
98
            //checks filter
99
44.4k
            fprintf(outfile, "packet length=%d/%d filter=%d\n",header->caplen, header->len, pcap_offline_filter(&bpf, header, pkt));
100
44.4k
            r = pcap_next_ex(pkts, &header, &pkt);
101
44.4k
        }
102
        //close structure
103
7.31k
        pcap_close(pkts);
104
7.31k
        pcap_freecode(&bpf);
105
7.31k
    }
106
5.75k
    else {
107
5.75k
        pcap_close(pkts);
108
5.75k
    }
109
13.0k
    free(filter);
110
111
13.0k
    unlink(filename);
112
13.0k
    return 0;
113
13.8k
}