1 /* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
2 * Patrick Schaaf <bof@bof.de>
3 * Martin Josefsson <gandalf@wlug.westbo.se>
4 * Copyright (C) 2003-2004 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
11 /* Shared library add-on to iptables to add IP set mangling target. */
20 #include <linux/netfilter_ipv4/ip_tables.h>
21 #include <linux/netfilter_ipv4/ip_set.h>
22 #include <linux/netfilter_ipv4/ipt_set.h>
23 #include "libipt_set.h"
25 /* Function which prints out usage message. */
26 static void help(void)
28 printf("SET v%s options:\n"
29 " --add-set name flags\n"
30 " --del-set name flags\n"
31 " add/del src/dst IP/port from/to named sets,\n"
32 " where flags are the comma separated list of\n"
34 "\n", IPTABLES_VERSION
);
37 static struct option opts
[] = {
38 {"add-set", 1, 0, '1'},
39 {"del-set", 1, 0, '2'},
43 /* Initialize the target. */
44 static void init(struct ipt_entry_target
*target
, unsigned int *nfcache
)
46 struct ipt_set_info_target
*info
=
47 (struct ipt_set_info_target
*) target
->data
;
49 memset(info
, 0, sizeof(struct ipt_set_info_target
));
51 info
->del_set
.index
= IP_SET_INVALID_ID
;
56 parse_target(char **argv
, int invert
, unsigned int *flags
,
57 struct ipt_set_info
*info
, const char *what
)
60 exit_error(PARAMETER_PROBLEM
,
61 "--%s can be specified only once", what
);
63 if (check_inverse(optarg
, &invert
, NULL
, 0))
64 exit_error(PARAMETER_PROBLEM
,
65 "Unexpected `!' after --%s", what
);
68 || argv
[optind
][0] == '-' || argv
[optind
][0] == '!')
69 exit_error(PARAMETER_PROBLEM
,
70 "--%s requires two args.", what
);
72 if (strlen(argv
[optind
-1]) > IP_SET_MAXNAMELEN
- 1)
73 exit_error(PARAMETER_PROBLEM
,
74 "setname `%s' too long, max %d characters.",
75 argv
[optind
-1], IP_SET_MAXNAMELEN
- 1);
77 get_set_byname(argv
[optind
- 1], info
);
78 parse_bindings(argv
[optind
], info
);
84 /* Function which parses command options; returns true if it
87 parse(int c
, char **argv
, int invert
, unsigned int *flags
,
88 const struct ipt_entry
*entry
, struct ipt_entry_target
**target
)
90 struct ipt_set_info_target
*myinfo
=
91 (struct ipt_set_info_target
*) (*target
)->data
;
94 case '1': /* --add-set <set> <flags> */
95 parse_target(argv
, invert
, flags
,
96 &myinfo
->add_set
, "add-set");
98 case '2': /* --del-set <set>[:<flags>] <flags> */
99 parse_target(argv
, invert
, flags
,
100 &myinfo
->del_set
, "del-set");
109 /* Final check; must specify at least one. */
110 static void final_check(unsigned int flags
)
113 exit_error(PARAMETER_PROBLEM
,
114 "You must specify either `--add-set' or `--del-set'");
118 print_target(const char *prefix
, const struct ipt_set_info
*info
)
121 char setname
[IP_SET_MAXNAMELEN
];
123 if (info
->index
== IP_SET_INVALID_ID
)
125 get_set_byid(setname
, info
->index
);
126 printf("%s %s", prefix
, setname
);
127 for (i
= 0; i
< IP_SET_MAX_BINDINGS
; i
++) {
132 info
->flags
[i
] & IPSET_SRC
? "src" : "dst");
137 /* Prints out the targinfo. */
139 print(const struct ipt_ip
*ip
,
140 const struct ipt_entry_target
*target
, int numeric
)
142 struct ipt_set_info_target
*info
=
143 (struct ipt_set_info_target
*) target
->data
;
145 print_target("add-set", &info
->add_set
);
146 print_target("del-set", &info
->del_set
);
149 /* Saves the union ipt_targinfo in parsable form to stdout. */
151 save(const struct ipt_ip
*ip
, const struct ipt_entry_target
*target
)
153 struct ipt_set_info_target
*info
=
154 (struct ipt_set_info_target
*) target
->data
;
156 print_target("--add-set", &info
->add_set
);
157 print_target("--del-set", &info
->del_set
);
161 struct iptables_target ipt_set_target
164 .version
= IPTABLES_VERSION
,
165 .size
= IPT_ALIGN(sizeof(struct ipt_set_info_target
)),
166 .userspacesize
= IPT_ALIGN(sizeof(struct ipt_set_info_target
)),
170 .final_check
= &final_check
,
178 register_target(&ipt_set_target
);