Hi again all, I really don't want to be a bother, but I need to know if I am posting on the right list. I noticed that the fellow that posted a question about his rules after my post has received several responses and I have not gotten any replies at all - not a problem, I promise - but it makes me wonder if this is a list on setting up rules or can I get the kind of help for programming in userland that I need too? Where would I find such a list?
I know that most lists are just volunteers that answer out of kindness and I really appreciate you guys for that - but if I am posting to the wrong list I kind of need to know 'cause I am stuck in a major way. Thanks for any help you can be pointing me to the right place. Jeff -----Original Message----- From: Jeffrey D. Brower [mailto:[EMAIL PROTECTED] Sent: Monday, August 09, 2004 10:19 PM To: '[EMAIL PROTECTED]' Subject: SIOCGETFS returns NULLS for fr_flags and fr_ifname Greetings, I have been beating my head for 3 days and searched the archives and googled the net - so I decided to bother you guys and beg for help. Attached is a program named ipfistat.c that is a hack to create the Ipfstat like output that I need based on interface. I can get the general stats with no problem and I can get hit counts for each rule by rule number. My problem is getting ahold of the interface and the flags. You should be able to run it and do no damage - it only reads kmem and does printf. Specifically, when I load fp->fr_flags it comes in NULL and the same with the interface. I have tried to make it as close to ipfilter as possible and most of it is a collection of cut, paste and hack (as is most of my programming) and so it looks very much like ipfilter (mostly same naming, I use ipfilter includes and the output looks like ipstat -vhio when you run my ipfistat 3 I am running on FreeBSD Release 4. I noticed that the printbin() from ipstat dumps 336 bytes to the screen for each rule. My program only loads 328 bytes. I don't know why but I doubt that what I need is in there. I am just convinced that I have missed some small piece of information that I did not notice in the man 4 ipf screen. Please, please... If you know how to get the rule flags and interface... Thank you in advance for your help. Thanks! Jeff Brower Program follows: /* Almost all of this is a cut and paste hack from several programs that make up the great and powerful ipfilter package. This is a great package and I love it. That said, this hack is an attempt to get ahold of the filter stats on a per rule basis and summarize them by interface (rather than by rule, or in general, like you can get from ipstat). I'm a novice at this - so be kind. This program is written for Jeff Brower's fun and joy only. I can guarantee that it will not work as it is and may never work in any useful way on your system or mine. If you are interested in the final version after I can get it working feel free to drop me an email at [EMAIL PROTECTED] to see if I ever got it going. In the meantime, the code in this program is indeed mostly cut and paste from ipfilter programs - and so I proclaim the program subject to the same copyright that it carries: IPFILTER: Copyright (C) 1993-2001 by Darren Reed Please see the IPFILTER.LICENCE file for details Additionally, I declare this particular program subject to the Beer License. If you like this and you meet me, buy me a beer. Jeff Brower - [EMAIL PROTECTED] */ /* ipfistat.c compile comand: gcc -lkvm ipfistat.c -o ipfistat */ #include <stdio.h> #include <fcntl.h> #include </usr/include/sys/ioctl.h> #include </usr/include/netinet/in.h> #include </usr/src/sys/contrib/ipfilter/netinet/ip_compat.h> #include </usr/src/sys/contrib/ipfilter/netinet/ip_fil.h> #include <kvm.h> static int kvm_fd = -1; static char *kvm_errstr = NULL; static char *kvm_kern = NULL; static char *kvm_core = NULL; static kvm_t *kvm_f = NULL; static int noiselevel = 0; int kmemcpy(buf, pos, n) register char *buf; long pos; register int n; { register int r; if (!n) return 0; while ((r = kvm_read(kvm_f, pos, buf, (size_t)n)) < n) if (r <= 0) { fprintf(stderr, "pos=0x%x ", (u_int)pos); perror("kmemcpy:read"); return -1; } else { buf += r; pos += r; n -= r; } return 0; } static void bindump(fp) struct frentry *fp; { int i = sizeof(*fp), j=0; u_char *s; for (s = (u_char *)fp; i; i--, s++) { j++; printf("%02x ", *s); if (j == 16) { printf("\n"); j = 0; } } printf("\n\n"); } static void printifname(format, name, ifp) char *format, *name; void *ifp; { printf("%s%s", format, name); if ((ifp == NULL) && strcmp(name, "-") && strcmp(name, "*")) printf("(!)"); } static void printfr(fp) struct frentry *fp; { printf("Hits: %ld\tRule: [", fp->fr_hits); if (fp->fr_flags == NULL) printf("(Flags are NULL!) "); if (fp->fr_flags & FR_PASS) printf("pass "); if (fp->fr_flags & FR_NOMATCH) printf("nomatch "); if (fp->fr_flags & FR_BLOCK) printf("block "); if (fp->fr_flags & FR_OUTQUE) printf("out "); else printf("in "); if (fp->fr_flags & FR_QUICK) printf("quick "); if (*fp->fr_ifname) { printifname("on ", fp->fr_ifname, fp->fr_ifa); } printf("]\n"); } static void printlist(fp) frentry_t *fp; { struct frentry fb; int n; for (n = 1; fp; n++) { if (kmemcpy((char *)&fb, (u_long)fp, sizeof(fb)) == -1) { perror("kmemcpy"); return; } fp = &fb; if (noiselevel > 1) { printf("Line %d\t", n); /* print line number */ printfr(fp); /* print the rule */ } if (noiselevel > 2) { bindump(fp); /* binary dump of rule */ } if (fp->fr_grp) printlist(fp->fr_grp); fp = fp->fr_next; } } static void showlist(fiop) struct friostat *fiop; { struct frentry *fp = NULL; int set; set = fiop->f_active; fp = (struct frentry *)fiop->f_fin[set]; if (!fp) { return; } printlist(fp); fp = (struct frentry *)fiop->f_fout[set]; if (!fp) { return; } printlist(fp); } main(int argc, char **argv) { /* define some variables we need */ friostat_t fio; friostat_t *fiop = &fio; int fd, n; char *name = NULL; char *device = IPL_NAME; /* Edit the parameter for verbosity */ if (argc!=2) { fprintf(stderr, "Missing verbosity level (0, 1, 2, 3).\n"); exit(-1); } if (sscanf(argv[1], "%i", &noiselevel) != 1) { fprintf(stderr, "Whoops! What you entered was not a number.\n"); exit(-1); } if ( (noiselevel < 0) || (noiselevel > 3) ) { fprintf(stderr, "Whoops! 0=Quiet 1=Some 2=Verbose 3=Chatty\n"); exit(-1); } /* open up the kernel memory file handle */ kvm_f = kvm_open(kvm_kern, kvm_core, NULL, O_RDONLY, kvm_errstr); if (kvm_f == NULL) { perror("kvm_open:open"); exit(-1); } /* open up the file handle for the SIOC call in ipfilter */ if ((fd = open(device, O_RDONLY)) < 0) { perror("open"); exit(-1); } /* Do the ioctl SIOC call to GET the Filter Stats (SIOCGFS) */ bzero((char *)&fio, sizeof(fio)); if (ioctl(fd, SIOCGETFS, &fiop) == -1) { perror("ioctl(SIOCGETFS)"); exit(-1); } if (noiselevel > 0) { printf(" Input Packets:\t\tblocked %lu passed %lu nomatch %lu", fio.f_st[0].fr_block, fio.f_st[0].fr_pass, fio.f_st[0].fr_nom); printf(" counted %lu short %lu\n", fio.f_st[0].fr_acct, fio.f_st[0].fr_short); printf("Output Packets:\t\tblocked %lu passed %lu nomatch %lu", fio.f_st[1].fr_block, fio.f_st[1].fr_pass, fio.f_st[1].fr_nom); printf(" counted %lu short %lu\n", fio.f_st[1].fr_acct, fio.f_st[1].fr_short); } showlist(fiop); return 0; }
