* Shortcuts to counting rules?
@ 2008-10-30 0:20 Rick Jones
2008-10-30 1:13 ` Philip Craig
0 siblings, 1 reply; 7+ messages in thread
From: Rick Jones @ 2008-10-30 0:20 UTC (permalink / raw)
To: netfilter
I would like to teach netperf (www.netperf.org) to determine if a
firewall is enabled and if so how many rules there are. To that end
after some searching/stumbling around I have gotten to the prototype
code at the end of this message.
The downside is that it requires the person compiling netperf to have
"iptables-dev" (or its equivalent) installed. I have noticed that at
the end of the day (so to speak) it comes down to a pair of getsockopt()
calls against a socket for each tablename.
open("/proc/net/ip_tables_names", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0440, st_size=0, ...}) = 0
mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1,
0) = 0x20000000002c8000
read(3, "nat\nmangle\nfilter\n", 1024) = 18
socket(PF_INET, SOCK_RAW, IPPROTO_RAW) = 4
getsockopt(4, SOL_IP, 0x40 /* IP_??? */,
"nat\0\0\0\0\0?\3p\212L\200\t\0\0\0\0\0\0\0\0\0\0\0\0\0"..., [84]) = 0
getsockopt(4, SOL_IP, 0x41 /* IP_??? */,
"nat\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., [1008]) = 0
close(4) = 0
socket(PF_INET, SOCK_RAW, IPPROTO_RAW) = 4
getsockopt(4, SOL_IP, 0x40 /* IP_??? */,
"mangle\0\0?\3p\212L\200\t\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., [84]) = 0
getsockopt(4, SOL_IP, 0x41 /* IP_??? */,
"mangle\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., [1776]) = 0
close(4) = 0
socket(PF_INET, SOCK_RAW, IPPROTO_RAW) = 4
getsockopt(4, SOL_IP, 0x40 /* IP_??? */,
"filter\0\0?\3p\212L\200\t\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., [84]) = 0
getsockopt(4, SOL_IP, 0x41 /* IP_??? */,
"filter\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., [7680]) = 0
close(4) = 0
[drift - is it worth teaching strace about those getsockopts?]
Are there any reasonable ways I might relax that requirement that
iptables-dev be present? Are some of the datastructures used in the
getsockopt() calls "stable enough" to do that that netperf could make
the getsockopt() calls directly without having to pull-in libiptc?
Netperf does not particularly care about the rules themselves, just
their number.
thanks,
rick jones
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <time.h>
#include "libiptc/libiptc.h"
#include "iptables.h"
#define NETFW_UNKNONW -1
#define NETFW_IPTABLES 1
static int
count_rules(iptc_handle_t *messiah) {
const char *chain;
const struct ipt_entry *rule;
int count = 0;
chain = iptc_first_chain(messiah);
while (chain) {
rule = iptc_first_rule(chain,messiah);
while (rule) {
count++;
rule = iptc_next_rule(rule,messiah);
}
chain = iptc_next_chain(messiah);
}
return count;
}
void
get_firewall_info(int *firewalltype, int *rulecount) {
FILE *namesfile = NULL;
char tablename[IPT_TABLE_MAXNAMELEN + 1];
iptc_handle_t messiah; /* handles, always handles */
int mycount = 0;
*firewalltype = NETFW_IPTABLES;
*rulecount = -1;
namesfile = fopen("/proc/net/ip_tables_names","r");
if (!namesfile)
return;
while (fgets(tablename,
sizeof(tablename),
namesfile)) {
/* no end of line is bad */
if (tablename[strlen(tablename) - 1] != '\n') {
/* we want to signal the problem somehow */
/* so set the rulecount to -1 always here */
*rulecount = -1;
return;
}
/* but we dont want to have one in our calls */
tablename[strlen(tablename) - 1] = '\0';
messiah = iptc_init(tablename);
mycount += count_rules(&messiah);
iptc_free(&messiah);
}
*rulecount = mycount;
}
int
main(int argc, char *argv[]) {
int firewalltype,rulecount;
get_firewall_info(&firewalltype,&rulecount);
printf("firewalltype is %d, rulecount
%d\n",firewalltype,rulecount);
return 0;
}
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: Shortcuts to counting rules?
2008-10-30 0:20 Shortcuts to counting rules? Rick Jones
@ 2008-10-30 1:13 ` Philip Craig
2008-10-30 16:40 ` Rick Jones
0 siblings, 1 reply; 7+ messages in thread
From: Philip Craig @ 2008-10-30 1:13 UTC (permalink / raw)
To: Rick Jones; +Cc: netfilter
Rick Jones wrote:
> Are there any reasonable ways I might relax that requirement that
> iptables-dev be present? Are some of the datastructures used in the
> getsockopt() calls "stable enough" to do that that netperf could make
> the getsockopt() calls directly without having to pull-in libiptc?
> Netperf does not particularly care about the rules themselves, just
> their number.
libiptc is only intended for use by iptables itself. The fact that
iptables-dev includes libiptc is a bug IMO. There's probably some
applications out that that wrongly depend on it already though.
The getsockopt() calls are part of the linux ABI. Using them is safe.
You just need to make sure you handle the case that they aren't
implemented.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Shortcuts to counting rules?
2008-10-30 1:13 ` Philip Craig
@ 2008-10-30 16:40 ` Rick Jones
2008-10-30 18:46 ` Rick Jones
2008-10-31 1:29 ` Philip Craig
0 siblings, 2 replies; 7+ messages in thread
From: Rick Jones @ 2008-10-30 16:40 UTC (permalink / raw)
To: Philip Craig; +Cc: netfilter
Philip Craig wrote:
> Rick Jones wrote:
>
>>Are there any reasonable ways I might relax that requirement that
>>iptables-dev be present? Are some of the datastructures used in the
>>getsockopt() calls "stable enough" to do that that netperf could make
>>the getsockopt() calls directly without having to pull-in libiptc?
>>Netperf does not particularly care about the rules themselves, just
>>their number.
>
>
> libiptc is only intended for use by iptables itself. The fact that
> iptables-dev includes libiptc is a bug IMO. There's probably some
> applications out that that wrongly depend on it already though.
I can see the appeal to an application since it does provide a nice
abstraction.
> The getsockopt() calls are part of the linux ABI. Using them is safe.
> You just need to make sure you handle the case that they aren't
> implemented.
Time to go find their documentation then I suppose.
thanks,
rick jones
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Shortcuts to counting rules?
2008-10-30 16:40 ` Rick Jones
@ 2008-10-30 18:46 ` Rick Jones
2008-10-31 1:26 ` Rick Jones
2008-10-31 1:29 ` Philip Craig
1 sibling, 1 reply; 7+ messages in thread
From: Rick Jones @ 2008-10-30 18:46 UTC (permalink / raw)
To: Rick Jones; +Cc: Philip Craig, netfilter
Rick Jones wrote:
> Philip Craig wrote:
>> The getsockopt() calls are part of the linux ABI. Using them is safe.
>> You just need to make sure you handle the case that they aren't
>> implemented.
>
>
> Time to go find their documentation then I suppose.
Looks like struct ipt_getinfo and ip6t_getinfo are only in header files
that come with "iptables-dev?"
rick jones
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Shortcuts to counting rules?
2008-10-30 18:46 ` Rick Jones
@ 2008-10-31 1:26 ` Rick Jones
2008-10-31 1:39 ` Philip Craig
0 siblings, 1 reply; 7+ messages in thread
From: Rick Jones @ 2008-10-31 1:26 UTC (permalink / raw)
To: netfilter; +Cc: Philip Craig
Rick Jones wrote:
> Rick Jones wrote:
>
>> Philip Craig wrote:
>>
>>> The getsockopt() calls are part of the linux ABI. Using them is safe.
>>> You just need to make sure you handle the case that they aren't
>>> implemented.
>>
>>
>>
>> Time to go find their documentation then I suppose.
>
>
> Looks like struct ipt_getinfo and ip6t_getinfo are only in header files
> that come with "iptables-dev?"
Having found linux/netfilter_ipv4/ip_tables.h and its ipv6 counterpart,
I will confess to having an Emily Litella moment with the above.
In messing about further and at the risk of yet another emily litella
moment (I have no pride when I'm trying to learn something new :) with
what the getsockopt(IPT_SO_GET_INFO) returns vs what I get by iterating
with libiptc calls, I take it that I cannot just use num_entries from
ipt_getinfo but have to retrieve the entries and run through them
skipping over chain entries?
tardy:~/iptables-1.4.1.1# cc -o fw_count
fw_count.ctardy:~/iptables-1.4.1.1# ./fw_count
name is mangle valid is 1f num is 6 size is 916
name is nat valid is 19 num is 4 size is 620
name is filter valid is e num is 4 size is 620
firewalltype is 1, rulecount 14
tardy:~/iptables-1.4.1.1# cc -DHAVE_IT_ALL -Iinclude -Llibiptc -o
fw_count fw_count.c -liptc
tardy:~/iptables-1.4.1.1# ./fw_count
chain count 5
chain count 3
chain count 3
firewalltype is 1, rulecount 0
The "tardy" system has no rules defined, and there are five chains for
mangle and three each for nat and filter, but that leaves me with one -
is that expected?
tardy:~/iptables-1.4.1.1# cat fw_count.c
#if defined(HAVE_LIBIPTC_H) && defined(HAVE_IPTABLES_H) &&
defined(HAVE_LIBIPTC)
#define HAVE_IT_ALL
#endif
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#if defined(HAVE_IT_ALL)
#include "libiptc/libiptc.h"
#include "iptables.h"
#else
/* seems linux/netfilter_ipv4/ip_tables.h needs IFNAMSIZ and does not get
* it on its own */
#include <net/if.h>
#include <linux/netfilter_ipv4/ip_tables.h>
/* need to consider IPv6 here at some point */
#endif
#define NETFW_UNKNOWN -1
#define NETFW_IPTABLES 1
#if defined(HAVE_IT_ALL)
static int
count_rules(iptc_handle_t *messiah) {
const char *chain;
const struct ipt_entry *rule;
int count = 0;
int chain_count = 0;
chain = iptc_first_chain(messiah);
while (chain) {
chain_count++;
rule = iptc_first_rule(chain,messiah);
while (rule) {
count++;
rule = iptc_next_rule(rule,messiah);
}
chain = iptc_next_chain(messiah);
}
printf("chain count %d\n",chain_count);
return count;
}
#else
static int
count_rules(char *table) {
struct ipt_getinfo info;
static int sock = -1;;
int len = sizeof(info);
if (-1 == sock)
sock = socket(AF_INET,SOCK_RAW,IPPROTO_RAW);
strncpy(info.name,table,IPT_TABLE_MAXNAMELEN);
info.name[IPT_TABLE_MAXNAMELEN-1] = '\0';
getsockopt(sock,SOL_IP,IPT_SO_GET_INFO,&info,&len);
printf("name is %s valid is %x num is %d size is %d\n",
info.name,
info.valid_hooks,
info.num_entries,
info.size);
return info.num_entries;
}
#endif
void
get_firewall_info(int *firewalltype, int *rulecount) {
#if defined(HAVE_IT_ALL)
iptc_handle_t messiah; /* handles, always handles */
#endif
FILE *namesfile = NULL;
char tablename[IPT_TABLE_MAXNAMELEN + 1];
int mycount = 0;
*firewalltype = NETFW_IPTABLES;
*rulecount = -1;
namesfile = fopen("/proc/net/ip_tables_names","r");
if (!namesfile)
return;
while (fgets(tablename,
sizeof(tablename),
namesfile)) {
/* no end of line is bad */
if (tablename[strlen(tablename) - 1] != '\n') {
/* we want to signal the problem somehow */
/* so set the rulecount to -1 always here */
*rulecount = -1;
return;
}
/* but we dont want to have one in our calls */
tablename[strlen(tablename) - 1] = '\0';
#if defined(HAVE_IT_ALL)
messiah = iptc_init(tablename);
mycount += count_rules(&messiah);
iptc_free(&messiah);
#else
mycount += count_rules(tablename);
#endif
}
*rulecount = mycount;
}
int
main(int argc, char *argv[]) {
int firewalltype,rulecount;
get_firewall_info(&firewalltype,&rulecount);
printf("firewalltype is %d, rulecount
%d\n",firewalltype,rulecount);
return 0;
}
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: Shortcuts to counting rules?
2008-10-31 1:26 ` Rick Jones
@ 2008-10-31 1:39 ` Philip Craig
0 siblings, 0 replies; 7+ messages in thread
From: Philip Craig @ 2008-10-31 1:39 UTC (permalink / raw)
To: Rick Jones; +Cc: netfilter
Rick Jones wrote:
> In messing about further and at the risk of yet another emily litella
> moment (I have no pride when I'm trying to learn something new :) with
> what the getsockopt(IPT_SO_GET_INFO) returns vs what I get by iterating
> with libiptc calls, I take it that I cannot just use num_entries from
> ipt_getinfo but have to retrieve the entries and run through them
> skipping over chain entries?
Getting beyond my knowledge sorry. Try asking on the netfilter-devel list.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Shortcuts to counting rules?
2008-10-30 16:40 ` Rick Jones
2008-10-30 18:46 ` Rick Jones
@ 2008-10-31 1:29 ` Philip Craig
1 sibling, 0 replies; 7+ messages in thread
From: Philip Craig @ 2008-10-31 1:29 UTC (permalink / raw)
To: Rick Jones; +Cc: netfilter
Rick Jones wrote:
> I can see the appeal to an application since it does provide a nice
> abstraction.
Sure, but there was never any intention for it to be stable. iptables
can change that library at any time, with no guarentee that any other
apps trying to use it will keep working.
>> The getsockopt() calls are part of the linux ABI. Using them is safe.
>> You just need to make sure you handle the case that they aren't
>> implemented.
>
> Time to go find their documentation then I suppose.
I don't expect there is any, but I might be wrong.
> Looks like struct ipt_getinfo and ip6t_getinfo are only in header files
> that come with "iptables-dev?"
They are defined in the kernel header files. It's a stable ABI, so creating
a local copy is fine (which is what iptables does now... iptables used to
require the presence of the kernel headers).
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2008-10-31 1:39 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-10-30 0:20 Shortcuts to counting rules? Rick Jones
2008-10-30 1:13 ` Philip Craig
2008-10-30 16:40 ` Rick Jones
2008-10-30 18:46 ` Rick Jones
2008-10-31 1:26 ` Rick Jones
2008-10-31 1:39 ` Philip Craig
2008-10-31 1:29 ` Philip Craig
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.