1 /* Shared library add-on to iptables to add IP range matching support. */
9 #include <linux/netfilter_ipv4/ipt_iprange.h>
11 /* Function which prints out usage message. */
16 "iprange match v%s options:\n"
17 "[!] --src-range ip-ip Match source IP in the specified range\n"
18 "[!] --dst-range ip-ip Match destination IP in the specified range\n"
23 static struct option opts
[] = {
24 { "src-range", 1, 0, '1' },
25 { "dst-range", 1, 0, '2' },
30 parse_iprange(char *arg
, struct ipt_iprange
*range
)
35 dash
= strchr(arg
, '-');
39 ip
= dotted_to_addr(arg
);
41 exit_error(PARAMETER_PROBLEM
, "iprange match: Bad IP address `%s'\n",
43 range
->min_ip
= ip
->s_addr
;
46 ip
= dotted_to_addr(dash
+1);
48 exit_error(PARAMETER_PROBLEM
, "iprange match: Bad IP address `%s'\n",
50 range
->max_ip
= ip
->s_addr
;
52 range
->max_ip
= range
->min_ip
;
55 /* Function which parses command options; returns true if it
58 parse(int c
, char **argv
, int invert
, unsigned int *flags
,
59 const struct ipt_entry
*entry
,
60 unsigned int *nfcache
,
61 struct ipt_entry_match
**match
)
63 struct ipt_iprange_info
*info
= (struct ipt_iprange_info
*)(*match
)->data
;
67 if (*flags
& IPRANGE_SRC
)
68 exit_error(PARAMETER_PROBLEM
,
69 "iprange match: Only use --src-range ONCE!");
70 *flags
|= IPRANGE_SRC
;
72 info
->flags
|= IPRANGE_SRC
;
73 check_inverse(optarg
, &invert
, &optind
, 0);
75 info
->flags
|= IPRANGE_SRC_INV
;
77 parse_iprange(optarg
, &info
->src
);
82 if (*flags
& IPRANGE_DST
)
83 exit_error(PARAMETER_PROBLEM
,
84 "iprange match: Only use --dst-range ONCE!");
85 *flags
|= IPRANGE_DST
;
87 info
->flags
|= IPRANGE_DST
;
88 check_inverse(optarg
, &invert
, &optind
, 0);
90 info
->flags
|= IPRANGE_DST_INV
;
92 parse_iprange(optarg
, &info
->dst
);
102 /* Final check; must have specified --src-range or --dst-range. */
104 final_check(unsigned int flags
)
107 exit_error(PARAMETER_PROBLEM
,
108 "iprange match: You must specify `--src-range' or `--dst-range'");
112 print_iprange(const struct ipt_iprange
*range
)
114 const unsigned char *byte_min
, *byte_max
;
116 byte_min
= (const unsigned char *) &(range
->min_ip
);
117 byte_max
= (const unsigned char *) &(range
->max_ip
);
118 printf("%d.%d.%d.%d-%d.%d.%d.%d ",
119 byte_min
[0], byte_min
[1], byte_min
[2], byte_min
[3],
120 byte_max
[0], byte_max
[1], byte_max
[2], byte_max
[3]);
123 /* Prints out the info. */
125 print(const struct ipt_ip
*ip
,
126 const struct ipt_entry_match
*match
,
129 struct ipt_iprange_info
*info
= (struct ipt_iprange_info
*)match
->data
;
131 if (info
->flags
& IPRANGE_SRC
) {
132 printf("source IP range ");
133 if (info
->flags
& IPRANGE_SRC_INV
)
135 print_iprange(&info
->src
);
137 if (info
->flags
& IPRANGE_DST
) {
138 printf("destination IP range ");
139 if (info
->flags
& IPRANGE_DST_INV
)
141 print_iprange(&info
->dst
);
145 /* Saves the union ipt_info in parsable form to stdout. */
147 save(const struct ipt_ip
*ip
, const struct ipt_entry_match
*match
)
149 struct ipt_iprange_info
*info
= (struct ipt_iprange_info
*)match
->data
;
151 if (info
->flags
& IPRANGE_SRC
) {
152 if (info
->flags
& IPRANGE_SRC_INV
)
154 printf("--src-range ");
155 print_iprange(&info
->src
);
156 if (info
->flags
& IPRANGE_DST
)
159 if (info
->flags
& IPRANGE_DST
) {
160 if (info
->flags
& IPRANGE_DST_INV
)
162 printf("--dst-range ");
163 print_iprange(&info
->dst
);
167 static struct iptables_match iprange
= {
170 .version
= IPTABLES_VERSION
,
171 .size
= IPT_ALIGN(sizeof(struct ipt_iprange_info
)),
172 .userspacesize
= IPT_ALIGN(sizeof(struct ipt_iprange_info
)),
175 .final_check
= &final_check
,
183 register_match(&iprange
);