GNUnet  0.11.x
Functions | Variables
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 "gnunet_dnsparser_lib.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 64 of file gnunet-dns-redirector.c.

References buf, GNUNET_DNSPARSER_RawRecord::data, GNUNET_DNSPARSER_Record::data, GNUNET_DNSPARSER_RawRecord::data_len, 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, GNUNET_DNSPARSER_Record::raw, GNUNET_DNSPARSER_Record::type, and verbosity.

Referenced by modify_request().

65 {
66  char buf[INET6_ADDRSTRLEN];
67 
68  switch (record->type)
69  {
71  if (record->data.raw.data_len != sizeof(struct in_addr))
72  return;
73  if (NULL != n4)
74  {
75  if (verbosity > 1)
76  fprintf (stderr,
77  "Changing A record from `%s' to `%s'\n",
78  inet_ntop (AF_INET, record->data.raw.data, buf, sizeof(buf)),
79  n4);
80  GNUNET_assert (1 == inet_pton (AF_INET, n4, record->data.raw.data));
81  }
82  break;
83 
85  if (record->data.raw.data_len != sizeof(struct in6_addr))
86  return;
87  if (NULL != n6)
88  {
89  if (verbosity > 1)
90  fprintf (stderr,
91  "Changing AAAA record from `%s' to `%s'\n",
92  inet_ntop (AF_INET6, record->data.raw.data, buf, sizeof(buf)),
93  n6);
94  GNUNET_assert (1 == inet_pton (AF_INET6, n6, record->data.raw.data));
95  }
96  break;
97 
104  break;
105 
106  default:
107  break;
108  }
109 }
uint16_t type
See GNUNET_DNSPARSER_TYPE_*.
#define GNUNET_DNSPARSER_TYPE_CNAME
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static char * n6
New target for AAAA records.
#define GNUNET_DNSPARSER_TYPE_MX
#define GNUNET_DNSPARSER_TYPE_PTR
static char * n4
New target for A records.
#define GNUNET_DNSPARSER_TYPE_SOA
static char buf[2048]
union GNUNET_DNSPARSER_Record::@24 data
Payload of the record (which one of these is valid depends on the 'type').
size_t data_len
Number of bytes in data.
void * data
Binary record data.
#define GNUNET_DNSPARSER_TYPE_TXT
#define GNUNET_DNSPARSER_TYPE_AAAA
#define GNUNET_DNSPARSER_TYPE_NS
static unsigned int verbosity
Selected level of verbosity.
struct GNUNET_DNSPARSER_RawRecord raw
Raw data for all other types.
#define GNUNET_DNSPARSER_TYPE_A
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 136 of file gnunet-dns-redirector.c.

References GNUNET_DNSPARSER_Packet::answers, buf, GNUNET_break, GNUNET_DNS_request_answer(), GNUNET_DNS_request_forward(), GNUNET_DNSPARSER_free_packet(), GNUNET_DNSPARSER_pack(), GNUNET_DNSPARSER_parse(), GNUNET_free_non_null, GNUNET_NO, GNUNET_OK, len, modify_record(), GNUNET_DNSPARSER_Packet::num_answers, p, ret, and verbosity.

Referenced by run().

