GNUnet 0.22.2
regex.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet
3 Copyright (C) 2012, 2013, 2015 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 */
27#include "platform.h"
28#include "gnunet_util_lib.h"
29
33#define DOT "(0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F)"
34
35
36void
37GNUNET_REGEX_ipv4toregexsearch (const struct in_addr *ip,
38 uint16_t port,
39 char *rxstr)
40{
41 GNUNET_snprintf (rxstr,
43 "4-%04X-%08X",
44 (unsigned int) port,
45 ntohl (ip->s_addr));
46}
47
48
49void
50GNUNET_REGEX_ipv6toregexsearch (const struct in6_addr *ipv6,
51 uint16_t port,
52 char *rxstr)
53{
54 const uint32_t *addr;
55
56 addr = (const uint32_t *) ipv6;
57 GNUNET_snprintf (rxstr,
59 "6-%04X-%08X%08X%08X%08X",
60 (unsigned int) port,
61 ntohl (addr[0]),
62 ntohl (addr[1]),
63 ntohl (addr[2]),
64 ntohl (addr[3]));
65}
66
67
74static char *
76 uint8_t mask)
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}
129
130
137static char *
139 uint16_t mask)
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}
167
168
176static int
177needs_parens (const char *arg)
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}
209
210
221static char *
222compute_policy (unsigned int start,
223 unsigned int end,
224 unsigned int step,
225 const struct GNUNET_STRINGS_PortPolicy *pp)
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}
492
493
503static char *
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}
565
566
575static char *
576address_to_regex (const void *addr,
577 const void *mask,
578 size_t len)
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}
613
614
621static char *
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}
646
647
654static char *
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}
679
680
681char *
683{
685 char *reg;
686 char *tmp;
687 char *line;
688 unsigned int i;
689
691 if (NULL == np)
692 return NULL;
693 reg = NULL;
694 for (i = 0; (0 == i) || (0 != np[i].network.s_addr); i++)
695 {
696 line = ipv4_to_regex (&np[i]);
697 if (NULL == line)
698 {
699 GNUNET_free (reg);
700 GNUNET_free (np);
701 return NULL;
702 }
703 if (NULL == reg)
704 {
705 reg = line;
706 }
707 else
708 {
709 GNUNET_asprintf (&tmp,
710 "%s|(%s)",
711 reg, line);
712 GNUNET_free (reg);
714 reg = tmp;
715 }
716 if (0 == np[i].network.s_addr)
717 break;
718 }
719 GNUNET_free (np);
720 return reg;
721}
722
723
724char *
726{
727 struct in6_addr zero;
729 char *reg;
730 char *tmp;
731 char *line;
732 unsigned int i;
733
735 if (NULL == np)
736 return NULL;
737 reg = NULL;
738 memset (&zero, 0, sizeof(struct in6_addr));
739 for (i = 0; (0 == i) || (0 != memcmp (&zero, &np[i].network, sizeof(struct
740 in6_addr))
741 );
742 i++)
743 {
744 line = ipv6_to_regex (&np[i]);
745 if (NULL == line)
746 {
747 GNUNET_free (reg);
748 GNUNET_free (np);
749 return NULL;
750 }
751 if (NULL == reg)
752 {
753 reg = line;
754 }
755 else
756 {
757 GNUNET_asprintf (&tmp,
758 "%s|(%s)",
759 reg, line);
760 GNUNET_free (reg);
762 reg = tmp;
763 }
764 if (0 == memcmp (&zero, &np[i].network, sizeof(struct in6_addr)))
765 break;
766 }
767 GNUNET_free (np);
768 return reg;
769}
770
771
772/* end of regex.c */
static mp_limb_t d[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:143
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:103
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:38
static int ret
Final status code.
Definition: gnunet-arm.c:93
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:33
static uint16_t port
Port number.
Definition: gnunet-bcd.c:146
static char * line
Desired phone line (string to be converted to a hash).
static char * value
Value of the record to add/remove.
static const struct GNUNET_CRYPTO_PrivateKey zero
Public key of all zeros.
static int ipv6
Option -6: IPv6 requested.
Definition: gnunet-vpn.c:65
#define GNUNET_log(kind,...)
@ GNUNET_YES
@ GNUNET_NO
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#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_.
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_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
char * GNUNET_REGEX_ipv6policy2regex(const char *policy)
Convert an exit policy to a regular expression.
Definition: regex.c:725
char * GNUNET_REGEX_ipv4policy2regex(const char *policy)
Convert an exit policy to a regular expression.
Definition: regex.c:682
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.
Definition: regex.c:37
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.
Definition: regex.c:50
struct GNUNET_STRINGS_IPv6NetworkPolicy * GNUNET_STRINGS_parse_ipv6_policy(const char *routeListX)
Parse an IPv6 network policy.
Definition: strings.c:1450
struct GNUNET_STRINGS_IPv4NetworkPolicy * GNUNET_STRINGS_parse_ipv4_policy(const char *routeListX)
Parse an IPv4 network policy.
Definition: strings.c:1275
#define GNUNET_TUN_IPV4_REGEXLEN
Maximum regex string length for use with GNUNET_REGEX_ipv4toregexsearch.
#define GNUNET_TUN_IPV6_REGEXLEN
Maximum regex string length for use with GNUNET_REGEX_ipv6toregexsearch.
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
static char * ipv4_to_regex(const struct GNUNET_STRINGS_IPv4NetworkPolicy *v4)
Convert a single line of an IPv4 policy to a regular expression.
Definition: regex.c:622
static char * ipv6_to_regex(const struct GNUNET_STRINGS_IPv6NetworkPolicy *v6)
Convert a single line of an IPv4 policy to a regular expression.
Definition: regex.c:655
static char * num_to_regex(uint16_t value, uint16_t mask)
Convert the given 16-bit number to a regex.
Definition: regex.c:138
static int needs_parens(const char *arg)
Do we need to put parents around the given argument?
Definition: regex.c:177
#define DOT
'wildcard', matches all possible values (for HEX encoding).
Definition: regex.c:33
static char * nibble_to_regex(uint8_t value, uint8_t mask)
Convert the given 4-bit (!) number to a regex.
Definition: regex.c:75
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
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
IPV4 network in CIDR notation.
struct in_addr network
IPv4 address.
struct GNUNET_STRINGS_PortPolicy pp
Policy for port access.
struct in_addr netmask
IPv4 netmask.
network in CIDR notation for IPV6.
struct GNUNET_STRINGS_PortPolicy pp
Policy for port access.
struct in6_addr network
IPv6 address.
struct in6_addr netmask
IPv6 netmask.
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).