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