blob: 08bc9d95872f7d32d1fa9f1aa8b87fb44dba29c5 [file] [log] [blame]
Marc Bouchere6869a82000-03-20 06:03:29 +00001/* Shared library add-on to iptables to add NFMARK matching support. */
Jan Engelhardtd95d92f2008-01-20 13:41:22 +00002#include <stdbool.h>
Marc Bouchere6869a82000-03-20 06:03:29 +00003#include <stdio.h>
4#include <netdb.h>
5#include <string.h>
6#include <stdlib.h>
7#include <getopt.h>
8
Yasuyuki KOZAKAI0af771d2007-07-24 06:53:14 +00009#include <xtables.h>
Jan Engelhardtd95d92f2008-01-20 13:41:22 +000010#include <linux/netfilter/xt_mark.h>
Marc Bouchere6869a82000-03-20 06:03:29 +000011
Jan Engelhardtd95d92f2008-01-20 13:41:22 +000012enum {
13 F_MARK = 1 << 0,
14};
15
16static void mark_mt_help(void)
Marc Bouchere6869a82000-03-20 06:03:29 +000017{
18 printf(
Jan Engelhardtd95d92f2008-01-20 13:41:22 +000019"mark match options:\n"
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020020"[!] --mark value[/mask] Match nfmark value with optional mask\n");
Marc Bouchere6869a82000-03-20 06:03:29 +000021}
22
Jan Engelhardtd95d92f2008-01-20 13:41:22 +000023static const struct option mark_mt_opts[] = {
24 {.name = "mark", .has_arg = true, .val = '1'},
Max Kellermann9ee386a2008-01-29 13:48:05 +000025 { .name = NULL }
Marc Bouchere6869a82000-03-20 06:03:29 +000026};
27
Jan Engelhardtd95d92f2008-01-20 13:41:22 +000028static int mark_mt_parse(int c, char **argv, int invert, unsigned int *flags,
29 const void *entry, struct xt_entry_match **match)
30{
31 struct xt_mark_mtinfo1 *info = (void *)(*match)->data;
Jan Engelhardta8097542009-01-27 17:39:01 +010032 unsigned int mark, mask = UINT32_MAX;
Jan Engelhardtd95d92f2008-01-20 13:41:22 +000033 char *end;
34
35 switch (c) {
36 case '1': /* --mark */
Jan Engelhardta41545c2009-01-27 21:27:19 +010037 xtables_param_act(XTF_ONLY_ONCE, "mark", "--mark", *flags & F_MARK);
Jan Engelhardt5f2922c2009-01-27 18:43:01 +010038 if (!xtables_strtoui(optarg, &end, &mark, 0, UINT32_MAX))
Jan Engelhardta41545c2009-01-27 21:27:19 +010039 xtables_param_act(XTF_BAD_VALUE, "mark", "--mark", optarg);
Jan Engelhardtd95d92f2008-01-20 13:41:22 +000040 if (*end == '/')
Jan Engelhardt5f2922c2009-01-27 18:43:01 +010041 if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX))
Jan Engelhardta41545c2009-01-27 21:27:19 +010042 xtables_param_act(XTF_BAD_VALUE, "mark", "--mark", optarg);
Jan Engelhardtd95d92f2008-01-20 13:41:22 +000043 if (*end != '\0')
Jan Engelhardta41545c2009-01-27 21:27:19 +010044 xtables_param_act(XTF_BAD_VALUE, "mark", "--mark", optarg);
Jan Engelhardtd95d92f2008-01-20 13:41:22 +000045
46 if (invert)
47 info->invert = true;
48 info->mark = mark;
49 info->mask = mask;
50 *flags |= F_MARK;
51 return true;
52 }
53 return false;
54}
55
Marc Bouchere6869a82000-03-20 06:03:29 +000056static int
Jan Engelhardt181dead2007-10-04 16:27:07 +000057mark_parse(int c, char **argv, int invert, unsigned int *flags,
58 const void *entry, struct xt_entry_match **match)
Marc Bouchere6869a82000-03-20 06:03:29 +000059{
Yasuyuki KOZAKAI0af771d2007-07-24 06:53:14 +000060 struct xt_mark_info *markinfo = (struct xt_mark_info *)(*match)->data;
Marc Bouchere6869a82000-03-20 06:03:29 +000061
62 switch (c) {
63 char *end;
64 case '1':
Harald Welteb77f1da2002-03-14 11:35:58 +000065 check_inverse(optarg, &invert, &optind, 0);
Marc Bouchere6869a82000-03-20 06:03:29 +000066 markinfo->mark = strtoul(optarg, &end, 0);
67 if (*end == '/') {
68 markinfo->mask = strtoul(end+1, &end, 0);
69 } else
70 markinfo->mask = 0xffffffff;
71 if (*end != '\0' || end == optarg)
72 exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
73 if (invert)
74 markinfo->invert = 1;
75 *flags = 1;
76 break;
77
78 default:
79 return 0;
80 }
81 return 1;
82}
83
Jan Engelhardtd95d92f2008-01-20 13:41:22 +000084static void print_mark(unsigned int mark, unsigned int mask)
Marc Bouchere6869a82000-03-20 06:03:29 +000085{
Jan Engelhardtd95d92f2008-01-20 13:41:22 +000086 if (mask != 0xffffffffU)
87 printf("0x%x/0x%x ", mark, mask);
Marc Bouchere6869a82000-03-20 06:03:29 +000088 else
Jan Engelhardtd95d92f2008-01-20 13:41:22 +000089 printf("0x%x ", mark);
Marc Bouchere6869a82000-03-20 06:03:29 +000090}
91
Jan Engelhardtd95d92f2008-01-20 13:41:22 +000092static void mark_mt_check(unsigned int flags)
Marc Bouchere6869a82000-03-20 06:03:29 +000093{
Jan Engelhardtd95d92f2008-01-20 13:41:22 +000094 if (flags == 0)
Marc Bouchere6869a82000-03-20 06:03:29 +000095 exit_error(PARAMETER_PROBLEM,
Jan Engelhardtd95d92f2008-01-20 13:41:22 +000096 "mark match: The --mark option is required");
97}
98
99static void
100mark_mt_print(const void *ip, const struct xt_entry_match *match, int numeric)
101{
102 const struct xt_mark_mtinfo1 *info = (const void *)match->data;
103
104 printf("mark match ");
105 if (info->invert)
106 printf("!");
107 print_mark(info->mark, info->mask);
Marc Bouchere6869a82000-03-20 06:03:29 +0000108}
109
Marc Bouchere6869a82000-03-20 06:03:29 +0000110static void
Jan Engelhardt181dead2007-10-04 16:27:07 +0000111mark_print(const void *ip, const struct xt_entry_match *match, int numeric)
Marc Bouchere6869a82000-03-20 06:03:29 +0000112{
Yasuyuki KOZAKAI0af771d2007-07-24 06:53:14 +0000113 struct xt_mark_info *info = (struct xt_mark_info *)match->data;
Harald Welte42479cc2002-09-20 15:25:13 +0000114
Marc Bouchere6869a82000-03-20 06:03:29 +0000115 printf("MARK match ");
Harald Welte42479cc2002-09-20 15:25:13 +0000116
117 if (info->invert)
118 printf("!");
119
Jan Engelhardtd95d92f2008-01-20 13:41:22 +0000120 print_mark(info->mark, info->mask);
121}
122
123static void mark_mt_save(const void *ip, const struct xt_entry_match *match)
124{
125 const struct xt_mark_mtinfo1 *info = (const void *)match->data;
126
127 if (info->invert)
Pablo Sebastian Greco3cc6fc32008-09-29 08:51:32 +0200128 printf("! ");
Jan Engelhardtd95d92f2008-01-20 13:41:22 +0000129
130 printf("--mark ");
131 print_mark(info->mark, info->mask);
Marc Bouchere6869a82000-03-20 06:03:29 +0000132}
133
Marc Bouchere6869a82000-03-20 06:03:29 +0000134static void
Jan Engelhardt181dead2007-10-04 16:27:07 +0000135mark_save(const void *ip, const struct xt_entry_match *match)
Marc Bouchere6869a82000-03-20 06:03:29 +0000136{
Yasuyuki KOZAKAI0af771d2007-07-24 06:53:14 +0000137 struct xt_mark_info *info = (struct xt_mark_info *)match->data;
Harald Welte42479cc2002-09-20 15:25:13 +0000138
139 if (info->invert)
140 printf("! ");
141
Marc Bouchere6869a82000-03-20 06:03:29 +0000142 printf("--mark ");
Jan Engelhardtd95d92f2008-01-20 13:41:22 +0000143 print_mark(info->mark, info->mask);
Marc Bouchere6869a82000-03-20 06:03:29 +0000144}
145
Jan Engelhardt181dead2007-10-04 16:27:07 +0000146static struct xtables_match mark_match = {
Jan Engelhardt23545c22008-02-14 04:23:04 +0100147 .family = AF_UNSPEC,
Yasuyuki KOZAKAIde9d2442007-07-24 06:55:05 +0000148 .name = "mark",
Jan Engelhardtd95d92f2008-01-20 13:41:22 +0000149 .revision = 0,
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200150 .version = XTABLES_VERSION,
Yasuyuki KOZAKAIde9d2442007-07-24 06:55:05 +0000151 .size = XT_ALIGN(sizeof(struct xt_mark_info)),
152 .userspacesize = XT_ALIGN(sizeof(struct xt_mark_info)),
Jan Engelhardtd95d92f2008-01-20 13:41:22 +0000153 .help = mark_mt_help,
Jan Engelhardt181dead2007-10-04 16:27:07 +0000154 .parse = mark_parse,
Jan Engelhardtd95d92f2008-01-20 13:41:22 +0000155 .final_check = mark_mt_check,
Jan Engelhardt181dead2007-10-04 16:27:07 +0000156 .print = mark_print,
157 .save = mark_save,
Jan Engelhardtd95d92f2008-01-20 13:41:22 +0000158 .extra_opts = mark_mt_opts,
159};
160
161static struct xtables_match mark_mt_reg = {
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200162 .version = XTABLES_VERSION,
Jan Engelhardtd95d92f2008-01-20 13:41:22 +0000163 .name = "mark",
164 .revision = 1,
Jan Engelhardt23545c22008-02-14 04:23:04 +0100165 .family = AF_UNSPEC,
Jan Engelhardtd95d92f2008-01-20 13:41:22 +0000166 .size = XT_ALIGN(sizeof(struct xt_mark_mtinfo1)),
167 .userspacesize = XT_ALIGN(sizeof(struct xt_mark_mtinfo1)),
168 .help = mark_mt_help,
169 .parse = mark_mt_parse,
170 .final_check = mark_mt_check,
171 .print = mark_mt_print,
172 .save = mark_mt_save,
173 .extra_opts = mark_mt_opts,
Yasuyuki KOZAKAIde9d2442007-07-24 06:55:05 +0000174};
175
Marc Bouchere6869a82000-03-20 06:03:29 +0000176void _init(void)
177{
Jan Engelhardt181dead2007-10-04 16:27:07 +0000178 xtables_register_match(&mark_match);
Jan Engelhardtd95d92f2008-01-20 13:41:22 +0000179 xtables_register_match(&mark_mt_reg);
Marc Bouchere6869a82000-03-20 06:03:29 +0000180}