iptables-1.2.9-2.3.1.src.rpm
[iptables.git] / extensions / libip6t_condition.c
1 /* Shared library add-on to ip6tables for condition match */
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <getopt.h>
6 #include <ip6tables.h>
7
8 #include<linux/netfilter_ipv6/ip6_tables.h>
9 #include<linux/netfilter_ipv6/ip6t_condition.h>
10
11
12 static void
13 help(void)
14 {
15         printf("condition match v%s options:\n"
16                "--condition [!] filename       "
17                "Match on boolean value stored in /proc file\n",
18                IPTABLES_VERSION);
19 }
20
21
22 static struct option opts[] = {
23         { .name = "condition", .has_arg = 1, .flag = 0, .val = 'X' },
24         { .name = 0 }
25 };
26
27
28 static void
29 init(struct ip6t_entry_match *m, unsigned int *nfcache)
30 {
31         *nfcache |= NFC_UNKNOWN;
32 }
33
34
35 static int
36 parse(int c, char **argv, int invert, unsigned int *flags,
37       const struct ip6t_entry *entry, unsigned int *nfcache,
38       struct ip6t_entry_match **match)
39 {
40         struct condition6_info *info =
41             (struct condition6_info *) (*match)->data;
42
43         if (c == 'X') {
44                 if (*flags)
45                         exit_error(PARAMETER_PROBLEM,
46                                    "Can't specify multiple conditions");
47
48                 check_inverse(optarg, &invert, &optind, 0);
49
50                 if (strlen(argv[optind - 1]) < CONDITION6_NAME_LEN)
51                         strcpy(info->name, argv[optind - 1]);
52                 else
53                         exit_error(PARAMETER_PROBLEM,
54                                    "File name too long");
55
56                 info->invert = invert;
57                 *flags = 1;
58                 return 1;
59         }
60
61         return 0;
62 }
63
64
65 static void
66 final_check(unsigned int flags)
67 {
68         if (!flags)
69                 exit_error(PARAMETER_PROBLEM,
70                            "Condition match: must specify --condition");
71 }
72
73
74 static void
75 print(const struct ip6t_ip6 *ip,
76                   const struct ip6t_entry_match *match, int numeric)
77 {
78         const struct condition6_info *info =
79             (const struct condition6_info *) match->data;
80
81         printf("condition %s%s ", (info->invert) ? "!" : "", info->name);
82 }
83
84
85 static void
86 save(const struct ip6t_ip6 *ip,
87                  const struct ip6t_entry_match *match)
88 {
89         const struct condition6_info *info =
90             (const struct condition6_info *) match->data;
91
92         printf("--condition %s\"%s\" ", (info->invert) ? "! " : "", info->name);
93 }
94
95
96 static struct ip6tables_match condition = {
97         .name = "condition",
98         .version = IPTABLES_VERSION,
99         .size = IP6T_ALIGN(sizeof(struct condition6_info)),
100         .userspacesize = IP6T_ALIGN(sizeof(struct condition6_info)),
101         .help = &help,
102         .init = &init,
103         .parse = &parse,
104         .final_check = &final_check,
105         .print = &print,
106         .save = &save,
107         .extra_opts = opts
108 };
109
110
111 void
112 _init(void)
113 {
114         register_match6(&condition);
115 }