1 /* Shared library add-on to iptables to add addrtype matching support
3 * This program is released under the terms of GNU GPL */
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[] = {
31 static void help_types(void)
35 for (i = 0; rtn_names[i]; i++)
36 printf(" %s\n", rtn_names[i]);
39 static void help(void)
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"
52 parse_type(const char *name, size_t strlen, u_int16_t *mask)
56 for (i = 0; rtn_names[i]; i++)
57 if (strncasecmp(name, rtn_names[i], strlen) == 0) {
58 /* build up bitmask for kernel module */
66 static void parse_types(const char *arg, u_int16_t *mask)
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);
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;
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);
99 info->invert_source = 1;
100 *flags |= IPT_ADDRTYPE_OPT_SRCTYPE;
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);
109 info->invert_dest = 1;
110 *flags |= IPT_ADDRTYPE_OPT_DSTTYPE;
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 = "";
131 for (i = 0; rtn_names[i]; i++)
132 if (mask & (1 << i)) {
133 printf("%s%s", sep, rtn_names[i]);
140 static void print(const struct ipt_ip *ip,
141 const struct ipt_entry_match *match,
144 const struct ipt_addrtype_info *info =
145 (struct ipt_addrtype_info *) match->data;
147 printf("ADDRTYPE match ");
150 if (info->invert_source)
152 print_types(info->source);
156 if (info->invert_dest)
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;
169 printf("--src-type ");
170 if (info->invert_source)
172 print_types(info->source);
175 printf("--dst-type ");
176 if (info->invert_dest)
178 print_types(info->dest);
182 static struct option opts[] = {
183 { "src-type", 1, 0, '1' },
184 { "dst-type", 1, 0, '2' },
189 struct iptables_match addrtype = {
192 .version = IPTABLES_VERSION,
193 .size = IPT_ALIGN(sizeof(struct ipt_addrtype_info)),
194 .userspacesize = IPT_ALIGN(sizeof(struct ipt_addrtype_info)),
197 .final_check = &final_check,
206 register_match(&addrtype);