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