From ba2d891523121b651be54a4ce915bcee33d2ed38 Mon Sep 17 00:00:00 2001 From: Yasuyuki KOZAKAI Date: Tue, 24 Jul 2007 07:09:51 +0000 Subject: Unifies libip[6]t_mac.c into libxt_mac.c --- extensions/libxt_mac.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 extensions/libxt_mac.c (limited to 'extensions/libxt_mac.c') diff --git a/extensions/libxt_mac.c b/extensions/libxt_mac.c new file mode 100644 index 00000000..61da13bd --- /dev/null +++ b/extensions/libxt_mac.c @@ -0,0 +1,157 @@ +/* Shared library add-on to iptables to add MAC address support. */ +#include +#include +#include +#include +#include +#if defined(__GLIBC__) && __GLIBC__ == 2 +#include +#else +#include +#endif +#include +#include + +/* Function which prints out usage message. */ +static void +help(void) +{ + printf( +"MAC v%s options:\n" +" --mac-source [!] XX:XX:XX:XX:XX:XX\n" +" Match source MAC address\n" +"\n", IPTABLES_VERSION); +} + +static struct option opts[] = { + { "mac-source", 1, 0, '1' }, + {0} +}; + +static void +parse_mac(const char *mac, struct xt_mac_info *info) +{ + unsigned int i = 0; + + if (strlen(mac) != ETH_ALEN*3-1) + exit_error(PARAMETER_PROBLEM, "Bad mac address `%s'", mac); + + for (i = 0; i < ETH_ALEN; i++) { + long number; + char *end; + + number = strtol(mac + i*3, &end, 16); + + if (end == mac + i*3 + 2 + && number >= 0 + && number <= 255) + info->srcaddr[i] = number; + else + exit_error(PARAMETER_PROBLEM, + "Bad mac address `%s'", mac); + } +} + +/* Function which parses command options; returns true if it + ate an option */ +static int +parse(int c, char **argv, int invert, unsigned int *flags, + const void *entry, + unsigned int *nfcache, + struct xt_entry_match **match) +{ + struct xt_mac_info *macinfo = (struct xt_mac_info *)(*match)->data; + + switch (c) { + case '1': + check_inverse(optarg, &invert, &optind, 0); + parse_mac(argv[optind-1], macinfo); + if (invert) + macinfo->invert = 1; + *flags = 1; + break; + + default: + return 0; + } + + return 1; +} + +static void print_mac(unsigned char macaddress[ETH_ALEN]) +{ + unsigned int i; + + printf("%02X", macaddress[0]); + for (i = 1; i < ETH_ALEN; i++) + printf(":%02X", macaddress[i]); + printf(" "); +} + +/* Final check; must have specified --mac. */ +static void final_check(unsigned int flags) +{ + if (!flags) + exit_error(PARAMETER_PROBLEM, + "You must specify `--mac-source'"); +} + +/* Prints out the matchinfo. */ +static void +print(const void *ip, + const struct xt_entry_match *match, + int numeric) +{ + printf("MAC "); + + if (((struct xt_mac_info *)match->data)->invert) + printf("! "); + + print_mac(((struct xt_mac_info *)match->data)->srcaddr); +} + +/* Saves the union ipt_matchinfo in parsable form to stdout. */ +static void save(const void *ip, const struct xt_entry_match *match) +{ + if (((struct xt_mac_info *)match->data)->invert) + printf("! "); + + printf("--mac-source "); + print_mac(((struct xt_mac_info *)match->data)->srcaddr); +} + +static struct xtables_match mac = { + .next = NULL, + .family = AF_INET, + .name = "mac", + .version = IPTABLES_VERSION, + .size = XT_ALIGN(sizeof(struct xt_mac_info)), + .userspacesize = XT_ALIGN(sizeof(struct xt_mac_info)), + .help = &help, + .parse = &parse, + .final_check = &final_check, + .print = &print, + .save = &save, + .extra_opts = opts +}; + +static struct xtables_match mac6 = { + .next = NULL, + .family = AF_INET6, + .name = "mac", + .version = IPTABLES_VERSION, + .size = XT_ALIGN(sizeof(struct xt_mac_info)), + .userspacesize = XT_ALIGN(sizeof(struct xt_mac_info)), + .help = &help, + .parse = &parse, + .final_check = &final_check, + .print = &print, + .save = &save, + .extra_opts = opts +}; + +void _init(void) +{ + xtables_register_match(&mac); + xtables_register_match(&mac6); +} -- cgit v1.2.3