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
);