GNUnet  0.20.0
regex.c File Reference
#include "platform.h"
#include "gnunet_util_lib.h"
Include dependency graph for regex.c:

Go to the source code of this file.

Macros

#define DOT   "(0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F)"
 'wildcard', matches all possible values (for HEX encoding). More...
 

Functions

void GNUNET_TUN_ipv4toregexsearch (const struct in_addr *ip, uint16_t port, char *rxstr)
 Create a regex in rxstr from the given ip and port. More...
 
void GNUNET_TUN_ipv6toregexsearch (const struct in6_addr *ipv6, uint16_t port, char *rxstr)
 Create a regex in rxstr from the given ipv6 and port. More...
 
static char * nibble_to_regex (uint8_t value, uint8_t mask)
 Convert the given 4-bit (!) number to a regex. More...
 
static char * num_to_regex (uint16_t value, uint16_t mask)
 Convert the given 16-bit number to a regex. More...
 
static int needs_parens (const char *arg)
 Do we need to put parents around the given argument? More...
 
static char * compute_policy (unsigned int start, unsigned int end, unsigned int step, const struct GNUNET_STRINGS_PortPolicy *pp)
 Compute port policy for the given range of port numbers. More...
 
static char * port_to_regex (const struct GNUNET_STRINGS_PortPolicy *pp)
 Convert a port policy to a regular expression. More...
 
static char * address_to_regex (const void *addr, const void *mask, size_t len)
 Convert an address (IPv4 or IPv6) to a regex. More...
 
static char * ipv4_to_regex (const struct GNUNET_STRINGS_IPv4NetworkPolicy *v4)
 Convert a single line of an IPv4 policy to a regular expression. More...
 
static char * ipv6_to_regex (const struct GNUNET_STRINGS_IPv6NetworkPolicy *v6)
 Convert a single line of an IPv4 policy to a regular expression. More...
 
char * GNUNET_TUN_ipv4policy2regex (const char *policy)
 Convert an exit policy to a regular expression. More...
 
char * GNUNET_TUN_ipv6policy2regex (const char *policy)
 Convert an exit policy to a regular expression. More...
 
void GNUNET_TUN_service_name_to_hash (const char *service_name, struct GNUNET_HashCode *hc)
 Hash the service name of a hosted service to the hash code that is used to identify the service on the network. More...
 
void GNUNET_TUN_compute_service_cadet_port (const struct GNUNET_HashCode *desc, uint16_t ip_port, struct GNUNET_HashCode *cadet_port)
 Compute the CADET port given a service descriptor (returned from GNUNET_TUN_service_name_to_hash) and a TCP/UDP port ip_port. More...
 

Macro Definition Documentation

◆ DOT

#define DOT   "(0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F)"

'wildcard', matches all possible values (for HEX encoding).

Definition at line 33 of file regex.c.

Function Documentation

◆ nibble_to_regex()

static char* nibble_to_regex ( uint8_t  value,
uint8_t  mask 
)
static

Convert the given 4-bit (!) number to a regex.

Parameters
valuethe value, only the lowest 4 bits will be looked at
maskwhich bits in value are wildcards (any value)?

Definition at line 75 of file regex.c.

77 {
78  char *ret;
79 
80  value &= mask;
81  switch (mask)
82  {
83  case 0:
84  return GNUNET_strdup (DOT);
85 
86  case 8:
88  "(%X|%X|%X|%X|%X|%X|%X|%X)",
89  value,
90  value + 1,
91  value + 2,
92  value + 3,
93  value + 4,
94  value + 5,
95  value + 6,
96  value + 7);
97  return ret;
98 
99  case 12:
101  "(%X|%X|%X|%X)",
102  value,
103  value + 1,
104  value + 2,
105  value + 3);
106  return ret;
107 
108  case 14:
110  "(%X|%X)",
111  value,
112  value + 1);
113  return ret;
114 
115  case 15:
117  "%X",
118  value);
119  return ret;
120 
121  default:
123  _ ("Bad mask: %d\n"),
124  mask);
125  GNUNET_break (0);
126  return NULL;
127  }
128 }
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static char * value
Value of the record to add/remove.
#define GNUNET_log(kind,...)
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_WARNING
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
#define DOT
'wildcard', matches all possible values (for HEX encoding).
Definition: regex.c:33

References _, DOT, GNUNET_asprintf(), GNUNET_break, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_strdup, ret, and value.

Referenced by num_to_regex().

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

◆ num_to_regex()

static char* num_to_regex ( uint16_t  value,
uint16_t  mask 
)
static

