GNUnet 0.21.0
gnunet-dns-monitor.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2011 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
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/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_dns_service.h"
30
35
39static int inbound_only;
40
44static int outbound_only;
45
49static int ret;
50
54static unsigned int verbosity;
55
56
63static const char *
64get_type (uint16_t type)
65{
66 static char buf[6];
67
68 switch (type)
69 {
70 case GNUNET_DNSPARSER_TYPE_A: return "A";
71
72 case GNUNET_DNSPARSER_TYPE_NS: return "NS";
73
74 case GNUNET_DNSPARSER_TYPE_CNAME: return "CNAME";
75
76 case GNUNET_DNSPARSER_TYPE_SOA: return "SOA";
77
78 case GNUNET_DNSPARSER_TYPE_PTR: return "PTR";
79
80 case GNUNET_DNSPARSER_TYPE_MX: return "MX";
81
82 case GNUNET_DNSPARSER_TYPE_TXT: return "TXT";
83
84 case GNUNET_DNSPARSER_TYPE_AAAA: return "AAAA";
85
86 case GNUNET_DNSPARSER_TYPE_SRV: return "SRV";
87
88 case GNUNET_DNSPARSER_TYPE_URI: return "URI";
89 }
90 GNUNET_snprintf (buf, sizeof(buf), "%u", (unsigned int) type);
91 return buf;
92}
93
94
101static const char *
102get_class (uint16_t class)
103{
104 static char buf[6];
105
106 switch (class)
107 {
108 case GNUNET_TUN_DNS_CLASS_INTERNET: return "IN";
109
110 case GNUNET_TUN_DNS_CLASS_CHAOS: return "CHAOS";
111
112 case GNUNET_TUN_DNS_CLASS_HESIOD: return "HESIOD";
113 }
114 GNUNET_snprintf (buf, sizeof(buf), "%u", (unsigned int) class);
115 return buf;
116}
117
118
124static void
126{
127 fprintf (stdout,
128 "\t\t%s %s: %s\n",
130 get_type (query->type),
131 query->name);
132}
133
134
140static void
142{
143 const char *format;
144 char buf[INET6_ADDRSTRLEN];
145 char *tmp;
146
147 tmp = NULL;
148 switch (record->type)
149 {
151 if (record->data.raw.data_len != sizeof(struct in_addr))
152 format = "<invalid>";
153 else
154 format = inet_ntop (AF_INET, record->data.raw.data, buf, sizeof(buf));
155 break;
156
158 if (record->data.raw.data_len != sizeof(struct in6_addr))
159 format = "<invalid>";
160 else
161 format = inet_ntop (AF_INET6, record->data.raw.data, buf, sizeof(buf));
162 break;
163
167 format = record->data.hostname;
168 break;
169
171 if (NULL == record->data.soa)
172 format = "<invalid>";
173 else
174 {
175 GNUNET_asprintf (&tmp,
176 "origin: %s, mail: %s, serial = %u, refresh = %u s, retry = %u s, expire = %u s, minimum = %u s",
177 record->data.soa->mname,
178 record->data.soa->rname,
179 (unsigned int) record->data.soa->serial,
180 (unsigned int) record->data.soa->refresh,
181 (unsigned int) record->data.soa->retry,
182 (unsigned int) record->data.soa->expire,
183 (unsigned int) record->data.soa->minimum_ttl);
184 format = tmp;
185 }
186 break;
187
189 if (record->data.mx == NULL)
190 format = "<invalid>";
191 else
192 {
193 GNUNET_asprintf (&tmp,
194 "%u: %s",
195 record->data.mx->preference,
196 record->data.mx->mxhost);
197 format = tmp;
198 }
199 break;
200
202 if (NULL == record->data.srv)
203 format = "<invalid>";
204 else
205 {
206 GNUNET_asprintf (&tmp,
207 "priority %u, weight = %u, port = %u, target = %s",
208 (unsigned int) record->data.srv->priority,
209 (unsigned int) record->data.srv->weight,
210 (unsigned int) record->data.srv->port,
211 record->data.srv->target);
212 format = tmp;
213 }
214 break;
215
217 if (NULL == record->data.uri)
218 format = "<invalid>";
219 else
220 {
221 GNUNET_asprintf (&tmp,
222 "priority %u, weight = %u, target = \"%s\"",
223 (unsigned int) record->data.uri->priority,
224 (unsigned int) record->data.uri->weight,
225 record->data.uri->target);
226 format = tmp;
227 }
228 break;
229
230
232 GNUNET_asprintf (&tmp,
233 "%.*s",
234 (unsigned int) record->data.raw.data_len,
235 (char*) record->data.raw.data);
236 format = tmp;
237 break;
238
239 default:
240 format = "<payload>";
241 break;
242 }
243 fprintf (stdout,
244 "\t\t%s %s: %s = %s (%u s)\n",
245 get_class (record->dns_traffic_class),
246 get_type (record->type),
247 record->name,
248 format,
249 (unsigned int) (GNUNET_TIME_absolute_get_remaining (
250 record->expiration_time).rel_value_us / 1000LL
251 / 1000LL));
252 GNUNET_free (tmp);
253}
254
255
279static void
282 size_t request_length,
283 const char *request)
284{
285 static const char *return_codes[] = {
286 "No error", "Format error", "Server failure", "Name error",
287 "Not implemented", "Refused", "YXDomain", "YXRRset",
288 "NXRRset", "NOT AUTH", "NOT ZONE", "<invalid>",
289 "<invalid>", "<invalid>", "<invalid>", "<invalid>"
290 };
291 static const char *op_codes[] = {
292 "Query", "Inverse query", "Status", "<invalid>",
293 "<invalid>", "<invalid>", "<invalid>", "<invalid>",
294 "<invalid>", "<invalid>", "<invalid>", "<invalid>",
295 "<invalid>", "<invalid>", "<invalid>", "<invalid>"
296 };
298 unsigned int i;
299
300 p = GNUNET_DNSPARSER_parse (request, request_length);
301 if (NULL == p)
302 {
303 fprintf (stderr, "Received malformed DNS packet!\n");
304 // FIXME: drop instead?
306 return;
307 }
308 fprintf (stdout,
309 "%s with ID: %5u Flags: %s%s%s%s%s%s, Return Code: %s, Opcode: %s\n",
310 p->flags.query_or_response ? "Response" : "Query",
311 p->id,
312 p->flags.recursion_desired ? "RD " : "",
313 p->flags.message_truncated ? "MT " : "",
314 p->flags.authoritative_answer ? "AA " : "",
315 p->flags.checking_disabled ? "CD " : "",
316 p->flags.authenticated_data ? "AD " : "",
317 p->flags.recursion_available ? "RA " : "",
318 return_codes[p->flags.return_code & 15],
319 op_codes[p->flags.opcode & 15]);
320 if (p->num_queries > 0)
321 fprintf (stdout,
322 "\tQueries:\n");
323 for (i = 0; i < p->num_queries; i++)
324 display_query (&p->queries[i]);
325
326 if (p->num_answers > 0)
327 fprintf (stdout,
328 "\tAnswers:\n");
329 for (i = 0; i < p->num_answers; i++)
330 display_record (&p->answers[i]);
331 fprintf (stdout, "\n");
334}
335
336
340static void
341do_disconnect (void *cls)
342{
343 if (NULL != handle)
344 {
346 handle = NULL;
347 }
348}
349
350
359static void
360run (void *cls, char *const *args, const char *cfgfile,
361 const struct GNUNET_CONFIGURATION_Handle *cfg)
362{
364
367 flags = 0;
368 if (inbound_only)
370 if (outbound_only)
372 handle =
374 flags,
376 NULL);
378}
379
380
381int
382main (int argc, char *const *argv)
383{
386 "inbound-only",
387 gettext_noop ("only monitor DNS queries"),
388 &inbound_only),
389
391 "outbound-only",
392 gettext_noop ("only monitor DNS queries"),
394
397 };
398
399 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
400 return 2;
401 ret = (GNUNET_OK ==
402 GNUNET_PROGRAM_run (argc, argv, "gnunet-dns-monitor",
404 ("Monitor DNS queries."), options,
405 &run, NULL)) ? ret : 1;
406 GNUNET_free_nz ((void *) argv);
407 return ret;
408}
409
410
411/* end of gnunet-dns-monitor.c */
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
#define gettext_noop(String)
Definition: gettext.h:70
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:109
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
static void do_disconnect(void *cls)
Shutdown.
static unsigned int verbosity
Selected level of verbosity.
static void display_record(const struct GNUNET_DNSPARSER_Record *record)
Output the given DNS record to stdout.
static void display_query(const struct GNUNET_DNSPARSER_Query *query)
Output the given DNS query to stdout.
static int ret
Global return value (0 success).
static int inbound_only
Option -i.
static const char * get_class(uint16_t class)
Convert numeric DNS record class to a string.
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
Main function that will be run by the scheduler.
static int outbound_only
Option -o.
int main(int argc, char *const *argv)
static const char * get_type(uint16_t type)
Convert numeric DNS record type to a string.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static void display_request(void *cls, struct GNUNET_DNS_RequestHandle *rh, size_t request_length, const char *request)
Signature of a function that is called whenever the DNS service encounters a DNS request and needs to...
static uint32_t type
Type string converted to DNS type value.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-uri.c:38
static struct GNUNET_VPN_RedirectionRequest * request
Opaque redirection request handle.
Definition: gnunet-vpn.c:40
API to access the DNS service.
#define GNUNET_DNSPARSER_TYPE_URI
void GNUNET_DNSPARSER_free_packet(struct GNUNET_DNSPARSER_Packet *p)
Free memory taken by a packet.
Definition: dnsparser.c:947
#define GNUNET_DNSPARSER_TYPE_SRV
#define GNUNET_DNSPARSER_TYPE_SOA
#define GNUNET_DNSPARSER_TYPE_A
#define GNUNET_DNSPARSER_TYPE_PTR
#define GNUNET_DNSPARSER_TYPE_NS
#define GNUNET_DNSPARSER_TYPE_CNAME
#define GNUNET_DNSPARSER_TYPE_AAAA
#define GNUNET_DNSPARSER_TYPE_MX
#define GNUNET_DNSPARSER_TYPE_TXT
struct GNUNET_DNSPARSER_Packet * GNUNET_DNSPARSER_parse(const char *udp_payload, size_t udp_payload_length)
Parse a UDP payload of a DNS packet in to a nice struct for further processing and manipulation.
Definition: dnsparser.c:727
void GNUNET_DNS_disconnect(struct GNUNET_DNS_Handle *dh)
Disconnect from the DNS service.
Definition: dns_api.c:363
void GNUNET_DNS_request_forward(struct GNUNET_DNS_RequestHandle *rh)
If a GNUNET_DNS_RequestHandler calls this function, the client has no desire to interfer with the req...
Definition: dns_api.c:237
struct GNUNET_DNS_Handle * GNUNET_DNS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, enum GNUNET_DNS_Flags flags, GNUNET_DNS_RequestHandler rh, void *rh_cls)
Connect to the service-dns.
Definition: dns_api.c:340
GNUNET_DNS_Flags
Flags that specify when to call the client's handler.
@ GNUNET_DNS_FLAG_RESPONSE_MONITOR
Set this flag to see all requests just before they are returned to the network.
@ GNUNET_DNS_FLAG_REQUEST_MONITOR
Set this flag to see all requests first prior to resolution (for monitoring).
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_verbose(unsigned int *level)
Define the '-V' verbosity option.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_flag(char shortName, const char *name, const char *description, int *val)
Allow user to specify a flag (which internally means setting an integer to 1/GNUNET_YES/GNUNET_OK.
@ GNUNET_OK
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_free_nz(ptr)
Wrapper around free.
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration,...
Definition: program.c:400
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1334
enum GNUNET_GenericReturnValue GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1230
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:405
#define GNUNET_TUN_DNS_CLASS_HESIOD
#define GNUNET_TUN_DNS_CLASS_CHAOS
#define GNUNET_TUN_DNS_CLASS_INTERNET
A few common DNS classes (ok, only one is common, but I list a couple more to make it clear what we'r...
Easy-to-process, parsed version of a DNS packet.
struct GNUNET_TUN_DnsFlags flags
Bitfield of DNS flags.
uint16_t dns_traffic_class
See GNUNET_TUN_DNS_CLASS_*.
uint16_t type
See GNUNET_DNSPARSER_TYPE_*.
char * name
Name of the record that the query is for (0-terminated).
A DNS response record.
DNS handle.
Definition: dns_api.c:57
GNUNET_DNS_RequestHandler rh
Function to call to get replies.
Definition: dns_api.c:71
Handle to identify an individual DNS request.
Definition: dns_api.c:35
Definition of a command line option.
uint64_t rel_value_us
The actual value.