aboutsummaryrefslogtreecommitdiff
path: root/src/dns/gnunet-dns-monitor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dns/gnunet-dns-monitor.c')
-rw-r--r--src/dns/gnunet-dns-monitor.c380
1 files changed, 199 insertions, 181 deletions
diff --git a/src/dns/gnunet-dns-monitor.c b/src/dns/gnunet-dns-monitor.c
index e822b3211..819cb025d 100644
--- a/src/dns/gnunet-dns-monitor.c
+++ b/src/dns/gnunet-dns-monitor.c
@@ -11,12 +11,12 @@
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU Affero General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19*/ 19 */
20 20
21/** 21/**
22 * @file src/dns/gnunet-dns-monitor.c 22 * @file src/dns/gnunet-dns-monitor.c
@@ -62,22 +62,31 @@ static unsigned int verbosity;
62 * @return type as string, only valid until the next call to this function 62 * @return type as string, only valid until the next call to this function
63 */ 63 */
64static const char * 64static const char *
65get_type (uint16_t type) 65get_type(uint16_t type)
66{ 66{
67 static char buf[6]; 67 static char buf[6];
68
68 switch (type) 69 switch (type)
69 { 70 {
70 case GNUNET_DNSPARSER_TYPE_A: return "A"; 71 case GNUNET_DNSPARSER_TYPE_A: return "A";
71 case GNUNET_DNSPARSER_TYPE_NS: return "NS"; 72
72 case GNUNET_DNSPARSER_TYPE_CNAME: return "CNAME"; 73 case GNUNET_DNSPARSER_TYPE_NS: return "NS";
73 case GNUNET_DNSPARSER_TYPE_SOA: return "SOA"; 74
74 case GNUNET_DNSPARSER_TYPE_PTR: return "PTR"; 75 case GNUNET_DNSPARSER_TYPE_CNAME: return "CNAME";
75 case GNUNET_DNSPARSER_TYPE_MX: return "MX"; 76
76 case GNUNET_DNSPARSER_TYPE_TXT: return "TXT"; 77 case GNUNET_DNSPARSER_TYPE_SOA: return "SOA";
77 case GNUNET_DNSPARSER_TYPE_AAAA: return "AAAA"; 78
78 case GNUNET_DNSPARSER_TYPE_SRV: return "SRV"; 79 case GNUNET_DNSPARSER_TYPE_PTR: return "PTR";
79 } 80
80 GNUNET_snprintf (buf, sizeof (buf), "%u", (unsigned int) type); 81 case GNUNET_DNSPARSER_TYPE_MX: return "MX";
82
83 case GNUNET_DNSPARSER_TYPE_TXT: return "TXT";
84
85 case GNUNET_DNSPARSER_TYPE_AAAA: return "AAAA";
86
87 case GNUNET_DNSPARSER_TYPE_SRV: return "SRV";
88 }
89 GNUNET_snprintf(buf, sizeof(buf), "%u", (unsigned int)type);
81 return buf; 90 return buf;
82} 91}
83 92
@@ -89,16 +98,19 @@ get_type (uint16_t type)
89 * @return class as string, only valid until the next call to this function 98 * @return class as string, only valid until the next call to this function
90 */ 99 */
91static const char * 100static const char *
92get_class (uint16_t class) 101get_class(uint16_t class)
93{ 102{
94 static char buf[6]; 103 static char buf[6];
104
95 switch (class) 105 switch (class)
96 { 106 {
97 case GNUNET_TUN_DNS_CLASS_INTERNET: return "IN"; 107 case GNUNET_TUN_DNS_CLASS_INTERNET: return "IN";
98 case GNUNET_TUN_DNS_CLASS_CHAOS: return "CHAOS"; 108
99 case GNUNET_TUN_DNS_CLASS_HESIOD: return "HESIOD"; 109 case GNUNET_TUN_DNS_CLASS_CHAOS: return "CHAOS";
100 } 110
101 GNUNET_snprintf (buf, sizeof (buf), "%u", (unsigned int) class); 111 case GNUNET_TUN_DNS_CLASS_HESIOD: return "HESIOD";
112 }
113 GNUNET_snprintf(buf, sizeof(buf), "%u", (unsigned int)class);
102 return buf; 114 return buf;
103} 115}
104 116
@@ -109,13 +121,13 @@ get_class (uint16_t class)
109 * @param query query to display. 121 * @param query query to display.
110 */ 122 */
111static void 123static void
112display_query (const struct GNUNET_DNSPARSER_Query *query) 124display_query(const struct GNUNET_DNSPARSER_Query *query)
113{ 125{
114 fprintf (stdout, 126 fprintf(stdout,
115 "\t\t%s %s: %s\n", 127 "\t\t%s %s: %s\n",
116 get_class (query->dns_traffic_class), 128 get_class(query->dns_traffic_class),
117 get_type (query->type), 129 get_type(query->type),
118 query->name); 130 query->name);
119} 131}
120 132
121 133
@@ -125,7 +137,7 @@ display_query (const struct GNUNET_DNSPARSER_Query *query)
125 * @param record record to display. 137 * @param record record to display.
126 */ 138 */
127static void 139static void
128display_record (const struct GNUNET_DNSPARSER_Record *record) 140display_record(const struct GNUNET_DNSPARSER_Record *record)
129{ 141{
130 const char *format; 142 const char *format;
131 char buf[INET6_ADDRSTRLEN]; 143 char buf[INET6_ADDRSTRLEN];
@@ -133,86 +145,93 @@ display_record (const struct GNUNET_DNSPARSER_Record *record)
133 145
134 tmp = NULL; 146 tmp = NULL;
135 switch (record->type) 147 switch (record->type)
136 {
137 case GNUNET_DNSPARSER_TYPE_A:
138 if (record->data.raw.data_len != sizeof (struct in_addr))
139 format = "<invalid>";
140 else
141 format = inet_ntop (AF_INET, record->data.raw.data, buf, sizeof (buf));
142 break;
143 case GNUNET_DNSPARSER_TYPE_AAAA:
144 if (record->data.raw.data_len != sizeof (struct in6_addr))
145 format = "<invalid>";
146 else
147 format = inet_ntop (AF_INET6, record->data.raw.data, buf, sizeof (buf));
148 break;
149 case GNUNET_DNSPARSER_TYPE_NS:
150 case GNUNET_DNSPARSER_TYPE_CNAME:
151 case GNUNET_DNSPARSER_TYPE_PTR:
152 format = record->data.hostname;
153 break;
154 case GNUNET_DNSPARSER_TYPE_SOA:
155 if (NULL == record->data.soa)
156 format = "<invalid>";
157 else
158 { 148 {
159 GNUNET_asprintf (&tmp, 149 case GNUNET_DNSPARSER_TYPE_A:
160 "origin: %s, mail: %s, serial = %u, refresh = %u s, retry = %u s, expire = %u s, minimum = %u s", 150 if (record->data.raw.data_len != sizeof(struct in_addr))
161 record->data.soa->mname, 151 format = "<invalid>";
162 record->data.soa->rname, 152 else
163 (unsigned int) record->data.soa->serial, 153 format = inet_ntop(AF_INET, record->data.raw.data, buf, sizeof(buf));
164 (unsigned int) record->data.soa->refresh, 154 break;
165 (unsigned int) record->data.soa->retry, 155
166 (unsigned int) record->data.soa->expire, 156 case GNUNET_DNSPARSER_TYPE_AAAA:
167 (unsigned int) record->data.soa->minimum_ttl); 157 if (record->data.raw.data_len != sizeof(struct in6_addr))
168 format = tmp; 158 format = "<invalid>";
169 } 159 else
170 break; 160 format = inet_ntop(AF_INET6, record->data.raw.data, buf, sizeof(buf));
171 case GNUNET_DNSPARSER_TYPE_MX: 161 break;
172 if (record->data.mx == NULL) 162
173 format = "<invalid>"; 163 case GNUNET_DNSPARSER_TYPE_NS:
174 else 164 case GNUNET_DNSPARSER_TYPE_CNAME:
175 { 165 case GNUNET_DNSPARSER_TYPE_PTR:
176 GNUNET_asprintf (&tmp, 166 format = record->data.hostname;
177 "%u: %s", 167 break;
178 record->data.mx->preference, 168
179 record->data.mx->mxhost); 169 case GNUNET_DNSPARSER_TYPE_SOA:
180 format = tmp; 170 if (NULL == record->data.soa)
181 } 171 format = "<invalid>";
182 break; 172 else
183 case GNUNET_DNSPARSER_TYPE_SRV: 173 {
184 if (NULL == record->data.srv) 174 GNUNET_asprintf(&tmp,
185 format = "<invalid>"; 175 "origin: %s, mail: %s, serial = %u, refresh = %u s, retry = %u s, expire = %u s, minimum = %u s",
186 else 176 record->data.soa->mname,
187 { 177 record->data.soa->rname,
188 GNUNET_asprintf (&tmp, 178 (unsigned int)record->data.soa->serial,
189 "priority %u, weight = %s, port = %u, target = %s", 179 (unsigned int)record->data.soa->refresh,
190 (unsigned int) record->data.srv->priority, 180 (unsigned int)record->data.soa->retry,
191 (unsigned int) record->data.srv->weight, 181 (unsigned int)record->data.soa->expire,
192 (unsigned int) record->data.srv->port, 182 (unsigned int)record->data.soa->minimum_ttl);
193 record->data.srv->target); 183 format = tmp;
184 }
185 break;
186
187 case GNUNET_DNSPARSER_TYPE_MX:
188 if (record->data.mx == NULL)
189 format = "<invalid>";
190 else
191 {
192 GNUNET_asprintf(&tmp,
193 "%u: %s",
194 record->data.mx->preference,
195 record->data.mx->mxhost);
196 format = tmp;
197 }
198 break;
199
200 case GNUNET_DNSPARSER_TYPE_SRV:
201 if (NULL == record->data.srv)
202 format = "<invalid>";
203 else
204 {
205 GNUNET_asprintf(&tmp,
206 "priority %u, weight = %s, port = %u, target = %s",
207 (unsigned int)record->data.srv->priority,
208 (unsigned int)record->data.srv->weight,
209 (unsigned int)record->data.srv->port,
210 record->data.srv->target);
211 format = tmp;
212 }
213 break;
214
215 case GNUNET_DNSPARSER_TYPE_TXT:
216 GNUNET_asprintf(&tmp,
217 "%.*s",
218 (unsigned int)record->data.raw.data_len,
219 record->data.raw.data);
194 format = tmp; 220 format = tmp;
221 break;
222
223 default:
224 format = "<payload>";
225 break;
195 } 226 }
196 break; 227 fprintf(stdout,
197 case GNUNET_DNSPARSER_TYPE_TXT: 228 "\t\t%s %s: %s = %s (%u s)\n",
198 GNUNET_asprintf (&tmp, 229 get_class(record->dns_traffic_class),
199 "%.*s", 230 get_type(record->type),
200 (unsigned int) record->data.raw.data_len, 231 record->name,
201 record->data.raw.data); 232 format,
202 format = tmp; 233 (unsigned int)(GNUNET_TIME_absolute_get_remaining(record->expiration_time).rel_value_us / 1000LL / 1000LL));
203 break; 234 GNUNET_free_non_null(tmp);
204 default:
205 format = "<payload>";
206 break;
207 }
208 fprintf (stdout,
209 "\t\t%s %s: %s = %s (%u s)\n",
210 get_class (record->dns_traffic_class),
211 get_type (record->type),
212 record->name,
213 format,
214 (unsigned int) (GNUNET_TIME_absolute_get_remaining (record->expiration_time).rel_value_us / 1000LL / 1000LL));
215 GNUNET_free_non_null (tmp);
216} 235}
217 236
218 237
@@ -240,62 +259,62 @@ display_record (const struct GNUNET_DNSPARSER_Record *record)
240 * @param request udp payload of the DNS request 259 * @param request udp payload of the DNS request
241 */ 260 */
242static void 261static void
243display_request (void *cls, 262display_request(void *cls,
244 struct GNUNET_DNS_RequestHandle *rh, 263 struct GNUNET_DNS_RequestHandle *rh,
245 size_t request_length, 264 size_t request_length,
246 const char *request) 265 const char *request)
247{ 266{
248 static const char *return_codes[] = 267 static const char *return_codes[] =
249 { 268 {
250 "No error", "Format error", "Server failure", "Name error", 269 "No error", "Format error", "Server failure", "Name error",
251 "Not implemented", "Refused", "YXDomain", "YXRRset", 270 "Not implemented", "Refused", "YXDomain", "YXRRset",
252 "NXRRset", "NOT AUTH", "NOT ZONE", "<invalid>", 271 "NXRRset", "NOT AUTH", "NOT ZONE", "<invalid>",
253 "<invalid>", "<invalid>", "<invalid>", "<invalid>" 272 "<invalid>", "<invalid>", "<invalid>", "<invalid>"
254 }; 273 };
255 static const char *op_codes[] = 274 static const char *op_codes[] =
256 { 275 {
257 "Query", "Inverse query", "Status", "<invalid>", 276 "Query", "Inverse query", "Status", "<invalid>",
258 "<invalid>", "<invalid>", "<invalid>", "<invalid>", 277 "<invalid>", "<invalid>", "<invalid>", "<invalid>",
259 "<invalid>", "<invalid>", "<invalid>", "<invalid>", 278 "<invalid>", "<invalid>", "<invalid>", "<invalid>",
260 "<invalid>", "<invalid>", "<invalid>", "<invalid>" 279 "<invalid>", "<invalid>", "<invalid>", "<invalid>"
261 }; 280 };
262 struct GNUNET_DNSPARSER_Packet *p; 281 struct GNUNET_DNSPARSER_Packet *p;
263 unsigned int i; 282 unsigned int i;
264 283
265 p = GNUNET_DNSPARSER_parse (request, request_length); 284 p = GNUNET_DNSPARSER_parse(request, request_length);
266 if (NULL == p) 285 if (NULL == p)
267 { 286 {
268 fprintf (stderr, "Received malformed DNS packet!\n"); 287 fprintf(stderr, "Received malformed DNS packet!\n");
269 // FIXME: drop instead? 288 // FIXME: drop instead?
270 GNUNET_DNS_request_forward (rh); 289 GNUNET_DNS_request_forward(rh);
271 return; 290 return;
272 } 291 }
273 fprintf (stdout, 292 fprintf(stdout,
274 "%s with ID: %5u Flags: %s%s%s%s%s%s, Return Code: %s, Opcode: %s\n", 293 "%s with ID: %5u Flags: %s%s%s%s%s%s, Return Code: %s, Opcode: %s\n",
275 p->flags.query_or_response ? "Response" : "Query", 294 p->flags.query_or_response ? "Response" : "Query",
276 p->id, 295 p->id,
277 p->flags.recursion_desired ? "RD " : "", 296 p->flags.recursion_desired ? "RD " : "",
278 p->flags.message_truncated ? "MT " : "", 297 p->flags.message_truncated ? "MT " : "",
279 p->flags.authoritative_answer ? "AA " : "", 298 p->flags.authoritative_answer ? "AA " : "",
280 p->flags.checking_disabled ? "CD " : "", 299 p->flags.checking_disabled ? "CD " : "",
281 p->flags.authenticated_data ? "AD " : "", 300 p->flags.authenticated_data ? "AD " : "",
282 p->flags.recursion_available ? "RA " : "", 301 p->flags.recursion_available ? "RA " : "",
283 return_codes[p->flags.return_code & 15], 302 return_codes[p->flags.return_code & 15],
284 op_codes[p->flags.opcode & 15]); 303 op_codes[p->flags.opcode & 15]);
285 if (p->num_queries > 0) 304 if (p->num_queries > 0)
286 fprintf (stdout, 305 fprintf(stdout,
287 "\tQueries:\n"); 306 "\tQueries:\n");
288 for (i=0;i<p->num_queries;i++) 307 for (i = 0; i < p->num_queries; i++)
289 display_query (&p->queries[i]); 308 display_query(&p->queries[i]);
290 309
291 if (p->num_answers > 0) 310 if (p->num_answers > 0)
292 fprintf (stdout, 311 fprintf(stdout,
293 "\tAnswers:\n"); 312 "\tAnswers:\n");
294 for (i=0;i<p->num_answers;i++) 313 for (i = 0; i < p->num_answers; i++)
295 display_record (&p->answers[i]); 314 display_record(&p->answers[i]);
296 fprintf (stdout, "\n"); 315 fprintf(stdout, "\n");
297 GNUNET_DNSPARSER_free_packet (p); 316 GNUNET_DNSPARSER_free_packet(p);
298 GNUNET_DNS_request_forward (rh); 317 GNUNET_DNS_request_forward(rh);
299} 318}
300 319
301 320
@@ -303,13 +322,13 @@ display_request (void *cls,
303 * Shutdown. 322 * Shutdown.
304 */ 323 */
305static void 324static void
306do_disconnect (void *cls) 325do_disconnect(void *cls)
307{ 326{
308 if (NULL != handle) 327 if (NULL != handle)
309 { 328 {
310 GNUNET_DNS_disconnect (handle); 329 GNUNET_DNS_disconnect(handle);
311 handle = NULL; 330 handle = NULL;
312 } 331 }
313} 332}
314 333
315 334
@@ -322,8 +341,8 @@ do_disconnect (void *cls)
322 * @param cfg configuration 341 * @param cfg configuration
323 */ 342 */
324static void 343static void
325run (void *cls, char *const *args, const char *cfgfile, 344run(void *cls, char *const *args, const char *cfgfile,
326 const struct GNUNET_CONFIGURATION_Handle *cfg) 345 const struct GNUNET_CONFIGURATION_Handle *cfg)
327{ 346{
328 enum GNUNET_DNS_Flags flags; 347 enum GNUNET_DNS_Flags flags;
329 348
@@ -335,41 +354,40 @@ run (void *cls, char *const *args, const char *cfgfile,
335 if (outbound_only) 354 if (outbound_only)
336 flags |= GNUNET_DNS_FLAG_RESPONSE_MONITOR; 355 flags |= GNUNET_DNS_FLAG_RESPONSE_MONITOR;
337 handle = 356 handle =
338 GNUNET_DNS_connect (cfg, 357 GNUNET_DNS_connect(cfg,
339 flags, 358 flags,
340 &display_request, 359 &display_request,
341 NULL); 360 NULL);
342 GNUNET_SCHEDULER_add_shutdown (&do_disconnect, NULL); 361 GNUNET_SCHEDULER_add_shutdown(&do_disconnect, NULL);
343} 362}
344 363
345 364
346int 365int
347main (int argc, char *const *argv) 366main(int argc, char *const *argv)
348{ 367{
349 struct GNUNET_GETOPT_CommandLineOption options[] = { 368 struct GNUNET_GETOPT_CommandLineOption options[] = {
369 GNUNET_GETOPT_option_flag('i',
370 "inbound-only",
371 gettext_noop("only monitor DNS queries"),
372 &inbound_only),
350 373
351 GNUNET_GETOPT_option_flag ('i', 374 GNUNET_GETOPT_option_flag('o',
352 "inbound-only", 375 "outbound-only",
353 gettext_noop ("only monitor DNS queries"), 376 gettext_noop("only monitor DNS queries"),
354 &inbound_only), 377 &outbound_only),
355
356 GNUNET_GETOPT_option_flag ('o',
357 "outbound-only",
358 gettext_noop ("only monitor DNS queries"),
359 &outbound_only),
360 378
361 GNUNET_GETOPT_option_verbose (&verbosity), 379 GNUNET_GETOPT_option_verbose(&verbosity),
362 GNUNET_GETOPT_OPTION_END 380 GNUNET_GETOPT_OPTION_END
363 }; 381 };
364 382
365 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) 383 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args(argc, argv, &argc, &argv))
366 return 2; 384 return 2;
367 ret = (GNUNET_OK == 385 ret = (GNUNET_OK ==
368 GNUNET_PROGRAM_run (argc, argv, "gnunet-dns-monitor", 386 GNUNET_PROGRAM_run(argc, argv, "gnunet-dns-monitor",
369 gettext_noop 387 gettext_noop
370 ("Monitor DNS queries."), options, 388 ("Monitor DNS queries."), options,
371 &run, NULL)) ? ret : 1; 389 &run, NULL)) ? ret : 1;
372 GNUNET_free ((void*) argv); 390 GNUNET_free((void*)argv);
373 return ret; 391 return ret;
374} 392}
375 393