Convert the given 16-bit number to a regex.

Parameters
valuethe value
maskwhich bits in value are wildcards (any value)?

Definition at line 138 of file regex.c.

140 {
141  const uint8_t *v = (const uint8_t *) &value;
142  const uint8_t *m = (const uint8_t *) &mask;
143  char *a;
144  char *b;
145  char *c;
146  char *d;
147  char *ret;
148 
149  a = nibble_to_regex (v[0] >> 4, m[0] >> 4);
150  b = nibble_to_regex (v[0] & 15, m[0] & 15);
151  c = nibble_to_regex (v[1] >> 4, m[1] >> 4);
152  d = nibble_to_regex (v[1] & 15, m[1] & 15);
153  ret = NULL;
154  if ((NULL != a) &&
155  (NULL != b) &&
156  (NULL != c) &&
157  (NULL != d))
159  "%s%s%s%s",
160  a, b, c, d);
161  GNUNET_free (a);
162  GNUNET_free (b);
163  GNUNET_free (c);
164  GNUNET_free (d);
165  return ret;
166 }
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:104
#define GNUNET_free(ptr)
Wrapper around free.
static char * nibble_to_regex(uint8_t value, uint8_t mask)
Convert the given 4-bit (!) number to a regex.
Definition: regex.c:75

References GNUNET_asprintf(), GNUNET_free, m, nibble_to_regex(), ret, and value.

Referenced by address_to_regex().

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

◆ needs_parens()

static int needs_parens ( const char *  arg)
static

Do we need to put parents around the given argument?

Parameters
argpart of a regular expression
Returns
GNUNET_YES if we should parens, GNUNET_NO if not

Definition at line 177 of file regex.c.

178 {
179  size_t off;
180  size_t len;
181  unsigned int op;
182 
183  op = 0;
184  len = strlen (arg);
185  for (off = 0; off < len; off++)
186  {
187  switch (arg[off])
188  {
189  case '(':
190  op++;
191  break;
192 
193  case ')':
194  GNUNET_assert (op > 0);
195  op--;
196  break;
197 
198  case '|':
199  if (0 == op)
200  return GNUNET_YES;
201  break;
202 
203  default:
204  break;
205  }
206  }
207  return GNUNET_NO;
208 }
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
@ GNUNET_YES
@ GNUNET_NO
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.

References find_typedefs::arg, GNUNET_assert, GNUNET_NO, GNUNET_YES, len, and op.

Referenced by compute_policy().

Here is the caller graph for this function:

◆ compute_policy()

static char* compute_policy ( unsigned int  start,
unsigned int  end,
unsigned int  step,
const struct GNUNET_STRINGS_PortPolicy pp 
)
static

Compute port policy for the given range of port numbers.

Parameters
startstarting offset
endend offset
stepincrement level (power of 16)
ppport policy to convert
Returns
corresponding regex

Definition at line 222 of file regex.c.

