blob: 3e0942de4d8c97064518776b3dca4d19ae183050 [file] [log] [blame]
Grzegorz Janoszka6640b3c2003-05-31 17:31:31 +00001/* Shared library add-on to iptables to add IPMARK target support.
2 * (C) 2003 by Grzegorz Janoszka <Grzegorz.Janoszka@pro.onet.pl>
3 *
4 * based on original MARK target
5 *
6 * This program is distributed under the terms of GNU GPL
7 */
8#include <stdio.h>
9#include <string.h>
10#include <stdlib.h>
11#include <getopt.h>
12
13#include <iptables.h>
14#include <linux/netfilter_ipv4/ip_tables.h>
15#include <linux/netfilter_ipv4/ipt_IPMARK.h>
16
17#define IPT_ADDR_USED 1
18#define IPT_AND_MASK_USED 2
19#define IPT_OR_MASK_USED 4
20
21struct ipmarkinfo {
22 struct ipt_entry_target t;
23 struct ipt_ipmark_target_info ipmark;
24};
25
26/* Function which prints out usage message. */
27static void
28help(void)
29{
30 printf(
31"IPMARK target v%s options:\n"
32" --addr src/dst use source or destination ip address\n"
33" --and-mask value logical AND ip address with this value becomes MARK\n"
34" --or-mask value logical OR ip address with this value becomes MARK\n"
35"\n",
Oliver Fuddcbc96392003-06-19 11:58:06 +000036IPTABLES_VERSION);
Grzegorz Janoszka6640b3c2003-05-31 17:31:31 +000037}
38
39static struct option opts[] = {
40 { "addr", 1, 0, '1' },
41 { "and-mask", 1, 0, '2' },
42 { "or-mask", 1, 0, '3' },
43 { 0 }
44};
45
46/* Initialize the target. */
47static void
48init(struct ipt_entry_target *t, unsigned int *nfcache)
49{
50 struct ipt_ipmark_target_info *ipmarkinfo =
51 (struct ipt_ipmark_target_info *)t->data;
52
53 ipmarkinfo->andmask=0xffffffff;
54 ipmarkinfo->ormask=0;
55
Grzegorz Janoszka6640b3c2003-05-31 17:31:31 +000056}
57
58/* Function which parses command options; returns true if it
59 ate an option */
60static int
61parse(int c, char **argv, int invert, unsigned int *flags,
62 const struct ipt_entry *entry,
63 struct ipt_entry_target **target)
64{
65 struct ipt_ipmark_target_info *ipmarkinfo
66 = (struct ipt_ipmark_target_info *)(*target)->data;
67
68 switch (c) {
69 char *end;
70 case '1':
71 if(!strcmp(optarg, "src")) ipmarkinfo->addr=IPT_IPMARK_SRC;
72 else if(!strcmp(optarg, "dst")) ipmarkinfo->addr=IPT_IPMARK_DST;
73 else exit_error(PARAMETER_PROBLEM, "Bad addr value `%s' - should be `src' or `dst'", optarg);
74 if (*flags & IPT_ADDR_USED)
75 exit_error(PARAMETER_PROBLEM,
76 "IPMARK target: Can't specify --addr twice");
77 *flags |= IPT_ADDR_USED;
78 break;
79
80 case '2':
81 ipmarkinfo->andmask = strtoul(optarg, &end, 0);
82 if (*end != '\0' || end == optarg)
83 exit_error(PARAMETER_PROBLEM, "Bad and-mask value `%s'", optarg);
84 if (*flags & IPT_AND_MASK_USED)
85 exit_error(PARAMETER_PROBLEM,
86 "IPMARK target: Can't specify --and-mask twice");
87 *flags |= IPT_AND_MASK_USED;
88 break;
89 case '3':
90 ipmarkinfo->ormask = strtoul(optarg, &end, 0);
91 if (*end != '\0' || end == optarg)
92 exit_error(PARAMETER_PROBLEM, "Bad or-mask value `%s'", optarg);
93 if (*flags & IPT_OR_MASK_USED)
94 exit_error(PARAMETER_PROBLEM,
95 "IPMARK target: Can't specify --or-mask twice");
96 *flags |= IPT_OR_MASK_USED;
97 break;
98
99 default:
100 return 0;
101 }
102
103 return 1;
104}
105
106static void
107final_check(unsigned int flags)
108{
109 if (!(flags & IPT_ADDR_USED))
110 exit_error(PARAMETER_PROBLEM,
111 "IPMARK target: Parameter --addr is required");
112 if (!(flags & (IPT_AND_MASK_USED | IPT_OR_MASK_USED)))
113 exit_error(PARAMETER_PROBLEM,
114 "IPMARK target: Parameter --and-mask or --or-mask is required");
115}
116
117/* Prints out the targinfo. */
118static void
119print(const struct ipt_ip *ip,
120 const struct ipt_entry_target *target,
121 int numeric)
122{
123 const struct ipt_ipmark_target_info *ipmarkinfo =
124 (const struct ipt_ipmark_target_info *)target->data;
125
126 if(ipmarkinfo->addr == IPT_IPMARK_SRC)
127 printf("IPMARK src");
128 else
129 printf("IPMARK dst");
130 printf(" ip and 0x%lx or 0x%lx", ipmarkinfo->andmask, ipmarkinfo->ormask);
131}
132
133/* Saves the union ipt_targinfo in parsable form to stdout. */
134static void
135save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
136{
137 const struct ipt_ipmark_target_info *ipmarkinfo =
138 (const struct ipt_ipmark_target_info *)target->data;
139
140 if(ipmarkinfo->addr == IPT_IPMARK_SRC)
141 printf("--addr=src ");
142 else
143 printf("--addr=dst ");
144 if(ipmarkinfo->andmask != 0xffffffff)
145 printf("--and-mask 0x%lx ", ipmarkinfo->andmask);
146 if(ipmarkinfo->ormask != 0)
147 printf("--or-mask 0x%lx ", ipmarkinfo->ormask);
148}
149
Pablo Neira8caee8b2004-12-28 13:11:59 +0000150static struct iptables_target ipmark = {
151 .next = NULL,
152 .name = "IPMARK",
153 .version = IPTABLES_VERSION,
154 .size = IPT_ALIGN(sizeof(struct ipt_ipmark_target_info)),
155 .userspacesize = IPT_ALIGN(sizeof(struct ipt_ipmark_target_info)),
156 .help = &help,
157 .init = &init,
158 .parse = &parse,
159 .final_check = &final_check,
160 .print = &print,
161 .save = &save,
162 .extra_opts = opts
Grzegorz Janoszka6640b3c2003-05-31 17:31:31 +0000163};
164
165void _init(void)
166{
167 register_target(&ipmark);
168}