From 020936c8c3375e1efe44a3087c891a4b2cbfe044 Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Tue, 22 Jun 2010 10:49:41 +0200 Subject: ipset 5: last new feature added - the hash types can now store protocol together port, not only port - lots of fixes everywhere: parser, error reporting, manpage The last bits on the todo list before announcing ipset 5: - recheck all the error messages - add possibly more tests - polish manpage --- lib/parse.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) (limited to 'lib/parse.c') diff --git a/lib/parse.c b/lib/parse.c index a07168d..b1fecc7 100644 --- a/lib/parse.c +++ b/lib/parse.c @@ -31,6 +31,7 @@ #define range_separator(str) ipset_strchr(str, IPSET_RANGE_SEPARATOR) #define elem_separator(str) ipset_strchr(str, IPSET_ELEM_SEPARATOR) #define name_separator(str) ipset_strchr(str, IPSET_NAME_SEPARATOR) +#define proto_separator(str) ipset_strchr(str, IPSET_PROTO_SEPARATOR) #define syntax_err(fmt, args...) \ ipset_err(session, "Syntax error: " fmt , ## args) @@ -280,6 +281,88 @@ error: return err; } +/** + * ipset_parse_proto - parse protocol name + * @session: session structure + * @opt: option kind of the data + * @str: string to parse + * + * Parse string as a protocol name. "any" is supported + * as a special protocol name for ipset itself. + * The parsed protocol are stored in the data blob of the session. + * + * Returns 0 on success or a negative error code. + */ +int +ipset_parse_proto(struct ipset_session *session, + enum ipset_opt opt, const char *str) +{ + uint8_t proto = 0; + + assert(session); + assert(opt == IPSET_OPT_PROTO); + assert(str); + + if (STREQ(str, "any")) + proto = IPSET_IPPROTO_ANY; + else { + struct protoent *protoent = getprotobyname(str); + if (protoent == NULL) + return syntax_err("cannot parse '%s' as a protocol name", str); + proto = protoent->p_proto; + } + if (!proto || proto == IPSET_IPPROTO_TCPUDP) + return syntax_err("invalid protocol '%s'", str); + + return ipset_session_data_set(session, opt, &proto); +} + +/** + * ipset_parse_proto_port - parse (optional) protocol and a single port + * @session: session structure + * @opt: option kind of the data + * @str: string to parse + * + * Parse string as a protocol and port, separated by a colon. + * The protocol part is optional. + * The parsed protocol and port numbers are stored in the data + * blob of the session. + * + * Returns 0 on success or a negative error code. + */ +int +ipset_parse_proto_port(struct ipset_session *session, + enum ipset_opt opt, const char *str) +{ + char *a, *saved, *tmp; + int err = 0; + + assert(session); + assert(opt == IPSET_OPT_PORT); + assert(str); + + saved = tmp = strdup(str); + if (tmp == NULL) + return ipset_err(session, + "Cannot allocate memory to duplicate %s.", + str); + + a = proto_separator(tmp); + if (a != NULL) { + /* proto:port */ + *a++ = '\0'; + err = ipset_parse_proto(session, IPSET_OPT_PROTO, tmp); + if (err) + goto error; + tmp = a; + } + err = ipset_parse_single_port(session, opt, tmp); + +error: + free(saved); + return err; +} + /** * ipset_parse_family - parse INET|INET6 family names * @session: session structure -- cgit v1.2.3