blob: c8b4f8f7eb500a4e12806a4356c28b48f4fb8023 [file] [log] [blame]
Harald Welte2e2d3f32001-09-02 15:34:18 +00001/* Shared library add-on to iptables to add realm matching support. */
Sampsa Rantad6aa9662001-07-30 13:30:14 +00002#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"
Harald Welte80fe35d2002-05-29 13:08:15 +000023"\n", IPTABLES_VERSION);
Sampsa Rantad6aa9662001-07-30 13:30:14 +000024}
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':
Simon Lodal4066ee92004-09-22 01:57:41 +000052 check_inverse(argv[optind], &invert, &optind, 0);
53 optarg = argv[optind-1];
Sampsa Rantad6aa9662001-07-30 13:30:14 +000054 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)
Simon Lodal4066ee92004-09-22 01:57:41 +000076 printf("! ");
Sampsa Rantad6aa9662001-07-30 13:30:14 +000077
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
Pablo Neira8caee8b2004-12-28 13:11:59 +0000116static struct iptables_match realm = { NULL,
117 .name = "realm",
118 .version = IPTABLES_VERSION,
119 .size = IPT_ALIGN(sizeof(struct ipt_realm_info)),
120 .userspacesize = IPT_ALIGN(sizeof(struct ipt_realm_info)),
121 .help = &help,
122 .init = &init,
123 .parse = &parse,
124 .final_check = &final_check,
125 .print = &print,
126 .save = &save,
127 .extra_opts = opts
Sampsa Rantad6aa9662001-07-30 13:30:14 +0000128};
129
130void _init(void)
131{
132 register_match(&realm);
133}
134
135