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 54 printf(" MAC"); 55 56 if (info->invert) 57 printf(" !"); 58 59 print_mac(info->srcaddr); 60 } 61 62 static void mac_save(const void *ip, const struct xt_entry_match *match) 63 { 64 const struct xt_mac_info *info = (void *)match->data; 65 66 if (info->invert) 67 printf(" !"); 68 69 printf(" --mac-source"); 70 print_mac(info->srcaddr); 71 } 72 73 static void print_mac_xlate(const unsigned char *macaddress, 74 struct xt_xlate *xl) 75 { 76 unsigned int i; 77 78 xt_xlate_add(xl, "%02x", macaddress[0]); 79 for (i = 1; i < ETH_ALEN; ++i) 80 xt_xlate_add(xl, ":%02x", macaddress[i]); 81 } 82 83 static int mac_xlate(struct xt_xlate *xl, 84 const struct xt_xlate_mt_params *params) 85 { 86 const struct xt_mac_info *info = (void *)params->match->data; 87 88 xt_xlate_add(xl, "ether saddr%s ", info->invert ? " !=" : ""); 89 print_mac_xlate(info->srcaddr, xl); 90 91 return 1; 92 } 93 94 static struct xtables_match mac_match = { 95 .family = NFPROTO_UNSPEC, 96 .name = "mac", 97 .version = XTABLES_VERSION, 98 .size = XT_ALIGN(sizeof(struct xt_mac_info)), 99 .userspacesize = XT_ALIGN(sizeof(struct xt_mac_info)), 100 .help = mac_help, 101 .x6_parse = mac_parse, 102 .print = mac_print, 103 .save = mac_save, 104 .x6_options = mac_opts, 105 .xlate = mac_xlate, 106 }; 107 108 void _init(void) 109 { 110 xtables_register_match(&mac_match); 111 } 112