regex.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808
  1. /*
  2. This file is part of GNUnet
  3. (C) 2012, 2013 Christian Grothoff (and other contributing authors)
  4. GNUnet is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published
  6. by the Free Software Foundation; either version 3, or (at your
  7. option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNUnet; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  15. Boston, MA 02111-1307, USA.
  16. */
  17. /**
  18. * @file src/tun/regex.c
  19. * @brief functions to convert IP networks to regexes
  20. * @author Maximilian Szengel
  21. * @author Christian Grothoff
  22. */
  23. #include "platform.h"
  24. #include "gnunet_util_lib.h"
  25. #include "gnunet_tun_lib.h"
  26. /**
  27. * Create a regex in @a rxstr from the given @a ip and @a netmask.
  28. *
  29. * @param ip IPv4 representation.
  30. * @param port destination port
  31. * @param rxstr generated regex, must be at least #GNUNET_TUN_IPV4_REGEXLEN
  32. * bytes long.
  33. */
  34. void
  35. GNUNET_TUN_ipv4toregexsearch (const struct in_addr *ip,
  36. uint16_t port,
  37. char *rxstr)
  38. {
  39. GNUNET_snprintf (rxstr,
  40. GNUNET_TUN_IPV4_REGEXLEN,
  41. "4-%04X-%08X",
  42. (unsigned int) port,
  43. ntohl (ip->s_addr));
  44. }
  45. /**
  46. * Create a regex in @a rxstr from the given @a ipv6 and @a prefixlen.
  47. *
  48. * @param ipv6 IPv6 representation.
  49. * @param port destination port
  50. * @param rxstr generated regex, must be at least #GNUNET_TUN_IPV6_REGEXLEN
  51. * bytes long.
  52. */
  53. void
  54. GNUNET_TUN_ipv6toregexsearch (const struct in6_addr *ipv6,
  55. uint16_t port,
  56. char *rxstr)
  57. {
  58. const uint32_t *addr;
  59. addr = (const uint32_t *) ipv6;
  60. GNUNET_snprintf (rxstr,
  61. GNUNET_TUN_IPV6_REGEXLEN,
  62. "6-%04X-%08X%08X%08X%08X",
  63. (unsigned int) port,
  64. ntohl (addr[0]),
  65. ntohl (addr[1]),
  66. ntohl (addr[2]),
  67. ntohl (addr[3]));
  68. }
  69. /**
  70. * Convert the given 4-bit (!) number to a regex.
  71. *
  72. * @param value the value, only the lowest 4 bits will be looked at
  73. * @param mask which bits in value are wildcards (any value)?
  74. */
  75. static char *
  76. nibble_to_regex (uint8_t value,
  77. uint8_t mask)
  78. {
  79. char *ret;
  80. value &= mask;
  81. switch (mask)
  82. {
  83. case 0:
  84. return GNUNET_strdup ("."); /* wildcard */
  85. case 8:
  86. GNUNET_asprintf (&ret,
  87. "(%X|%X|%X|%X|%X|%X|%X|%X)",
  88. value,
  89. value + 1,
  90. value + 2,
  91. value + 3,
  92. value + 4,
  93. value + 5,
  94. value + 6,
  95. value + 7);
  96. return ret;
  97. case 12:
  98. GNUNET_asprintf (&ret,
  99. "(%X|%X|%X|%X)",
  100. value,
  101. value + 1,
  102. value + 2,
  103. value + 3);
  104. return ret;
  105. case 14:
  106. GNUNET_asprintf (&ret,
  107. "(%X|%X)",
  108. value,
  109. value + 1);
  110. return ret;
  111. case 15:
  112. GNUNET_asprintf (&ret,
  113. "%X",
  114. value);
  115. return ret;
  116. default:
  117. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  118. _("Bad mask: %d\n"),
  119. mask);
  120. GNUNET_break (0);
  121. return NULL;
  122. }
  123. }
  124. /**
  125. * Convert the given 16-bit number to a regex.
  126. *
  127. * @param value the value
  128. * @param mask which bits in value are wildcards (any value)?
  129. */
  130. static char *
  131. num_to_regex (uint16_t value,
  132. uint16_t mask)
  133. {
  134. const uint8_t *v = (const uint8_t *) &value;
  135. const uint8_t *m = (const uint8_t *) &mask;
  136. char *a;
  137. char *b;
  138. char *c;
  139. char *d;
  140. char *ret;
  141. a = nibble_to_regex (v[0] >> 4, m[0] >> 4);
  142. b = nibble_to_regex (v[0] & 15, m[0] & 15);
  143. c = nibble_to_regex (v[1] >> 4, m[1] >> 4);
  144. d = nibble_to_regex (v[1] & 15, m[1] & 15);
  145. ret = NULL;
  146. if ( (NULL != a) &&
  147. (NULL != b) &&
  148. (NULL != c) &&
  149. (NULL != d) )
  150. GNUNET_asprintf (&ret,
  151. "%s%s%s%s",
  152. a, b, c, d);
  153. GNUNET_free_non_null (a);
  154. GNUNET_free_non_null (b);
  155. GNUNET_free_non_null (c);
  156. GNUNET_free_non_null (d);
  157. return ret;
  158. }
  159. /**
  160. * Do we need to put parents around the given argument?
  161. *
  162. * @param arg part of a regular expression
  163. * @return #GNUNET_YES if we should parens,
  164. * #GNUNET_NO if not
  165. */
  166. static int
  167. needs_parens (const char *arg)
  168. {
  169. size_t off;
  170. size_t len;
  171. unsigned int op;
  172. op = 0;
  173. len = strlen (arg);
  174. for (off=0;off<len;off++)
  175. {
  176. switch (arg[off])
  177. {
  178. case '(':
  179. op++;
  180. break;
  181. case ')':
  182. GNUNET_assert (op > 0);
  183. op--;
  184. break;
  185. case '|':
  186. if (0 == op)
  187. return GNUNET_YES;
  188. break;
  189. default:
  190. break;
  191. }
  192. }
  193. return GNUNET_NO;
  194. }
  195. /**
  196. * Compute port policy for the given range of
  197. * port numbers.
  198. *
  199. * @param start starting offset
  200. * @param end end offset
  201. * @param step increment level (power of 16)
  202. * @param pp port policy to convert
  203. * @return corresponding regex
  204. */
  205. static char *
  206. compute_policy (unsigned int start,
  207. unsigned int end,
  208. unsigned int step,
  209. const struct GNUNET_STRINGS_PortPolicy *pp)
  210. {
  211. unsigned int i;
  212. char before[36]; /* 16 * 2 + 3 dots + 0-terminator */
  213. char middlel[33]; /* 16 * 2 + 0-terminator */
  214. char middleh[33]; /* 16 * 2 + 0-terminator */
  215. char after[36]; /* 16 * 2 + 3 dots + 0-terminator */
  216. char beforep[36+2]; /* 16 * 2 + 3 dots + 0-terminator + ()*/
  217. char middlehp[33+2]; /* 16 * 2 + 0-terminator + () */
  218. char middlelp[33+2]; /* 16 * 2 + 0-terminator + () */
  219. char afterp[36+2]; /* 16 * 2 + 3 dots + 0-terminator + () */
  220. char dots[4];
  221. char buf[3];
  222. char *middle;
  223. char *ret;
  224. unsigned int xstep;
  225. char *recl;
  226. char *rech;
  227. char *reclp;
  228. char *rechp;
  229. unsigned int start_port;
  230. unsigned int end_port;
  231. GNUNET_assert (GNUNET_YES == pp->negate_portrange);
  232. start_port = pp->start_port;
  233. if (1 == start_port)
  234. start_port = 0;
  235. end_port = pp->end_port;
  236. GNUNET_assert ((end - start) / step <= 0xF);
  237. before[0] = '\0';
  238. middlel[0] = '\0';
  239. middleh[0] = '\0';
  240. after[0] = '\0';
  241. for (i=start;i<=end;i+=step)
  242. {
  243. GNUNET_snprintf (buf,
  244. sizeof (buf),
  245. "%X|",
  246. (i - start) / step);
  247. if (i / step < start_port / step)
  248. strcat (before, buf);
  249. else if (i / step > end_port / step)
  250. strcat (after, buf);
  251. else if (i / step == start_port / step)
  252. strcat (middlel, buf);
  253. else if (i / step == end_port / step)
  254. strcat (middleh, buf);
  255. }
  256. if (strlen (before) > 0)
  257. before[strlen (before)-1] = '\0';
  258. if (strlen (middlel) > 0)
  259. middlel[strlen (middlel)-1] = '\0';
  260. if (strlen (middleh) > 0)
  261. middleh[strlen (middleh)-1] = '\0';
  262. if (strlen (after) > 0)
  263. after[strlen (after)-1] = '\0';
  264. if (needs_parens (before))
  265. GNUNET_snprintf (beforep,
  266. sizeof (beforep),
  267. "(%s)",
  268. before);
  269. else
  270. strcpy (beforep, before);
  271. if (needs_parens (middlel))
  272. GNUNET_snprintf (middlelp,
  273. sizeof (middlelp),
  274. "(%s)",
  275. middlel);
  276. else
  277. strcpy (middlelp, middlel);
  278. if (needs_parens (middleh))
  279. GNUNET_snprintf (middlehp,
  280. sizeof (middlehp),
  281. "(%s)",
  282. middleh);
  283. else
  284. strcpy (middlehp, middleh);
  285. if (needs_parens (after))
  286. GNUNET_snprintf (afterp,
  287. sizeof (afterp),
  288. "(%s)",
  289. after);
  290. else
  291. strcpy (afterp, after);
  292. dots[0] = '\0';
  293. for (xstep=step/16;xstep>0;xstep/=16)
  294. strcat (dots, ".");
  295. if (step >= 16)
  296. {
  297. if (strlen (middlel) > 0)
  298. recl = compute_policy ((start_port / step) * step,
  299. (start_port / step) * step + step - 1,
  300. step / 16,
  301. pp);
  302. else
  303. recl = GNUNET_strdup ("");
  304. if (strlen (middleh) > 0)
  305. rech = compute_policy ((end_port / step) * step,
  306. (end_port / step) * step + step - 1,
  307. step / 16,
  308. pp);
  309. else
  310. rech = GNUNET_strdup ("");
  311. }
  312. else
  313. {
  314. recl = GNUNET_strdup ("");
  315. rech = GNUNET_strdup ("");
  316. middlel[0] = '\0';
  317. middlelp[0] = '\0';
  318. middleh[0] = '\0';
  319. middlehp[0] = '\0';
  320. }
  321. if (needs_parens (recl))
  322. GNUNET_asprintf (&reclp,
  323. "(%s)",
  324. recl);
  325. else
  326. reclp = GNUNET_strdup (recl);
  327. if (needs_parens (rech))
  328. GNUNET_asprintf (&rechp,
  329. "(%s)",
  330. rech);
  331. else
  332. rechp = GNUNET_strdup (rech);
  333. if ( (strlen (middleh) > 0) &&
  334. (strlen (rech) > 0) &&
  335. (strlen (middlel) > 0) &&
  336. (strlen (recl) > 0) )
  337. {
  338. GNUNET_asprintf (&middle,
  339. "%s%s|%s%s",
  340. middlel,
  341. reclp,
  342. middleh,
  343. rechp);
  344. }
  345. else if ( (strlen (middleh) > 0) &&
  346. (strlen (rech) > 0) )
  347. {
  348. GNUNET_asprintf (&middle,
  349. "%s%s",
  350. middleh,
  351. rechp);
  352. }
  353. else if ( (strlen (middlel) > 0) &&
  354. (strlen (recl) > 0) )
  355. {
  356. GNUNET_asprintf (&middle,
  357. "%s%s",
  358. middlel,
  359. reclp);
  360. }
  361. else
  362. {
  363. middle = GNUNET_strdup ("");
  364. }
  365. if ( (strlen(before) > 0) &&
  366. (strlen(after) > 0) )
  367. {
  368. if (strlen (dots) > 0)
  369. {
  370. if (strlen (middle) > 0)
  371. GNUNET_asprintf (&ret,
  372. "(%s%s|%s|%s%s)",
  373. beforep, dots,
  374. middle,
  375. afterp, dots);
  376. else
  377. GNUNET_asprintf (&ret,
  378. "(%s|%s)%s",
  379. beforep,
  380. afterp,
  381. dots);
  382. }
  383. else
  384. {
  385. if (strlen (middle) > 0)
  386. GNUNET_asprintf (&ret,
  387. "(%s|%s|%s)",
  388. before,
  389. middle,
  390. after);
  391. else if (1 == step)
  392. GNUNET_asprintf (&ret,
  393. "%s|%s",
  394. before,
  395. after);
  396. else
  397. GNUNET_asprintf (&ret,
  398. "(%s|%s)",
  399. before,
  400. after);
  401. }
  402. }
  403. else if (strlen (before) > 0)
  404. {
  405. if (strlen (dots) > 0)
  406. {
  407. if (strlen (middle) > 0)
  408. GNUNET_asprintf (&ret,
  409. "(%s%s|%s)",
  410. beforep, dots,
  411. middle);
  412. else
  413. GNUNET_asprintf (&ret,
  414. "%s%s",
  415. beforep, dots);
  416. }
  417. else
  418. {
  419. if (strlen (middle) > 0)
  420. GNUNET_asprintf (&ret,
  421. "(%s|%s)",
  422. before,
  423. middle);
  424. else
  425. GNUNET_asprintf (&ret,
  426. "%s",
  427. before);
  428. }
  429. }
  430. else if (strlen (after) > 0)
  431. {
  432. if (strlen (dots) > 0)
  433. {
  434. if (strlen (middle) > 0)
  435. GNUNET_asprintf (&ret,
  436. "(%s|%s%s)",
  437. middle,
  438. afterp, dots);
  439. else
  440. GNUNET_asprintf (&ret,
  441. "%s%s",
  442. afterp, dots);
  443. }
  444. else
  445. {
  446. if (strlen (middle) > 0)
  447. GNUNET_asprintf (&ret,
  448. "%s|%s",
  449. middle,
  450. after);
  451. else
  452. GNUNET_asprintf (&ret,
  453. "%s",
  454. after);
  455. }
  456. }
  457. else if (strlen (middle) > 0)
  458. {
  459. GNUNET_asprintf (&ret,
  460. "%s",
  461. middle);
  462. }
  463. else
  464. {
  465. ret = GNUNET_strdup ("");
  466. }
  467. GNUNET_free (middle);
  468. GNUNET_free (reclp);
  469. GNUNET_free (rechp);
  470. GNUNET_free (recl);
  471. GNUNET_free (rech);
  472. return ret;
  473. }
  474. /**
  475. * Convert a port policy to a regular expression. Note: this is a
  476. * very simplistic implementation, we might want to consider doing
  477. * something more sophisiticated (resulting in smaller regular
  478. * expressions) at a later time.
  479. *
  480. * @param pp port policy to convert
  481. * @return NULL on error
  482. */
  483. static char *
  484. port_to_regex (const struct GNUNET_STRINGS_PortPolicy *pp)
  485. {
  486. char *reg;
  487. char *ret;
  488. char *pos;
  489. unsigned int i;
  490. unsigned int cnt;
  491. if ( (0 == pp->start_port) ||
  492. ( (1 == pp->start_port) &&
  493. (0xFFFF == pp->end_port) &&
  494. (GNUNET_NO == pp->negate_portrange)) )
  495. return GNUNET_strdup ("....");
  496. if ( (pp->start_port == pp->end_port) &&
  497. (GNUNET_NO == pp->negate_portrange))
  498. {
  499. GNUNET_asprintf (&ret,
  500. "%04X",
  501. pp->start_port);
  502. return ret;
  503. }
  504. if (pp->end_port < pp->start_port)
  505. return NULL;
  506. if (GNUNET_YES == pp->negate_portrange)
  507. {
  508. ret = compute_policy (0, 0xFFFF, 0x1000, pp);
  509. }
  510. else
  511. {
  512. cnt = pp->end_port - pp->start_port + 1;
  513. reg = GNUNET_malloc (cnt * 5 + 1);
  514. pos = reg;
  515. for (i=1;i<=0xFFFF;i++)
  516. {
  517. if ( (i >= pp->start_port) && (i <= pp->end_port) )
  518. {
  519. if (pos == reg)
  520. {
  521. GNUNET_snprintf (pos,
  522. 5,
  523. "%04X",
  524. i);
  525. }
  526. else
  527. {
  528. GNUNET_snprintf (pos,
  529. 6,
  530. "|%04X",
  531. i);
  532. }
  533. pos += strlen (pos);
  534. }
  535. }
  536. GNUNET_asprintf (&ret,
  537. "(%s)",
  538. reg);
  539. GNUNET_free (reg);
  540. }
  541. return ret;
  542. }
  543. /**
  544. * Convert an address (IPv4 or IPv6) to a regex.
  545. *
  546. * @param addr address
  547. * @param mask network mask
  548. * @param len number of bytes in @a addr and @a mask
  549. * @return NULL on error, otherwise regex for the address
  550. */
  551. static char *
  552. address_to_regex (const void *addr,
  553. const void *mask,
  554. size_t len)
  555. {
  556. const uint16_t *a = addr;
  557. const uint16_t *m = mask;
  558. char *ret;
  559. char *tmp;
  560. char *reg;
  561. unsigned int i;
  562. ret = NULL;
  563. GNUNET_assert (1 != (len % 2));
  564. for (i=0;i<len / 2;i++)
  565. {
  566. reg = num_to_regex (a[i], m[i]);
  567. if (NULL == reg)
  568. {
  569. GNUNET_free_non_null (ret);
  570. return NULL;
  571. }
  572. if (NULL == ret)
  573. {
  574. ret = reg;
  575. }
  576. else
  577. {
  578. GNUNET_asprintf (&tmp,
  579. "%s%s",
  580. ret, reg);
  581. GNUNET_free (ret);
  582. GNUNET_free (reg);
  583. ret = tmp;
  584. }
  585. }
  586. return ret;
  587. }
  588. /**
  589. * Convert a single line of an IPv4 policy to a regular expression.
  590. *
  591. * @param v4 line to convert
  592. * @return NULL on error
  593. */
  594. static char *
  595. ipv4_to_regex (const struct GNUNET_STRINGS_IPv4NetworkPolicy *v4)
  596. {
  597. char *reg;
  598. char *pp;
  599. char *ret;
  600. reg = address_to_regex (&v4->network,
  601. &v4->netmask,
  602. sizeof (struct in_addr));
  603. if (NULL == reg)
  604. return NULL;
  605. pp = port_to_regex (&v4->pp);
  606. if (NULL == pp)
  607. {
  608. GNUNET_free (reg);
  609. return NULL;
  610. }
  611. GNUNET_asprintf (&ret,
  612. "4-%s-%s",
  613. pp, reg);
  614. GNUNET_free (pp);
  615. GNUNET_free (reg);
  616. return ret;
  617. }
  618. /**
  619. * Convert a single line of an IPv4 policy to a regular expression.
  620. *
  621. * @param v6 line to convert
  622. * @return NULL on error
  623. */
  624. static char *
  625. ipv6_to_regex (const struct GNUNET_STRINGS_IPv6NetworkPolicy *v6)
  626. {
  627. char *reg;
  628. char *pp;
  629. char *ret;
  630. reg = address_to_regex (&v6->network,
  631. &v6->netmask,
  632. sizeof (struct in6_addr));
  633. if (NULL == reg)
  634. return NULL;
  635. pp = port_to_regex (&v6->pp);
  636. if (NULL == pp)
  637. {
  638. GNUNET_free (reg);
  639. return NULL;
  640. }
  641. GNUNET_asprintf (&ret,
  642. "6-%s-%s",
  643. pp, reg);
  644. GNUNET_free (pp);
  645. GNUNET_free (reg);
  646. return ret;
  647. }
  648. /**
  649. * Convert an exit policy to a regular expression. The exit policy
  650. * specifies a set of subnets this peer is willing to serve as an
  651. * exit for; the resulting regular expression will match the
  652. * IPv4 address strings as returned by 'GNUNET_TUN_ipv4toregexsearch'.
  653. *
  654. * @param policy exit policy specification
  655. * @return regular expression, NULL on error
  656. */
  657. char *
  658. GNUNET_TUN_ipv4policy2regex (const char *policy)
  659. {
  660. struct GNUNET_STRINGS_IPv4NetworkPolicy *np;
  661. char *reg;
  662. char *tmp;
  663. char *line;
  664. unsigned int i;
  665. np = GNUNET_STRINGS_parse_ipv4_policy (policy);
  666. if (NULL == np)
  667. return NULL;
  668. reg = NULL;
  669. for (i=0; (0 == i) || (0 != np[i].network.s_addr); i++)
  670. {
  671. line = ipv4_to_regex (&np[i]);
  672. if (NULL == line)
  673. {
  674. GNUNET_free_non_null (reg);
  675. GNUNET_free (np);
  676. return NULL;
  677. }
  678. if (NULL == reg)
  679. {
  680. reg = line;
  681. }
  682. else
  683. {
  684. GNUNET_asprintf (&tmp,
  685. "%s|(%s)",
  686. reg, line);
  687. GNUNET_free (reg);
  688. GNUNET_free (line);
  689. reg = tmp;
  690. }
  691. if (0 == np[i].network.s_addr)
  692. break;
  693. }
  694. GNUNET_free (np);
  695. return reg;
  696. }
  697. /**
  698. * Convert an exit policy to a regular expression. The exit policy
  699. * specifies a set of subnets this peer is willing to serve as an
  700. * exit for; the resulting regular expression will match the
  701. * IPv6 address strings as returned by #GNUNET_TUN_ipv6toregexsearch().
  702. *
  703. * @param policy exit policy specification
  704. * @return regular expression, NULL on error
  705. */
  706. char *
  707. GNUNET_TUN_ipv6policy2regex (const char *policy)
  708. {
  709. struct in6_addr zero;
  710. struct GNUNET_STRINGS_IPv6NetworkPolicy *np;
  711. char *reg;
  712. char *tmp;
  713. char *line;
  714. unsigned int i;
  715. np = GNUNET_STRINGS_parse_ipv6_policy (policy);
  716. if (NULL == np)
  717. return NULL;
  718. reg = NULL;
  719. memset (&zero, 0, sizeof (struct in6_addr));
  720. for (i=0; (0 == i) || (0 != memcmp (&zero, &np[i].network, sizeof (struct in6_addr))); i++)
  721. {
  722. line = ipv6_to_regex (&np[i]);
  723. if (NULL == line)
  724. {
  725. GNUNET_free_non_null (reg);
  726. GNUNET_free (np);
  727. return NULL;
  728. }
  729. if (NULL == reg)
  730. {
  731. reg = line;
  732. }
  733. else
  734. {
  735. GNUNET_asprintf (&tmp,
  736. "%s|(%s)",
  737. reg, line);
  738. GNUNET_free (reg);
  739. GNUNET_free (line);
  740. reg = tmp;
  741. }
  742. if (0 == memcmp (&zero, &np[i].network, sizeof (struct in6_addr)))
  743. break;
  744. }
  745. GNUNET_free (np);
  746. return reg;
  747. }
  748. /**
  749. * Hash the service name of a hosted service to the
  750. * hash code that is used to identify the service on
  751. * the network.
  752. *
  753. * @param service_name a string
  754. * @param hc corresponding hash
  755. */
  756. void
  757. GNUNET_TUN_service_name_to_hash (const char *service_name,
  758. struct GNUNET_HashCode *hc)
  759. {
  760. GNUNET_CRYPTO_hash (service_name,
  761. strlen (service_name),
  762. hc);
  763. }
  764. /* end of regex.c */