]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
libxtables: XTTYPE_PROTOCOL support
authorJan Engelhardt <jengelh@medozas.de>
Sat, 7 May 2011 10:56:39 +0000 (12:56 +0200)
committerJan Engelhardt <jengelh@medozas.de>
Sun, 8 May 2011 22:52:18 +0000 (00:52 +0200)
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
include/xtables.h.in
xtoptions.c

index 50aa414cdaf192b415944d5a47072d0b5e12b411..c3996a094e930c5876f6daa6bde2079b58052927 100644 (file)
@@ -63,6 +63,7 @@ struct in_addr;
  * %XTTYPE_HOST:       one host or address (ptr: union nf_inet_addr)
  * %XTTYPE_HOSTMASK:   one host or address, with an optional prefix length
  *                     (ptr: union nf_inet_addr; only host portion is stored)
+ * %XTTYPE_PROTOCOL:   protocol number/name from /etc/protocols (ptr: uint8_t)
  * %XTTYPE_PORT:       16-bit port name or number
  * %XTTYPE_PORT_NE:    16-bit port name or number, stored as network-endian
  * %XTTYPE_PORTRC:     colon-separated port range (names acceptable)
@@ -87,6 +88,7 @@ enum xt_option_type {
        XTTYPE_SYSLOGLEVEL,
        XTTYPE_HOST,
        XTTYPE_HOSTMASK,
+       XTTYPE_PROTOCOL,
        XTTYPE_PORT,
        XTTYPE_PORT_NE,
        XTTYPE_PORTRC,
@@ -147,7 +149,7 @@ struct xt_option_call {
        bool invert;
        uint8_t nvals;
        union {
-               uint8_t u8, u8_range[2], syslog_level;
+               uint8_t u8, u8_range[2], syslog_level, protocol;
                uint16_t u16, u16_range[2], port, port_range[2];
                uint32_t u32, u32_range[2];
                uint64_t u64, u64_range[2];
index 413de1b864d0ad2a828f611b969f3bb8306f3b8a..70370edba7b8997f088996b8755760682b44e070 100644 (file)
@@ -492,6 +492,29 @@ static int xtables_getportbyname(const char *name)
        return ntohs(ret);
 }
 
+/**
+ * Validate and parse a protocol specification (number or name) by use of
+ * /etc/protocols and put the result into @cb->val.protocol.
+ */
+static void xtopt_parse_protocol(struct xt_option_call *cb)
+{
+       const struct protoent *entry;
+       unsigned int value = -1;
+
+       if (xtables_strtoui(cb->arg, NULL, &value, 0, UINT8_MAX)) {
+               cb->val.protocol = value;
+               return;
+       }
+       entry = getprotobyname(cb->arg);
+       if (entry == NULL)
+               xt_params->exit_err(PARAMETER_PROBLEM,
+                       "Protocol \"%s\" does not resolve to anything.\n",
+                       cb->arg);
+       cb->val.protocol = entry->p_proto;
+       if (cb->entry->flags & XTOPT_PUT)
+               *(uint8_t *)XTOPT_MKPTR(cb) = cb->val.protocol;
+}
+
 /**
  * Validate and parse a port specification and put the result into
  * @cb->val.port.
@@ -665,6 +688,7 @@ static void (*const xtopt_subparse[])(struct xt_option_call *) = {
        [XTTYPE_SYSLOGLEVEL] = xtopt_parse_sysloglevel,
        [XTTYPE_HOST]        = xtopt_parse_host,
        [XTTYPE_HOSTMASK]    = xtopt_parse_hostmask,
+       [XTTYPE_PROTOCOL]    = xtopt_parse_protocol,
        [XTTYPE_PORT]        = xtopt_parse_port,
        [XTTYPE_PORT_NE]     = xtopt_parse_port,
        [XTTYPE_PORTRC]      = xtopt_parse_mport,
@@ -691,6 +715,7 @@ static const size_t xtopt_psize[] = {
        [XTTYPE_SYSLOGLEVEL] = sizeof(uint8_t),
        [XTTYPE_HOST]        = sizeof(union nf_inet_addr),
        [XTTYPE_HOSTMASK]    = sizeof(union nf_inet_addr),
+       [XTTYPE_PROTOCOL]    = sizeof(uint8_t),
        [XTTYPE_PORT]        = sizeof(uint16_t),
        [XTTYPE_PORT_NE]     = sizeof(uint16_t),
        [XTTYPE_PORTRC]      = sizeof(uint16_t[2]),