libipt_realm.c revision 80fe35d6339b53a12ddaec41885613e4e37ed031
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", IPTABLES_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 check_inverse(optarg, &invert, &optind, 0); 53 realminfo->id = strtoul(optarg, &end, 0); 54 if (*end == '/') { 55 realminfo->mask = strtoul(end+1, &end, 0); 56 } else 57 realminfo->mask = 0xffffffff; 58 if (*end != '\0' || end == optarg) 59 exit_error(PARAMETER_PROBLEM, "Bad REALM value `%s'", optarg); 60 if (invert) 61 realminfo->invert = 1; 62 *flags = 1; 63 break; 64 65 default: 66 return 0; 67 } 68 return 1; 69} 70 71static void 72print_realm(unsigned long id, unsigned long mask, int invert, int numeric) 73{ 74 if (invert) 75 fputc('!', stdout); 76 77 if(mask != 0xffffffff) 78 printf("0x%lx/0x%lx ", id, mask); 79 else 80 printf("0x%lx ", id); 81} 82 83/* Prints out the matchinfo. */ 84static void 85print(const struct ipt_ip *ip, 86 const struct ipt_entry_match *match, 87 int numeric) 88{ 89 printf("REALM match "); 90 print_realm(((struct ipt_realm_info *)match->data)->id, 91 ((struct ipt_realm_info *)match->data)->mask, 92 ((struct ipt_realm_info *)match->data)->invert, numeric); 93} 94 95 96/* Saves the union ipt_matchinfo in parsable form to stdout. */ 97static void 98save(const struct ipt_ip *ip, const struct ipt_entry_match *match) 99{ 100 printf("--realm "); 101 print_realm(((struct ipt_realm_info *)match->data)->id, 102 ((struct ipt_realm_info *)match->data)->mask, 103 ((struct ipt_realm_info *)match->data)->invert, 0); 104} 105 106/* Final check; must have specified --mark. */ 107static void 108final_check(unsigned int flags) 109{ 110 if (!flags) 111 exit_error(PARAMETER_PROBLEM, 112 "REALM match: You must specify `--realm'"); 113} 114 115struct iptables_match realm 116= { NULL, 117 "realm", 118 IPTABLES_VERSION, 119 IPT_ALIGN(sizeof(struct ipt_realm_info)), 120 IPT_ALIGN(sizeof(struct ipt_realm_info)), 121 &help, 122 &init, 123 &parse, 124 &final_check, 125 &print, 126 &save, 127 opts 128}; 129 130void _init(void) 131{ 132 register_match(&realm); 133} 134 135 136