xref: /aosp_15_r20/external/libpcap/testprogs/fuzz/fuzz_both.c (revision 8b26181f966a6af5cf6981a6f474313de533bb28)
1*8b26181fSAndroid Build Coastguard Worker #include <stdio.h>
2*8b26181fSAndroid Build Coastguard Worker #include <stdlib.h>
3*8b26181fSAndroid Build Coastguard Worker #include <fcntl.h>
4*8b26181fSAndroid Build Coastguard Worker #include <errno.h>
5*8b26181fSAndroid Build Coastguard Worker #include <string.h>
6*8b26181fSAndroid Build Coastguard Worker 
7*8b26181fSAndroid Build Coastguard Worker #include <pcap/pcap.h>
8*8b26181fSAndroid Build Coastguard Worker 
9*8b26181fSAndroid Build Coastguard Worker FILE * outfile = NULL;
10*8b26181fSAndroid Build Coastguard Worker 
bufferToFile(const char * name,const uint8_t * Data,size_t Size)11*8b26181fSAndroid Build Coastguard Worker static int bufferToFile(const char * name, const uint8_t *Data, size_t Size) {
12*8b26181fSAndroid Build Coastguard Worker     FILE * fd;
13*8b26181fSAndroid Build Coastguard Worker     if (remove(name) != 0) {
14*8b26181fSAndroid Build Coastguard Worker         if (errno != ENOENT) {
15*8b26181fSAndroid Build Coastguard Worker             printf("failed remove, errno=%d\n", errno);
16*8b26181fSAndroid Build Coastguard Worker             return -1;
17*8b26181fSAndroid Build Coastguard Worker         }
18*8b26181fSAndroid Build Coastguard Worker     }
19*8b26181fSAndroid Build Coastguard Worker     fd = fopen(name, "wb");
20*8b26181fSAndroid Build Coastguard Worker     if (fd == NULL) {
21*8b26181fSAndroid Build Coastguard Worker         printf("failed open, errno=%d\n", errno);
22*8b26181fSAndroid Build Coastguard Worker         return -2;
23*8b26181fSAndroid Build Coastguard Worker     }
24*8b26181fSAndroid Build Coastguard Worker     if (fwrite (Data, 1, Size, fd) != Size) {
25*8b26181fSAndroid Build Coastguard Worker         fclose(fd);
26*8b26181fSAndroid Build Coastguard Worker         return -3;
27*8b26181fSAndroid Build Coastguard Worker     }
28*8b26181fSAndroid Build Coastguard Worker     fclose(fd);
29*8b26181fSAndroid Build Coastguard Worker     return 0;
30*8b26181fSAndroid Build Coastguard Worker }
31*8b26181fSAndroid Build Coastguard Worker 
fuzz_openFile(const char * name)32*8b26181fSAndroid Build Coastguard Worker void fuzz_openFile(const char * name) {
33*8b26181fSAndroid Build Coastguard Worker     if (outfile != NULL) {
34*8b26181fSAndroid Build Coastguard Worker         fclose(outfile);
35*8b26181fSAndroid Build Coastguard Worker     }
36*8b26181fSAndroid Build Coastguard Worker     outfile = fopen(name, "w");
37*8b26181fSAndroid Build Coastguard Worker }
38*8b26181fSAndroid Build Coastguard Worker 
LLVMFuzzerTestOneInput(const uint8_t * Data,size_t Size)39*8b26181fSAndroid Build Coastguard Worker int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
40*8b26181fSAndroid Build Coastguard Worker     pcap_t * pkts;
41*8b26181fSAndroid Build Coastguard Worker     char errbuf[PCAP_ERRBUF_SIZE];
42*8b26181fSAndroid Build Coastguard Worker     const u_char *pkt;
43*8b26181fSAndroid Build Coastguard Worker     struct pcap_pkthdr *header;
44*8b26181fSAndroid Build Coastguard Worker     int r;
45*8b26181fSAndroid Build Coastguard Worker     size_t filterSize;
46*8b26181fSAndroid Build Coastguard Worker     char * filter;
47*8b26181fSAndroid Build Coastguard Worker     struct bpf_program bpf;
48*8b26181fSAndroid Build Coastguard Worker 
49*8b26181fSAndroid Build Coastguard Worker 
50*8b26181fSAndroid Build Coastguard Worker     //initialize output file
51*8b26181fSAndroid Build Coastguard Worker     if (outfile == NULL) {
52*8b26181fSAndroid Build Coastguard Worker         outfile = fopen("/dev/null", "w");
53*8b26181fSAndroid Build Coastguard Worker         if (outfile == NULL) {
54*8b26181fSAndroid Build Coastguard Worker             return 0;
55*8b26181fSAndroid Build Coastguard Worker         }
56*8b26181fSAndroid Build Coastguard Worker     }
57*8b26181fSAndroid Build Coastguard Worker 
58*8b26181fSAndroid Build Coastguard Worker     if (Size < 1) {
59*8b26181fSAndroid Build Coastguard Worker         return 0;
60*8b26181fSAndroid Build Coastguard Worker     }
61*8b26181fSAndroid Build Coastguard Worker     filterSize = Data[0];
62*8b26181fSAndroid Build Coastguard Worker     if (Size < 1+filterSize || filterSize == 0) {
63*8b26181fSAndroid Build Coastguard Worker         return 0;
64*8b26181fSAndroid Build Coastguard Worker     }
65*8b26181fSAndroid Build Coastguard Worker 
66*8b26181fSAndroid Build Coastguard Worker     //rewrite buffer to a file as libpcap does not have buffer inputs
67*8b26181fSAndroid Build Coastguard Worker     if (bufferToFile("/tmp/fuzz.pcap", Data+1+filterSize, Size-(1+filterSize)) < 0) {
68*8b26181fSAndroid Build Coastguard Worker         return 0;
69*8b26181fSAndroid Build Coastguard Worker     }
70*8b26181fSAndroid Build Coastguard Worker 
71*8b26181fSAndroid Build Coastguard Worker     //initialize structure
72*8b26181fSAndroid Build Coastguard Worker     pkts = pcap_open_offline("/tmp/fuzz.pcap", errbuf);
73*8b26181fSAndroid Build Coastguard Worker     if (pkts == NULL) {
74*8b26181fSAndroid Build Coastguard Worker         fprintf(outfile, "Couldn't open pcap file %s\n", errbuf);
75*8b26181fSAndroid Build Coastguard Worker         return 0;
76*8b26181fSAndroid Build Coastguard Worker     }
77*8b26181fSAndroid Build Coastguard Worker 
78*8b26181fSAndroid Build Coastguard Worker     filter = malloc(filterSize);
79*8b26181fSAndroid Build Coastguard Worker     memcpy(filter, Data+1, filterSize);
80*8b26181fSAndroid Build Coastguard Worker     //null terminate string
81*8b26181fSAndroid Build Coastguard Worker     filter[filterSize-1] = 0;
82*8b26181fSAndroid Build Coastguard Worker 
83*8b26181fSAndroid Build Coastguard Worker     if (pcap_compile(pkts, &bpf, filter, 1, PCAP_NETMASK_UNKNOWN) == 0) {
84*8b26181fSAndroid Build Coastguard Worker         //loop over packets
85*8b26181fSAndroid Build Coastguard Worker         r = pcap_next_ex(pkts, &header, &pkt);
86*8b26181fSAndroid Build Coastguard Worker         while (r > 0) {
87*8b26181fSAndroid Build Coastguard Worker             //checks filter
88*8b26181fSAndroid Build Coastguard Worker             fprintf(outfile, "packet length=%d/%d filter=%d\n",header->caplen, header->len, pcap_offline_filter(&bpf, header, pkt));
89*8b26181fSAndroid Build Coastguard Worker             r = pcap_next_ex(pkts, &header, &pkt);
90*8b26181fSAndroid Build Coastguard Worker         }
91*8b26181fSAndroid Build Coastguard Worker         //close structure
92*8b26181fSAndroid Build Coastguard Worker         pcap_close(pkts);
93*8b26181fSAndroid Build Coastguard Worker         pcap_freecode(&bpf);
94*8b26181fSAndroid Build Coastguard Worker     }
95*8b26181fSAndroid Build Coastguard Worker     else {
96*8b26181fSAndroid Build Coastguard Worker         pcap_close(pkts);
97*8b26181fSAndroid Build Coastguard Worker     }
98*8b26181fSAndroid Build Coastguard Worker     free(filter);
99*8b26181fSAndroid Build Coastguard Worker 
100*8b26181fSAndroid Build Coastguard Worker     return 0;
101*8b26181fSAndroid Build Coastguard Worker }
102