1#include <stdio.h> 2#if defined(__GLIBC__) && __GLIBC__ == 2 3#include <net/ethernet.h> 4#else 5#include <linux/if_ether.h> 6#endif 7#include <xtables.h> 8#include <linux/netfilter/xt_mac.h> 9 10enum { 11 O_MAC = 0, 12}; 13 14static void mac_help(void) 15{ 16 printf( 17"mac match options:\n" 18"[!] --mac-source XX:XX:XX:XX:XX:XX\n" 19" Match source MAC address\n"); 20} 21 22#define s struct xt_mac_info 23static const struct xt_option_entry mac_opts[] = { 24 {.name = "mac-source", .id = O_MAC, .type = XTTYPE_ETHERMAC, 25 .flags = XTOPT_MAND | XTOPT_INVERT | XTOPT_PUT, 26 XTOPT_POINTER(s, srcaddr)}, 27 XTOPT_TABLEEND, 28}; 29#undef s 30 31static void mac_parse(struct xt_option_call *cb) 32{ 33 struct xt_mac_info *macinfo = cb->data; 34 35 xtables_option_parse(cb); 36 if (cb->invert) 37 macinfo->invert = 1; 38} 39 40static void print_mac(const unsigned char *macaddress) 41{ 42 unsigned int i; 43 44 printf(" %02X", macaddress[0]); 45 for (i = 1; i < ETH_ALEN; ++i) 46 printf(":%02X", macaddress[i]); 47} 48 49static void 50mac_print(const void *ip, const struct xt_entry_match *match, int numeric) 51{ 52 const struct xt_mac_info *info = (void *)match->data; 53 printf(" MAC"); 54 55 if (info->invert) 56 printf(" !"); 57 58 print_mac(info->srcaddr); 59} 60 61static void mac_save(const void *ip, const struct xt_entry_match *match) 62{ 63 const struct xt_mac_info *info = (void *)match->data; 64 65 if (info->invert) 66 printf(" !"); 67 68 printf(" --mac-source"); 69 print_mac(info->srcaddr); 70} 71 72static struct xtables_match mac_match = { 73 .family = NFPROTO_UNSPEC, 74 .name = "mac", 75 .version = XTABLES_VERSION, 76 .size = XT_ALIGN(sizeof(struct xt_mac_info)), 77 .userspacesize = XT_ALIGN(sizeof(struct xt_mac_info)), 78 .help = mac_help, 79 .x6_parse = mac_parse, 80 .print = mac_print, 81 .save = mac_save, 82 .x6_options = mac_opts, 83}; 84 85void _init(void) 86{ 87 xtables_register_match(&mac_match); 88} 89