226 {
227  unsigned int i;
228  char before[36]; /* 16 * 2 + 3 dots + 0-terminator */
229  char middlel[33]; /* 16 * 2 + 0-terminator */
230  char middleh[33]; /* 16 * 2 + 0-terminator */
231  char after[36]; /* 16 * 2 + 3 dots + 0-terminator */
232  char beforep[36 + 2]; /* 16 * 2 + 3 dots + 0-terminator + ()*/
233  char middlehp[33 + 2]; /* 16 * 2 + 0-terminator + () */
234  char middlelp[33 + 2]; /* 16 * 2 + 0-terminator + () */
235  char afterp[36 + 2]; /* 16 * 2 + 3 dots + 0-terminator + () */
236  char dots[5 * strlen (DOT)];
237  char buf[3];
238  char *middle;
239  char *ret;
240  unsigned int xstep;
241  char *recl;
242  char *rech;
243  char *reclp;
244  char *rechp;
245  unsigned int start_port;
246  unsigned int end_port;
247 
249  start_port = pp->start_port;
250  if (1 == start_port)
251  start_port = 0;
252  end_port = pp->end_port;
253  GNUNET_assert ((end - start) / step <= 0xF);
254  before[0] = '\0';
255  middlel[0] = '\0';
256  middleh[0] = '\0';
257  after[0] = '\0';
258  for (i = start; i <= end; i += step)
259  {
261  sizeof(buf),
262  "%X|",
263  (i - start) / step);
264  if (i / step < start_port / step)
265  strcat (before, buf);
266  else if (i / step > end_port / step)
267  strcat (after, buf);
268  else if (i / step == start_port / step)
269  strcat (middlel, buf);
270  else if (i / step == end_port / step)
271  strcat (middleh, buf);
272  }
273  if (strlen (before) > 0)
274  before[strlen (before) - 1] = '\0';
275  if (strlen (middlel) > 0)
276  middlel[strlen (middlel) - 1] = '\0';
277  if (strlen (middleh) > 0)
278  middleh[strlen (middleh) - 1] = '\0';
279  if (strlen (after) > 0)
280  after[strlen (after) - 1] = '\0';
281  if (needs_parens (before))
282  GNUNET_snprintf (beforep,
283  sizeof(beforep),
284  "(%s)",
285  before);
286  else
287  strcpy (beforep, before);
288  if (needs_parens (middlel))
289  GNUNET_snprintf (middlelp,
290  sizeof(middlelp),
291  "(%s)",
292  middlel);
293  else
294  strcpy (middlelp, middlel);
295  if (needs_parens (middleh))
296  GNUNET_snprintf (middlehp,
297  sizeof(middlehp),
298  "(%s)",
299  middleh);
300  else
301  strcpy (middlehp, middleh);
302  if (needs_parens (after))
303  GNUNET_snprintf (afterp,
304  sizeof(afterp),
305  "(%s)",
306  after);
307  else
308  strcpy (afterp, after);
309  dots[0] = '\0';
310  for (xstep = step / 16; xstep > 0; xstep /= 16)
311  strcat (dots, DOT);
312  if (step >= 16)
313  {
314  if (strlen (middlel) > 0)
315  recl = compute_policy ((start_port / step) * step,
316  (start_port / step) * step + step - 1,
317  step / 16,
318  pp);
319  else
320  recl = GNUNET_strdup ("");
321  if (strlen (middleh) > 0)
322  rech = compute_policy ((end_port / step) * step,
323  (end_port / step) * step + step - 1,
324  step / 16,
325  pp);
326  else
327  rech = GNUNET_strdup ("");
328  }
329  else
330  {
331  recl = GNUNET_strdup ("");
332  rech = GNUNET_strdup ("");
333  middlel[0] = '\0';
334  middlelp[0] = '\0';
335  middleh[0] = '\0';
336  middlehp[0] = '\0';
337  }
338  if (needs_parens (recl))
339  GNUNET_asprintf (&reclp,
340  "(%s)",
341  recl);
342  else
343  reclp = GNUNET_strdup (recl);
344  if (needs_parens (rech))
345  GNUNET_asprintf (&rechp,
346  "(%s)",
347  rech);
348  else
349  rechp = GNUNET_strdup (rech);
350 
351  if ((strlen (middleh) > 0) &&
352  (strlen (rech) > 0) &&
353  (strlen (middlel) > 0) &&
354  (strlen (recl) > 0))
355  {
356  GNUNET_asprintf (&middle,
357  "%s%s|%s%s",
358  middlel,
359  reclp,
360  middleh,
361  rechp);
362  }
363  else if ((strlen (middleh) > 0) &&
364  (strlen (rech) > 0))
365  {
366  GNUNET_asprintf (&middle,
367  "%s%s",
368  middleh,
369  rechp);
370  }
371  else if ((strlen (middlel) > 0) &&
372  (strlen (recl) > 0))
373  {
374  GNUNET_asprintf (&middle,
375  "%s%s",
376  middlel,
377  reclp);
378  }
379  else
380  {
381  middle = GNUNET_strdup ("");
382  }
383  if ((strlen (before) > 0) &&
384  (strlen (after) > 0))
385  {
386  if (strlen (dots) > 0)
387  {
388  if (strlen (middle) > 0)
390  "(%s%s|%s|%s%s)",
391  beforep, dots,
392  middle,
393  afterp, dots);
394  else
396  "(%s|%s)%s",
397  beforep,
398  afterp,
399  dots);
400  }
401  else
402  {
403  if (strlen (middle) > 0)
405  "(%s|%s|%s)",
406  before,
407  middle,
408  after);
409  else if (1 == step)
411  "%s|%s",
412  before,
413  after);
414  else
416  "(%s|%s)",
417  before,
418  after);
419  }
420  }
421  else if (strlen (before) > 0)
422  {
423  if (strlen (dots) > 0)
424  {
425  if (strlen (middle) > 0)
427  "(%s%s|%s)",
428  beforep, dots,
429  middle);
430  else
432  "%s%s",
433  beforep, dots);
434  }
435  else
436  {
437  if (strlen (middle) > 0)
439  "(%s|%s)",
440  before,
441  middle);
442  else
444  "%s",
445  before);
446  }
447  }
448  else if (strlen (after) > 0)
449  {
450  if (strlen (dots) > 0)
451  {
452  if (strlen (middle) > 0)
454  "(%s|%s%s)",
455  middle,
456  afterp, dots);
457  else
459  "%s%s",
460  afterp, dots);
461  }
462  else
463  {
464  if (strlen (middle) > 0)
466  "%s|%s",
467  middle,
468  after);
469  else
471  "%s",
472  after);
473  }
474  }
475  else if (strlen (middle) > 0)
476  {
478  "%s",
479  middle);
480  }
481  else
482  {
483  ret = GNUNET_strdup ("");
484  }
485  GNUNET_free (middle);
486  GNUNET_free (reclp);
487  GNUNET_free (rechp);
488  GNUNET_free (recl);
489  GNUNET_free (rech);
490  return ret;
491 }
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
static char buf[2048]
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.
static int needs_parens(const char *arg)
Do we need to put parents around the given argument?
Definition: regex.c:177
static char * compute_policy(unsigned int start, unsigned int end, unsigned int step, const struct GNUNET_STRINGS_PortPolicy *pp)
Compute port policy for the given range of port numbers.
Definition: regex.c:222
uint16_t start_port
Starting port range (0 if none given).
int negate_portrange
GNUNET_YES if the port range should be negated ("!" in policy).
uint16_t end_port
End of port range (0 if none given).

