libipt_realm.c revision 8115e5425721cd610b6390c3d4c24540773b0520
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/* Function which parses command options; returns true if it
32   ate an option */
33static int
34parse(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
64static void
65print_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. */
74static void
75print(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. */
90static void
91save(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. */
103static void
104final_check(unsigned int flags)
105{
106	if (!flags)
107		exit_error(PARAMETER_PROBLEM,
108			   "REALM match: You must specify `--realm'");
109}
110
111static 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
124void _init(void)
125{
126	register_match(&realm);
127}
128
129
130