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