regex.c 20 KB

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