Busybox: Upgrade to 1.21.1 (stable). lsof active.
[tomato.git] / release / src / router / iptables / extensions / libipt_addrtype.c
blobd8e192966c547f33182b92fc0f166aac5afb037a
1 /* Shared library add-on to iptables to add addrtype matching support
2 *
3 * This program is released under the terms of GNU GPL */
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <getopt.h>
9 #include <iptables.h>
11 #include <linux/netfilter_ipv4/ip_tables.h>
12 #include <linux/netfilter_ipv4/ipt_addrtype.h>
14 /* from linux/rtnetlink.h, must match order of enumeration */
15 static char *rtn_names[] = {
16 "UNSPEC",
17 "UNICAST",
18 "LOCAL",
19 "BROADCAST",
20 "ANYCAST",
21 "MULTICAST",
22 "BLACKHOLE",
23 "UNREACHABLE",
24 "PROHIBIT",
25 "THROW",
26 "NAT",
27 "XRESOLVE",
28 NULL
31 static void help_types(void)
33 int i;
35 for (i = 0; rtn_names[i]; i++)
36 printf(" %s\n", rtn_names[i]);
39 static void help(void)
41 printf(
42 "Address type match v%s options:\n"
43 " [!] --src-type type[,...] Match source address type\n"
44 " [!] --dst-type type[,...] Match destination address type\n"
45 "\n"
46 "Valid types: \n"
47 , IPTABLES_VERSION);
48 help_types();
51 static int
52 parse_type(const char *name, size_t strlen, u_int16_t *mask)
54 int i;
56 for (i = 0; rtn_names[i]; i++)
57 if (strncasecmp(name, rtn_names[i], strlen) == 0) {
58 /* build up bitmask for kernel module */
59 *mask |= (1 << i);
60 return 1;
63 return 0;
66 static void parse_types(const char *arg, u_int16_t *mask)
68 const char *comma;
70 while ((comma = strchr(arg, ',')) != NULL) {
71 if (comma == arg || !parse_type(arg, comma-arg, mask))
72 exit_error(PARAMETER_PROBLEM,
73 "addrtype: bad type `%s'", arg);
74 arg = comma + 1;
77 if (strlen(arg) == 0 || !parse_type(arg, strlen(arg), mask))
78 exit_error(PARAMETER_PROBLEM, "addrtype: bad type `%s'", arg);
81 #define IPT_ADDRTYPE_OPT_SRCTYPE 0x1
82 #define IPT_ADDRTYPE_OPT_DSTTYPE 0x2
84 static int parse(int c, char **argv, int invert, unsigned int *flags,
85 const struct ipt_entry *entry, unsigned int *nfcache,
86 struct ipt_entry_match **match)
88 struct ipt_addrtype_info *info =
89 (struct ipt_addrtype_info *) (*match)->data;
91 switch (c) {
92 case '1':
93 if (*flags&IPT_ADDRTYPE_OPT_SRCTYPE)
94 exit_error(PARAMETER_PROBLEM,
95 "addrtype: can't specify src-type twice");
96 check_inverse(optarg, &invert, &optind, 0);
97 parse_types(argv[optind-1], &info->source);
98 if (invert)
99 info->invert_source = 1;
100 *flags |= IPT_ADDRTYPE_OPT_SRCTYPE;
101 break;
102 case '2':
103 if (*flags&IPT_ADDRTYPE_OPT_DSTTYPE)
104 exit_error(PARAMETER_PROBLEM,
105 "addrtype: can't specify dst-type twice");
106 check_inverse(optarg, &invert, &optind, 0);
107 parse_types(argv[optind-1], &info->dest);
108 if (invert)
109 info->invert_dest = 1;
110 *flags |= IPT_ADDRTYPE_OPT_DSTTYPE;
111 break;
112 default:
113 return 0;
116 return 1;
119 static void final_check(unsigned int flags)
121 if (!(flags & (IPT_ADDRTYPE_OPT_SRCTYPE|IPT_ADDRTYPE_OPT_DSTTYPE)))
122 exit_error(PARAMETER_PROBLEM,
123 "addrtype: you must specify --src-type or --dst-type");
126 static void print_types(u_int16_t mask)
128 const char *sep = "";
129 int i;
131 for (i = 0; rtn_names[i]; i++)
132 if (mask & (1 << i)) {
133 printf("%s%s", sep, rtn_names[i]);
134 sep = ",";
137 printf(" ");
140 static void print(const struct ipt_ip *ip,
141 const struct ipt_entry_match *match,
142 int numeric)
144 const struct ipt_addrtype_info *info =
145 (struct ipt_addrtype_info *) match->data;
147 printf("ADDRTYPE match ");
148 if (info->source) {
149 printf("src-type ");
150 if (info->invert_source)
151 printf("!");
152 print_types(info->source);
154 if (info->dest) {
155 printf("dst-type ");
156 if (info->invert_dest)
157 printf("!");
158 print_types(info->dest);
162 static void save(const struct ipt_ip *ip,
163 const struct ipt_entry_match *match)
165 const struct ipt_addrtype_info *info =
166 (struct ipt_addrtype_info *) match->data;
168 if (info->source) {
169 printf("--src-type ");
170 if (info->invert_source)
171 printf("! ");
172 print_types(info->source);
174 if (info->dest) {
175 printf("--dst-type ");
176 if (info->invert_dest)
177 printf("! ");
178 print_types(info->dest);
182 static struct option opts[] = {
183 { "src-type", 1, 0, '1' },
184 { "dst-type", 1, 0, '2' },
185 { 0 }
188 static
189 struct iptables_match addrtype = {
190 .next = NULL,
191 .name = "addrtype",
192 .version = IPTABLES_VERSION,
193 .size = IPT_ALIGN(sizeof(struct ipt_addrtype_info)),
194 .userspacesize = IPT_ALIGN(sizeof(struct ipt_addrtype_info)),
195 .help = &help,
196 .parse = &parse,
197 .final_check = &final_check,
198 .print = &print,
199 .save = &save,
200 .extra_opts = opts
204 void _init(void)
206 register_match(&addrtype);