]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
libxtables: XTTYPE_ETHERMAC support
authorJan Engelhardt <jengelh@medozas.de>
Sun, 8 May 2011 11:31:19 +0000 (13:31 +0200)
committerJan Engelhardt <jengelh@medozas.de>
Mon, 9 May 2011 15:11:42 +0000 (17:11 +0200)
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
include/xtables.h.in
xtoptions.c

index c3996a094e930c5876f6daa6bde2079b58052927..0fe4b9047f52b7866d67d901089c7c0a8e2fa6d4 100644 (file)
@@ -70,6 +70,7 @@ struct in_addr;
  * %XTTYPE_PORTRC_NE:  same as %XTTYPE_PORTRC, stored in network-endian
  * %XTTYPE_PLEN:       prefix length
  * %XTTYPE_PLENMASK:   prefix length (ptr: union nf_inet_addr)
+ * %XTTYPE_ETHERMAC:   Ethernet MAC address in hex form
  */
 enum xt_option_type {
        XTTYPE_NONE,
@@ -95,6 +96,7 @@ enum xt_option_type {
        XTTYPE_PORTRC_NE,
        XTTYPE_PLEN,
        XTTYPE_PLENMASK,
+       XTTYPE_ETHERMAC,
 };
 
 /**
@@ -164,6 +166,7 @@ struct xt_option_call {
                struct {
                        uint32_t mark, mask;
                };
+               uint8_t ethermac[6];
        } val;
        /* Wished for a world where the ones below were gone: */
        union {
index 70370edba7b8997f088996b8755760682b44e070..8d54dd8b3c1a59e3ed3513e9e7e7c2b46a6f3c9a 100644 (file)
@@ -672,6 +672,30 @@ static void xtopt_parse_hostmask(struct xt_option_call *cb)
        cb->arg = orig_arg;
 }
 
+static void xtopt_parse_ethermac(struct xt_option_call *cb)
+{
+       const char *arg = cb->arg;
+       unsigned int i;
+       char *end;
+
+       for (i = 0; i < ARRAY_SIZE(cb->val.ethermac) - 1; ++i) {
+               cb->val.ethermac[i] = strtoul(arg, &end, 16);
+               if (cb->val.ethermac[i] > UINT8_MAX || *end != ':')
+                       goto out;
+               arg = end + 1;
+       }
+       i = ARRAY_SIZE(cb->val.ethermac) - 1;
+       cb->val.ethermac[i] = strtoul(arg, &end, 16);
+       if (cb->val.ethermac[i] > UINT8_MAX || *end != '\0')
+               goto out;
+       if (cb->entry->flags & XTOPT_PUT)
+               memcpy(XTOPT_MKPTR(cb), cb->val.ethermac,
+                      sizeof(cb->val.ethermac));
+       return;
+ out:
+       xt_params->exit_err(PARAMETER_PROBLEM, "ether");
+}
+
 static void (*const xtopt_subparse[])(struct xt_option_call *) = {
        [XTTYPE_UINT8]       = xtopt_parse_int,
        [XTTYPE_UINT16]      = xtopt_parse_int,
@@ -695,6 +719,7 @@ static void (*const xtopt_subparse[])(struct xt_option_call *) = {
        [XTTYPE_PORTRC_NE]   = xtopt_parse_mport,
        [XTTYPE_PLEN]        = xtopt_parse_plen,
        [XTTYPE_PLENMASK]    = xtopt_parse_plenmask,
+       [XTTYPE_ETHERMAC]    = xtopt_parse_ethermac,
 };
 
 static const size_t xtopt_psize[] = {
@@ -721,6 +746,7 @@ static const size_t xtopt_psize[] = {
        [XTTYPE_PORTRC]      = sizeof(uint16_t[2]),
        [XTTYPE_PORTRC_NE]   = sizeof(uint16_t[2]),
        [XTTYPE_PLENMASK]    = sizeof(union nf_inet_addr),
+       [XTTYPE_ETHERMAC]    = sizeof(uint8_t[6]),
 };
 
 /**