1 /*
2  * Copyright (c) 2016-2021, OARC, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in
14  *    the documentation and/or other materials provided with the
15  *    distribution.
16  *
17  * 3. Neither the name of the copyright holder nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #include "config.h"
36 
37 #include "dump_cds.h"
38 #include "dnscap.h"
39 #include "hashtbl.h"
40 #include "iaddr.h"
41 
42 #if HAVE_LIBTINYCBOR
43 
44 #include <stdlib.h>
45 #if HAVE_TINYCBOR_CBOR_H
46 #include <tinycbor/cbor.h>
47 #endif
48 #if HAVE_CBOR_H
49 #include <cbor.h>
50 #endif
51 #include <assert.h>
52 
53 #define need8(v, p, l, d)                                           \
54     if (l < 1) {                                                    \
55         if (sizeof(d) > 1)                                          \
56             fprintf(stderr, "cds need 1B/8b, had %lu: %s\n", l, d); \
57         return 1;                                                   \
58     }                                                               \
59     v = *p;                                                         \
60     p += 1;                                                         \
61     l -= 1
62 
63 #define need16(v, p, l, d)                                           \
64     if (l < 2) {                                                     \
65         if (sizeof(d) > 1)                                           \
66             fprintf(stderr, "cds need 2B/16b, had %lu: %s\n", l, d); \
67         return 1;                                                    \
68     }                                                                \
69     v = (*p << 8) + *(p + 1);                                        \
70     p += 2;                                                          \
71     l -= 2
72 
73 #define need32(v, p, l, d)                                           \
74     if (l < 4) {                                                     \
75         if (sizeof(d) > 1)                                           \
76             fprintf(stderr, "cds need 4B/32b, had %lu: %s\n", l, d); \
77         return 1;                                                    \
78     }                                                                \
79     v = (*p << 24) + (*(p + 1) << 16) + (*(p + 2) << 8) + *(p + 3);  \
80     p += 4;                                                          \
81     l -= 4
82 
83 #define need64(v, p, l, d)                                                                                                                      \
84     if (l < 8) {                                                                                                                                \
85         if (sizeof(d) > 1)                                                                                                                      \
86             fprintf(stderr, "cds need 8B/64b, had %lu: %s\n", l, d);                                                                            \
87         return 1;                                                                                                                               \
88     }                                                                                                                                           \
89     v = (*p << 56) + (*(p + 1) << 48) + (*(p + 2) << 40) + (*(p + 3) << 32) + (*(p + 4) << 24) + (*(p + 5) << 16) + (*(p + 6) << 8) + *(p + 7); \
90     p += 8;                                                                                                                                     \
91     l -= 8
92 
93 #define needxb(b, x, p, l, d)                                             \
94     if (l < x) {                                                          \
95         if (sizeof(d) > 1)                                                \
96             fprintf(stderr, "cds need %d bytes, had %lu: %s\n", x, l, d); \
97         return 1;                                                         \
98     }                                                                     \
99     memcpy(b, p, x);                                                      \
100     p += x;                                                               \
101     l -= x
102 
103 #define advancexb(x, p, l, d)                                                          \
104     if (l < x) {                                                                       \
105         if (sizeof(d) > 1)                                                             \
106             fprintf(stderr, "cds needed to advance %d bytes, had %lu: %s\n", x, l, d); \
107         return 1;                                                                      \
108     }                                                                                  \
109     p += x;                                                                            \
110     l -= x
111 
112 static uint8_t* cbor_buf              = 0;
113 static uint8_t* cbor_buf_p            = 0;
114 static size_t   cbor_size             = 1024 * 1024;
115 static uint8_t* message_buf           = 0;
116 static size_t   message_size          = 64 * 1024;
117 static int      cbor_flushed          = 1;
118 static hashtbl* rdata_tbl             = 0;
119 static size_t   MAX_RLABELS           = CDS_DEFAULT_MAX_RLABELS;
120 static size_t   MIN_RLABEL_SIZE       = CDS_DEFAULT_MIN_RLABEL_SIZE;
121 static int      use_rdata_index       = 0;
122 static int      use_rdata_rindex      = 0;
123 static size_t   RDATA_RINDEX_SIZE     = CDS_DEFAULT_RDATA_RINDEX_SIZE;
124 static size_t   RDATA_RINDEX_MIN_SIZE = CDS_DEFAULT_RDATA_RINDEX_MIN_SIZE;
125 static size_t   RDATA_INDEX_MIN_SIZE  = CDS_DEFAULT_RDATA_INDEX_MIN_SIZE;
126 
127 struct rdata;
128 struct rdata {
129     struct rdata* prev;
130     struct rdata* next;
131     uint8_t*      data;
132     size_t        len;
133     size_t        idx;
134 };
135 
136 struct last {
137     my_bpftimeval ts;
138     ip_header_t   ip;
139 
140     uint16_t dns_type;
141     uint16_t dns_class;
142     uint32_t dns_ttl;
143 
144     dns_rlabel_t* dns_rlabel;
145     dns_rlabel_t* dns_rlabel_last;
146     size_t        dns_rlabels;
147 
148     size_t        rdata_index;
149     size_t        rdata_num;
150     struct rdata* rdata;
151     struct rdata* rdata_last;
152 };
153 static struct last last;
154 
155 /*
156  * Set/Get
157  */
158 
cds_set_cbor_size(size_t size)159 int cds_set_cbor_size(size_t size)
160 {
161     if (!size) {
162         return DUMP_CDS_EINVAL;
163     }
164 
165     cbor_size = size;
166     if (message_size > cbor_size) {
167         message_size = cbor_size;
168     }
169 
170     return DUMP_CDS_OK;
171 }
172 
cds_set_message_size(size_t size)173 int cds_set_message_size(size_t size)
174 {
175     if (!size) {
176         return DUMP_CDS_EINVAL;
177     }
178 
179     message_size = size;
180     if (message_size > cbor_size) {
181         message_size = cbor_size;
182     }
183 
184     return DUMP_CDS_OK;
185 }
186 
cds_set_max_rlabels(size_t size)187 int cds_set_max_rlabels(size_t size)
188 {
189     if (!size) {
190         return DUMP_CDS_EINVAL;
191     }
192 
193     MAX_RLABELS = size;
194 
195     return DUMP_CDS_OK;
196 }
197 
cds_set_min_rlabel_size(size_t size)198 int cds_set_min_rlabel_size(size_t size)
199 {
200     if (!size) {
201         return DUMP_CDS_EINVAL;
202     }
203 
204     MIN_RLABEL_SIZE = size;
205 
206     return DUMP_CDS_OK;
207 }
208 
cds_set_use_rdata_index(int use)209 int cds_set_use_rdata_index(int use)
210 {
211     use_rdata_index = use ? 1 : 0;
212 
213     return DUMP_CDS_OK;
214 }
215 
cds_set_use_rdata_rindex(int use)216 int cds_set_use_rdata_rindex(int use)
217 {
218     use_rdata_rindex = use ? 1 : 0;
219 
220     return DUMP_CDS_OK;
221 }
222 
cds_set_rdata_index_min_size(size_t size)223 int cds_set_rdata_index_min_size(size_t size)
224 {
225     if (!size) {
226         return DUMP_CDS_EINVAL;
227     }
228 
229     RDATA_INDEX_MIN_SIZE = size;
230 
231     return DUMP_CDS_OK;
232 }
233 
cds_set_rdata_rindex_min_size(size_t size)234 int cds_set_rdata_rindex_min_size(size_t size)
235 {
236     if (!size) {
237         return DUMP_CDS_EINVAL;
238     }
239 
240     RDATA_RINDEX_MIN_SIZE = size;
241 
242     return DUMP_CDS_OK;
243 }
244 
cds_set_rdata_rindex_size(size_t size)245 int cds_set_rdata_rindex_size(size_t size)
246 {
247     if (!size) {
248         return DUMP_CDS_EINVAL;
249     }
250 
251     RDATA_RINDEX_SIZE = size;
252 
253     return DUMP_CDS_OK;
254 }
255 
256 /*
257  * DNS
258  */
259 
check_dns_label(size_t * labels,uint8_t ** p,size_t * l)260 static int check_dns_label(size_t* labels, uint8_t** p, size_t* l)
261 {
262     uint8_t len;
263 
264     while (1) {
265         need8(len, *p, *l, "");
266         *labels += 1;
267 
268         if ((len & 0xc0) == 0xc0) {
269             advancexb(1, *p, *l, "");
270             break;
271         } else if (len & 0xc0) {
272             break;
273         } else if (len) {
274             advancexb(len, *p, *l, "");
275         } else {
276             break;
277         }
278     }
279 
280     return 0;
281 }
282 
rdata_hash(const void * _item)283 static unsigned int rdata_hash(const void* _item)
284 {
285     const struct rdata* item = (const struct rdata*)_item;
286     size_t              n, o, p;
287     unsigned int        key = 0;
288 
289     for (n = 0, o = 0, p = 0; n < item->len; n++) {
290         p |= item->data[n] << (o * 8);
291         o++;
292         if (o > 3) {
293             key ^= p;
294             p = 0;
295             o = 0;
296         }
297     }
298     if (o) {
299         key ^= p;
300     }
301 
302     return key;
303 }
304 
rdata_cmp(const void * _a,const void * _b)305 static int rdata_cmp(const void* _a, const void* _b)
306 {
307     const struct rdata *a = (const struct rdata*)_a, *b = (const struct rdata*)_b;
308 
309     if (a->len == b->len) {
310         return memcmp(a->data, b->data, a->len);
311     } else if (a->len < b->len)
312         return -1;
313     return 1;
314 }
315 
rdata_free(void * d)316 static void rdata_free(void* d)
317 {
318     struct rdata* item = (struct rdata*)d;
319 
320     if (item) {
321         if (item->data) {
322             free(item->data);
323         }
324         free(item);
325     }
326 }
327 
rdata_add(uint8_t * p,size_t len)328 static int rdata_add(uint8_t* p, size_t len)
329 {
330     struct rdata* key;
331 
332     if (len < RDATA_INDEX_MIN_SIZE)
333         return 1;
334 
335     if (!(key = calloc(1, sizeof(struct rdata)))) {
336         return 0;
337     }
338     if (!(key->data = calloc(1, len))) {
339         free(key);
340         return 0;
341     }
342 
343     key->len = len;
344     memcpy(key->data, p, len);
345     key->idx = last.rdata_index++;
346 
347     /*    printf("rdata_add  %u: ", rdata_hash(key));*/
348     /*    {*/
349     /*        size_t n = len;*/
350     /*        uint8_t* x = p;*/
351     /*        while (n--) {*/
352     /*            printf("%02x", *x);*/
353     /*            x++;*/
354     /*        }*/
355     /*    }*/
356     /*    printf("\n");*/
357     hash_add(key, key, rdata_tbl);
358 
359     return 0;
360 }
361 
rdata_find(uint8_t * p,size_t len,size_t * found)362 static size_t rdata_find(uint8_t* p, size_t len, size_t* found)
363 {
364     struct rdata  key;
365     struct rdata* r;
366 
367     if (len < RDATA_INDEX_MIN_SIZE)
368         return 1;
369 
370     key.data = p;
371     key.len  = len;
372 
373     /*    printf("rdata_find %u: ", rdata_hash(&key));*/
374     /*    {*/
375     /*        size_t n = len;*/
376     /*        uint8_t* x = p;*/
377     /*        while (n--) {*/
378     /*            printf("%02x", *x);*/
379     /*            x++;*/
380     /*        }*/
381     /*    }*/
382     /*    printf("\n");*/
383 
384     if ((r = hash_find(&key, rdata_tbl))) {
385         /*        printf("rdata found %lu at %lu\n", len, found->idx);*/
386         *found = r->idx;
387         return 0;
388     }
389 
390     return 1;
391 }
392 
rdata_find2(uint8_t * p,size_t len,size_t * found)393 int rdata_find2(uint8_t* p, size_t len, size_t* found)
394 {
395     struct rdata* r = last.rdata;
396     size_t        n = 0;
397 
398     if (len < RDATA_RINDEX_MIN_SIZE)
399         return 1;
400 
401     while (r) {
402         if (r->len == len && !memcmp(p, r->data, len)) {
403             break;
404         }
405         r = r->next;
406         n++;
407     }
408     if (r) {
409         /*        printf("rdata found at %lu: ", n);*/
410         /*        {*/
411         /*            size_t n = len;*/
412         /*            uint8_t* x = p;*/
413         /*            while (n--) {*/
414         /*                printf("%02x", *x);*/
415         /*                x++;*/
416         /*            }*/
417         /*        }*/
418         /*        printf("\n");*/
419 
420         if (last.rdata != r) {
421             struct rdata *prev = r->prev, *next = r->next;
422 
423             if (prev) {
424                 prev->next = next;
425             }
426             if (next) {
427                 next->prev = prev;
428             }
429 
430             r->prev          = 0;
431             r->next          = last.rdata;
432             last.rdata->prev = r;
433             last.rdata       = r;
434         }
435 
436         *found = n;
437         return 0;
438     }
439 
440     return 1;
441 }
442 
rdata_add2(uint8_t * p,size_t len)443 int rdata_add2(uint8_t* p, size_t len)
444 {
445     struct rdata* r;
446 
447     if (len < RDATA_RINDEX_MIN_SIZE)
448         return 1;
449 
450     if (!(r = calloc(1, sizeof(struct rdata)))) {
451         return -1;
452     }
453     if (!(r->data = calloc(1, len))) {
454         free(r);
455         return -1;
456     }
457 
458     r->len = len;
459     memcpy(r->data, p, len);
460 
461     /*    printf("rdata_add: ");*/
462     /*    {*/
463     /*        size_t n = len;*/
464     /*        uint8_t* x = p;*/
465     /*        while (n--) {*/
466     /*            printf("%02x", *x);*/
467     /*            x++;*/
468     /*        }*/
469     /*    }*/
470     /*    printf("\n");*/
471 
472     if (last.rdata) {
473         last.rdata->prev = r;
474     }
475     r->next    = last.rdata;
476     last.rdata = r;
477     last.rdata_num++;
478 
479     if (last.rdata_last) {
480         if (last.rdata_num >= RDATA_RINDEX_SIZE) {
481             r = last.rdata_last;
482 
483             last.rdata_last       = r->prev;
484             last.rdata_last->next = 0;
485             last.rdata_num--;
486             free(r->data);
487             free(r);
488         }
489     } else {
490         last.rdata_last = r;
491     }
492 
493     return 0;
494 }
495 
parse_dns_rr(char is_q,dns_rr_t * rr,size_t expected_rrs,size_t * actual_rrs,uint8_t ** p,size_t * l)496 static int parse_dns_rr(char is_q, dns_rr_t* rr, size_t expected_rrs, size_t* actual_rrs, uint8_t** p, size_t* l)
497 {
498     uint8_t      len;
499     uint8_t*     p2;
500     size_t       l2, idx;
501     dns_label_t* label;
502     size_t       num_labels, offset;
503 
504     while (expected_rrs--) {
505         /* first pass check number of labels */
506         p2 = *p;
507         l2 = *l;
508 
509         if (check_dns_label(&(rr->labels), &p2, &l2)) {
510             if (!rr->labels) {
511                 fprintf(stderr, "cds no labels\n");
512                 return 1;
513             }
514         }
515 
516         /* second pass, allocate labels and fill */
517         if (!(rr->label = calloc(rr->labels, sizeof(dns_label_t)))) {
518             fprintf(stderr, "cds out of memory\n");
519             return -1;
520         }
521 
522         *actual_rrs += 1;
523 
524         label           = rr->label;
525         rr->have_labels = 1;
526 
527         while (1) {
528             need8(len, *p, *l, "name length");
529 
530             if ((len & 0xc0) == 0xc0) {
531                 label->offset_p = *p;
532                 need8(label->offset, *p, *l, "name offset");
533                 label->offset |= (len & 0x3f) << 8;
534                 label->have_offset = 1;
535                 label->is_complete = 1;
536                 break;
537             } else if (len & 0xc0) {
538                 label->extension_bits      = len;
539                 label->have_extension_bits = 1;
540                 label->is_complete         = 1;
541                 break;
542             } else if (len) {
543                 label->size      = len;
544                 label->have_size = 1;
545                 label->label     = *p;
546                 advancexb(len, *p, *l, "name label");
547                 label->have_label = 1;
548             } else {
549                 label->have_size   = 1;
550                 label->is_complete = 1;
551                 break;
552             }
553 
554             label->is_complete = 1;
555             label++;
556         }
557 
558         need16(rr->type, *p, *l, "type");
559         rr->have_type = 1;
560         need16(rr->class, *p, *l, "class");
561         rr->have_class = 1;
562 
563         if (!is_q) {
564             need32(rr->ttl, *p, *l, "ttl");
565             rr->have_ttl = 1;
566             need16(rr->rdlength, *p, *l, "rdlength");
567             rr->have_rdlength = 1;
568             rr->rdata         = *p;
569             advancexb(rr->rdlength, *p, *l, "rdata");
570 
571             if (use_rdata_index) {
572                 if (!rdata_find(rr->rdata, rr->rdlength, &(rr->rdata_index))) {
573                     rr->have_rdata_index = 1;
574                 } else {
575                     rdata_add(rr->rdata, rr->rdlength);
576                 }
577             } else if (use_rdata_rindex) {
578                 if (!rdata_find2(rr->rdata, rr->rdlength, &(rr->rdata_rindex))) {
579                     rr->have_rdata_rindex = 1;
580                 } else {
581                     rdata_add2(rr->rdata, rr->rdlength);
582                 }
583             }
584 
585             num_labels = offset = 0;
586             switch (rr->type) {
587             case 2: /* NS */
588             case 3: /* MD */
589             case 4: /* MF */
590             case 5: /* CNAME */
591             case 7: /* MB */
592             case 8: /* MG */
593             case 9: /* MR */
594             case 12: /* PTR */
595             case 30: /* NXT */
596             case 39: /* DNAME */
597             case 47: /* NSEC */
598             case 249: /* TKEY */
599             case 250: /* TSIG */
600                 num_labels = 1;
601                 break;
602 
603             case 6: /* SOA */
604             case 14: /* MINFO */
605             case 17: /* RP */
606             case 58: /* TALINK */
607                 num_labels = 2;
608                 break;
609 
610             case 15: /* MX */
611             case 18: /* AFSDB */
612             case 21: /* RT */
613             case 36: /* KX */
614             case 107: /* LP */
615                 num_labels = 1;
616                 offset     = 2;
617                 break;
618 
619             case 26: /* PX */
620                 num_labels = 2;
621                 offset     = 2;
622                 break;
623 
624             case 24: /* SIG */
625             case 46: /* RRSIG */
626                 num_labels = 1;
627                 offset     = 18;
628                 break;
629 
630             case 33: /* SRV */
631                 num_labels = 1;
632                 offset     = 6;
633                 break;
634 
635             case 35: /* NAPTR */
636                 num_labels = 1;
637                 p2         = *p;
638                 l2         = *l;
639                 advancexb(2, p2, l2, "naptr int16 #1");
640                 advancexb(2, p2, l2, "naptr int16 #2");
641                 need8(len, p2, l2, "naptr str len #1");
642                 advancexb(len, p2, l2, "naptr str #1");
643                 need8(len, p2, l2, "naptr str len #2");
644                 advancexb(len, p2, l2, "naptr str #2");
645                 need8(len, p2, l2, "naptr str len #3");
646                 advancexb(len, p2, l2, "naptr str #3");
647                 offset = p2 - *p;
648                 break;
649 
650             case 55: /* HIP TODO */
651                 break;
652             }
653 
654             if (num_labels) {
655                 dns_rdata_t* rdata;
656 
657                 rr->mixed_rdatas = num_labels + (offset ? 1 : 0) + 1;
658                 if (!(rr->mixed_rdata = calloc(rr->mixed_rdatas, sizeof(dns_rdata_t)))) {
659                     fprintf(stderr, "cds out of memory\n");
660                     return -1;
661                 }
662 
663                 p2                   = rr->rdata;
664                 l2                   = rr->rdlength;
665                 rdata                = rr->mixed_rdata;
666                 rr->have_mixed_rdata = 1;
667 
668                 if (offset) {
669                     rdata->rdata_len = offset;
670                     rdata->rdata     = p2;
671                     advancexb((int)offset, p2, l2, "mixed rdata");
672                     rdata->have_rdata  = 1;
673                     rdata->is_complete = 1;
674                     rdata++;
675                 }
676                 while (num_labels--) {
677                     uint8_t* p3;
678                     size_t   l3;
679 
680                     /* first pass check number of rdata labels */
681 
682                     p3 = p2;
683                     l3 = l2;
684 
685                     if (check_dns_label(&(rdata->labels), &p3, &l3)) {
686                         if (!rdata->labels) {
687                             fprintf(stderr, "cds mixed rdata no labels\n");
688                             return 1;
689                         }
690                     }
691 
692                     /* second pass, allocate mixed rdata */
693                     if (!(rdata->label = calloc(rdata->labels, sizeof(dns_label_t)))) {
694                         fprintf(stderr, "cds out of memory\n");
695                         return -1;
696                     }
697 
698                     label              = rdata->label;
699                     rdata->have_labels = 1;
700                     while (1) {
701                         need8(len, p2, l2, "name length");
702 
703                         if ((len & 0xc0) == 0xc0) {
704                             label->offset_p = p2;
705                             need8(label->offset, p2, l2, "name offset");
706                             label->offset |= (len & 0x3f) << 8;
707                             label->have_offset = 1;
708                             label->is_complete = 1;
709                             break;
710                         } else if (len & 0xc0) {
711                             label->extension_bits      = len;
712                             label->have_extension_bits = 1;
713                             label->is_complete         = 1;
714                             break;
715                         } else if (len) {
716                             label->size      = len;
717                             label->have_size = 1;
718                             label->label     = p2;
719                             advancexb(len, p2, l2, "name label");
720                             label->have_label = 1;
721                         } else {
722                             label->have_size   = 1;
723                             label->is_complete = 1;
724                             break;
725                         }
726 
727                         label->is_complete = 1;
728                         label++;
729                     }
730                     rdata->is_complete = 1;
731                     rdata++;
732                 }
733                 if (l2) {
734                     /*printf("last rdata %lu\n", l2);*/
735                     rdata->rdata_len = l2;
736                     rdata->rdata     = p2;
737                     advancexb((int)l2, p2, l2, "mixed rdata");
738                     rdata->have_rdata  = 1;
739                     rdata->is_complete = 1;
740                 } else {
741                     rr->mixed_rdatas--;
742                 }
743             }
744             rr->have_rdata = 1;
745         }
746 
747         rr->is_complete = 1;
748         rr++;
749     }
750 
751     return 0;
752 }
753 
754 int print_cbor = 0;
755 
parse_dns(dns_t * dns,uint8_t ** p,size_t * l)756 static int parse_dns(dns_t* dns, uint8_t** p, size_t* l)
757 {
758     int ret;
759 
760     need16(dns->id, *p, *l, "dns id");
761     dns->have_id = 1;
762     need16(dns->raw, *p, *l, "raw dns bits");
763     dns->have_raw = 1;
764     need16(dns->qdcount, *p, *l, "qdcount");
765     dns->have_qdcount = 1;
766     need16(dns->ancount, *p, *l, "ancount");
767     dns->have_ancount = 1;
768     need16(dns->nscount, *p, *l, "nscount");
769     dns->have_nscount = 1;
770     need16(dns->arcount, *p, *l, "arcount");
771     dns->have_arcount = 1;
772 
773     dns->header_is_complete = 1;
774 
775     if (dns->qdcount) {
776         if (!(dns->question = calloc(dns->qdcount, sizeof(dns_rr_t)))) {
777             fprintf(stderr, "cds out of memory\n");
778             return -1;
779         }
780         ret = parse_dns_rr(1, dns->question, dns->qdcount, &(dns->questions), p, l);
781         /*if (ret) printf("qr %d\n", ret);*/
782         if (ret > -1 && dns->questions) {
783             dns->have_questions = 1;
784         }
785         if (ret) {
786             return ret;
787         }
788     }
789 
790     if (dns->ancount) {
791         if (!(dns->answer = calloc(dns->ancount, sizeof(dns_rr_t)))) {
792             fprintf(stderr, "cds out of memory\n");
793             return -1;
794         }
795         ret = parse_dns_rr(0, dns->answer, dns->ancount, &(dns->answers), p, l);
796         /*if (ret) printf("an %d\n", ret);*/
797         if (ret > -1 && dns->answers) {
798             dns->have_answers = 1;
799         }
800         if (ret) {
801             return ret;
802         }
803     }
804 
805     if (dns->nscount) {
806         if (!(dns->authority = calloc(dns->nscount, sizeof(dns_rr_t)))) {
807             fprintf(stderr, "cds out of memory\n");
808             return -1;
809         }
810         ret = parse_dns_rr(0, dns->authority, dns->nscount, &(dns->authorities), p, l);
811         /*if (ret) { printf("ns %d %lu\n", ret, dns->authorities);*/
812         /*{*/
813         /*    size_t n;*/
814         /*    for (n = 0; n < dns->authorities; n++) {*/
815         /*        printf("%lu %d\n", n, dns->authority[n].is_complete);*/
816         /*        if (!dns->authority[n].is_complete) print_cbor = 1;*/
817         /*    }*/
818         /*} }*/
819         if (ret > -1 && dns->authorities) {
820             dns->have_authorities = 1;
821         }
822         if (ret) {
823             return ret;
824         }
825     }
826 
827     if (dns->arcount) {
828         if (!(dns->additional = calloc(dns->arcount, sizeof(dns_rr_t)))) {
829             fprintf(stderr, "cds out of memory\n");
830             return -1;
831         }
832         ret = parse_dns_rr(0, dns->additional, dns->arcount, &(dns->additionals), p, l);
833         /*if (ret) printf("ar %d\n", ret);*/
834         if (ret > -1 && dns->additionals) {
835             dns->have_additionals = 1;
836         }
837         if (ret) {
838             return ret;
839         }
840     }
841 
842     return 0;
843 }
844 
encode_label(CborEncoder * encoder,dns_label_t * label,size_t labels)845 static CborError encode_label(CborEncoder* encoder, dns_label_t* label, size_t labels)
846 {
847     CborError   cbor_err = CborNoError;
848     CborEncoder array;
849 
850     if (labels && label[labels - 1].have_size && !label[labels - 1].size) {
851         labels--;
852     }
853 
854     cbor_err = cbor_encoder_create_array(encoder, &array, labels);
855     while (labels--) {
856         if (label->have_offset) {
857             if (label->have_n_offset) {
858                 if (cbor_err == CborNoError)
859                     cbor_err = cbor_encode_uint(&array, label->n_offset);
860             } else {
861                 if (cbor_err == CborNoError)
862                     cbor_err = cbor_encode_negative_int(&array, label->offset);
863             }
864         } else if (label->have_extension_bits) {
865             if (cbor_err == CborNoError)
866                 cbor_err = cbor_encode_simple_value(&array, label->extension_bits >> 6);
867         } else if (label->have_label) {
868             if (cbor_err == CborNoError)
869                 cbor_err = cbor_encode_text_string(&array, (const char*)label->label, label->size);
870         } else {
871             if (cbor_err == CborNoError)
872                 cbor_err = cbor_encode_null(&array);
873         }
874 
875         label++;
876     }
877     if (cbor_err == CborNoError)
878         cbor_err = cbor_encoder_close_container_checked(encoder, &array);
879 
880     return cbor_err;
881 }
882 
883 /*
884  * OUTPUT
885  */
886 
print_label(dns_label_t * label,size_t labels)887 int print_label(dns_label_t* label, size_t labels)
888 {
889     size_t n;
890 
891     for (n = 0; n < labels; n++) {
892         if (label[n].have_offset) {
893             if (label[n].have_n_offset) {
894                 printf(" %lu", label[n].n_offset);
895             } else {
896                 printf(" %d", -label[n].offset);
897             }
898         } else if (label[n].have_extension_bits) {
899             printf(" %x", label[n].extension_bits);
900         } else if (label[n].have_label) {
901             printf(" %.*s", label[n].size, label[n].label);
902         } else {
903             printf(" $");
904         }
905     }
906     return 0;
907 }
908 
print_rlabel(dns_rlabel_t * label)909 int print_rlabel(dns_rlabel_t* label)
910 {
911     size_t n;
912 
913     for (n = 0; n < label->labels; n++) {
914         if (label->label[n].size) {
915             printf(" %.*s", label->label[n].size, label->label[n].label);
916         } else if (label->label[n].have_n_offset) {
917             printf(" %lu", label->label[n].n_offset);
918         } else {
919             printf(" $");
920         }
921     }
922     return 0;
923 }
924 
dns_rlabel_add(dns_label_t * label,size_t labels)925 int dns_rlabel_add(dns_label_t* label, size_t labels)
926 {
927     dns_rlabel_t* copy;
928     size_t        n, size = 0;
929 
930     for (n = 0; n < labels; n++) {
931         if ((label[n].have_offset && !label[n].have_n_offset)
932             || label[n].have_extension_bits) {
933             return 1;
934         }
935         if (label[n].have_size) {
936             size += label[n].size;
937         }
938     }
939     /*printf("label size: %lu\n", size);*/
940     if (size < MIN_RLABEL_SIZE) {
941         return 1;
942     }
943 
944     if (!(copy = calloc(1, sizeof(dns_rlabel_t)))) {
945         return -1;
946     }
947 
948     assert(labels <= CDS_RLABEL_T_LABELS);
949     copy->labels = labels;
950 
951     for (n = 0; n < labels; n++) {
952         if (label[n].have_n_offset) {
953             copy->label[n].have_n_offset = 1;
954             copy->label[n].n_offset      = label[n].n_offset;
955             continue;
956         }
957         if (label[n].size) {
958             assert(label[n].size <= CDS_RLABEL_LABEL_T_LABEL);
959 
960             copy->label[n].size = label[n].size;
961             memcpy(&(copy->label[n].label), label[n].label, label[n].size);
962         }
963     }
964 
965     /*printf("add"); print_label(label, labels); printf("\n");*/
966 
967     if (last.dns_rlabel) {
968         last.dns_rlabel->prev = copy;
969     }
970     copy->next      = last.dns_rlabel;
971     last.dns_rlabel = copy;
972     last.dns_rlabels++;
973     if (last.dns_rlabel_last) {
974         if (last.dns_rlabels >= MAX_RLABELS) {
975             dns_rlabel_t* remove = last.dns_rlabel_last;
976 
977             /*printf("remove %p %p\n", remove, remove->prev);*/
978 
979             last.dns_rlabel_last       = remove->prev;
980             last.dns_rlabel_last->next = 0;
981             free(remove);
982             last.dns_rlabels--;
983         }
984     } else {
985         last.dns_rlabel_last = copy;
986     }
987 
988     return 0;
989 }
990 
dns_rlabel_find(dns_label_t * label,size_t labels,size_t * rlabel_idx)991 static size_t dns_rlabel_find(dns_label_t* label, size_t labels, size_t* rlabel_idx)
992 {
993     size_t        n, n2, size = 0;
994     dns_rlabel_t* rlabel;
995 
996     for (n = 0; n < labels; n++) {
997         if ((label[n].have_offset && !label[n].have_n_offset)
998             || label[n].have_extension_bits) {
999             return 1;
1000         }
1001         if (label[n].have_size) {
1002             size += label[n].size;
1003         }
1004     }
1005     /*printf("label size: %lu\n", size);*/
1006     if (size < MIN_RLABEL_SIZE) {
1007         return 1;
1008     }
1009 
1010     /*printf("find"); print_label(label, labels); printf("\n");*/
1011 
1012     n      = 0;
1013     rlabel = last.dns_rlabel;
1014     while (rlabel) {
1015         if (rlabel->labels == labels) {
1016             /*printf("check"); print_rlabel(rlabel); printf("\n");*/
1017 
1018             for (n2 = 0; n2 < labels; n2++) {
1019                 /*printf("%d %lu <> %d %lu\n", label[n2].have_n_offset, label[n2].n_offset, rlabel->label[n2].have_n_offset, rlabel->label[n2].n_offset);*/
1020                 if (label[n2].have_n_offset
1021                     || rlabel->label[n2].have_n_offset) {
1022                     if (label[n2].n_offset == rlabel->label[n2].n_offset)
1023                         continue;
1024                 } else if (label[n2].size == rlabel->label[n2].size
1025                            && !memcmp(label[n2].label, rlabel->label[n2].label, label[n2].size)) {
1026                     continue;
1027                 }
1028                 break;
1029             }
1030 
1031             if (n2 == labels) {
1032                 /*printf("found at %lu: ", n); print_rlabel(rlabel); printf("\n");*/
1033                 break;
1034             }
1035         }
1036         rlabel = rlabel->next;
1037         n++;
1038     }
1039     if (rlabel) {
1040         if (last.dns_rlabel != rlabel) {
1041             dns_rlabel_t *prev = rlabel->prev, *next = rlabel->next;
1042 
1043             if (prev) {
1044                 prev->next = next;
1045             }
1046             if (next) {
1047                 next->prev = prev;
1048             }
1049 
1050             rlabel->prev          = 0;
1051             rlabel->next          = last.dns_rlabel;
1052             last.dns_rlabel->prev = rlabel;
1053             last.dns_rlabel       = rlabel;
1054         }
1055 
1056         *rlabel_idx = n;
1057         return 0;
1058     }
1059 
1060     return 1;
1061 }
1062 
free_rdata(dns_rdata_t * rdata)1063 static void free_rdata(dns_rdata_t* rdata)
1064 {
1065     if (rdata->label) {
1066         free(rdata->label);
1067     }
1068 }
1069 
free_rr(dns_rr_t * rr)1070 static void free_rr(dns_rr_t* rr)
1071 {
1072     size_t n;
1073 
1074     if (rr->label) {
1075         free(rr->label);
1076     }
1077     for (n = 0; n < rr->mixed_rdatas; n++) {
1078         free_rdata(&(rr->mixed_rdata[n]));
1079     }
1080     if (rr->mixed_rdata) {
1081         free(rr->mixed_rdata);
1082     }
1083 }
1084 
free_dns(dns_t * dns)1085 static void free_dns(dns_t* dns)
1086 {
1087     size_t n;
1088 
1089     for (n = 0; n < dns->questions; n++) {
1090         free_rr(&(dns->question[n]));
1091     }
1092     for (n = 0; n < dns->answers; n++) {
1093         free_rr(&(dns->answer[n]));
1094     }
1095     for (n = 0; n < dns->authorities; n++) {
1096         free_rr(&(dns->authority[n]));
1097     }
1098     for (n = 0; n < dns->additionals; n++) {
1099         free_rr(&(dns->additional[n]));
1100     }
1101 }
1102 
dns_rr_build_offset(dns_rr_t * rr_list,size_t count,uint16_t * offset,size_t offsets,size_t * n_offset,const u_char * payload)1103 void dns_rr_build_offset(dns_rr_t* rr_list, size_t count, uint16_t* offset, size_t offsets, size_t* n_offset, const u_char* payload)
1104 {
1105     dns_rr_t* rrp;
1106     size_t    rr, n, n2;
1107 
1108     for (rr = 0; rr < count && *n_offset < offsets; rr++) {
1109         rrp = &(rr_list[rr]);
1110 
1111         for (n = 0; n < rrp->labels && *n_offset < offsets; n++) {
1112             if (rrp->label[n].size) {
1113                 rrp->label[n].offset = rrp->label[n].label - payload - 1;
1114                 offset[*n_offset]    = rrp->label[n].offset;
1115                 *n_offset += 1;
1116             } else if (rrp->label[n].have_offset) {
1117                 offset[*n_offset] = rrp->label[n].offset_p - payload - 1;
1118                 *n_offset += 1;
1119             }
1120 
1121             /*                printf("%u %u %u %.*s\n",*/
1122             /*                    rrp->label[n].size,*/
1123             /*                    rrp->label[n].extension_bits,*/
1124             /*                    rrp->label[n].offset,*/
1125             /*                    rrp->label[n].size ? rrp->label[n].size : 0,*/
1126             /*                    rrp->label[n].size ? (char*)rrp->label[n].label : ""*/
1127             /*                );*/
1128         }
1129         for (n = 0; n < rrp->mixed_rdatas && *n_offset < offsets; n++) {
1130             for (n2 = 0; n2 < rrp->mixed_rdata[n].labels; n2++) {
1131                 if (rrp->mixed_rdata[n].label[n2].size) {
1132                     rrp->mixed_rdata[n].label[n2].offset = rrp->mixed_rdata[n].label[n2].label - payload - 1;
1133                     offset[*n_offset]                    = rrp->mixed_rdata[n].label[n2].offset;
1134                     *n_offset += 1;
1135                 } else if (rrp->mixed_rdata[n].label[n2].have_offset) {
1136                     offset[*n_offset] = rrp->mixed_rdata[n].label[n2].offset_p - payload - 1;
1137                     *n_offset += 1;
1138                 }
1139 
1140                 /*                    printf(" %u %u %u %.*s\n",*/
1141                 /*                        rrp->mixed_rdata[n].label[n2].size,*/
1142                 /*                        rrp->mixed_rdata[n].label[n2].extension_bits,*/
1143                 /*                        rrp->mixed_rdata[n].label[n2].offset,*/
1144                 /*                        rrp->mixed_rdata[n].label[n2].size ? rrp->mixed_rdata[n].label[n2].size : 0,*/
1145                 /*                        rrp->mixed_rdata[n].label[n2].size ? (char*)rrp->mixed_rdata[n].label[n2].label : ""*/
1146                 /*                    );*/
1147             }
1148         }
1149     }
1150 }
1151 
dns_rr_set_offset(dns_rr_t * rr_list,size_t count,uint16_t * offset,size_t n_offset)1152 void dns_rr_set_offset(dns_rr_t* rr_list, size_t count, uint16_t* offset, size_t n_offset)
1153 {
1154     dns_rr_t* rrp;
1155     size_t    rr, n, n2, n3;
1156 
1157     for (rr = 0; rr < count; rr++) {
1158         rrp = &(rr_list[rr]);
1159 
1160         for (n = 0; n < rrp->labels; n++) {
1161             if (!rrp->label[n].size && rrp->label[n].offset) {
1162                 for (n3 = 0; n3 < n_offset; n3++) {
1163                     if (rrp->label[n].offset == offset[n3]) {
1164                         /*                            printf("%u => %lu\n", rrp->label[n].offset, n3);*/
1165                         rrp->label[n].n_offset      = n3;
1166                         rrp->label[n].have_n_offset = 1;
1167                         break;
1168                     }
1169                 }
1170             }
1171         }
1172         for (n = 0; n < rrp->mixed_rdatas; n++) {
1173             for (n2 = 0; n2 < rrp->mixed_rdata[n].labels; n2++) {
1174                 if (!rrp->mixed_rdata[n].label[n2].size && rrp->mixed_rdata[n].label[n2].offset) {
1175                     for (n3 = 0; n3 < n_offset; n3++) {
1176                         if (rrp->mixed_rdata[n].label[n2].offset == offset[n3]) {
1177                             /*                                printf("%u => %lu\n", rrp->mixed_rdata[n].label[n2].offset, n3);*/
1178                             rrp->mixed_rdata[n].label[n2].n_offset      = n3;
1179                             rrp->mixed_rdata[n].label[n2].have_n_offset = 1;
1180                             break;
1181                         }
1182                     }
1183                 }
1184             }
1185         }
1186     }
1187 }
1188 
dns_rr_build_rlabel(dns_rr_t * rr_list,size_t count)1189 void dns_rr_build_rlabel(dns_rr_t* rr_list, size_t count)
1190 {
1191     dns_rr_t* rrp;
1192     size_t    rr, n;
1193 
1194     for (rr = 0; rr < count; rr++) {
1195         rrp = &(rr_list[rr]);
1196 
1197         if (rrp->labels) {
1198             if (!dns_rlabel_find(rrp->label, rrp->labels, &(rrp->rlabel_idx))) {
1199                 rrp->have_rlabel_idx = 1;
1200             } else {
1201                 dns_rlabel_add(rrp->label, rrp->labels);
1202             }
1203         }
1204 
1205         for (n = 0; n < rrp->mixed_rdatas; n++) {
1206             if (rrp->mixed_rdata[n].labels) {
1207                 if (!dns_rlabel_find(rrp->mixed_rdata[n].label, rrp->mixed_rdata[n].labels, &(rrp->mixed_rdata[n].rlabel_idx))) {
1208                     rrp->mixed_rdata[n].have_rlabel_idx = 1;
1209                 } else {
1210                     dns_rlabel_add(rrp->mixed_rdata[n].label, rrp->mixed_rdata[n].labels);
1211                 }
1212             }
1213         }
1214     }
1215 }
1216 
dns_build_rrs(CborEncoder * message,dns_rr_t * rr_list,size_t count)1217 CborError dns_build_rrs(CborEncoder* message, dns_rr_t* rr_list, size_t count)
1218 {
1219     CborError   cbor_err = CborNoError;
1220     CborEncoder rrs;
1221     dns_rr_t*   rr = rr_list;
1222     size_t      n  = count;
1223 
1224     if (cbor_err == CborNoError)
1225         cbor_err = cbor_encoder_create_array(message, &rrs, n);
1226     while (n--) {
1227         CborEncoder item;
1228         if (!(rr->have_type && rr->type == 41)) {
1229             if (rr->have_type && rr->type == last.dns_type) {
1230                 rr->have_type = 0;
1231             }
1232             if (rr->have_class && rr->class == last.dns_class) {
1233                 rr->have_class = 0;
1234             }
1235             if (rr->have_ttl && rr->ttl == last.dns_ttl) {
1236                 rr->have_ttl = 0;
1237             }
1238         }
1239         if (rr->have_rdlength && rr->have_rdata) {
1240             rr->have_rdlength = 0;
1241         }
1242 
1243         rr->bits = rr->have_type
1244                    | rr->have_class << 1
1245                    | rr->have_ttl << 2
1246                    | rr->have_rdlength << 3;
1247         if (rr->bits && rr->bits != 0xf) {
1248             rr->have_bits = 1;
1249         }
1250 
1251         if (cbor_err == CborNoError)
1252             cbor_err = cbor_encoder_create_array(&rrs, &item,
1253                 (rr->is_complete ? 0 : 1) + rr->have_labels
1254                     + rr->have_bits + rr->have_type + rr->have_class + rr->have_ttl + rr->have_rdlength
1255                     + rr->have_rdata);
1256         if (!rr->is_complete) {
1257             if (cbor_err == CborNoError)
1258                 cbor_err = cbor_encode_boolean(&item, false);
1259         }
1260         if (rr->have_labels) {
1261             if (rr->have_rlabel_idx) {
1262                 if (cbor_err == CborNoError)
1263                     cbor_err = cbor_encode_negative_int(&item, rr->rlabel_idx);
1264             } else {
1265                 if (cbor_err == CborNoError)
1266                     cbor_err = encode_label(&item, rr->label, rr->labels);
1267             }
1268         }
1269         if (rr->have_bits && cbor_err == CborNoError)
1270             cbor_err = cbor_encode_simple_value(&item, rr->bits);
1271         if (rr->have_type && cbor_err == CborNoError)
1272             cbor_err = cbor_encode_uint(&item, rr->type);
1273         if (rr->have_class && cbor_err == CborNoError)
1274             cbor_err = cbor_encode_uint(&item, rr->class);
1275         if (rr->have_ttl && cbor_err == CborNoError)
1276             cbor_err = cbor_encode_uint(&item, rr->ttl);
1277         if (rr->have_rdlength && cbor_err == CborNoError)
1278             cbor_err = cbor_encode_uint(&item, rr->rdlength);
1279         if (rr->have_rdata_index) {
1280             if (cbor_err == CborNoError)
1281                 cbor_err = cbor_encode_uint(&item, rr->rdata_index);
1282         } else if (rr->have_rdata_rindex) {
1283             if (cbor_err == CborNoError)
1284                 cbor_err = cbor_encode_negative_int(&item, rr->rdata_rindex);
1285         } else if (rr->have_mixed_rdata) {
1286             CborEncoder  rdatas;
1287             size_t       n2    = rr->mixed_rdatas;
1288             dns_rdata_t* rdata = rr->mixed_rdata;
1289 
1290             if (cbor_err == CborNoError)
1291                 cbor_err = cbor_encoder_create_array(&item, &rdatas, rr->mixed_rdatas);
1292             while (n2--) {
1293                 if (rdata->have_labels) {
1294                     if (rdata->have_rlabel_idx) {
1295                         if (cbor_err == CborNoError)
1296                             cbor_err = cbor_encode_negative_int(&rdatas, rdata->rlabel_idx);
1297                     } else {
1298                         if (cbor_err == CborNoError)
1299                             cbor_err = encode_label(&rdatas, rdata->label, rdata->labels);
1300                     }
1301                 } else if (rdata->have_rdata) {
1302                     if (cbor_err == CborNoError)
1303                         cbor_err = cbor_encode_byte_string(&rdatas, rdata->rdata, rdata->rdata_len);
1304                 }
1305 
1306                 rdata++;
1307             }
1308             if (cbor_err == CborNoError)
1309                 cbor_err = cbor_encoder_close_container_checked(&item, &rdatas);
1310         } else if (rr->have_rdata && cbor_err == CborNoError)
1311             cbor_err = cbor_encode_byte_string(&item, rr->rdata, rr->rdlength);
1312         if (cbor_err == CborNoError)
1313             cbor_err = cbor_encoder_close_container_checked(&rrs, &item);
1314 
1315         if (!(rr->have_type && rr->type == 41)) {
1316             if (rr->have_type) {
1317                 last.dns_type = rr->type;
1318             }
1319             if (rr->have_class) {
1320                 last.dns_class = rr->class;
1321             }
1322             if (rr->have_ttl) {
1323                 last.dns_ttl = rr->ttl;
1324             }
1325         }
1326         rr++;
1327     }
1328     if (cbor_err == CborNoError)
1329         cbor_err = cbor_encoder_close_container_checked(message, &rrs);
1330 
1331     return cbor_err;
1332 }
1333 
output_cds(iaddr from,iaddr to,uint8_t proto,unsigned flags,unsigned sport,unsigned dport,my_bpftimeval ts,const u_char * pkt_copy,size_t olen,const u_char * payload,size_t payloadlen)1334 int output_cds(iaddr from, iaddr to, uint8_t proto, unsigned flags, unsigned sport, unsigned dport, my_bpftimeval ts, const u_char* pkt_copy, size_t olen, const u_char* payload, size_t payloadlen)
1335 {
1336     CborEncoder cbor, message;
1337     CborError   cbor_err = CborNoError;
1338     ip_header_t ip;
1339     dns_t       dns;
1340     uint8_t*    malformed      = 0;
1341     size_t      malformed_size = 0;
1342     size_t      dns_parts      = 0;
1343 
1344     if (!payload) {
1345         return DUMP_CDS_EINVAL;
1346     }
1347     if (!payloadlen) {
1348         return DUMP_CDS_EINVAL;
1349     }
1350 
1351     if (!cbor_buf) {
1352         memset(&last, 0, sizeof(last));
1353         if (!(cbor_buf = calloc(1, cbor_size + message_size))) {
1354             return DUMP_CDS_ENOMEM;
1355         }
1356     }
1357     if (!cbor_buf_p) {
1358         cbor_buf_p = cbor_buf;
1359     }
1360     if (!message_buf) {
1361         if (!(message_buf = calloc(1, message_size))) {
1362             return DUMP_CDS_ENOMEM;
1363         }
1364     }
1365     if (cbor_flushed) {
1366         dns_rlabel_t* rlabel;
1367         struct rdata* r;
1368 
1369         cbor_buf_p = cbor_buf;
1370         while ((rlabel = last.dns_rlabel)) {
1371             last.dns_rlabel = rlabel->next;
1372             free(rlabel);
1373         }
1374         while ((r = last.rdata)) {
1375             last.rdata = r->next;
1376             rdata_free(r);
1377         }
1378         memset(&last, 0, sizeof(last));
1379         if (rdata_tbl) {
1380             hash_free(rdata_tbl);
1381             rdata_tbl = 0;
1382         }
1383 
1384         cbor_encoder_init(&cbor, message_buf, message_size, 0);
1385         cbor_err = cbor_encoder_create_array(&cbor, &message, 5 + (use_rdata_index ? 3 : 0) + (use_rdata_rindex ? 4 : 0));
1386         if (cbor_err == CborNoError)
1387             cbor_err = cbor_encode_text_stringz(&message, "CDSv1");
1388         if (cbor_err == CborNoError)
1389             cbor_err = cbor_encode_uint(&message, CDS_OPTION_RLABELS);
1390         if (cbor_err == CborNoError)
1391             cbor_err = cbor_encode_uint(&message, MAX_RLABELS);
1392         if (cbor_err == CborNoError)
1393             cbor_err = cbor_encode_uint(&message, CDS_OPTION_RLABEL_MIN_SIZE);
1394         if (cbor_err == CborNoError)
1395             cbor_err = cbor_encode_uint(&message, MIN_RLABEL_SIZE);
1396         if (use_rdata_index) {
1397             if (cbor_err == CborNoError)
1398                 cbor_err = cbor_encode_uint(&message, CDS_OPTION_USE_RDATA_INDEX);
1399             if (cbor_err == CborNoError)
1400                 cbor_err = cbor_encode_uint(&message, CDS_OPTION_RDATA_INDEX_MIN_SIZE);
1401             if (cbor_err == CborNoError)
1402                 cbor_err = cbor_encode_uint(&message, RDATA_INDEX_MIN_SIZE);
1403         } else if (use_rdata_rindex) {
1404             if (cbor_err == CborNoError)
1405                 cbor_err = cbor_encode_uint(&message, CDS_OPTION_RDATA_RINDEX_SIZE);
1406             if (cbor_err == CborNoError)
1407                 cbor_err = cbor_encode_uint(&message, RDATA_RINDEX_SIZE);
1408             if (cbor_err == CborNoError)
1409                 cbor_err = cbor_encode_uint(&message, CDS_OPTION_RDATA_RINDEX_MIN_SIZE);
1410             if (cbor_err == CborNoError)
1411                 cbor_err = cbor_encode_uint(&message, RDATA_RINDEX_MIN_SIZE);
1412         }
1413         if (cbor_err == CborNoError)
1414             cbor_err = cbor_encoder_close_container_checked(&cbor, &message);
1415         if (cbor_err != CborNoError) {
1416             fprintf(stderr, "cbor error[%d]: %s\n", cbor_err, cbor_error_string(cbor_err));
1417             return DUMP_CDS_ECBOR;
1418         }
1419 
1420         /*        *cbor_buf_p = 0x9f;*/
1421         /*        cbor_buf_p++;*/
1422 
1423         if ((cbor_size - (cbor_buf_p - cbor_buf)) < cbor_encoder_get_buffer_size(&cbor, message_buf)) {
1424             return DUMP_CDS_EBUF;
1425         }
1426         memcpy(cbor_buf_p, message_buf, cbor_encoder_get_buffer_size(&cbor, message_buf));
1427         cbor_buf_p += cbor_encoder_get_buffer_size(&cbor, message_buf);
1428 
1429         cbor_flushed = 0;
1430     }
1431     if (!rdata_tbl) {
1432         if (!(rdata_tbl = hash_create(64 * 1024, rdata_hash, rdata_cmp, rdata_free))) {
1433             return DUMP_CDS_ENOMEM;
1434         }
1435     }
1436 
1437     /*
1438      * IP Header
1439      */
1440 
1441     memset(&ip, 0, sizeof(ip_header_t));
1442 
1443     /* fill ip */
1444     if (from.af == AF_INET6) {
1445         ip.is_v6 = 1;
1446         memcpy(&(ip.src_addr6), &(from.u.a6), sizeof(struct in6_addr));
1447         memcpy(&(ip.dest_addr6), &(to.u.a6), sizeof(struct in6_addr));
1448         ip.src_port6  = sport;
1449         ip.dest_port6 = dport;
1450     } else {
1451         memcpy(&(ip.src_addr4), &(from.u.a4), sizeof(struct in_addr));
1452         memcpy(&(ip.dest_addr4), &(to.u.a4), sizeof(struct in_addr));
1453         ip.src_port4  = sport;
1454         ip.dest_port4 = dport;
1455     }
1456 
1457     /* deduplicate */
1458     {
1459         int         dedup = 0;
1460         ip_header_t reverse;
1461 
1462         reverse = ip;
1463 
1464         /* check last.ip */
1465         if (ip.is_v6) {
1466             if (!memcmp(&(ip.src_addr6), &(last.ip.src_addr6), sizeof(struct in6_addr)))
1467                 dedup++;
1468             else
1469                 ip.have_src_addr = 1;
1470 
1471             if (!memcmp(&(ip.dest_addr6), &(last.ip.dest_addr6), sizeof(struct in6_addr)))
1472                 dedup++;
1473             else
1474                 ip.have_dest_addr = 1;
1475 
1476             if (ip.src_port6 == last.ip.src_port6)
1477                 dedup++;
1478             else
1479                 ip.have_src_port = 1;
1480 
1481             if (ip.dest_port6 == last.ip.dest_port6)
1482                 dedup++;
1483             else
1484                 ip.have_dest_port = 1;
1485         } else {
1486             if (!memcmp(&(ip.src_addr4), &(last.ip.src_addr4), sizeof(struct in_addr)))
1487                 dedup++;
1488             else
1489                 ip.have_src_addr = 1;
1490 
1491             if (!memcmp(&(ip.dest_addr4), &(last.ip.dest_addr4), sizeof(struct in_addr)))
1492                 dedup++;
1493             else
1494                 ip.have_dest_addr = 1;
1495 
1496             if (ip.src_port4 == last.ip.src_port4)
1497                 dedup++;
1498             else
1499                 ip.have_src_port = 1;
1500 
1501             if (ip.dest_port4 == last.ip.dest_port4)
1502                 dedup++;
1503             else
1504                 ip.have_dest_port = 1;
1505         }
1506 
1507         /* check reverse last.ip */
1508         if (ip.is_v6) {
1509             if (!memcmp(&(ip.src_addr6), &(last.ip.dest_addr6), sizeof(struct in6_addr)))
1510                 dedup--;
1511             else
1512                 reverse.have_src_addr = 1;
1513 
1514             if (!memcmp(&(ip.dest_addr6), &(last.ip.src_addr6), sizeof(struct in6_addr)))
1515                 dedup--;
1516             else
1517                 reverse.have_dest_addr = 1;
1518 
1519             if (ip.src_port6 == last.ip.dest_port6)
1520                 dedup--;
1521             else
1522                 reverse.have_src_port = 1;
1523 
1524             if (ip.dest_port6 == last.ip.src_port6)
1525                 dedup--;
1526             else
1527                 reverse.have_dest_port = 1;
1528         } else {
1529             if (!memcmp(&(ip.src_addr4), &(last.ip.dest_addr4), sizeof(struct in_addr)))
1530                 dedup--;
1531             else
1532                 reverse.have_src_addr = 1;
1533 
1534             if (!memcmp(&(ip.dest_addr4), &(last.ip.src_addr4), sizeof(struct in_addr)))
1535                 dedup--;
1536             else
1537                 reverse.have_dest_addr = 1;
1538 
1539             if (ip.src_port4 == last.ip.dest_port4)
1540                 dedup--;
1541             else
1542                 reverse.have_src_port = 1;
1543 
1544             if (ip.dest_port4 == last.ip.src_port4)
1545                 dedup--;
1546             else
1547                 reverse.have_dest_port = 1;
1548         }
1549 
1550         if (dedup < 0) {
1551             ip            = reverse;
1552             ip.is_reverse = 1;
1553             /*fprintf(stderr, "reverse of last ip ");*/
1554         }
1555         /*fprintf(stderr, "v6:%d src:%d dest:%d sport:%d dport:%d\n", ip.is_v6, ip.have_src_addr, ip.have_dest_addr, ip.have_src_port, ip.have_dest_port);*/
1556 
1557         ip.bits = ip.is_v6
1558                   | ip.have_src_addr << 1
1559                   | ip.have_dest_addr << 2
1560                   | (ip.have_src_port | ip.have_dest_port) << 3;
1561 
1562         if (ip.is_v6) {
1563             last.ip.src_addr6  = ip.src_addr6;
1564             last.ip.dest_addr6 = ip.dest_addr6;
1565             last.ip.src_port6  = ip.src_port6;
1566             last.ip.dest_port6 = ip.dest_port6;
1567         } else {
1568             last.ip.src_addr4  = ip.src_addr4;
1569             last.ip.dest_addr4 = ip.dest_addr4;
1570             last.ip.src_port4  = ip.src_port4;
1571             last.ip.dest_port4 = ip.dest_port4;
1572         }
1573     }
1574 
1575     /*
1576      * DNS Message
1577      */
1578 
1579     if (flags & DNSCAP_OUTPUT_ISDNS) {
1580         uint8_t*  p = (uint8_t*)payload;
1581         size_t    l = payloadlen, rr, n, n2, n3;
1582         int       ret;
1583         dns_rr_t* rrp;
1584 
1585         size_t   n_offset = 0;
1586         uint16_t offset[256]; /* TODO: Handle offsets better */
1587 
1588         memset(&dns, 0, sizeof(dns));
1589         ret = parse_dns(&dns, &p, &l);
1590 
1591         if (ret < 0) {
1592             free_dns(&dns);
1593             return DUMP_CDS_ENOMEM;
1594         } else if (ret > 0) {
1595             malformed      = p;
1596             malformed_size = l;
1597         }
1598 
1599         if (dns.have_qdcount && dns.qdcount == dns.questions) {
1600             dns.have_qdcount = 0;
1601         }
1602         if (dns.have_ancount && dns.ancount == dns.answers) {
1603             dns.have_ancount = 0;
1604         }
1605         if (dns.have_nscount && dns.nscount == dns.authorities) {
1606             dns.have_nscount = 0;
1607         }
1608         if (dns.have_arcount && dns.arcount == dns.additionals) {
1609             dns.have_arcount = 0;
1610         }
1611 
1612         dns.cnt_bits = dns.have_qdcount
1613                        | dns.have_ancount << 1
1614                        | dns.have_nscount << 2
1615                        | dns.have_arcount << 3;
1616         if (dns.cnt_bits && dns.cnt_bits != 0xf) {
1617             dns.have_cnt_bits = 1;
1618         }
1619 
1620         dns.rr_bits = dns.have_questions
1621                       | dns.have_answers << 1
1622                       | dns.have_authorities << 2
1623                       | dns.have_additionals << 3;
1624         if (dns.rr_bits && dns.rr_bits != 0xf) {
1625             dns.have_rr_bits = 1;
1626         }
1627 
1628         dns_rr_build_offset(dns.question, dns.questions, &offset[0], sizeof(offset), &n_offset, payload);
1629         dns_rr_build_offset(dns.answer, dns.answers, &offset[0], sizeof(offset), &n_offset, payload);
1630         dns_rr_build_offset(dns.authority, dns.authorities, &offset[0], sizeof(offset), &n_offset, payload);
1631         dns_rr_build_offset(dns.additional, dns.additionals, &offset[0], sizeof(offset), &n_offset, payload);
1632 
1633         /*        for (n = 0; n < n_offset; n++) {*/
1634         /*            printf("%lu: %u\n", n, offset[n]);*/
1635         /*        }*/
1636 
1637         dns_rr_set_offset(dns.question, dns.questions, &offset[0], n_offset);
1638         dns_rr_set_offset(dns.answer, dns.answers, &offset[0], n_offset);
1639         dns_rr_set_offset(dns.authority, dns.authorities, &offset[0], n_offset);
1640         dns_rr_set_offset(dns.additional, dns.additionals, &offset[0], n_offset);
1641 
1642         dns_rr_build_rlabel(dns.question, dns.questions);
1643         dns_rr_build_rlabel(dns.answer, dns.answers);
1644         dns_rr_build_rlabel(dns.authority, dns.authorities);
1645         dns_rr_build_rlabel(dns.additional, dns.additionals);
1646     }
1647 
1648     /*
1649      * CBOR
1650      */
1651 
1652     cbor_encoder_init(&cbor, message_buf, message_size, 0);
1653     cbor_err = cbor_encoder_create_array(&cbor, &message,
1654         /* timestamp */
1655         1
1656             /* message bits */
1657             + 1
1658             /* ip header */
1659             + 1 + ip.have_src_addr + ip.have_dest_addr + (ip.have_src_port | ip.have_dest_port)
1660             /* dns message */
1661             + dns.have_id + dns.have_raw
1662             + dns.have_cnt_bits + dns.have_qdcount + dns.have_ancount + dns.have_nscount + dns.have_arcount
1663             + dns.have_rr_bits + dns.have_questions + dns.have_answers + dns.have_authorities + dns.have_additionals
1664             + (malformed ? 1 : 0));
1665 
1666     /*
1667      * Encode timestamp
1668      */
1669 
1670     {
1671         CborEncoder timestamp;
1672 
1673         if (cbor_err == CborNoError)
1674             cbor_err = cbor_encoder_create_array(&message, &timestamp, 2);
1675         if (last.ts.tv_sec && last.ts.tv_sec <= ts.tv_sec) {
1676             if (cbor_err == CborNoError)
1677                 cbor_err = cbor_encode_negative_int(&timestamp, ts.tv_sec - last.ts.tv_sec);
1678             if (cbor_err == CborNoError)
1679                 cbor_err = cbor_encode_int(&timestamp, ts.tv_usec - last.ts.tv_usec);
1680         } else {
1681             if (cbor_err == CborNoError)
1682                 cbor_err = cbor_encode_uint(&timestamp, ts.tv_sec);
1683             if (cbor_err == CborNoError)
1684                 cbor_err = cbor_encode_uint(&timestamp, ts.tv_usec);
1685         }
1686         if (cbor_err == CborNoError)
1687             cbor_err = cbor_encoder_close_container_checked(&message, &timestamp);
1688 
1689         last.ts = ts;
1690     }
1691 
1692     /*
1693      * Encode message bits
1694      */
1695 
1696     if (cbor_err == CborNoError)
1697         cbor_err = cbor_encode_uint(&message,
1698             (flags & DNSCAP_OUTPUT_ISDNS ? 1 : 0)
1699                 + (flags & DNSCAP_OUTPUT_ISDNS ? proto == IPPROTO_TCP ? 1 << 1 : 0
1700                                                : 0)
1701                 + (flags & DNSCAP_OUTPUT_ISFRAG ? 1 << 2 : 0)
1702                 + (malformed ? 1 << 3 : 0));
1703 
1704     /*
1705      * Encode IP Header
1706      */
1707 
1708     if (ip.is_reverse) {
1709         if (cbor_err == CborNoError)
1710             cbor_err = cbor_encode_negative_int(&message, ip.bits);
1711     } else {
1712         if (cbor_err == CborNoError)
1713             cbor_err = cbor_encode_uint(&message, ip.bits);
1714     }
1715 
1716     if (ip.is_v6) {
1717         if (ip.have_src_addr && cbor_err == CborNoError)
1718             cbor_err = cbor_encode_byte_string(&message, (uint8_t*)&(ip.src_addr6), sizeof(struct in6_addr));
1719         if (ip.have_dest_addr && cbor_err == CborNoError)
1720             cbor_err = cbor_encode_byte_string(&message, (uint8_t*)&(ip.dest_addr6), sizeof(struct in6_addr));
1721         if (ip.have_src_port && ip.have_dest_port) {
1722             if (cbor_err == CborNoError)
1723                 cbor_err = cbor_encode_uint(&message, (ip.dest_port6 << 16) | ip.src_port6);
1724         } else if (ip.have_src_port) {
1725             if (cbor_err == CborNoError)
1726                 cbor_err = cbor_encode_uint(&message, ip.src_port6);
1727         } else if (ip.have_dest_port) {
1728             if (cbor_err == CborNoError)
1729                 cbor_err = cbor_encode_negative_int(&message, ip.dest_port6);
1730         }
1731     } else {
1732         if (ip.have_src_addr && cbor_err == CborNoError)
1733             cbor_err = cbor_encode_byte_string(&message, (uint8_t*)&(ip.src_addr4), sizeof(struct in_addr));
1734         if (ip.have_dest_addr && cbor_err == CborNoError)
1735             cbor_err = cbor_encode_byte_string(&message, (uint8_t*)&(ip.dest_addr4), sizeof(struct in_addr));
1736         if (ip.have_src_port && ip.have_dest_port) {
1737             if (cbor_err == CborNoError)
1738                 cbor_err = cbor_encode_uint(&message, (ip.dest_port4 << 16) | ip.src_port4);
1739         } else if (ip.have_src_port) {
1740             if (cbor_err == CborNoError)
1741                 cbor_err = cbor_encode_uint(&message, ip.src_port4);
1742         } else if (ip.have_dest_port) {
1743             if (cbor_err == CborNoError)
1744                 cbor_err = cbor_encode_negative_int(&message, ip.dest_port4);
1745         }
1746     }
1747 
1748     /*
1749      * Encode DNS Message
1750      */
1751     if (flags & DNSCAP_OUTPUT_ISDNS && !dns.header_is_complete) {
1752         if (cbor_err == CborNoError)
1753             cbor_err = cbor_encode_boolean(&message, false);
1754     }
1755     if (dns.have_id && cbor_err == CborNoError)
1756         cbor_err = cbor_encode_uint(&message, dns.id);
1757     if (dns.have_raw && cbor_err == CborNoError)
1758         cbor_err = cbor_encode_uint(&message, dns.raw);
1759     if (dns.have_cnt_bits && cbor_err == CborNoError)
1760         cbor_err = cbor_encode_negative_int(&message, dns.cnt_bits);
1761     if (dns.have_qdcount && cbor_err == CborNoError)
1762         cbor_err = cbor_encode_uint(&message, dns.qdcount);
1763     if (dns.have_ancount && cbor_err == CborNoError)
1764         cbor_err = cbor_encode_uint(&message, dns.ancount);
1765     if (dns.have_nscount && cbor_err == CborNoError)
1766         cbor_err = cbor_encode_uint(&message, dns.nscount);
1767     if (dns.have_arcount && cbor_err == CborNoError)
1768         cbor_err = cbor_encode_uint(&message, dns.arcount);
1769     if (dns.have_rr_bits && cbor_err == CborNoError)
1770         cbor_err = cbor_encode_simple_value(&message, dns.rr_bits);
1771     if (dns.have_questions) {
1772         CborEncoder rrs;
1773         dns_rr_t*   rr = dns.question;
1774         size_t      n  = dns.questions;
1775 
1776         if (cbor_err == CborNoError)
1777             cbor_err = cbor_encoder_create_array(&message, &rrs, n);
1778         while (n--) {
1779             CborEncoder item;
1780 
1781             if (rr->have_type && rr->type == last.dns_type) {
1782                 rr->have_type = 0;
1783             }
1784             if (rr->have_class && rr->class == last.dns_class) {
1785                 rr->have_class = 0;
1786             }
1787 
1788             if (cbor_err == CborNoError)
1789                 cbor_err = cbor_encoder_create_array(&rrs, &item,
1790                     (rr->is_complete ? 0 : 1) + rr->have_labels + rr->have_type + rr->have_class);
1791             if (!rr->is_complete) {
1792                 if (cbor_err == CborNoError)
1793                     cbor_err = cbor_encode_boolean(&item, false);
1794             }
1795             if (rr->have_labels) {
1796                 if (rr->have_rlabel_idx) {
1797                     if (cbor_err == CborNoError)
1798                         cbor_err = cbor_encode_negative_int(&item, rr->rlabel_idx);
1799                 } else {
1800                     if (cbor_err == CborNoError)
1801                         cbor_err = encode_label(&item, rr->label, rr->labels);
1802                 }
1803             }
1804             if (rr->have_type && cbor_err == CborNoError)
1805                 cbor_err = cbor_encode_uint(&item, rr->type);
1806             if (rr->have_class && cbor_err == CborNoError)
1807                 cbor_err = cbor_encode_negative_int(&item, rr->class);
1808             if (cbor_err == CborNoError)
1809                 cbor_err = cbor_encoder_close_container_checked(&rrs, &item);
1810 
1811             if (rr->have_type) {
1812                 last.dns_type = rr->type;
1813             }
1814             if (rr->have_class) {
1815                 last.dns_class = rr->class;
1816             }
1817 
1818             rr++;
1819         }
1820         if (cbor_err == CborNoError)
1821             cbor_err = cbor_encoder_close_container_checked(&message, &rrs);
1822     }
1823     if (dns.have_answers && cbor_err == CborNoError)
1824         cbor_err = dns_build_rrs(&message, dns.answer, dns.answers);
1825     if (dns.have_authorities && cbor_err == CborNoError)
1826         cbor_err = dns_build_rrs(&message, dns.authority, dns.authorities);
1827     if (dns.have_additionals && cbor_err == CborNoError)
1828         cbor_err = dns_build_rrs(&message, dns.additional, dns.additionals);
1829 
1830     /*
1831      * Encode malformed
1832      */
1833 
1834     if (malformed && cbor_err == CborNoError)
1835         cbor_err = cbor_encode_byte_string(&message, (uint8_t*)malformed, malformed_size);
1836 
1837     /*
1838      * Close
1839      */
1840 
1841     free_dns(&dns);
1842 
1843     if (cbor_err == CborNoError)
1844         cbor_err = cbor_encoder_close_container_checked(&cbor, &message);
1845     if (cbor_err != CborNoError) {
1846         fprintf(stderr, "cbor error[%d]: %s\n", cbor_err, cbor_error_string(cbor_err));
1847         return DUMP_CDS_ECBOR;
1848     }
1849 
1850     /*    if (print_cbor>1)*/
1851     /*    {*/
1852     /*        uint8_t* p = message_buf;*/
1853     /*        size_t s = cbor_encoder_get_buffer_size(&cbor, message_buf);*/
1854 
1855     /*        while (s--) {*/
1856     /*            printf("%02x", *p++);*/
1857     /*        }*/
1858     /*        printf("\n");*/
1859     /*    }*/
1860 
1861     if (((cbor_size + message_size) - (cbor_buf_p - cbor_buf)) < cbor_encoder_get_buffer_size(&cbor, message_buf)) {
1862         return DUMP_CDS_EBUF;
1863     }
1864     memcpy(cbor_buf_p, message_buf, cbor_encoder_get_buffer_size(&cbor, message_buf));
1865     cbor_buf_p += cbor_encoder_get_buffer_size(&cbor, message_buf);
1866 
1867     if (cbor_buf_p < (cbor_buf + cbor_size)) {
1868         return DUMP_CDS_OK;
1869     }
1870 
1871     cbor_flushed = 1;
1872     return DUMP_CDS_FLUSH;
1873 }
1874 
dump_cds(FILE * fp)1875 int dump_cds(FILE* fp)
1876 {
1877     CborError cbor_err;
1878 
1879     if (!fp) {
1880         return DUMP_CDS_EINVAL;
1881     }
1882 
1883     /*    *cbor_buf_p = 0xff;*/
1884     /*    cbor_buf_p++;*/
1885 
1886     /*    fprintf(stderr, "cds output: %lu bytes\n", cbor_buf_p - cbor_buf);*/
1887 
1888     if (fwrite(cbor_buf, cbor_buf_p - cbor_buf, 1, fp) != 1) {
1889         return DUMP_CDS_EWRITE;
1890     }
1891 
1892     return DUMP_CDS_OK;
1893 }
1894 
have_cds_support()1895 int have_cds_support()
1896 {
1897     return 1;
1898 }
1899 
1900 #else /* HAVE_LIBTINYCBOR */
1901 
cds_set_cbor_size(size_t size)1902 int cds_set_cbor_size(size_t size)
1903 {
1904     return DUMP_CDS_ENOSUP;
1905 }
1906 
cds_set_message_size(size_t size)1907 int cds_set_message_size(size_t size)
1908 {
1909     return DUMP_CDS_ENOSUP;
1910 }
1911 
cds_set_max_rlabels(size_t size)1912 int cds_set_max_rlabels(size_t size)
1913 {
1914     return DUMP_CDS_ENOSUP;
1915 }
1916 
cds_set_min_rlabel_size(size_t size)1917 int cds_set_min_rlabel_size(size_t size)
1918 {
1919     return DUMP_CDS_ENOSUP;
1920 }
1921 
cds_set_use_rdata_index(int use)1922 int cds_set_use_rdata_index(int use)
1923 {
1924     return DUMP_CDS_ENOSUP;
1925 }
1926 
cds_set_use_rdata_rindex(int use)1927 int cds_set_use_rdata_rindex(int use)
1928 {
1929     return DUMP_CDS_ENOSUP;
1930 }
1931 
cds_set_rdata_index_min_size(size_t size)1932 int cds_set_rdata_index_min_size(size_t size)
1933 {
1934     return DUMP_CDS_ENOSUP;
1935 }
1936 
cds_set_rdata_rindex_min_size(size_t size)1937 int cds_set_rdata_rindex_min_size(size_t size)
1938 {
1939     return DUMP_CDS_ENOSUP;
1940 }
1941 
cds_set_rdata_rindex_size(size_t size)1942 int cds_set_rdata_rindex_size(size_t size)
1943 {
1944     return DUMP_CDS_ENOSUP;
1945 }
1946 
output_cds(iaddr from,iaddr to,uint8_t proto,unsigned flags,unsigned sport,unsigned dport,my_bpftimeval ts,const u_char * pkt_copy,size_t olen,const u_char * payload,size_t payloadlen)1947 int output_cds(iaddr from, iaddr to, uint8_t proto, unsigned flags, unsigned sport, unsigned dport, my_bpftimeval ts, const u_char* pkt_copy, size_t olen, const u_char* payload, size_t payloadlen)
1948 {
1949     return DUMP_CDS_ENOSUP;
1950 }
1951 
dump_cds(FILE * fp)1952 int dump_cds(FILE* fp)
1953 {
1954     return DUMP_CDS_ENOSUP;
1955 }
1956 
have_cds_support()1957 int have_cds_support()
1958 {
1959     return 0;
1960 }
1961 
1962 #endif
1963