libipt_realm.c revision 8caee8b9e34fed4562fcff553197c161fc9d9979
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(argv[optind], &invert, &optind, 0);
53		optarg = argv[optind-1];
54		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)
76		printf("! ");
77
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
116static 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
128};
129
130void _init(void)
131{
132	register_match(&realm);
133}
134
135
136