diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2014-09-25 08:42:57 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2014-09-25 08:53:52 +0300 |
commit | c711cf9ecbbe0df7f7f27cec789a75c0b4e39040 (patch) | |
tree | 6ca6ae15720c1da84f30e430ef39964867061b24 /src/ipstr.c | |
parent | 82658ac36ae527e7d1cd949fb379ef26caad31cb (diff) | |
download | grecs-c711cf9ecbbe0df7f7f27cec789a75c0b4e39040.tar.gz grecs-c711cf9ecbbe0df7f7f27cec789a75c0b4e39040.tar.bz2 |
Add support for IPv6, multiple addresses and CIDRs.
* am/grecs.m4 (GRECS_SETUP): New option sockaddr-list.
Build grecs.h at configure stage.
* src/Make.am (GRECS_SRC): Add cidr.c and ipstr.c
[GRECS_COND_SOCKADDR_LIST] (GRECS_SRC): Add sockaddr.c
Remove rule for building grecs.h (see above).
* src/cidr.c: New file.
* src/ipstr.c: New file.
* src/sockaddr.c: New file.
* src/format.c (grecs_data_type_string): Change spelling of sockaddr.
* src/grecs-lex.l: Treat square brackets as part of word.
* src/grecs.hin (GRECS_SOCKADDR_LIST): New define.
[GRECS_SOCKADDR_LIST] (grecs_sockaddr): New member: next.
(grecs_str_is_ipv4,grecs_str_is_ipv6)
(grecs_str_is_ipaddr,grecs_str_is_num): New functions.
[GRECS_SOCKADDR_LIST] (grecs_sockaddr_hints): New struct.
[GRECS_SOCKADDR_LIST] (grecs_sockaddr_new,grecs_sockaddr_free)
(grecs_str_to_sockaddr): New protos.
(grecs_cidr): New struct.
(grecs_str_to_cidr,grecs_sockaddr_to_cidr)
(grecs_sockadd_cidr_match): New protos.
* src/tree.c [GRECS_SOCKADDR_LIST] (grecs_sockaddr_hints): New global.
[!GRECS_SOCKADDR_LIST] (string_to_sockaddr): Retain for backward
compatibility.
[GRECS_SOCKADDR_LIST] (grecs_string_convert): Use grecs_str_to_sockaddr.
(grecs_prop_tab): Add entry for grecs_type_cidr
Diffstat (limited to 'src/ipstr.c')
-rw-r--r-- | src/ipstr.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/ipstr.c b/src/ipstr.c new file mode 100644 index 0000000..5676301 --- /dev/null +++ b/src/ipstr.c @@ -0,0 +1,88 @@ +/* grecs - Gray's Extensible Configuration System + Copyright (C) 2007-2014 Sergey Poznyakoff + + Grecs is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3 of the License, or (at your + option) any later version. + + Grecs is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Grecs. If not, see <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <string.h> +#include <ctype.h> +#include "grecs.h" + +int +grecs_str_is_ipv4(const char *addr) +{ + int dot_count = 0; + int digit_count = 0; + + for (; *addr; addr++) { + if (!isascii(*addr)) + return 0; + if (*addr == '.') { + if (++dot_count > 3) + break; + digit_count = 0; + } else if (!(isdigit(*addr) && ++digit_count <= 3)) + return 0; + } + + return (dot_count == 3); +} + +int +grecs_str_is_ipv6(const char *addr) +{ + int col_count = 0; /* Number of colons */ + int dcol = 0; /* Did we encounter a double-colon? */ + int dig_count = 0; /* Number of digits in the last group */ + + for (; *addr; addr++) { + if (!isascii(*addr)) + return 0; + else if (isxdigit(*addr)) { + if (++dig_count > 4) + return 0; + } else if (*addr == ':') { + if (col_count && dig_count == 0 && ++dcol > 1) + return 0; + if (++col_count > 7) + return 0; + dig_count = 0; + } else + return 0; + } + + return (col_count == 7 || dcol); +} + +int +grecs_str_is_num(const char *s) +{ + for (; *s; ++s) + if (!isdigit(*s)) + return 0; + return 1; +} + +int +grecs_str_is_ipaddr(const char *addr) +{ + if (strchr (addr, '.')) + return grecs_str_is_ipv4(addr); + else if (strchr (addr, ':')) + return grecs_str_is_ipv6(addr); + return 0; +} + |