#include #include #include #include #include #include FILE * outfile = NULL; static int bufferToFile(const char * name, const uint8_t *Data, size_t Size) { FILE * fd; if (remove(name) != 0) { if (errno != ENOENT) { printf("failed remove, errno=%d\n", errno); return -1; } } fd = fopen(name, "wb"); if (fd == NULL) { printf("failed open, errno=%d\n", errno); return -2; } if (fwrite (Data, 1, Size, fd) != Size) { fclose(fd); return -3; } fclose(fd); return 0; } void fuzz_openFile(const char * name) { if (outfile != NULL) { fclose(outfile); } outfile = fopen(name, "w"); } int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { pcap_t * pkts; char errbuf[PCAP_ERRBUF_SIZE]; const u_char *pkt; struct pcap_pkthdr *header; int r; size_t filterSize; char * filter; struct bpf_program bpf; //initialize output file if (outfile == NULL) { outfile = fopen("/dev/null", "w"); if (outfile == NULL) { return 0; } } if (Size < 1) { return 0; } filterSize = Data[0]; if (Size < 1+filterSize || filterSize == 0) { return 0; } //rewrite buffer to a file as libpcap does not have buffer inputs if (bufferToFile("/tmp/fuzz.pcap", Data+1+filterSize, Size-(1+filterSize)) < 0) { return 0; } //initialize structure pkts = pcap_open_offline("/tmp/fuzz.pcap", errbuf); if (pkts == NULL) { fprintf(outfile, "Couldn't open pcap file %s\n", errbuf); return 0; } filter = malloc(filterSize); memcpy(filter, Data+1, filterSize); //null terminate string filter[filterSize-1] = 0; if (pcap_compile(pkts, &bpf, filter, 1, PCAP_NETMASK_UNKNOWN) == 0) { //loop over packets r = pcap_next_ex(pkts, &header, &pkt); while (r > 0) { //checks filter fprintf(outfile, "packet length=%d/%d filter=%d\n",header->caplen, header->len, pcap_offline_filter(&bpf, header, pkt)); r = pcap_next_ex(pkts, &header, &pkt); } //close structure pcap_close(pkts); pcap_freecode(&bpf); } else { pcap_close(pkts); } free(filter); return 0; }