]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
libxtables: XTTYPE_HOSTMASK support
authorJan Engelhardt <jengelh@medozas.de>
Thu, 5 May 2011 12:19:25 +0000 (14:19 +0200)
committerJan Engelhardt <jengelh@medozas.de>
Sun, 8 May 2011 22:46:09 +0000 (00:46 +0200)
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
include/xtables.h.in
xtoptions.c

index 9bb42351ab8eef4083b92fed2241f6a9e286a85c..caaec2faa582d69ba7ffffb2b6d52bc2c3aa86c4 100644 (file)
@@ -61,6 +61,8 @@ struct in_addr;
  * %XTTYPE_MARKMASK32: 32-bit mark with optional mask
  * %XTTYPE_SYSLOGLEVEL:        syslog level by name or number
  * %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_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)
@@ -84,6 +86,7 @@ enum xt_option_type {
        XTTYPE_MARKMASK32,
        XTTYPE_SYSLOGLEVEL,
        XTTYPE_HOST,
+       XTTYPE_HOSTMASK,
        XTTYPE_PORT,
        XTTYPE_PORT_NE,
        XTTYPE_PORTRC,
index 3cc2e0ccf23a05846f4bf9f6416c9c1e8fe29136..36f90e470f2fb76b08d4e2dfb3da638184dae0a5 100644 (file)
@@ -622,6 +622,33 @@ static void xtopt_parse_plenmask(struct xt_option_call *cb)
                memcpy(XTOPT_MKPTR(cb), mask, sizeof(union nf_inet_addr));
 }
 
+static void xtopt_parse_hostmask(struct xt_option_call *cb)
+{
+       const char *orig_arg = cb->arg;
+       char *work, *p;
+
+       if (strchr(cb->arg, '/') == NULL) {
+               xtopt_parse_host(cb);
+               return;
+       }
+       work = strdup(orig_arg);
+       if (work == NULL)
+               xt_params->exit_err(PARAMETER_PROBLEM, "strdup");
+       p = strchr(work, '/'); /* by def this can't be NULL now */
+       *p++ = '\0';
+       /*
+        * Because xtopt_parse_host and xtopt_parse_plenmask would store
+        * different things in the same target area, XTTYPE_HOSTMASK must
+        * disallow XTOPT_PUT, which it does by forcing its absence,
+        * cf. not being listed in xtopt_psize.
+        */
+       cb->arg = work;
+       xtopt_parse_host(cb);
+       cb->arg = p;
+       xtopt_parse_plenmask(cb);
+       cb->arg = orig_arg;
+}
+
 static void (*const xtopt_subparse[])(struct xt_option_call *) = {
        [XTTYPE_UINT8]       = xtopt_parse_int,
        [XTTYPE_UINT16]      = xtopt_parse_int,
@@ -637,6 +664,7 @@ static void (*const xtopt_subparse[])(struct xt_option_call *) = {
        [XTTYPE_MARKMASK32]  = xtopt_parse_markmask,
        [XTTYPE_SYSLOGLEVEL] = xtopt_parse_sysloglevel,
        [XTTYPE_HOST]        = xtopt_parse_host,
+       [XTTYPE_HOSTMASK]    = xtopt_parse_hostmask,
        [XTTYPE_PORT]        = xtopt_parse_port,
        [XTTYPE_PORT_NE]     = xtopt_parse_port,
        [XTTYPE_PORTRC]      = xtopt_parse_mport,
@@ -662,6 +690,7 @@ static const size_t xtopt_psize[] = {
        [XTTYPE_STRING]      = -1,
        [XTTYPE_SYSLOGLEVEL] = sizeof(uint8_t),
        [XTTYPE_HOST]        = sizeof(union nf_inet_addr),
+       [XTTYPE_HOSTMASK]    = sizeof(union nf_inet_addr),
        [XTTYPE_PORT]        = sizeof(uint16_t),
        [XTTYPE_PORT_NE]     = sizeof(uint16_t),
        [XTTYPE_PORTRC]      = sizeof(uint16_t[2]),