References buf, DOT, end, GNUNET_STRINGS_PortPolicy::end_port, GNUNET_asprintf(), GNUNET_assert, GNUNET_free, GNUNET_snprintf(), GNUNET_strdup, GNUNET_YES, needs_parens(), GNUNET_STRINGS_PortPolicy::negate_portrange, ret, start, and GNUNET_STRINGS_PortPolicy::start_port.

Referenced by port_to_regex().

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

◆ port_to_regex()

static char* port_to_regex ( const struct GNUNET_STRINGS_PortPolicy pp)
static

Convert a port policy to a regular expression.

Note: this is a very simplistic implementation, we might want to consider doing something more sophisiticated (resulting in smaller regular expressions) at a later time.

Parameters
ppport policy to convert
Returns
NULL on error

Definition at line 504 of file regex.c.

505 {
506  char *reg;
507  char *ret;
508  char *pos;
509  unsigned int i;
510  unsigned int cnt;
511 
512  if ((0 == pp->start_port) ||
513  ((1 == pp->start_port) &&
514  (0xFFFF == pp->end_port) &&
515  (GNUNET_NO == pp->negate_portrange)))
516  return GNUNET_strdup (DOT DOT DOT DOT);
517  if ((pp->start_port == pp->end_port) &&
518  (GNUNET_NO == pp->negate_portrange))
519  {
521  "%04X",
522  pp->start_port);
523  return ret;
524  }
525  if (pp->end_port < pp->start_port)
526  return NULL;
527 
528  if (GNUNET_YES == pp->negate_portrange)
529  {
530  ret = compute_policy (0, 0xFFFF, 0x1000, pp);
531  }
532  else
533  {
534  cnt = pp->end_port - pp->start_port + 1;
535  reg = GNUNET_malloc (cnt * 5 + 1);
536  pos = reg;
537  for (i = 1; i <= 0xFFFF; i++)
538  {
539  if ((i >= pp->start_port) && (i <= pp->end_port))
540  {
541  if (pos == reg)
542  {
543  GNUNET_snprintf (pos,
544  5,
545  "%04X",
546  i);
547  }
548  else
549  {
550  GNUNET_snprintf (pos,
551  6,
552  "|%04X",
553  i);
554  }
555  pos += strlen (pos);
556  }
557  }
559  "(%s)",
560  reg);
561  GNUNET_free (reg);
562  }
563  return ret;
564 }
#define GNUNET_malloc(size)
Wrapper around malloc.

References compute_policy(), DOT, GNUNET_STRINGS_PortPolicy::end_port, GNUNET_asprintf(), GNUNET_free, GNUNET_malloc, GNUNET_NO, GNUNET_snprintf(), GNUNET_strdup, GNUNET_YES, GNUNET_STRINGS_PortPolicy::negate_portrange, ret, and GNUNET_STRINGS_PortPolicy::start_port.

Referenced by ipv4_to_regex(), and ipv6_to_regex().

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

◆ address_to_regex()

static char* address_to_regex ( const void *  addr,
const void *  mask,
size_t  len 
)
static

