diff options
author | Marc Boucher <marc@mbsi.ca> | 2000-03-20 06:03:29 +0000 |
---|---|---|
committer | Marc Boucher <marc@mbsi.ca> | 2000-03-20 06:03:29 +0000 |
commit | e6869a8f59d779ff4d5a0984c86d80db70784962 (patch) | |
tree | cbaf2a4e3f8249de3967b959a214c27ff5fdee2a /extensions/libipt_mac.c |
reorganized tree after kernel merge
Diffstat (limited to 'extensions/libipt_mac.c')
-rw-r--r-- | extensions/libipt_mac.c | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/extensions/libipt_mac.c b/extensions/libipt_mac.c new file mode 100644 index 00000000..36d89692 --- /dev/null +++ b/extensions/libipt_mac.c @@ -0,0 +1,144 @@ +/* Shared library add-on to iptables to add MAC address support. */ +#include <stdio.h> +#include <netdb.h> +#include <string.h> +#include <stdlib.h> +#include <getopt.h> +#if defined(__GLIBC__) && __GLIBC__ == 2 +#include <net/ethernet.h> +#else +#include <linux/if_ether.h> +#endif +#include <iptables.h> +#include <linux/netfilter_ipv4/ipt_mac.h> + +/* 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", NETFILTER_VERSION); +} + +static struct option opts[] = { + { "mac-source", 1, 0, '1' }, + {0} +}; + +/* Initialize the match. */ +static void +init(struct ipt_entry_match *m, unsigned int *nfcache) +{ + /* Can't cache this */ + *nfcache |= NFC_UNKNOWN; +} + +static void +parse_mac(const char *mac, struct ipt_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 struct ipt_entry *entry, + unsigned int *nfcache, + struct ipt_entry_match **match) +{ + struct ipt_mac_info *macinfo = (struct ipt_mac_info *)(*match)->data; + + switch (c) { + case '1': + if (check_inverse(optarg, &invert)) + optind++; + 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], int invert) +{ + unsigned int i; + + printf("%s%02X", invert ? "!" : "", 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 struct ipt_ip *ip, + const struct ipt_entry_match *match, + int numeric) +{ + printf("MAC "); + print_mac(((struct ipt_mac_info *)match->data)->srcaddr, + ((struct ipt_mac_info *)match->data)->invert); +} + +/* Saves the union ipt_matchinfo in parsable form to stdout. */ +static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match) +{ + printf("--mac "); + print_mac(((struct ipt_mac_info *)match->data)->srcaddr, + ((struct ipt_mac_info *)match->data)->invert); +} + +struct iptables_match mac += { NULL, + "mac", + NETFILTER_VERSION, + sizeof(struct ipt_mac_info), + &help, + &init, + &parse, + &final_check, + &print, + &save, + opts +}; + +void _init(void) +{ + register_match(&mac); +} |