diff options
author | szengel <szengel@140774ce-b5e7-0310-ab8b-a85725594a96> | 2012-09-26 21:22:44 +0000 |
---|---|---|
committer | szengel <szengel@140774ce-b5e7-0310-ab8b-a85725594a96> | 2012-09-26 21:22:44 +0000 |
commit | 410f64e67e20412ec8b5dedb7623041676c1ea7b (patch) | |
tree | 31f9d42c204edc1b98dee7abdbc69c07c70300a2 /src/regex/regex.c | |
parent | 8005668f420a08871a4aaa4417b38d366a5acb15 (diff) |
ip/prefix to regex
git-svn-id: https://gnunet.org/svn/gnunet@24025 140774ce-b5e7-0310-ab8b-a85725594a96
Diffstat (limited to 'src/regex/regex.c')
-rw-r--r-- | src/regex/regex.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/src/regex/regex.c b/src/regex/regex.c index 26ad38d349..19b55fca38 100644 --- a/src/regex/regex.c +++ b/src/regex/regex.c @@ -2939,3 +2939,111 @@ GNUNET_REGEX_iterate_all_edges (struct GNUNET_REGEX_Automaton *a, iterator_cls); iterate_edge (a->start, iterator, iterator_cls); } + + +/** + * Create a string with binary IP notation for the given 'addr' in 'str'. + * + * @param af address family of the given 'addr'. + * @param addr address that should be converted to a string. + * struct in_addr * for IPv4 and struct in6_addr * for IPv6. + * @param str string that will contain binary notation of 'addr'. Expected + * to be at least 33 bytes long for IPv4 and 129 bytes long for IPv6. + */ +static void +iptobinstr (const int af, const void *addr, char *str) +{ + unsigned int i; + + switch (af) + { + case AF_INET: + { + uint32_t b = htonl (((struct in_addr *) addr)->s_addr); + + str[32] = '\0'; + str += 31; + for (i = 31; i >= 0; i--) + { + *str-- = (b & 1) + '0'; + b >>= 1; + } + break; + } + case AF_INET6: + { + struct in6_addr b = *(struct in6_addr *) addr; + + str[128] = '\0'; + str += 127; + for (i = 127; i >= 0; i--) + { + *str-- = (b.s6_addr[i / 8] & 1) + '0'; + b.s6_addr[i / 8] >>= 1; + } + break; + } + } +} + + +/** + * Get the ipv4 network prefix from the given 'netmask'. + * + * @param netmask netmask for which to get the prefix len. + * + * @return length of ipv4 prefix for 'netmask'. + */ +static unsigned int +ipv4netmasktoprefixlen (const char *netmask) +{ + struct in_addr a; + unsigned int len; + uint32_t t; + + if (1 != inet_pton (AF_INET, netmask, &a)) + return 0; + + for (len = 32, t = htonl (~a.s_addr); t & 1; t >>= 1, len--) ; + + return len; +} + + +/** + * Create a regex in 'rxstr' from the given 'ip' and 'netmask'. + * + * @param ip IPv4 representation. + * @param netmask netmask for the ip. + * @param rxstr generated regex, must be at least GNUNET_REGEX_IPV4_REGEXLEN + * bytes long. + */ +void +GNUNET_REGEX_ipv4toregex (const struct in_addr *ip, const char *netmask, + char *rxstr) +{ + unsigned int pfxlen; + + pfxlen = ipv4netmasktoprefixlen (netmask); + iptobinstr (AF_INET, ip, rxstr); + rxstr[pfxlen] = '\0'; + strcat (rxstr, "(0|1)*"); +} + + +/** + * Create a regex in 'rxstr' from the given 'ipv6' and 'prefixlen'. + * + * @param ipv6 IPv6 representation. + * @param prefixlen length of the ipv6 prefix. + * @param rxstr generated regex, must be at least GNUNET_REGEX_IPV6_REGEXLEN + * bytes long. + */ +void +GNUNET_REGEX_ipv6toregex (const struct in6_addr *ipv6, + const unsigned int prefixlen, char *rxstr) +{ + iptobinstr (AF_INET6, ipv6, rxstr); + rxstr[prefixlen] = '\0'; + strcat (rxstr, "(0|1)*"); +} |