GNUnet 0.22.2
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_REGEX_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_REGEX_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_REGEX_ipv4policy2regex (const char *policy)
 Convert an exit policy to a regular expression. More...
 
char * GNUNET_REGEX_ipv6policy2regex (const char *policy)
 Convert an exit policy to a regular expression. 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
Final status code.
Definition: gnunet-arm.c:93
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 mp_limb_t d[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:103
#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 d, 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:143
@ 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, 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 {
260 GNUNET_snprintf (buf,
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:38
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:33
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 compute_policy(), 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 compute_policy(), and 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) &&
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 {
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);
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, 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_REGEX_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_REGEX_ipv6policy2regex().

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