libxt_mac.c revision 967279231a9ecfa99f26694a954afc535c63db1d
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 15/* Function which prints out usage message. */ 16static void mac_help(void) 17{ 18 printf( 19"mac match options:\n" 20"[!] --mac-source XX:XX:XX:XX:XX:XX\n" 21" Match source MAC address\n"); 22} 23 24static const struct option mac_opts[] = { 25 { "mac-source", 1, NULL, '1' }, 26 { .name = NULL } 27}; 28 29static void 30parse_mac(const char *mac, struct xt_mac_info *info) 31{ 32 unsigned int i = 0; 33 34 if (strlen(mac) != ETH_ALEN*3-1) 35 exit_error(PARAMETER_PROBLEM, "Bad mac address `%s'", mac); 36 37 for (i = 0; i < ETH_ALEN; i++) { 38 long number; 39 char *end; 40 41 number = strtol(mac + i*3, &end, 16); 42 43 if (end == mac + i*3 + 2 44 && number >= 0 45 && number <= 255) 46 info->srcaddr[i] = number; 47 else 48 exit_error(PARAMETER_PROBLEM, 49 "Bad mac address `%s'", mac); 50 } 51} 52 53/* Function which parses command options; returns true if it 54 ate an option */ 55static int 56mac_parse(int c, char **argv, int invert, unsigned int *flags, 57 const void *entry, struct xt_entry_match **match) 58{ 59 struct xt_mac_info *macinfo = (struct xt_mac_info *)(*match)->data; 60 61 switch (c) { 62 case '1': 63 check_inverse(optarg, &invert, &optind, 0); 64 parse_mac(argv[optind-1], macinfo); 65 if (invert) 66 macinfo->invert = 1; 67 *flags = 1; 68 break; 69 70 default: 71 return 0; 72 } 73 74 return 1; 75} 76 77static void print_mac(unsigned char macaddress[ETH_ALEN]) 78{ 79 unsigned int i; 80 81 printf("%02X", macaddress[0]); 82 for (i = 1; i < ETH_ALEN; i++) 83 printf(":%02X", macaddress[i]); 84 printf(" "); 85} 86 87/* Final check; must have specified --mac. */ 88static void mac_check(unsigned int flags) 89{ 90 if (!flags) 91 exit_error(PARAMETER_PROBLEM, 92 "You must specify `--mac-source'"); 93} 94 95/* Prints out the matchinfo. */ 96static void 97mac_print(const void *ip, const struct xt_entry_match *match, int numeric) 98{ 99 printf("MAC "); 100 101 if (((struct xt_mac_info *)match->data)->invert) 102 printf("! "); 103 104 print_mac(((struct xt_mac_info *)match->data)->srcaddr); 105} 106 107/* Saves the union ipt_matchinfo in parsable form to stdout. */ 108static void mac_save(const void *ip, const struct xt_entry_match *match) 109{ 110 if (((struct xt_mac_info *)match->data)->invert) 111 printf("! "); 112 113 printf("--mac-source "); 114 print_mac(((struct xt_mac_info *)match->data)->srcaddr); 115} 116 117static struct xtables_match mac_match = { 118 .family = AF_INET, 119 .name = "mac", 120 .version = XTABLES_VERSION, 121 .size = XT_ALIGN(sizeof(struct xt_mac_info)), 122 .userspacesize = XT_ALIGN(sizeof(struct xt_mac_info)), 123 .help = mac_help, 124 .parse = mac_parse, 125 .final_check = mac_check, 126 .print = mac_print, 127 .save = mac_save, 128 .extra_opts = mac_opts, 129}; 130 131static struct xtables_match mac_match6 = { 132 .family = AF_INET6, 133 .name = "mac", 134 .version = XTABLES_VERSION, 135 .size = XT_ALIGN(sizeof(struct xt_mac_info)), 136 .userspacesize = XT_ALIGN(sizeof(struct xt_mac_info)), 137 .help = mac_help, 138 .parse = mac_parse, 139 .final_check = mac_check, 140 .print = mac_print, 141 .save = mac_save, 142 .extra_opts = mac_opts, 143}; 144 145void _init(void) 146{ 147 xtables_register_match(&mac_match); 148 xtables_register_match(&mac_match6); 149} 150