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 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 32 void fuzz_openFile(const char * name) { 33 if (outfile != NULL) { 34 fclose(outfile); 35 } 36 outfile = fopen(name, "w"); 37 } 38 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