GNUnet  0.20.0
gnunet-dns-redirector.c File Reference

Tool to change DNS replies (for testing) More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_dns_service.h"
Include dependency graph for gnunet-dns-redirector.c:

Go to the source code of this file.

Functions

static void modify_record (const struct GNUNET_DNSPARSER_Record *record)
 Modify the given DNS record. More...
 
static void modify_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 do something with it. More...
 
static void do_disconnect (void *cls)
 Shutdown. More...
 
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. More...
 
int main (int argc, char *const *argv)
 

Variables

static struct GNUNET_DNS_Handlehandle
 Handle to DNS service. More...
 
static char * n4
 New target for A records. More...
 
static char * n6
 New target for AAAA records. More...
 
static int ret
 Global return value (0 success). More...
 
static unsigned int verbosity
 Selected level of verbosity. More...
 

Detailed Description

Tool to change DNS replies (for testing)

Author
Christian Grothoff

Definition in file gnunet-dns-redirector.c.

Function Documentation

◆ modify_record()

static void modify_record ( const struct GNUNET_DNSPARSER_Record record)
static

Modify the given DNS record.

Parameters
recordrecord to modify

Definition at line 63 of file gnunet-dns-redirector.c.

64 {
65  char buf[INET6_ADDRSTRLEN];
66 
67  switch (record->type)
68  {
70  if (record->data.raw.data_len != sizeof(struct in_addr))
71  return;
72  if (NULL != n4)
73  {
74  if (verbosity > 1)
75  fprintf (stderr,
76  "Changing A record from `%s' to `%s'\n",
77  inet_ntop (AF_INET, record->data.raw.data, buf, sizeof(buf)),
78  n4);
79  GNUNET_assert (1 == inet_pton (AF_INET, n4, record->data.raw.data));
80  }
81  break;
82 
84  if (record->data.raw.data_len != sizeof(struct in6_addr))
85  return;
86  if (NULL != n6)
87  {
88  if (verbosity > 1)
89  fprintf (stderr,
90  "Changing AAAA record from `%s' to `%s'\n",
91  inet_ntop (AF_INET6, record->data.raw.data, buf, sizeof(buf)),
92  n6);
93  GNUNET_assert (1 == inet_pton (AF_INET6, n6, record->data.raw.data));
94  }
95  break;
96 
103  break;
104 
105  default:
106  break;
107  }
108 }
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
static unsigned int verbosity
Selected level of verbosity.
static char * n4
New target for A records.
static char * n6
New target for AAAA records.
static char buf[2048]
#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
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.

References buf, GNUNET_assert, GNUNET_DNSPARSER_TYPE_A, GNUNET_DNSPARSER_TYPE_AAAA, GNUNET_DNSPARSER_TYPE_CNAME, GNUNET_DNSPARSER_TYPE_MX, GNUNET_DNSPARSER_TYPE_NS, GNUNET_DNSPARSER_TYPE_PTR, GNUNET_DNSPARSER_TYPE_SOA, GNUNET_DNSPARSER_TYPE_TXT, n4, n6, record(), and verbosity.

Referenced by modify_request().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ modify_request()

static void modify_request ( void *  cls,
struct GNUNET_DNS_RequestHandle rh,
size_t  request_length,
const char *  request 
)
static

Signature of a function that is called whenever the DNS service encounters a DNS request and needs to do something with it.

The function has then the chance to generate or modify the response by calling one of the three "GNUNET_DNS_request_*" continuations.

When a request is intercepted, this function is called first to give the client a chance to do the complete address resolution; "rdata" will be NULL for this first call for a DNS request, unless some other client has already filled in a response.

If multiple clients exist, all of them are called before the global DNS. The global DNS is only called if all of the clients' functions call GNUNET_DNS_request_forward. Functions that call GNUNET_DNS_request_forward will be called again before a final response is returned to the application. If any of the clients' functions call GNUNET_DNS_request_drop, the response is dropped.

Parameters
clsclosure
rhrequest handle to user for reply
request_lengthnumber of bytes in request
requestudp payload of the DNS request

Definition at line 135 of file gnunet-dns-redirector.c.

139 {
140  struct GNUNET_DNSPARSER_Packet *p;
141  unsigned int i;
142  char *buf;
143  size_t len;
144  int ret;
145 
146  p = GNUNET_DNSPARSER_parse (request, request_length);
147  if (NULL == p)
148  {
149  fprintf (stderr, "Received malformed DNS packet, leaving it untouched\n");
151  return;
152  }
153  for (i = 0; i < p->num_answers; i++)
154  modify_record (&p->answers[i]);
155  buf = NULL;
156  ret = GNUNET_DNSPARSER_pack (p, 1024, &buf, &len);
158  if (GNUNET_OK != ret)
159  {
160  if (GNUNET_NO == ret)
161  fprintf (stderr,
162  "Modified DNS response did not fit, keeping old response\n");
163  else
164  GNUNET_break (0); /* our modifications should have been sane! */
166  }
167  else
168  {
169  if (verbosity > 0)
170  fprintf (stdout,
171  "Injecting modified DNS response\n");
173  }
174  GNUNET_free (buf);
175 }
static void modify_record(const struct GNUNET_DNSPARSER_Record *record)
Modify the given DNS record.
static int ret
Global return value (0 success).
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
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
void GNUNET_DNSPARSER_free_packet(struct GNUNET_DNSPARSER_Packet *p)
Free memory taken by a packet.
Definition: dnsparser.c:854
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:656
int GNUNET_DNSPARSER_pack(const struct GNUNET_DNSPARSER_Packet *p, uint16_t max, char **buf, size_t *buf_length)
Given a DNS packet p, generate the corresponding UDP payload.
Definition: dnsparser.c:1259
void GNUNET_DNS_request_forward(struct GNUNET_DNS_RequestHandle *rh)
If a GNUNET_DNS_RequestHandler calls this function, the request is given to other clients or the glob...
Definition: dns_api.c:237
void GNUNET_DNS_request_answer(struct GNUNET_DNS_RequestHandle *rh, uint16_t reply_length, const char *reply)
If a GNUNET_DNS_RequestHandler calls this function, the request is supposed to be answered with the d...
Definition: dns_api.c:296
@ GNUNET_OK
@ GNUNET_NO
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
#define GNUNET_free(ptr)
Wrapper around free.
Easy-to-process, parsed version of a DNS packet.

