blob: b8413522e9fcb12d80fd06464301d63729d57aff [file] [log] [blame]
Marc Bouchere6869a82000-03-20 06:03:29 +00001/* Shared library add-on to iptables to add MARK 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>
Martin Josefssonc5617bf2004-05-26 21:56:26 +00009/* For 64bit kernel / 32bit userspace */
10#include "../include/linux/netfilter_ipv4/ipt_MARK.h"
Marc Bouchere6869a82000-03-20 06:03:29 +000011
Marc Bouchere6869a82000-03-20 06:03:29 +000012/* Function which prints out usage message. */
13static void
14help(void)
15{
16 printf(
17"MARK target v%s options:\n"
18" --set-mark value Set nfmark value\n"
Rusty Russell3aef54d2005-01-03 03:48:40 +000019" --and-mark value Binary AND the nfmark with value\n"
20" --or-mark value Binary OR the nfmark with value\n"
Marc Bouchere6869a82000-03-20 06:03:29 +000021"\n",
Harald Welte80fe35d2002-05-29 13:08:15 +000022IPTABLES_VERSION);
Marc Bouchere6869a82000-03-20 06:03:29 +000023}
24
25static struct option opts[] = {
26 { "set-mark", 1, 0, '1' },
Rusty Russell3aef54d2005-01-03 03:48:40 +000027 { "and-mark", 1, 0, '2' },
28 { "or-mark", 1, 0, '3' },
Marc Bouchere6869a82000-03-20 06:03:29 +000029 { 0 }
30};
31
32/* Initialize the target. */
33static void
34init(struct ipt_entry_target *t, unsigned int *nfcache)
35{
36}
37
38/* Function which parses command options; returns true if it
39 ate an option */
40static int
Rusty Russell3aef54d2005-01-03 03:48:40 +000041parse_v0(int c, char **argv, int invert, unsigned int *flags,
42 const struct ipt_entry *entry,
43 struct ipt_entry_target **target)
Marc Bouchere6869a82000-03-20 06:03:29 +000044{
45 struct ipt_mark_target_info *markinfo
46 = (struct ipt_mark_target_info *)(*target)->data;
47
48 switch (c) {
Marc Bouchere6869a82000-03-20 06:03:29 +000049 case '1':
Martin Josefssonc5617bf2004-05-26 21:56:26 +000050 if (string_to_number_l(optarg, 0, 0,
51 &markinfo->mark))
Marc Bouchere6869a82000-03-20 06:03:29 +000052 exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
53 if (*flags)
54 exit_error(PARAMETER_PROBLEM,
55 "MARK target: Can't specify --set-mark twice");
56 *flags = 1;
57 break;
Rusty Russell3aef54d2005-01-03 03:48:40 +000058 case '2':
59 exit_error(PARAMETER_PROBLEM,
60 "MARK target: kernel too old for --and-mark");
61 case '3':
62 exit_error(PARAMETER_PROBLEM,
63 "MARK target: kernel too old for --or-mark");
Marc Bouchere6869a82000-03-20 06:03:29 +000064 default:
65 return 0;
66 }
67
68 return 1;
69}
70
71static void
72final_check(unsigned int flags)
73{
74 if (!flags)
75 exit_error(PARAMETER_PROBLEM,
Rusty Russell3aef54d2005-01-03 03:48:40 +000076 "MARK target: Parameter --set/and/or-mark"
77 " is required");
78}
79
80/* Function which parses command options; returns true if it
81 ate an option */
82static int
83parse_v1(int c, char **argv, int invert, unsigned int *flags,
84 const struct ipt_entry *entry,
85 struct ipt_entry_target **target)
86{
87 struct ipt_mark_target_info_v1 *markinfo
88 = (struct ipt_mark_target_info_v1 *)(*target)->data;
89
90 switch (c) {
91 case '1':
92 markinfo->mode = IPT_MARK_SET;
93 break;
94 case '2':
95 markinfo->mode = IPT_MARK_AND;
96 break;
97 case '3':
98 markinfo->mode = IPT_MARK_OR;
99 break;
100 default:
101 return 0;
102 }
103
Rusty Russell3aef54d2005-01-03 03:48:40 +0000104 if (string_to_number_l(optarg, 0, 0, &markinfo->mark))
Rusty Russell3aef54d2005-01-03 03:48:40 +0000105 exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
106
107 if (*flags)
108 exit_error(PARAMETER_PROBLEM,
109 "MARK target: Can't specify --set-mark twice");
110
111 *flags = 1;
112 return 1;
Marc Bouchere6869a82000-03-20 06:03:29 +0000113}
114
Martin Josefssonc5617bf2004-05-26 21:56:26 +0000115static void
116print_mark(unsigned long mark)
Marc Bouchere6869a82000-03-20 06:03:29 +0000117{
118 printf("0x%lx ", mark);
119}
120
121/* Prints out the targinfo. */
122static void
Rusty Russell3aef54d2005-01-03 03:48:40 +0000123print_v0(const struct ipt_ip *ip,
124 const struct ipt_entry_target *target,
125 int numeric)
Marc Bouchere6869a82000-03-20 06:03:29 +0000126{
127 const struct ipt_mark_target_info *markinfo =
128 (const struct ipt_mark_target_info *)target->data;
129 printf("MARK set ");
Martin Josefssonc5617bf2004-05-26 21:56:26 +0000130 print_mark(markinfo->mark);
Marc Bouchere6869a82000-03-20 06:03:29 +0000131}
132
133/* Saves the union ipt_targinfo in parsable form to stdout. */
134static void
Rusty Russell3aef54d2005-01-03 03:48:40 +0000135save_v0(const struct ipt_ip *ip, const struct ipt_entry_target *target)
Marc Bouchere6869a82000-03-20 06:03:29 +0000136{
137 const struct ipt_mark_target_info *markinfo =
138 (const struct ipt_mark_target_info *)target->data;
Rusty Russell7e53bf92000-03-20 07:03:28 +0000139
Martin Josefssonc5617bf2004-05-26 21:56:26 +0000140 printf("--set-mark ");
141 print_mark(markinfo->mark);
Marc Bouchere6869a82000-03-20 06:03:29 +0000142}
143
Rusty Russell3aef54d2005-01-03 03:48:40 +0000144/* Prints out the targinfo. */
145static void
146print_v1(const struct ipt_ip *ip,
147 const struct ipt_entry_target *target,
148 int numeric)
149{
150 const struct ipt_mark_target_info_v1 *markinfo =
151 (const struct ipt_mark_target_info_v1 *)target->data;
152
153 switch (markinfo->mode) {
154 case IPT_MARK_SET:
155 printf("MARK set ");
156 break;
157 case IPT_MARK_AND:
158 printf("MARK and ");
159 break;
160 case IPT_MARK_OR:
161 printf("MARK or ");
162 break;
163 }
164 print_mark(markinfo->mark);
165}
166
167/* Saves the union ipt_targinfo in parsable form to stdout. */
168static void
169save_v1(const struct ipt_ip *ip, const struct ipt_entry_target *target)
170{
171 const struct ipt_mark_target_info_v1 *markinfo =
172 (const struct ipt_mark_target_info_v1 *)target->data;
173
174 switch (markinfo->mode) {
175 case IPT_MARK_SET:
176 printf("--set-mark ");
177 break;
178 case IPT_MARK_AND:
179 printf("--and-mark ");
180 break;
181 case IPT_MARK_OR:
182 printf("--or-mark ");
183 break;
184 }
185 print_mark(markinfo->mark);
186}
187
Harald Welte3efb6ea2001-08-06 18:50:21 +0000188static
Rusty Russell3aef54d2005-01-03 03:48:40 +0000189struct iptables_target mark_v0 = {
Pablo Neira8caee8b2004-12-28 13:11:59 +0000190 .next = NULL,
191 .name = "MARK",
192 .version = IPTABLES_VERSION,
Rusty Russell3aef54d2005-01-03 03:48:40 +0000193 .revision = 0,
Pablo Neira8caee8b2004-12-28 13:11:59 +0000194 .size = IPT_ALIGN(sizeof(struct ipt_mark_target_info)),
195 .userspacesize = IPT_ALIGN(sizeof(struct ipt_mark_target_info)),
196 .help = &help,
197 .init = &init,
Rusty Russell3aef54d2005-01-03 03:48:40 +0000198 .parse = &parse_v0,
Pablo Neira8caee8b2004-12-28 13:11:59 +0000199 .final_check = &final_check,
Rusty Russell3aef54d2005-01-03 03:48:40 +0000200 .print = &print_v0,
201 .save = &save_v0,
202 .extra_opts = opts
203};
204
205static
206struct iptables_target mark_v1 = {
207 .next = NULL,
208 .name = "MARK",
209 .version = IPTABLES_VERSION,
210 .revision = 1,
211 .size = IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1)),
212 .userspacesize = IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1)),
213 .help = &help,
214 .init = &init,
215 .parse = &parse_v1,
216 .final_check = &final_check,
217 .print = &print_v1,
218 .save = &save_v1,
Pablo Neira8caee8b2004-12-28 13:11:59 +0000219 .extra_opts = opts
Marc Bouchere6869a82000-03-20 06:03:29 +0000220};
221
222void _init(void)
223{
Rusty Russell3aef54d2005-01-03 03:48:40 +0000224 register_target(&mark_v0);
225 register_target(&mark_v1);
Marc Bouchere6869a82000-03-20 06:03:29 +0000226}