]> The Tcpdump Group git mirrors - libpcap/blob - testprogs/fuzz/fuzz_pcap.c
Consolidate MAC-48 address matching code.
[libpcap] / testprogs / fuzz / fuzz_pcap.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <fcntl.h>
5 #include <errno.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 struct pcap_stat stats;
47 int fd = -1, r;
48
49 //initialize output file
50 if (outfile == NULL) {
51 outfile = fopen("/dev/null", "w");
52 if (outfile == NULL) {
53 return 0;
54 }
55 }
56
57 //generate temporary file name
58 snprintf(filename, FILENAME_MAX, "/tmp/libpcap_fuzz_pcap.XXXXXX");
59 if ((fd = mkstemp(filename)) < 0) {
60 return 0;
61 }
62 close(fd);
63
64 //rewrite buffer to a file as libpcap does not have buffer inputs
65 if (bufferToFile(filename, Data, Size) < 0) {
66 unlink(filename);
67 return 0;
68 }
69
70 //initialize structure
71 pkts = pcap_open_offline(filename, errbuf);
72 if (pkts == NULL) {
73 fprintf(outfile, "Couldn't open pcap file %s\n", errbuf);
74 unlink(filename);
75 return 0;
76 }
77
78 //loop over packets
79 r = pcap_next_ex(pkts, &header, &pkt);
80 while (r > 0) {
81 //TODO pcap_offline_filter
82 fprintf(outfile, "packet length=%d/%d\n",header->caplen, header->len);
83 r = pcap_next_ex(pkts, &header, &pkt);
84 }
85 if (pcap_stats(pkts, &stats) == 0) {
86 fprintf(outfile, "number of packets=%d\n", stats.ps_recv);
87 }
88 //close structure
89 pcap_close(pkts);
90
91 unlink(filename);
92 return 0;
93 }