libipt_realm.c revision 2e2d3f394f40ef4ac9f213652b2976e0911cb05c
1/* Shared library add-on to iptables to add realm matching 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 <iptables.h> 13#include <linux/netfilter_ipv4/ipt_realm.h> 14 15/* Function which prints out usage message. */ 16static void 17help(void) 18{ 19 printf( 20"REALM v%s options:\n" 21" --realm [!] value[/mask]\n" 22" Match realm\n" 23"\n", NETFILTER_VERSION); 24} 25 26static struct option opts[] = { 27 { "realm", 1, 0, '1' }, 28 {0} 29}; 30 31/* Initialize the match. */ 32static void 33init(struct ipt_entry_match *m, unsigned int *nfcache) 34{ 35 /* Can't cache this */ 36 *nfcache |= NFC_UNKNOWN; 37} 38 39/* Function which parses command options; returns true if it 40 ate an option */ 41static int 42parse(int c, char **argv, int invert, unsigned int *flags, 43 const struct ipt_entry *entry, 44 unsigned int *nfcache, 45 struct ipt_entry_match **match) 46{ 47 struct ipt_realm_info *realminfo = (struct ipt_realm_info *)(*match)->data; 48 49 switch (c) { 50 char *end; 51 case '1': 52 if (check_inverse(optarg, &invert)) 53 optind++; 54 realminfo->id = strtoul(optarg, &end, 0); 55 if (*end == '/') { 56 realminfo->mask = strtoul(end+1, &end, 0); 57 } else 58 realminfo->mask = 0xffffffff; 59 if (*end != '\0' || end == optarg) 60 exit_error(PARAMETER_PROBLEM, "Bad REALM value `%s'", optarg); 61 if (invert) 62 realminfo->invert = 1; 63 *flags = 1; 64 break; 65 66 default: 67 return 0; 68 } 69 return 1; 70} 71 72static void 73print_realm(unsigned long id, unsigned long mask, int invert, int numeric) 74{ 75 if (invert) 76 fputc('!', stdout); 77 78 if(mask != 0xffffffff) 79 printf("0x%lx/0x%lx ", id, mask); 80 else 81 printf("0x%lx ", id); 82} 83 84/* Prints out the matchinfo. */ 85static void 86print(const struct ipt_ip *ip, 87 const struct ipt_entry_match *match, 88 int numeric) 89{ 90 printf("REALM match "); 91 print_realm(((struct ipt_realm_info *)match->data)->id, 92 ((struct ipt_realm_info *)match->data)->mask, 93 ((struct ipt_realm_info *)match->data)->invert, numeric); 94} 95 96 97/* Saves the union ipt_matchinfo in parsable form to stdout. */ 98static void 99save(const struct ipt_ip *ip, const struct ipt_entry_match *match) 100{ 101 printf("--realm "); 102 print_realm(((struct ipt_realm_info *)match->data)->id, 103 ((struct ipt_realm_info *)match->data)->mask, 104 ((struct ipt_realm_info *)match->data)->invert, 0); 105} 106 107/* Final check; must have specified --mark. */ 108static void 109final_check(unsigned int flags) 110{ 111 if (!flags) 112 exit_error(PARAMETER_PROBLEM, 113 "REALM match: You must specify `--realm'"); 114} 115 116struct iptables_match realm 117= { NULL, 118 "realm", 119 NETFILTER_VERSION, 120 IPT_ALIGN(sizeof(struct ipt_realm_info)), 121 IPT_ALIGN(sizeof(struct ipt_realm_info)), 122 &help, 123 &init, 124 &parse, 125 &final_check, 126 &print, 127 &save, 128 opts 129}; 130 131void _init(void) 132{ 133 register_match(&realm); 134} 135 136 137