blob: a924ceb357dcc2c18f7d5d9b3ed4caaee11a3699 [file] [log] [blame]
Bart De Schuymerff587202005-02-08 20:02:28 +00001/* ebt_mark
2 *
3 * Authors:
4 * Bart De Schuymer <bdschuym@pandora.be>
5 *
Bart De Schuymer45462702006-10-03 10:04:46 +00006 * July, 2002, September 2006
Bart De Schuymerff587202005-02-08 20:02:28 +00007 */
8
Bart De Schuymera501b782002-07-20 16:15:39 +00009#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
Bart De Schuymera501b782002-07-20 16:15:39 +000012#include <getopt.h>
13#include "../include/ebtables_u.h"
14#include <linux/netfilter_bridge/ebt_mark_t.h>
15
Bart De Schuymer9cfd6542002-08-13 16:08:08 +000016static int mark_supplied;
Bart De Schuymera501b782002-07-20 16:15:39 +000017
Bart De Schuymer9cfd6542002-08-13 16:08:08 +000018#define MARK_TARGET '1'
Bart De Schuymera501b782002-07-20 16:15:39 +000019#define MARK_SETMARK '2'
Bart De Schuymer45462702006-10-03 10:04:46 +000020#define MARK_ORMARK '3'
21#define MARK_ANDMARK '4'
22#define MARK_XORMARK '5'
Bart De Schuymera501b782002-07-20 16:15:39 +000023static struct option opts[] =
24{
Bart De Schuymer9cfd6542002-08-13 16:08:08 +000025 { "mark-target" , required_argument, 0, MARK_TARGET },
Bart De Schuymerc0a330e2004-12-05 21:21:41 +000026 /* an oldtime messup, we should have always used the scheme
27 * <extension-name>-<option> */
Bart De Schuymera501b782002-07-20 16:15:39 +000028 { "set-mark" , required_argument, 0, MARK_SETMARK },
Bart De Schuymerc0a330e2004-12-05 21:21:41 +000029 { "mark-set" , required_argument, 0, MARK_SETMARK },
Bart De Schuymer45462702006-10-03 10:04:46 +000030 { "mark-or" , required_argument, 0, MARK_ORMARK },
31 { "mark-and" , required_argument, 0, MARK_ANDMARK },
32 { "mark-xor" , required_argument, 0, MARK_XORMARK },
Bart De Schuymera501b782002-07-20 16:15:39 +000033 { 0 }
34};
35
36static void print_help()
37{
38 printf(
39 "mark target options:\n"
Bart De Schuymerc0a330e2004-12-05 21:21:41 +000040 " --mark-set value : Set nfmark value\n"
Bart De Schuymer45462702006-10-03 10:04:46 +000041 " --mark-or value : Or nfmark with value (nfmark |= value)\n"
42 " --mark-and value : And nfmark with value (nfmark &= value)\n"
43 " --mark-xor value : Xor nfmark with value (nfmark ^= value)\n"
Bart De Schuymer9cfd6542002-08-13 16:08:08 +000044 " --mark-target target : ACCEPT, DROP, RETURN or CONTINUE\n");
Bart De Schuymera501b782002-07-20 16:15:39 +000045}
46
47static void init(struct ebt_entry_target *target)
48{
49 struct ebt_mark_t_info *markinfo =
50 (struct ebt_mark_t_info *)target->data;
51
52 markinfo->target = EBT_ACCEPT;
53 markinfo->mark = 0;
Bart De Schuymerb26649e2002-07-25 14:51:54 +000054 mark_supplied = 0;
Bart De Schuymera501b782002-07-20 16:15:39 +000055}
56
Bart De Schuymer9cfd6542002-08-13 16:08:08 +000057#define OPT_MARK_TARGET 0x01
Bart De Schuymera501b782002-07-20 16:15:39 +000058#define OPT_MARK_SETMARK 0x02
Bart De Schuymer45462702006-10-03 10:04:46 +000059#define OPT_MARK_ORMARK 0x04
60#define OPT_MARK_ANDMARK 0x08
61#define OPT_MARK_XORMARK 0x10
Bart De Schuymera501b782002-07-20 16:15:39 +000062static int parse(int c, char **argv, int argc,
63 const struct ebt_u_entry *entry, unsigned int *flags,
64 struct ebt_entry_target **target)
65{
Bart De Schuymera501b782002-07-20 16:15:39 +000066 struct ebt_mark_t_info *markinfo =
67 (struct ebt_mark_t_info *)(*target)->data;
68 char *end;
69
70 switch (c) {
71 case MARK_TARGET:
Bart De Schuymer45462702006-10-03 10:04:46 +000072 { int tmp;
Bart De Schuymerff587202005-02-08 20:02:28 +000073 ebt_check_option2(flags, OPT_MARK_TARGET);
Bart De Schuymer45462702006-10-03 10:04:46 +000074 if (FILL_TARGET(optarg, tmp))
Bart De Schuymerff587202005-02-08 20:02:28 +000075 ebt_print_error2("Illegal --mark-target target");
Bart De Schuymer45462702006-10-03 10:04:46 +000076 /* the 4 lsb are left to designate the target */
Bart De Schuymer09a3cac2006-12-15 11:38:03 +000077 markinfo->target = (markinfo->target & ~EBT_VERDICT_BITS) | (tmp & EBT_VERDICT_BITS);
Bart De Schuymer45462702006-10-03 10:04:46 +000078 }
79 return 1;
Bart De Schuymera501b782002-07-20 16:15:39 +000080 case MARK_SETMARK:
Bart De Schuymerff587202005-02-08 20:02:28 +000081 ebt_check_option2(flags, OPT_MARK_SETMARK);
Bart De Schuymer45462702006-10-03 10:04:46 +000082 if (*flags & (OPT_MARK_ORMARK|OPT_MARK_ANDMARK|OPT_MARK_XORMARK))
83 ebt_print_error2("--mark-set cannot be used together with specific --mark option");
84 break;
85 case MARK_ORMARK:
86 ebt_check_option2(flags, OPT_MARK_ORMARK);
87 if (*flags & (OPT_MARK_SETMARK|OPT_MARK_ANDMARK|OPT_MARK_XORMARK))
88 ebt_print_error2("--mark-or cannot be used together with specific --mark option");
Bart De Schuymer09a3cac2006-12-15 11:38:03 +000089 markinfo->target = (markinfo->target & EBT_VERDICT_BITS) | MARK_OR_VALUE;
Bart De Schuymer45462702006-10-03 10:04:46 +000090 break;
91 case MARK_ANDMARK:
92 ebt_check_option2(flags, OPT_MARK_ANDMARK);
93 if (*flags & (OPT_MARK_SETMARK|OPT_MARK_ORMARK|OPT_MARK_XORMARK))
94 ebt_print_error2("--mark-and cannot be used together with specific --mark option");
Bart De Schuymer09a3cac2006-12-15 11:38:03 +000095 markinfo->target = (markinfo->target & EBT_VERDICT_BITS) | MARK_AND_VALUE;
Bart De Schuymer45462702006-10-03 10:04:46 +000096 break;
97 case MARK_XORMARK:
98 ebt_check_option2(flags, OPT_MARK_XORMARK);
99 if (*flags & (OPT_MARK_SETMARK|OPT_MARK_ANDMARK|OPT_MARK_ORMARK))
100 ebt_print_error2("--mark-xor cannot be used together with specific --mark option");
Bart De Schuymer09a3cac2006-12-15 11:38:03 +0000101 markinfo->target = (markinfo->target & EBT_VERDICT_BITS) | MARK_XOR_VALUE;
Bart De Schuymera501b782002-07-20 16:15:39 +0000102 break;
103 default:
104 return 0;
105 }
Bart De Schuymer45462702006-10-03 10:04:46 +0000106 /* mutual code */
107 markinfo->mark = strtoul(optarg, &end, 0);
108 if (*end != '\0' || end == optarg)
109 ebt_print_error2("Bad MARK value '%s'", optarg);
110 mark_supplied = 1;
Bart De Schuymera501b782002-07-20 16:15:39 +0000111 return 1;
112}
113
114static void final_check(const struct ebt_u_entry *entry,
115 const struct ebt_entry_target *target, const char *name,
Bart De Schuymerc9b52932002-08-24 13:26:34 +0000116 unsigned int hookmask, unsigned int time)
Bart De Schuymera501b782002-07-20 16:15:39 +0000117{
Bart De Schuymerb26649e2002-07-25 14:51:54 +0000118 struct ebt_mark_t_info *markinfo =
119 (struct ebt_mark_t_info *)target->data;
120
Bart De Schuymerff587202005-02-08 20:02:28 +0000121 if (time == 0 && mark_supplied == 0) {
Bart De Schuymer64182a32004-01-21 20:39:54 +0000122 ebt_print_error("No mark value supplied");
Bart De Schuymer09a3cac2006-12-15 11:38:03 +0000123 } else if (BASE_CHAIN && (markinfo->target|~EBT_VERDICT_BITS) == EBT_RETURN)
Bart De Schuymerff587202005-02-08 20:02:28 +0000124 ebt_print_error("--mark-target RETURN not allowed on base chain");
Bart De Schuymera501b782002-07-20 16:15:39 +0000125}
126
127static void print(const struct ebt_u_entry *entry,
128 const struct ebt_entry_target *target)
129{
130 struct ebt_mark_t_info *markinfo =
131 (struct ebt_mark_t_info *)target->data;
Bart De Schuymer45462702006-10-03 10:04:46 +0000132 int tmp;
Bart De Schuymera501b782002-07-20 16:15:39 +0000133
Bart De Schuymer09a3cac2006-12-15 11:38:03 +0000134 tmp = markinfo->target & ~EBT_VERDICT_BITS;
Bart De Schuymer45462702006-10-03 10:04:46 +0000135 if (tmp == MARK_SET_VALUE)
136 printf("--mark-set");
137 else if (tmp == MARK_OR_VALUE)
138 printf("--mark-or");
139 else if (tmp == MARK_XOR_VALUE)
140 printf("--mark-xor");
141 else if (tmp == MARK_AND_VALUE)
142 printf("--mark-and");
143 else
144 ebt_print_error("oops, unknown mark action, try a later version of ebtables");
145 printf(" 0x%lx", markinfo->mark);
Bart De Schuymer09a3cac2006-12-15 11:38:03 +0000146 tmp = markinfo->target | ~EBT_VERDICT_BITS;
Bart De Schuymer45462702006-10-03 10:04:46 +0000147 printf(" --mark-target %s", TARGET_NAME(tmp));
Bart De Schuymera501b782002-07-20 16:15:39 +0000148}
149
150static int compare(const struct ebt_entry_target *t1,
151 const struct ebt_entry_target *t2)
152{
153 struct ebt_mark_t_info *markinfo1 =
154 (struct ebt_mark_t_info *)t1->data;
155 struct ebt_mark_t_info *markinfo2 =
156 (struct ebt_mark_t_info *)t2->data;
157
Bart De Schuymerb26649e2002-07-25 14:51:54 +0000158 return markinfo1->target == markinfo2->target &&
159 markinfo1->mark == markinfo2->mark;
Bart De Schuymera501b782002-07-20 16:15:39 +0000160}
161
162static struct ebt_u_target mark_target =
163{
Bart De Schuymer7cf1cca2003-08-30 16:20:19 +0000164 .name = EBT_MARK_TARGET,
165 .size = sizeof(struct ebt_mark_t_info),
166 .help = print_help,
167 .init = init,
168 .parse = parse,
169 .final_check = final_check,
170 .print = print,
171 .compare = compare,
172 .extra_ops = opts,
Bart De Schuymera501b782002-07-20 16:15:39 +0000173};
174
Bart De Schuymer64182a32004-01-21 20:39:54 +0000175void _init(void)
Bart De Schuymera501b782002-07-20 16:15:39 +0000176{
Bart De Schuymer8339ff12004-01-14 20:05:27 +0000177 ebt_register_target(&mark_target);
Bart De Schuymera501b782002-07-20 16:15:39 +0000178}