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