1/* 2 3 macsave match (experimental) 4 Copyright (C) 2006 Jonathan Zarate 5 6 Licensed under GNU GPL v2 or later. 7 8*/ 9#include <stdio.h> 10#include <string.h> 11#include <stdlib.h> 12#include <getopt.h> 13 14#include <iptables.h> 15#include <linux/netfilter_ipv4/ipt_macsave.h> 16 17 18static void help(void) 19{ 20 printf( 21 "macsave match (experimental) v0.01\n" 22 "Copyright (C) 2006 Jonathan Zarate\n" 23 "Options:\n" 24 "[!] --mac <mac address>\n"); 25} 26 27static void init(struct ipt_entry_match *m, unsigned int *nfcache) 28{ 29 *nfcache |= NFC_UNKNOWN; 30} 31 32static struct option opts[] = { 33 { .name = "mac", .has_arg = 1, .flag = 0, .val = '1' }, 34 { .name = 0 } 35}; 36 37static int parse(int c, char **argv, int invert, unsigned int *flags, 38 const struct ipt_entry *entry, unsigned int *nfcache, 39 struct ipt_entry_match **match) 40{ 41 struct ipt_macsave_match_info *info; 42 char *mac; 43 long n; 44 int i; 45 46 if (c != '1') return 0; 47 48 if (*flags) exit_error(PARAMETER_PROBLEM, "Multiple MACs are not supported"); 49 *flags = 1; 50 51 info = (struct ipt_macsave_match_info *)(*match)->data; 52 53 check_inverse(optarg, &invert, &optind, 0); 54 if (invert) info->invert = 1; 55 56 mac = argv[optind - 1]; 57 i = 0; 58 while (*mac) { 59 n = strtol(mac, &mac, 16); 60 if ((n < 0) || (n > 255)) break; 61 info->mac[i++] = n; 62 if (i == 6) break; 63 if ((*mac != ':') && (*mac != '-')) exit_error(PARAMETER_PROBLEM, "Invalid MAC address"); 64 ++mac; 65 } 66 if ((i != 6) || (*mac != 0)) exit_error(PARAMETER_PROBLEM, "Invalid MAC address"); 67 return 1; 68} 69 70static void final_check(unsigned int flags) 71{ 72 if (flags != 1) exit_error(PARAMETER_PROBLEM, "--mac expected"); 73} 74 75static void print_match(const struct ipt_macsave_match_info *info) 76{ 77 printf("--mac %02X:%02X:%02X:%02X:%02X:%02X ", 78 info->mac[0], info->mac[1], info->mac[2], 79 info->mac[3], info->mac[4], info->mac[5]); 80} 81 82static void print(const struct ipt_ip *ip, const struct ipt_entry_match *match, int numeric) 83{ 84 printf("macsave "); 85 print_match((const struct ipt_macsave_match_info *)match->data); 86} 87 88static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match) 89{ 90 print_match((const struct ipt_macsave_match_info *)match->data); 91} 92 93 94static struct iptables_match macsave_match = { 95 .name = "macsave", 96 .version = IPTABLES_VERSION, 97 .size = IPT_ALIGN(sizeof(struct ipt_macsave_match_info)), 98 .userspacesize = IPT_ALIGN(sizeof(struct ipt_macsave_match_info)), 99 .help = &help, 100 .init = &init, 101 .parse = &parse, 102 .final_check = &final_check, 103 .print = &print, 104 .save = &save, 105 .extra_opts = opts 106}; 107 108void _init(void) 109{ 110 register_match(&macsave_match); 111} 112