libipt_realm.c revision 80fe35d6339b53a12ddaec41885613e4e37ed031
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(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
71static void
72print_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. */
84static void
85print(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. */
97static void
98save(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. */
107static void
108final_check(unsigned int flags)
109{
110	if (!flags)
111		exit_error(PARAMETER_PROBLEM,
112			   "REALM match: You must specify `--realm'");
113}
114
115struct 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
130void _init(void)
131{
132	register_match(&realm);
133}
134
135
136