1 /* Shared library add-on to iptables to add IPMARK target support.
2 * (C) 2003 by Grzegorz Janoszka <Grzegorz.Janoszka@pro.onet.pl>
4 * based on original MARK target
6 * This program is distributed under the terms of GNU GPL
14 #include <linux/netfilter_ipv4/ip_tables.h>
15 #include <linux/netfilter_ipv4/ipt_IPMARK.h>
17 #define IPT_ADDR_USED 1
18 #define IPT_AND_MASK_USED 2
19 #define IPT_OR_MASK_USED 4
22 struct ipt_entry_target t;
23 struct ipt_ipmark_target_info ipmark;
26 /* Function which prints out usage message. */
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"
39 static struct option opts[] = {
40 { "addr", 1, 0, '1' },
41 { "and-mask", 1, 0, '2' },
42 { "or-mask", 1, 0, '3' },
46 /* Initialize the target. */
48 init(struct ipt_entry_target *t, unsigned int *nfcache)
50 struct ipt_ipmark_target_info *ipmarkinfo =
51 (struct ipt_ipmark_target_info *)t->data;
53 ipmarkinfo->andmask=0xffffffff;
58 /* Function which parses command options; returns true if it
61 parse(int c, char **argv, int invert, unsigned int *flags,
62 const struct ipt_entry *entry,
63 struct ipt_entry_target **target)
65 struct ipt_ipmark_target_info *ipmarkinfo
66 = (struct ipt_ipmark_target_info *)(*target)->data;
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;
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;
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;
107 final_check(unsigned int flags)
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");
117 /* Prints out the targinfo. */
119 print(const struct ipt_ip *ip,
120 const struct ipt_entry_target *target,
123 const struct ipt_ipmark_target_info *ipmarkinfo =
124 (const struct ipt_ipmark_target_info *)target->data;
126 if(ipmarkinfo->addr == IPT_IPMARK_SRC)
127 printf("IPMARK src");
129 printf("IPMARK dst");
130 printf(" ip and 0x%lx or 0x%lx", ipmarkinfo->andmask, ipmarkinfo->ormask);
133 /* Saves the union ipt_targinfo in parsable form to stdout. */
135 save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
137 const struct ipt_ipmark_target_info *ipmarkinfo =
138 (const struct ipt_ipmark_target_info *)target->data;
140 if(ipmarkinfo->addr == IPT_IPMARK_SRC)
141 printf("--addr=src ");
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);
150 static struct iptables_target 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)),
159 .final_check = &final_check,
167 register_target(&ipmark);