libxt_mac.c revision bbe83862a5e1baf15f7c923352d4afdf59bc70e2
1/* Shared library add-on to iptables to add MAC address support. */ 2#include <stdio.h> 3#include <netdb.h> 4#include <string.h> 5#include <stdlib.h> 6#include <getopt.h> 7#if defined(__GLIBC__) && __GLIBC__ == 2 8#include <net/ethernet.h> 9#else 10#include <linux/if_ether.h> 11#endif 12#include <xtables.h> 13#include <linux/netfilter/xt_mac.h> 14 15static void mac_help(void) 16{ 17 printf( 18"mac match options:\n" 19"[!] --mac-source XX:XX:XX:XX:XX:XX\n" 20" Match source MAC address\n"); 21} 22 23static const struct option mac_opts[] = { 24 { "mac-source", 1, NULL, '1' }, 25 { .name = NULL } 26}; 27 28static void 29parse_mac(const char *mac, struct xt_mac_info *info) 30{ 31 unsigned int i = 0; 32 33 if (strlen(mac) != ETH_ALEN*3-1) 34 xtables_error(PARAMETER_PROBLEM, "Bad mac address \"%s\"", mac); 35 36 for (i = 0; i < ETH_ALEN; i++) { 37 long number; 38 char *end; 39 40 number = strtol(mac + i*3, &end, 16); 41 42 if (end == mac + i*3 + 2 43 && number >= 0 44 && number <= 255) 45 info->srcaddr[i] = number; 46 else 47 xtables_error(PARAMETER_PROBLEM, 48 "Bad mac address `%s'", mac); 49 } 50} 51 52static int 53mac_parse(int c, char **argv, int invert, unsigned int *flags, 54 const void *entry, struct xt_entry_match **match) 55{ 56 struct xt_mac_info *macinfo = (struct xt_mac_info *)(*match)->data; 57 58 switch (c) { 59 case '1': 60 xtables_check_inverse(optarg, &invert, &optind, 0, argv); 61 parse_mac(optarg, macinfo); 62 if (invert) 63 macinfo->invert = 1; 64 *flags = 1; 65 break; 66 67 default: 68 return 0; 69 } 70 71 return 1; 72} 73 74static void print_mac(const unsigned char macaddress[ETH_ALEN]) 75{ 76 unsigned int i; 77 78 printf("%02X", macaddress[0]); 79 for (i = 1; i < ETH_ALEN; i++) 80 printf(":%02X", macaddress[i]); 81 printf(" "); 82} 83 84static void mac_check(unsigned int flags) 85{ 86 if (!flags) 87 xtables_error(PARAMETER_PROBLEM, 88 "You must specify `--mac-source'"); 89} 90 91static void 92mac_print(const void *ip, const struct xt_entry_match *match, int numeric) 93{ 94 const struct xt_mac_info *info = (void *)match->data; 95 printf("MAC "); 96 97 if (info->invert) 98 printf("! "); 99 100 print_mac(info->srcaddr); 101} 102 103static void mac_save(const void *ip, const struct xt_entry_match *match) 104{ 105 const struct xt_mac_info *info = (void *)match->data; 106 107 if (info->invert) 108 printf("! "); 109 110 printf("--mac-source "); 111 print_mac(info->srcaddr); 112} 113 114static struct xtables_match mac_match = { 115 .family = NFPROTO_UNSPEC, 116 .name = "mac", 117 .version = XTABLES_VERSION, 118 .size = XT_ALIGN(sizeof(struct xt_mac_info)), 119 .userspacesize = XT_ALIGN(sizeof(struct xt_mac_info)), 120 .help = mac_help, 121 .parse = mac_parse, 122 .final_check = mac_check, 123 .print = mac_print, 124 .save = mac_save, 125 .extra_opts = mac_opts, 126}; 127 128void _init(void) 129{ 130 xtables_register_match(&mac_match); 131} 132