libipt_realm.c revision 4066ee9e891e1d482cb90fb7c47213bfa6f3fb5b
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
116struct iptables_match realm
117= { NULL,
118    "realm",
119    IPTABLES_VERSION,
120    IPT_ALIGN(sizeof(struct ipt_realm_info)),
121    IPT_ALIGN(sizeof(struct ipt_realm_info)),
122    &help,
123    &init,
124    &parse,
125    &final_check,
126    &print,
127    &save,
128    opts
129};
130
131void _init(void)
132{
133	register_match(&realm);
134}
135
136
137