Convert an address (IPv4 or IPv6) to a regex.

Parameters
addraddress
masknetwork mask
lennumber of bytes in addr and mask
Returns
NULL on error, otherwise regex for the address

Definition at line 576 of file regex.c.

579 {
580  const uint16_t *a = addr;
581  const uint16_t *m = mask;
582  char *ret;
583  char *tmp;
584  char *reg;
585  unsigned int i;
586 
587  ret = NULL;
588  GNUNET_assert (1 != (len % 2));
589  for (i = 0; i < len / 2; i++)
590  {
591  reg = num_to_regex (a[i], m[i]);
592  if (NULL == reg)
593  {
594  GNUNET_free (ret);
595  return NULL;
596  }
597  if (NULL == ret)
598  {
599  ret = reg;
600  }
601  else
602  {
603  GNUNET_asprintf (&tmp,
604  "%s%s",
605  ret, reg);
606  GNUNET_free (ret);
607  GNUNET_free (reg);
608  ret = tmp;
609  }
610  }
611  return ret;
612 }
static char * num_to_regex(uint16_t value, uint16_t mask)
Convert the given 16-bit number to a regex.
Definition: regex.c:138

References GNUNET_asprintf(), GNUNET_assert, GNUNET_free, len, m, num_to_regex(), and ret.

Referenced by ipv4_to_regex(), and ipv6_to_regex().

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

◆ ipv4_to_regex()

static char* ipv4_to_regex ( const struct GNUNET_STRINGS_IPv4NetworkPolicy v4)
static

Convert a single line of an IPv4 policy to a regular expression.

Parameters
v4line to convert
Returns
NULL on error

Definition at line 622 of file regex.c.

623 {
624  char *reg;
625  char *pp;
626  char *ret;
627 
628  reg = address_to_regex (&v4->network,
629  &v4->netmask,
630  sizeof(struct in_addr));
631  if (NULL == reg)
632  return NULL;
633  pp = port_to_regex (&v4->pp);
634  if (NULL == pp)
635  {
636  GNUNET_free (reg);
637  return NULL;
638  }
640  "4-%s-%s",
641  pp, reg);
642  GNUNET_free (pp);
643  GNUNET_free (reg);
644  return ret;
645 }
static char * address_to_regex(const void *addr, const void *mask, size_t len)
Convert an address (IPv4 or IPv6) to a regex.
Definition: regex.c:576
static char * port_to_regex(const struct GNUNET_STRINGS_PortPolicy *pp)
Convert a port policy to a regular expression.
Definition: regex.c:504
struct in_addr network
IPv4 address.
struct GNUNET_STRINGS_PortPolicy pp
Policy for port access.
struct in_addr netmask
IPv4 netmask.

References address_to_regex(), GNUNET_asprintf(), GNUNET_free, GNUNET_STRINGS_IPv4NetworkPolicy::netmask, GNUNET_STRINGS_IPv4NetworkPolicy::network, port_to_regex(), GNUNET_STRINGS_IPv4NetworkPolicy::pp, and ret.

Referenced by GNUNET_TUN_ipv4policy2regex().

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

◆ ipv6_to_regex()

static char* ipv6_to_regex ( const struct GNUNET_STRINGS_IPv6NetworkPolicy v6)
static

Convert a single line of an IPv4 policy to a regular expression.

Parameters
v6line to convert
Returns
NULL on error

Definition at line 655 of file regex.c.

656 {
657  char *reg;
658  char *pp;
659  char *ret;
660 
661  reg = address_to_regex (&v6->network,
662  &v6->netmask,
663  sizeof(struct in6_addr));
664  if (NULL == reg)
665  return NULL;
666  pp = port_to_regex (&v6->pp);
667  if (NULL == pp)
668  {
669  GNUNET_free (reg);
670  return NULL;
671  }
673  "6-%s-%s",
674  pp, reg);
675  GNUNET_free (pp);
676  GNUNET_free (reg);
677  return ret;
678 }
struct GNUNET_STRINGS_PortPolicy pp
Policy for port access.
struct in6_addr network
IPv6 address.
struct in6_addr netmask
IPv6 netmask.

References address_to_regex(), GNUNET_asprintf(), GNUNET_free, GNUNET_STRINGS_IPv6NetworkPolicy::netmask, GNUNET_STRINGS_IPv6NetworkPolicy::network, port_to_regex(), GNUNET_STRINGS_IPv6NetworkPolicy::pp, and ret.

Referenced by GNUNET_TUN_ipv6policy2regex().

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