References buf, GNUNET_break, GNUNET_DNS_request_answer(), GNUNET_DNS_request_forward(), GNUNET_DNSPARSER_free_packet(), GNUNET_DNSPARSER_pack(), GNUNET_DNSPARSER_parse(), GNUNET_free, GNUNET_NO, GNUNET_OK, len, modify_record(), p, request, ret, and verbosity.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_disconnect()

static void do_disconnect ( void *  cls)
static

Shutdown.

Definition at line 182 of file gnunet-dns-redirector.c.

183 {
184  if (NULL != handle)
185  {
187  handle = NULL;
188  }
189 }
static struct GNUNET_DNS_Handle * handle
Handle to DNS service.
void GNUNET_DNS_disconnect(struct GNUNET_DNS_Handle *dh)
Disconnect from the DNS service.
Definition: dns_api.c:363

References GNUNET_DNS_disconnect(), and handle.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ run()

static void run ( void *  cls,
char *const *  args,
const char *  cfgfile,
const struct GNUNET_CONFIGURATION_Handle cfg 
)
static

Main function that will be run by the scheduler.

Parameters
clsclosure
argsremaining command-line arguments
cfgfilename of the configuration file used (for saving, can be NULL!)
cfgconfiguration

Definition at line 201 of file gnunet-dns-redirector.c.

203 {
204  struct in_addr i4;
205  struct in6_addr i6;
206 
207  if ((n4 != NULL) &&
208  (1 != inet_pton (AF_INET, n4, &i4)))
209  {
210  fprintf (stderr,
211  "`%s' is nto a valid IPv4 address!\n",
212  n4);
213  return;
214  }
215  if ((n6 != NULL) &&
216  (1 != inet_pton (AF_INET6, n6, &i6)))
217  {
218  fprintf (stderr,
219  "`%s' is nto a valid IPv6 address!\n",
220  n6);
221  return;
222  }
223 
224  handle =
228  NULL);
230 }
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static void do_disconnect(void *cls)
Shutdown.
static void modify_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...
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_FLAG_POST_RESOLUTION
This client wants to be called on the results of a DNS resolution (either resolved by PRE-RESOLUTION ...
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

References cfg, do_disconnect(), GNUNET_DNS_connect(), GNUNET_DNS_FLAG_POST_RESOLUTION, GNUNET_SCHEDULER_add_shutdown(), handle, modify_request(), n4, and n6.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ main()

int main ( int  argc,
char *const *  argv 
)

Definition at line 234 of file gnunet-dns-redirector.c.

235 {
238  "ipv4",
239  "IPV4",
240  gettext_noop ("set A records"),
241  &n4),
242 
244  "ipv4",
245  "IPV6",
246  gettext_noop ("set AAAA records"),
247  &n6),
248 
251  };
252 
253  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
254  return 2;
255 
256  ret = (GNUNET_OK ==
257  GNUNET_PROGRAM_run (argc, argv, "gnunet-dns-redirector",
259  ("Change DNS replies to point elsewhere."),
260  options,
261  &run, NULL)) ? ret : 1;
262  GNUNET_free_nz ((void *) argv);
263  return ret;
264 }
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 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.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_verbose(unsigned int *level)
Define the '-V' verbosity option.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_string(char shortName, const char *name, const char *argumentHelp, const char *description, char **str)
Allow user to specify a string.
#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
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:1222
Definition of a command line option.

References gettext_noop, GNUNET_free_nz, GNUNET_GETOPT_OPTION_END, GNUNET_GETOPT_option_string(), GNUNET_GETOPT_option_verbose(), GNUNET_OK, GNUNET_PROGRAM_run(), GNUNET_STRINGS_get_utf8_args(), n4, n6, options, ret, run(), and verbosity.

Here is the call graph for this function:

Variable Documentation

◆ handle

struct GNUNET_DNS_Handle* handle
static

Handle to DNS service.

Definition at line 34 of file gnunet-dns-redirector.c.

Referenced by do_disconnect(), and run().

◆ n4

char* n4
static

New target for A records.

Definition at line 39 of file gnunet-dns-redirector.c.

Referenced by main(), modify_record(), and run().

◆ n6

char* n6
static

New target for AAAA records.

Definition at line 44 of file gnunet-dns-redirector.c.

Referenced by main(), modify_record(), and run().

◆ ret

int ret
static

Global return value (0 success).

Definition at line 49 of file gnunet-dns-redirector.c.

Referenced by main(), and modify_request().

◆ verbosity

unsigned int verbosity
static

Selected level of verbosity.

Definition at line 54 of file gnunet-dns-redirector.c.

Referenced by main(), modify_record(), and modify_request().