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"
51 static void init(struct ipt_entry_match *m, unsigned int *nfcache)
53 /* caching not yet implemented */
54 *nfcache |= NFC_UNKNOWN;
58 parse_type(const char *name, size_t strlen, u_int16_t *mask)
62 for (i = 0; rtn_names[i]; i++)
63 if (strncasecmp(name, rtn_names[i], strlen) == 0) {
64 /* build up bitmask for kernel module */
72 static void parse_types(const char *arg, u_int16_t *mask)
76 while ((comma = strchr(arg, ',')) != NULL) {
77 if (comma == arg || !parse_type(arg, comma-arg, mask))
78 exit_error(PARAMETER_PROBLEM,
79 "addrtype: bad type `%s'", arg);
83 if (strlen(arg) == 0 || !parse_type(arg, strlen(arg), mask))
84 exit_error(PARAMETER_PROBLEM, "addrtype: bad type `%s'", arg);
87 #define IPT_ADDRTYPE_OPT_SRCTYPE 0x1
88 #define IPT_ADDRTYPE_OPT_DSTTYPE 0x2
90 static int parse(int c, char **argv, int invert, unsigned int *flags,
91 const struct ipt_entry *entry, unsigned int *nfcache,
92 struct ipt_entry_match **match)
94 struct ipt_addrtype_info *info =
95 (struct ipt_addrtype_info *) (*match)->data;
99 if (*flags&IPT_ADDRTYPE_OPT_SRCTYPE)
100 exit_error(PARAMETER_PROBLEM,
101 "addrtype: can't specify src-type twice");
102 check_inverse(optarg, &invert, &optind, 0);
103 parse_types(argv[optind-1], &info->source);
105 info->invert_source = 1;
106 *flags |= IPT_ADDRTYPE_OPT_SRCTYPE;
109 if (*flags&IPT_ADDRTYPE_OPT_DSTTYPE)
110 exit_error(PARAMETER_PROBLEM,
111 "addrtype: can't specify dst-type twice");
112 check_inverse(optarg, &invert, &optind, 0);
113 parse_types(argv[optind-1], &info->dest);
115 info->invert_dest = 1;
116 *flags |= IPT_ADDRTYPE_OPT_DSTTYPE;
125 static void final_check(unsigned int flags)
127 if (!(flags & (IPT_ADDRTYPE_OPT_SRCTYPE|IPT_ADDRTYPE_OPT_DSTTYPE)))
128 exit_error(PARAMETER_PROBLEM,
129 "addrtype: you must specify --src-type or --dst-type");
132 static void print_types(u_int16_t mask)
134 const char *sep = "";
137 for (i = 0; rtn_names[i]; i++)
138 if (mask & (1 << i)) {
139 printf("%s%s", sep, rtn_names[i]);
146 static void print(const struct ipt_ip *ip,
147 const struct ipt_entry_match *match,
150 const struct ipt_addrtype_info *info =
151 (struct ipt_addrtype_info *) match->data;
153 printf("ADDRTYPE match ");
156 if (info->invert_source)
158 print_types(info->source);
162 if (info->invert_dest)
164 print_types(info->dest);
168 static void save(const struct ipt_ip *ip,
169 const struct ipt_entry_match *match)
171 const struct ipt_addrtype_info *info =
172 (struct ipt_addrtype_info *) match->data;
175 printf("--src-type ");
176 if (info->invert_source)
178 print_types(info->source);
181 printf("--dst-type ");
182 if (info->invert_dest)
184 print_types(info->dest);
188 static struct option opts[] = {
189 { "src-type", 1, 0, '1' },
190 { "dst-type", 1, 0, '2' },
195 struct iptables_match addrtype = {
199 IPT_ALIGN(sizeof(struct ipt_addrtype_info)),
200 IPT_ALIGN(sizeof(struct ipt_addrtype_info)),
213 register_match(&addrtype);