140 {
141  struct GNUNET_DNSPARSER_Packet *p;
142  unsigned int i;
143  char *buf;
144  size_t len;
145  int ret;
146 
147  p = GNUNET_DNSPARSER_parse (request, request_length);
148  if (NULL == p)
149  {
150  fprintf (stderr, "Received malformed DNS packet, leaving it untouched\n");
152  return;
153  }
154  for (i = 0; i < p->num_answers; i++)
155  modify_record (&p->answers[i]);
156  buf = NULL;
157  ret = GNUNET_DNSPARSER_pack (p, 1024, &buf, &len);
159  if (GNUNET_OK != ret)
160  {
161  if (GNUNET_NO == ret)
162  fprintf (stderr,
163  "Modified DNS response did not fit, keeping old response\n");
164  else
165  GNUNET_break (0); /* our modifications should have been sane! */
167  }
168  else
169  {
170  if (verbosity > 0)
171  fprintf (stdout,
172  "Injecting modified DNS response\n");
173  GNUNET_DNS_request_answer (rh, len, buf);
174  }
175  GNUNET_free_non_null (buf);
176 }
struct GNUNET_DNSPARSER_Record * answers
Array of all answers in the packet, must contain "num_answers" entries.
static struct GNUNET_VPN_RedirectionRequest * request
Opaque redirection request handle.
Definition: gnunet-vpn.c:41
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:1257
void GNUNET_DNSPARSER_free_packet(struct GNUNET_DNSPARSER_Packet *p)
Free memory taken by a packet.
Definition: dnsparser.c:854
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
unsigned int num_answers
Number of answers in the packet, should be 0 for queries.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
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
static int ret
Global return value (0 success).
static char buf[2048]
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:302
static void modify_record(const struct GNUNET_DNSPARSER_Record *record)
Modify the given DNS record.
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:243
Easy-to-process, parsed version of a DNS packet.
static unsigned int verbosity
Selected level of verbosity.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
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 183 of file gnunet-dns-redirector.c.

References GNUNET_DNS_disconnect().

Referenced by run().

184 {
185  if (NULL != handle)
186  {
188  handle = NULL;
189  }
190 }
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:369
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 202 of file gnunet-dns-redirector.c.

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

Referenced by main().

204 {
205  struct in_addr i4;
206  struct in6_addr i6;
207 
208  if ((n4 != NULL) &&
209  (1 != inet_pton (AF_INET, n4, &i4)))
210  {
211  fprintf (stderr,
212  "`%s' is nto a valid IPv4 address!\n",
213  n4);
214  return;
215  }
216  if ((n6 != NULL) &&
217  (1 != inet_pton (AF_INET6, n6, &i6)))
218  {
219  fprintf (stderr,
220  "`%s' is nto a valid IPv6 address!\n",
221  n6);
222  return;
223  }
224 
225  handle =
226  GNUNET_DNS_connect (cfg,
229  NULL);
231 }
static struct GNUNET_DNS_Handle * handle
Handle to DNS service.
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, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1300
This client wants to be called on the results of a DNS resolution (either resolved by PRE-RESOLUTION ...
static char * n6
New target for AAAA records.
static char * n4
New target for A records.
static void do_disconnect(void *cls)
Shutdown.
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:346
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...
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 235 of file gnunet-dns-redirector.c.

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

236 {
239  "ipv4",
240  "IPV4",
241  gettext_noop ("set A records"),
242  &n4),
243 
245  "ipv4",
246  "IPV6",
247  gettext_noop ("set AAAA records"),
248  &n6),
249 
252  };
253 
254  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
255  return 2;
256 
257  ret = (GNUNET_OK ==
258  GNUNET_PROGRAM_run (argc, argv, "gnunet-dns-redirector",
260  ("Change DNS replies to point elsewhere."),
261  options,
262  &run, NULL)) ? ret : 1;
263  GNUNET_free ((void*) argv);
264  return ret;
265 }
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_verbose(unsigned int *level)
Define the &#39;-V&#39; verbosity option.
int GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1438
static char * n6
New target for AAAA records.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
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.
Definition of a command line option.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
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.
static char * n4
New target for A records.
static int ret
Global return value (0 success).
int 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, parse options).
Definition: program.c:367
static unsigned int verbosity
Selected level of verbosity.
#define GNUNET_free(ptr)
Wrapper around free.
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:

Variable Documentation

◆ handle

struct GNUNET_DNS_Handle* handle
static

Handle to DNS service.

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

◆ n4

char* n4
static

New target for A records.

Definition at line 40 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 45 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 50 of file gnunet-dns-redirector.c.

Referenced by main(), and modify_request().

◆ verbosity

unsigned int verbosity
static

Selected level of verbosity.

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

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