iptables-1.3.2-20050720
[iptables.git] / extensions / libipt_realm.c
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. */
16 static void
17 help(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
26 static struct option opts[] = {
27         { "realm", 1, 0, '1' },
28         {0}
29 };
30
31 /* Function which parses command options; returns true if it
32    ate an option */
33 static int
34 parse(int c, char **argv, int invert, unsigned int *flags,
35       const struct ipt_entry *entry,
36       unsigned int *nfcache,
37       struct ipt_entry_match **match)
38 {
39         struct ipt_realm_info *realminfo = (struct ipt_realm_info *)(*match)->data;
40
41         switch (c) {
42                 char *end;
43         case '1':
44                 check_inverse(argv[optind-1], &invert, &optind, 0);
45                 optarg = argv[optind-1];
46                 realminfo->id = strtoul(optarg, &end, 0);
47                 if (*end == '/') {
48                         realminfo->mask = strtoul(end+1, &end, 0);
49                 } else
50                         realminfo->mask = 0xffffffff;
51                 if (*end != '\0' || end == optarg)
52                         exit_error(PARAMETER_PROBLEM, "Bad REALM value `%s'", optarg);
53                 if (invert)
54                         realminfo->invert = 1;
55                 *flags = 1;
56                 break;
57
58         default:
59                 return 0;
60         }
61         return 1;
62 }
63
64 static void
65 print_realm(unsigned long id, unsigned long mask)
66 {
67         if (mask != 0xffffffff)
68                 printf("0x%lx/0x%lx ", id, mask);
69         else
70                 printf("0x%lx ", id);
71 }
72
73 /* Prints out the matchinfo. */
74 static void
75 print(const struct ipt_ip *ip,
76       const struct ipt_entry_match *match,
77       int numeric)
78 {
79         struct ipt_realm_info *ri = (struct ipt_realm_info *) match->data;
80
81         if (ri->invert)
82                 printf("! ");
83
84         printf("REALM match ");
85         print_realm(ri->id, ri->mask);
86 }
87
88
89 /* Saves the union ipt_matchinfo in parsable form to stdout. */
90 static void
91 save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
92 {
93         struct ipt_realm_info *ri = (struct ipt_realm_info *) match->data;
94
95         if (ri->invert)
96                 printf("! ");
97
98         printf("--realm ");
99         print_realm(ri->id, ri->mask);
100 }
101
102 /* Final check; must have specified --mark. */
103 static void
104 final_check(unsigned int flags)
105 {
106         if (!flags)
107                 exit_error(PARAMETER_PROBLEM,
108                            "REALM match: You must specify `--realm'");
109 }
110
111 static struct iptables_match realm = { NULL,
112         .name           = "realm",
113         .version        = IPTABLES_VERSION,
114         .size           = IPT_ALIGN(sizeof(struct ipt_realm_info)),
115         .userspacesize  = IPT_ALIGN(sizeof(struct ipt_realm_info)),
116         .help           = &help,
117         .parse          = &parse,
118         .final_check    = &final_check,
119         .print          = &print,
120         .save           = &save,
121         .extra_opts     = opts
122 };
123
124 void _init(void)
125 {
126         register_match(&realm);
127 }
128
129