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 10 enum { 11 O_MAC = 0, 12 }; 13 14 static 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 23 static 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 31 static 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 40 static 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 49 static void 50 mac_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 61 static 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 72 static 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 85 void _init(void) 86 { 87 xtables_register_match(&mac_match); 88 } 89