fix for f12, gcc4.4
[iptables.git] / extensions / libipt_CONNSECMARK.c
1 /*
2  * Shared library add-on to iptables to add CONNSECMARK target support.
3  *
4  * Based on the MARK and CONNMARK targets.
5  *
6  * Copyright (C) 2006 Red Hat, Inc., James Morris <jmorris@redhat.com>
7  */
8 #include <stdio.h>
9 #include <string.h>
10 #include <stdlib.h>
11 #include <getopt.h>
12 #include <iptables.h>
13 #include <linux/netfilter/xt_CONNSECMARK.h>
14
15 #define PFX "CONNSECMARK target: "
16
17 static void help(void)
18 {
19         printf(
20 "CONNSECMARK target v%s options:\n"
21 "  --save                   Copy security mark from packet to conntrack\n"
22 "  --restore                Copy security mark from connection to packet\n"
23 "\n",
24 IPTABLES_VERSION);
25 }
26
27 static struct option opts[] = {
28         { "save", 0, 0, '1' },
29         { "restore", 0, 0, '2' },
30         { 0 }
31 };
32
33 static int parse(int c, char **argv, int invert, unsigned int *flags,
34                  const struct ipt_entry *entry, struct ipt_entry_target **target)
35 {
36         struct xt_connsecmark_target_info *info =
37                 (struct xt_connsecmark_target_info*)(*target)->data;
38
39         switch (c) {
40         case '1':
41                 if (*flags & CONNSECMARK_SAVE)
42                         exit_error(PARAMETER_PROBLEM, PFX
43                                    "Can't specify --save twice");
44                 info->mode = CONNSECMARK_SAVE;
45                 *flags |= CONNSECMARK_SAVE;
46                 break;
47
48         case '2':
49                 if (*flags & CONNSECMARK_RESTORE)
50                         exit_error(PARAMETER_PROBLEM, PFX
51                                    "Can't specify --restore twice");
52                 info->mode = CONNSECMARK_RESTORE;
53                 *flags |= CONNSECMARK_RESTORE;
54                 break;
55
56         default:
57                 return 0;
58         }
59
60         return 1;
61 }
62
63 static void final_check(unsigned int flags)
64 {
65         if (!flags)
66                 exit_error(PARAMETER_PROBLEM, PFX "parameter required");
67
68         if (flags == (CONNSECMARK_SAVE|CONNSECMARK_RESTORE))
69                 exit_error(PARAMETER_PROBLEM, PFX "only one flag of --save "
70                            "or --restore is allowed");
71 }
72
73 static void print_connsecmark(struct xt_connsecmark_target_info *info)
74 {
75         switch (info->mode) {
76         case CONNSECMARK_SAVE:
77                 printf("save ");
78                 break;
79                 
80         case CONNSECMARK_RESTORE:
81                 printf("restore ");
82                 break;
83                 
84         default:
85                 exit_error(OTHER_PROBLEM, PFX "invalid mode %hhu\n", info->mode);
86         }
87 }
88
89 static void print(const struct ipt_ip *ip,
90                   const struct ipt_entry_target *target, int numeric)
91 {
92         struct xt_connsecmark_target_info *info =
93                 (struct xt_connsecmark_target_info*)(target)->data;
94
95         printf("CONNSECMARK ");
96         print_connsecmark(info);
97 }
98
99 static void save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
100 {
101         struct xt_connsecmark_target_info *info =
102                 (struct xt_connsecmark_target_info*)target->data;
103
104         printf("--");
105         print_connsecmark(info);
106 }
107
108 static struct iptables_target connsecmark = {
109         .next           = NULL,
110         .name           = "CONNSECMARK",
111         .version        = IPTABLES_VERSION,
112         .revision       = 0,
113         .size           = IPT_ALIGN(sizeof(struct xt_connsecmark_target_info)),
114         .userspacesize  = IPT_ALIGN(sizeof(struct xt_connsecmark_target_info)),
115         .parse          = &parse,
116         .help           = &help,
117         .final_check    = &final_check,
118         .print          = &print,
119         .save           = &save,
120         .extra_opts     = opts
121 };
122
123 void _init(void)
124 {
125         register_target(&connsecmark);
126 }