diff options
Diffstat (limited to 'lib/parse.c')
-rw-r--r-- | lib/parse.c | 48 |
1 files changed, 46 insertions, 2 deletions
diff --git a/lib/parse.c b/lib/parse.c index 974eaf8..4d2d8b3 100644 --- a/lib/parse.c +++ b/lib/parse.c @@ -280,7 +280,8 @@ static int parse_portname(struct ipset_session *session, const char *str, uint16_t *port, const char *proto) { - char *saved, *tmp, *protoname; + char *saved, *tmp; + const char *protoname; const struct protoent *protoent; struct servent *service; uint8_t protonum = 0; @@ -292,7 +293,7 @@ parse_portname(struct ipset_session *session, const char *str, if (tmp == NULL) goto error; - protoname = (char *)proto; + protoname = proto; if (string_to_u8(session, proto, &protonum, IPSET_WARNING) == 0) { protoent = getprotobynumber(protonum); if (protoent == NULL) @@ -1703,6 +1704,9 @@ ipset_parse_netmask(struct ipset_session *session, assert(str); data = ipset_session_data(session); + if (ipset_data_test(data, IPSET_OPT_BITMASK)) + return syntax_err("bitmask and netmask are mutually exclusive, provide only one"); + family = ipset_data_family(data); if (family == NFPROTO_UNSPEC) { family = NFPROTO_IPV4; @@ -1722,6 +1726,46 @@ ipset_parse_netmask(struct ipset_session *session, } /** + * ipset_parse_bitmask - parse string as a bitmask + * @session: session structure + * @opt: option kind of the data + * @str: string to parse + * + * Parse string as a bitmask value, depending on family type. + * If family is not set yet, INET is assumed. + * The value is stored in the data blob of the session. + * + * Returns 0 on success or a negative error code. + */ +int +ipset_parse_bitmask(struct ipset_session *session, + enum ipset_opt opt, const char *str) +{ + uint8_t family; + struct ipset_data *data; + + assert(session); + assert(opt == IPSET_OPT_BITMASK); + assert(str); + + data = ipset_session_data(session); + if (ipset_data_test(data, IPSET_OPT_NETMASK)) + return syntax_err("bitmask and netmask are mutually exclusive, provide only one"); + + family = ipset_data_family(data); + if (family == NFPROTO_UNSPEC) { + family = NFPROTO_IPV4; + ipset_data_set(data, IPSET_OPT_FAMILY, &family); + } + + if (parse_ipaddr(session, opt, str, family)) + return syntax_err("bitmask is not valid for family = %s", + family == NFPROTO_IPV4 ? "inet" : "inet6"); + + return 0; +} + +/** * ipset_parse_flag - "parse" option flags * @session: session structure * @opt: option kind of the data |