iptables-1.2.9-2.3.1.src.rpm
[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 /* Initialize the match. */
32 static void
33 init(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 */
41 static int
42 parse(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
71 static void
72 print_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. */
84 static void
85 print(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. */
97 static void
98 save(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. */
107 static void
108 final_check(unsigned int flags)
109 {
110         if (!flags)
111                 exit_error(PARAMETER_PROBLEM,
112                            "REALM match: You must specify `--realm'");
113 }
114
115 struct 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
130 void _init(void)
131 {
132         register_match(&realm);
133 }
134
135