@@ -12,6 +12,7 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
+#include <netinet/ether.h>
#include <netinet/in.h>
#include <net/if.h>
#include <linux/types.h>
@@ -68,6 +69,7 @@ struct in_addr;
* %XTTYPE_PLEN: prefix length
* %XTTYPE_PLENMASK: prefix length (ptr: union nf_inet_addr)
* %XTTYPE_ETHERMAC: Ethernet MAC address in hex form
+ * %XTTYPE_ETHERMACMASK: Ethernet MAC address in hex form with optional mask
*/
enum xt_option_type {
XTTYPE_NONE,
@@ -92,6 +94,7 @@ enum xt_option_type {
XTTYPE_PLEN,
XTTYPE_PLENMASK,
XTTYPE_ETHERMAC,
+ XTTYPE_ETHERMACMASK,
};
/**
@@ -167,7 +170,9 @@ struct xt_option_call {
struct {
uint32_t mark, mask;
};
- uint8_t ethermac[6];
+ struct {
+ uint8_t ethermac[ETH_ALEN], ethermacmask[ETH_ALEN];
+ };
} val;
/* Wished for a world where the ones below were gone: */
union {
@@ -791,6 +791,15 @@ static void xtopt_parse_ethermac(struct xt_option_call *cb)
xt_params->exit_err(PARAMETER_PROBLEM, "Invalid MAC address specified.");
}
+static void xtopt_parse_ethermacmask(struct xt_option_call *cb)
+{
+ memset(cb->val.ethermacmask, 0xff, ETH_ALEN);
+ if (xtables_parse_mac_and_mask(cb->arg, cb->val.ethermac,
+ cb->val.ethermacmask))
+ xt_params->exit_err(PARAMETER_PROBLEM,
+ "Invalid MAC/mask address specified.");
+}
+
static void (*const xtopt_subparse[])(struct xt_option_call *) = {
[XTTYPE_UINT8] = xtopt_parse_int,
[XTTYPE_UINT16] = xtopt_parse_int,
@@ -813,6 +822,7 @@ static void (*const xtopt_subparse[])(struct xt_option_call *) = {
[XTTYPE_PLEN] = xtopt_parse_plen,
[XTTYPE_PLENMASK] = xtopt_parse_plenmask,
[XTTYPE_ETHERMAC] = xtopt_parse_ethermac,
+ [XTTYPE_ETHERMACMASK]= xtopt_parse_ethermacmask,
};
/**
Accept an Ethernet MAC address with optional mask in the format xtables_parse_mac_and_mask() expects it. Does not support XTOPT_PUT (for now) due to the lack of defined data structure. Signed-off-by: Phil Sutter <phil@nwl.cc> --- include/xtables.h | 7 ++++++- libxtables/xtoptions.c | 10 ++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-)