blob: 52221821a4a23c216bb6d2690acbeaf1004e606f [file] [log] [blame]
Harald Welte0e81d5d2002-02-25 11:26:01 +00001/* Shared library add-on to iptables to add CONNMARK target support. */
2#include <stdio.h>
3#include <string.h>
4#include <stdlib.h>
5#include <getopt.h>
6
7#include <iptables.h>
8#include <linux/netfilter_ipv4/ip_tables.h>
9#include <linux/netfilter_ipv4/ipt_CONNMARK.h>
10
11#if 0
12struct markinfo {
13 struct ipt_entry_target t;
14 struct ipt_connmark_target_info mark;
15};
16#endif
17
18/* Function which prints out usage message. */
19static void
20help(void)
21{
22 printf(
23"CONNMARK target v%s options:\n"
24" --set-mark value Set conntrack mark value\n"
25" --save-mark Save the packet nfmark on the connection\n"
26" --restore-mark Restore saved nfmark value\n"
27"\n",
Harald Welte80fe35d2002-05-29 13:08:15 +000028IPTABLES_VERSION);
Harald Welte0e81d5d2002-02-25 11:26:01 +000029}
30
31static struct option opts[] = {
32 { "set-mark", 1, 0, '1' },
33 { "save-mark", 0, 0, '2' },
34 { "restore-mark", 0, 0, '3' },
35 { 0 }
36};
37
38/* Initialize the target. */
39static void
40init(struct ipt_entry_target *t, unsigned int *nfcache)
41{
42}
43
44/* Function which parses command options; returns true if it
45 ate an option */
46static int
47parse(int c, char **argv, int invert, unsigned int *flags,
48 const struct ipt_entry *entry,
49 struct ipt_entry_target **target)
50{
51 struct ipt_connmark_target_info *markinfo
52 = (struct ipt_connmark_target_info *)(*target)->data;
53
54 switch (c) {
55 char *end;
56 case '1':
57 markinfo->mode = IPT_CONNMARK_SET;
58 markinfo->mark = strtoul(optarg, &end, 0);
59 if (*end != '\0' || end == optarg)
60 exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
61 if (*flags)
62 exit_error(PARAMETER_PROBLEM,
63 "CONNMARK target: Can't specify --set-mark twice");
64 *flags = 1;
65 break;
66 case '2':
67 markinfo->mode = IPT_CONNMARK_SAVE;
68 if (*flags)
69 exit_error(PARAMETER_PROBLEM,
70 "CONNMARK target: Can't specify --save-mark twice");
71 *flags = 1;
72 break;
73 case '3':
74 markinfo->mode = IPT_CONNMARK_RESTORE;
75 if (*flags)
76 exit_error(PARAMETER_PROBLEM,
77 "CONNMARK target: Can't specify --restore-mark twice");
78 *flags = 1;
79 break;
80 default:
81 return 0;
82 }
83
84 return 1;
85}
86
87static void
88final_check(unsigned int flags)
89{
90 if (!flags)
91 exit_error(PARAMETER_PROBLEM,
92 "CONNMARK target: Parameter --set-mark is required");
93}
94
95static void
96print_mark(unsigned long mark, int numeric)
97{
98 printf("0x%lx ", mark);
99}
100
101/* Prints out the targinfo. */
102static void
103print(const struct ipt_ip *ip,
104 const struct ipt_entry_target *target,
105 int numeric)
106{
107 const struct ipt_connmark_target_info *markinfo =
108 (const struct ipt_connmark_target_info *)target->data;
109 switch (markinfo->mode) {
110 case IPT_CONNMARK_SET:
111 printf("CONNMARK set ");
112 print_mark(markinfo->mark, numeric);
113 break;
114 case IPT_CONNMARK_SAVE:
115 printf("CONNMARK save ");
116 break;
117 case IPT_CONNMARK_RESTORE:
118 printf("CONNMARK restore ");
119 break;
120 default:
121 printf("ERROR: UNKNOWN CONNMARK MODE ");
122 break;
123 }
124}
125
126/* Saves the union ipt_targinfo in parsable form to stdout. */
127static void
128save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
129{
130 const struct ipt_connmark_target_info *markinfo =
131 (const struct ipt_connmark_target_info *)target->data;
132
133 switch (markinfo->mode) {
134 case IPT_CONNMARK_SET:
135 printf("--set-mark 0x%lx ", markinfo->mark);
136 break;
137 case IPT_CONNMARK_SAVE:
138 printf("--save-mark ");
139 break;
140 case IPT_CONNMARK_RESTORE:
141 printf("--restore-mark ");
142 break;
143 default:
144 printf("ERROR: UNKNOWN CONNMARK MODE ");
145 break;
146 }
147}
148
Harald Weltecff123a2002-06-04 07:46:30 +0000149static
Harald Welte0e81d5d2002-02-25 11:26:01 +0000150struct iptables_target mark
151= { NULL,
152 "CONNMARK",
Harald Welte80fe35d2002-05-29 13:08:15 +0000153 IPTABLES_VERSION,
Harald Welte0e81d5d2002-02-25 11:26:01 +0000154 IPT_ALIGN(sizeof(struct ipt_connmark_target_info)),
155 IPT_ALIGN(sizeof(struct ipt_connmark_target_info)),
156 &help,
157 &init,
158 &parse,
159 &final_check,
160 &print,
161 &save,
162 opts
163};
164
165void _init(void)
166{
167 register_target(&mark);
168}