4 * Bart De Schuymer <bdschuym@pandora.be>
7 * added ip-sport and ip-dport; parsing of port arguments is
8 * based on code from iptables-1.2.7a
9 * Innominate Security Technologies AG <mhopf@innominate.com>
18 #include "../include/ebtables_u.h"
19 #include <linux/netfilter_bridge/ebt_ip.h>
23 #define IP_myTOS '3' /* include/bits/in.h seems to already define IP_TOS */
28 static struct option opts
[] =
30 { "ip-source" , required_argument
, 0, IP_SOURCE
},
31 { "ip-src" , required_argument
, 0, IP_SOURCE
},
32 { "ip-destination" , required_argument
, 0, IP_DEST
},
33 { "ip-dst" , required_argument
, 0, IP_DEST
},
34 { "ip-tos" , required_argument
, 0, IP_myTOS
},
35 { "ip-protocol" , required_argument
, 0, IP_PROTO
},
36 { "ip-proto" , required_argument
, 0, IP_PROTO
},
37 { "ip-source-port" , required_argument
, 0, IP_SPORT
},
38 { "ip-sport" , required_argument
, 0, IP_SPORT
},
39 { "ip-destination-port" , required_argument
, 0, IP_DPORT
},
40 { "ip-dport" , required_argument
, 0, IP_DPORT
},
44 /* put the mask into 4 bytes */
45 /* transform a protocol and service name into a port number */
46 static uint16_t parse_port(const char *protocol
, const char *name
)
48 struct servent
*service
;
52 port
= strtol(name
, &end
, 10);
55 (service
= getservbyname(name
, protocol
)) != NULL
)
56 return ntohs(service
->s_port
);
58 else if (port
>= 0 || port
<= 0xFFFF) {
61 ebt_print_error("Problem with specified %s port '%s'",
62 protocol
?protocol
:"", name
);
67 parse_port_range(const char *protocol
, const char *portstring
, uint16_t *ports
)
72 buffer
= strdup(portstring
);
73 if ((cp
= strchr(buffer
, ':')) == NULL
)
74 ports
[0] = ports
[1] = parse_port(protocol
, buffer
);
78 ports
[0] = buffer
[0] ? parse_port(protocol
, buffer
) : 0;
79 if (ebt_errormsg
[0] != '\0')
81 ports
[1] = cp
[0] ? parse_port(protocol
, cp
) : 0xFFFF;
82 if (ebt_errormsg
[0] != '\0')
85 if (ports
[0] > ports
[1])
86 ebt_print_error("Invalid portrange (min > max)");
91 static void print_port_range(uint16_t *ports
)
93 if (ports
[0] == ports
[1])
94 printf("%d ", ports
[0]);
96 printf("%d:%d ", ports
[0], ports
[1]);
99 static void print_help()
103 "--ip-src [!] address[/mask]: ip source specification\n"
104 "--ip-dst [!] address[/mask]: ip destination specification\n"
105 "--ip-tos [!] tos : ip tos specification\n"
106 "--ip-proto [!] protocol : ip protocol specification\n"
107 "--ip-sport [!] port[:port] : tcp/udp source port or port range\n"
108 "--ip-dport [!] port[:port] : tcp/udp destination port or port range\n");
111 static void init(struct ebt_entry_match
*match
)
113 struct ebt_ip_info
*ipinfo
= (struct ebt_ip_info
*)match
->data
;
115 ipinfo
->invflags
= 0;
119 #define OPT_SOURCE 0x01
120 #define OPT_DEST 0x02
122 #define OPT_PROTO 0x08
123 #define OPT_SPORT 0x10
124 #define OPT_DPORT 0x20
125 static int parse(int c
, char **argv
, int argc
, const struct ebt_u_entry
*entry
,
126 unsigned int *flags
, struct ebt_entry_match
**match
)
128 struct ebt_ip_info
*ipinfo
= (struct ebt_ip_info
*)(*match
)->data
;
134 ebt_check_option2(flags
, OPT_SOURCE
);
135 ipinfo
->bitmask
|= EBT_IP_SOURCE
;
139 ebt_check_option2(flags
, OPT_DEST
);
140 ipinfo
->bitmask
|= EBT_IP_DEST
;
142 if (ebt_check_inverse2(optarg
)) {
144 ipinfo
->invflags
|= EBT_IP_SOURCE
;
146 ipinfo
->invflags
|= EBT_IP_DEST
;
149 ebt_parse_ip_address(optarg
, &ipinfo
->saddr
, &ipinfo
->smsk
);
151 ebt_parse_ip_address(optarg
, &ipinfo
->daddr
, &ipinfo
->dmsk
);
157 ebt_check_option2(flags
, OPT_SPORT
);
158 ipinfo
->bitmask
|= EBT_IP_SPORT
;
159 if (ebt_check_inverse2(optarg
))
160 ipinfo
->invflags
|= EBT_IP_SPORT
;
162 ebt_check_option2(flags
, OPT_DPORT
);
163 ipinfo
->bitmask
|= EBT_IP_DPORT
;
164 if (ebt_check_inverse2(optarg
))
165 ipinfo
->invflags
|= EBT_IP_DPORT
;
168 parse_port_range(NULL
, optarg
, ipinfo
->sport
);
170 parse_port_range(NULL
, optarg
, ipinfo
->dport
);
174 ebt_check_option2(flags
, OPT_TOS
);
175 if (ebt_check_inverse2(optarg
))
176 ipinfo
->invflags
|= EBT_IP_TOS
;
177 i
= strtol(optarg
, &end
, 16);
178 if (i
< 0 || i
> 255 || *end
!= '\0')
179 ebt_print_error2("Problem with specified IP tos");
181 ipinfo
->bitmask
|= EBT_IP_TOS
;
185 ebt_check_option2(flags
, OPT_PROTO
);
186 if (ebt_check_inverse2(optarg
))
187 ipinfo
->invflags
|= EBT_IP_PROTO
;
188 i
= strtoul(optarg
, &end
, 10);
192 pe
= getprotobyname(optarg
);
194 ebt_print_error("Unknown specified IP protocol - %s", argv
[optind
- 1]);
195 ipinfo
->protocol
= pe
->p_proto
;
197 ipinfo
->protocol
= (unsigned char) i
;
199 ipinfo
->bitmask
|= EBT_IP_PROTO
;
207 static void final_check(const struct ebt_u_entry
*entry
,
208 const struct ebt_entry_match
*match
, const char *name
,
209 unsigned int hookmask
, unsigned int time
)
211 struct ebt_ip_info
*ipinfo
= (struct ebt_ip_info
*)match
->data
;
213 if (entry
->ethproto
!= ETH_P_IP
|| entry
->invflags
& EBT_IPROTO
) {
214 ebt_print_error("For IP filtering the protocol must be "
215 "specified as IPv4");
216 } else if (ipinfo
->bitmask
& (EBT_IP_SPORT
|EBT_IP_DPORT
) &&
217 (!(ipinfo
->bitmask
& EBT_IP_PROTO
) ||
218 ipinfo
->invflags
& EBT_IP_PROTO
||
219 (ipinfo
->protocol
!=IPPROTO_TCP
&&
220 ipinfo
->protocol
!=IPPROTO_UDP
&&
221 ipinfo
->protocol
!=IPPROTO_SCTP
&&
222 ipinfo
->protocol
!=IPPROTO_DCCP
)))
223 ebt_print_error("For port filtering the IP protocol must be "
224 "either 6 (tcp), 17 (udp), 33 (dccp) or "
228 static void print(const struct ebt_u_entry
*entry
,
229 const struct ebt_entry_match
*match
)
231 struct ebt_ip_info
*ipinfo
= (struct ebt_ip_info
*)match
->data
;
234 if (ipinfo
->bitmask
& EBT_IP_SOURCE
) {
236 if (ipinfo
->invflags
& EBT_IP_SOURCE
)
238 for (j
= 0; j
< 4; j
++)
239 printf("%d%s",((unsigned char *)&ipinfo
->saddr
)[j
],
240 (j
== 3) ? "" : ".");
241 printf("%s ", ebt_mask_to_dotted(ipinfo
->smsk
));
243 if (ipinfo
->bitmask
& EBT_IP_DEST
) {
245 if (ipinfo
->invflags
& EBT_IP_DEST
)
247 for (j
= 0; j
< 4; j
++)
248 printf("%d%s", ((unsigned char *)&ipinfo
->daddr
)[j
],
249 (j
== 3) ? "" : ".");
250 printf("%s ", ebt_mask_to_dotted(ipinfo
->dmsk
));
252 if (ipinfo
->bitmask
& EBT_IP_TOS
) {
254 if (ipinfo
->invflags
& EBT_IP_TOS
)
256 printf("0x%02X ", ipinfo
->tos
);
258 if (ipinfo
->bitmask
& EBT_IP_PROTO
) {
261 printf("--ip-proto ");
262 if (ipinfo
->invflags
& EBT_IP_PROTO
)
264 pe
= getprotobynumber(ipinfo
->protocol
);
266 printf("%d ", ipinfo
->protocol
);
268 printf("%s ", pe
->p_name
);
271 if (ipinfo
->bitmask
& EBT_IP_SPORT
) {
272 printf("--ip-sport ");
273 if (ipinfo
->invflags
& EBT_IP_SPORT
)
275 print_port_range(ipinfo
->sport
);
277 if (ipinfo
->bitmask
& EBT_IP_DPORT
) {
278 printf("--ip-dport ");
279 if (ipinfo
->invflags
& EBT_IP_DPORT
)
281 print_port_range(ipinfo
->dport
);
285 static int compare(const struct ebt_entry_match
*m1
,
286 const struct ebt_entry_match
*m2
)
288 struct ebt_ip_info
*ipinfo1
= (struct ebt_ip_info
*)m1
->data
;
289 struct ebt_ip_info
*ipinfo2
= (struct ebt_ip_info
*)m2
->data
;
291 if (ipinfo1
->bitmask
!= ipinfo2
->bitmask
)
293 if (ipinfo1
->invflags
!= ipinfo2
->invflags
)
295 if (ipinfo1
->bitmask
& EBT_IP_SOURCE
) {
296 if (ipinfo1
->saddr
!= ipinfo2
->saddr
)
298 if (ipinfo1
->smsk
!= ipinfo2
->smsk
)
301 if (ipinfo1
->bitmask
& EBT_IP_DEST
) {
302 if (ipinfo1
->daddr
!= ipinfo2
->daddr
)
304 if (ipinfo1
->dmsk
!= ipinfo2
->dmsk
)
307 if (ipinfo1
->bitmask
& EBT_IP_TOS
) {
308 if (ipinfo1
->tos
!= ipinfo2
->tos
)
311 if (ipinfo1
->bitmask
& EBT_IP_PROTO
) {
312 if (ipinfo1
->protocol
!= ipinfo2
->protocol
)
315 if (ipinfo1
->bitmask
& EBT_IP_SPORT
) {
316 if (ipinfo1
->sport
[0] != ipinfo2
->sport
[0] ||
317 ipinfo1
->sport
[1] != ipinfo2
->sport
[1])
320 if (ipinfo1
->bitmask
& EBT_IP_DPORT
) {
321 if (ipinfo1
->dport
[0] != ipinfo2
->dport
[0] ||
322 ipinfo1
->dport
[1] != ipinfo2
->dport
[1])
328 static struct ebt_u_match ip_match
=
331 .size
= sizeof(struct ebt_ip_info
),
335 .final_check
= final_check
,
343 ebt_register_match(&ip_match
);