]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - dnstap/dnstap_fstrm.c
Vendor import of Unbound 1.12.0.
[FreeBSD/FreeBSD.git] / dnstap / dnstap_fstrm.c
1 /*
2  * dnstap/dnstap_fstrm.c - Frame Streams protocol for dnstap
3  *
4  * Copyright (c) 2020, NLnet Labs. All rights reserved.
5  *
6  * This software is open source.
7  * 
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 
12  * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  * 
15  * Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  * 
19  * Neither the name of the NLNET LABS nor the names of its contributors may
20  * be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  * 
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  *
35  */
36
37 /**
38  * \file
39  *
40  * Definitions for the Frame Streams data transport protocol for
41  * dnstap message logs.
42  */
43
44 #include "config.h"
45 #include "dnstap/dnstap_fstrm.h"
46 #include "sldns/sbuffer.h"
47 #include "sldns/wire2str.h"
48
49 void* fstrm_create_control_frame_start(char* contenttype, size_t* len)
50 {
51         uint32_t* control;
52         size_t n;
53         /* start framestream message:
54          * 4byte 0: control indicator.
55          * 4byte bigendian: length of control frame
56          * 4byte bigendian: type START
57          * 4byte bigendian: option: content-type
58          * 4byte bigendian: length of string
59          * string of content type (dnstap)
60          */
61         n = 4+4+4+4+4+strlen(contenttype);
62         control = malloc(n);
63         if(!control)
64                 return NULL;
65         control[0] = 0;
66         control[1] = htonl(4+4+4+strlen(contenttype));
67         control[2] = htonl(FSTRM_CONTROL_FRAME_START);
68         control[3] = htonl(FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE);
69         control[4] = htonl(strlen(contenttype));
70         memmove(&control[5], contenttype, strlen(contenttype));
71         *len = n;
72         return control;
73 }
74
75 void* fstrm_create_control_frame_stop(size_t* len)
76 {
77         uint32_t* control;
78         size_t n;
79         /* stop framestream message:
80          * 4byte 0: control indicator.
81          * 4byte bigendian: length of control frame
82          * 4byte bigendian: type STOP
83          */
84         n = 4+4+4;
85         control = malloc(n);
86         if(!control)
87                 return NULL;
88         control[0] = 0;
89         control[1] = htonl(4);
90         control[2] = htonl(FSTRM_CONTROL_FRAME_STOP);
91         *len = n;
92         return control;
93 }
94
95 void* fstrm_create_control_frame_ready(char* contenttype, size_t* len)
96 {
97         uint32_t* control;
98         size_t n;
99         /* start bidirectional stream:
100          * 4 bytes 0 escape
101          * 4 bytes bigendian length of frame
102          * 4 bytes bigendian type READY
103          * 4 bytes bigendian frame option content type
104          * 4 bytes bigendian length of string
105          * string of content type.
106          */
107         /* len includes the escape and framelength */
108         n = 4+4+4+4+4+strlen(contenttype);
109         control = malloc(n);
110         if(!control) {
111                 return NULL;
112         }
113         control[0] = 0;
114         control[1] = htonl(4+4+4+strlen(contenttype));
115         control[2] = htonl(FSTRM_CONTROL_FRAME_READY);
116         control[3] = htonl(FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE);
117         control[4] = htonl(strlen(contenttype));
118         memmove(&control[5], contenttype, strlen(contenttype));
119         *len = n;
120         return control;
121 }
122
123 void* fstrm_create_control_frame_accept(char* contenttype, size_t* len)
124 {
125         uint32_t* control;
126         size_t n;
127         /* control frame on reply:
128          * 4 bytes 0 escape
129          * 4 bytes bigendian length of frame
130          * 4 bytes bigendian type ACCEPT
131          * 4 bytes bigendian frame option content type
132          * 4 bytes bigendian length of string
133          * string of content type.
134          */
135         /* len includes the escape and framelength */
136         n = 4+4+4+4+4+strlen(contenttype);
137         control = malloc(n);
138         if(!control) {
139                 return NULL;
140         }
141         control[0] = 0;
142         control[1] = htonl(4+4+4+strlen(contenttype));
143         control[2] = htonl(FSTRM_CONTROL_FRAME_ACCEPT);
144         control[3] = htonl(FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE);
145         control[4] = htonl(strlen(contenttype));
146         memmove(&control[5], contenttype, strlen(contenttype));
147         *len = n;
148         return control;
149 }
150
151 void* fstrm_create_control_frame_finish(size_t* len)
152 {
153         uint32_t* control;
154         size_t n;
155         /* control frame on reply:
156          * 4 bytes 0 escape
157          * 4 bytes bigendian length of frame
158          * 4 bytes bigendian type FINISH
159          */
160         /* len includes the escape and framelength */
161         n = 4+4+4;
162         control = malloc(n);
163         if(!control) {
164                 return NULL;
165         }
166         control[0] = 0;
167         control[1] = htonl(4);
168         control[2] = htonl(FSTRM_CONTROL_FRAME_FINISH);
169         *len = n;
170         return control;
171 }
172
173 char* fstrm_describe_control(void* pkt, size_t len)
174 {
175         uint32_t frametype = 0;
176         char buf[512];
177         char* str = buf;
178         size_t remain, slen = sizeof(buf);
179         uint8_t* pos;
180
181         buf[0]=0;
182         if(len < 4) {
183                 snprintf(buf, sizeof(buf), "malformed control frame, "
184                         "too short, len=%u", (unsigned int)len);
185                 return strdup(buf);
186         }
187         frametype = sldns_read_uint32(pkt);
188         if(frametype == FSTRM_CONTROL_FRAME_ACCEPT) {
189                 (void)sldns_str_print(&str, &slen, "accept");
190         } else if(frametype == FSTRM_CONTROL_FRAME_START) {
191                 (void)sldns_str_print(&str, &slen, "start");
192         } else if(frametype == FSTRM_CONTROL_FRAME_STOP) {
193                 (void)sldns_str_print(&str, &slen, "stop");
194         } else if(frametype == FSTRM_CONTROL_FRAME_READY) {
195                 (void)sldns_str_print(&str, &slen, "ready");
196         } else if(frametype == FSTRM_CONTROL_FRAME_FINISH) {
197                 (void)sldns_str_print(&str, &slen, "finish");
198         } else {
199                 (void)sldns_str_print(&str, &slen, "type%d", (int)frametype);
200         }
201
202         /* show the content type options */
203         pos = pkt + 4;
204         remain = len - 4;
205         while(remain >= 8) {
206                 uint32_t field_type = sldns_read_uint32(pos);
207                 uint32_t field_len = sldns_read_uint32(pos+4);
208                 if(remain < field_len) {
209                         (void)sldns_str_print(&str, &slen, "malformed_field");
210                         break;
211                 }
212                 if(field_type == FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE) {
213                         char tempf[512];
214                         (void)sldns_str_print(&str, &slen, " content-type(");
215                         if(field_len < sizeof(tempf)-1) {
216                                 memmove(tempf, pos+8, field_len);
217                                 tempf[field_len] = 0;
218                                 (void)sldns_str_print(&str, &slen, "%s", tempf);
219                         } else {
220                                 (void)sldns_str_print(&str, &slen, "<error-too-long>");
221                         }
222                         (void)sldns_str_print(&str, &slen, ")");
223                 } else {
224                         (void)sldns_str_print(&str, &slen,
225                                 " field(type %u, length %u)",
226                                 (unsigned int)field_type,
227                                 (unsigned int)field_len);
228                 }
229                 pos += 8 + field_len;
230                 remain -= (8 + field_len);
231         }
232         if(remain > 0)
233                 (void)sldns_str_print(&str, &slen, " trailing-bytes"
234                         "(length %u)", (unsigned int)remain);
235         return strdup(buf);
236 }