summaryrefslogtreecommitdiff
path: root/sbin/ipfstat
diff options
context:
space:
mode:
authordm <dm@cvs.openbsd.org>1996-01-25 05:41:50 +0000
committerdm <dm@cvs.openbsd.org>1996-01-25 05:41:50 +0000
commitd22510d35a65326e6c28cf24898e75ebb43f1702 (patch)
tree39d26580cbebbf88b26b3ce8999199204095ce79 /sbin/ipfstat
parent1dc3867108ccbee4e608e89a62fa5e5fbfa194c3 (diff)
IP filter 3.0.1
Diffstat (limited to 'sbin/ipfstat')
-rw-r--r--sbin/ipfstat/Makefile2
-rw-r--r--sbin/ipfstat/fils.c206
-rw-r--r--sbin/ipfstat/ipfstat.826
-rw-r--r--sbin/ipfstat/kmem.c3
4 files changed, 186 insertions, 51 deletions
diff --git a/sbin/ipfstat/Makefile b/sbin/ipfstat/Makefile
index bafd458b225..ba55b945e9e 100644
--- a/sbin/ipfstat/Makefile
+++ b/sbin/ipfstat/Makefile
@@ -2,7 +2,7 @@ PROG= ipfstat
MAN= ipfstat.8
SRCS= fils.c parse.c opt.c kmem.c
.PATH: ${.CURDIR}/../../sbin/ipf
-CFLAGS+=-DIPL_NAME=\"/dev/ipl\" -I${.CURDIR}/../../sbin/ipf
+CFLAGS+=-DIPL_NAME=\"/dev/ipl\" -I${.CURDIR}/../../sbin/ipf -I${.CURDIR}/../../sys/netinet
diff --git a/sbin/ipfstat/fils.c b/sbin/ipfstat/fils.c
index 7f440f6da39..ff91986d540 100644
--- a/sbin/ipfstat/fils.c
+++ b/sbin/ipfstat/fils.c
@@ -5,6 +5,7 @@
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
+
#include <stdio.h>
#include <string.h>
#if !defined(__SVR4) && !defined(__svr4__)
@@ -21,10 +22,13 @@
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
+#include <arpa/inet.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <net/if.h>
-#include <netinet/ip_fil.h>
+#include "ip_fil.h"
+#include "ip_frag.h"
+#include "ip_state.h"
#include <netdb.h>
#include <arpa/nameser.h>
#include <resolv.h>
@@ -35,7 +39,7 @@
#endif
#ifndef lint
-static char sccsid[] = "@(#)fils.c 1.15 11/11/95 (C) 1993 Darren Reed";
+static char sccsid[] = "@(#)fils.c 1.18 1/12/96 (C) 1993 Darren Reed";
#endif
#ifdef _PATH_UNIX
#define VMUNIX _PATH_UNIX
@@ -44,21 +48,27 @@ static char sccsid[] = "@(#)fils.c 1.15 11/11/95 (C) 1993 Darren Reed";
#endif
extern char *optarg;
-#define F_ST 0
-#define F_IN 1
-#define F_OUT 2
-#define F_FL 3
+
+#define PRINTF (void)printf
+#define FPRINTF (void)fprintf
+#define F_IN 0
+#define F_OUT 1
+#define F_AC 2
+static char *filters[4] = { "ipfilter(in)", "ipfilter(out)",
+ "ipacct(in)", "ipacct(out)" };
int opts = 0;
-static void showstats();
-static void showlist();
+static void showstats(), showfrstates();
+static void showlist(), showipstates();
int main(argc,argv)
int argc;
char *argv[];
{
- struct friostat fio;
+ friostat_t fio;
+ ips_stat_t ipsst;
+ ipfrstat_t ifrst;
char c, *name = NULL, *device = IPL_NAME;
int fd;
@@ -68,13 +78,19 @@ char *argv[];
(void)setuid(getuid());
(void)setgid(getgid());
- while ((c = getopt(argc, argv, "hIiovd:")) != -1)
+ while ((c = getopt(argc, argv, "afhIiosvd:")) != -1)
{
switch (c)
{
+ case 'a' :
+ opts |= OPT_ACCNT|OPT_SHOWLIST;
+ break;
case 'd' :
device = optarg;
break;
+ case 'f' :
+ opts |= OPT_FRSTATES;
+ break;
case 'h' :
opts |= OPT_HITS;
break;
@@ -87,6 +103,9 @@ char *argv[];
case 'o' :
opts |= OPT_OUTQUE|OPT_SHOWLIST;
break;
+ case 's' :
+ opts |= OPT_IPSTATES;
+ break;
case 'v' :
opts |= OPT_VERBOSE;
break;
@@ -97,23 +116,40 @@ char *argv[];
perror("open");
exit(-1);
}
+
bzero((char *)&fio, sizeof(fio));
+ bzero((char *)&ipsst, sizeof(ipsst));
+ bzero((char *)&ifrst, sizeof(ifrst));
+
if (ioctl(fd, SIOCGETFS, &fio) == -1) {
perror("ioctl(SIOCGETFS)");
exit(-1);
}
+ if ((opts & OPT_IPSTATES) && (ioctl(fd, SIOCGIPST, &ipsst) == -1)) {
+ perror("ioctl(SIOCGIPST)");
+ exit(-1);
+ }
+ if ((opts & OPT_FRSTATES) && (ioctl(fd, SIOCGFRST, &ifrst) == -1)) {
+ perror("ioctl(SIOCGFRST)");
+ exit(-1);
+ }
if (opts & OPT_VERBOSE)
- printf("opts %#x name %s\n", opts, name ? name : "<>");
- if (opts & OPT_SHOWLIST){
+ PRINTF("opts %#x name %s\n", opts, name ? name : "<>");
+ if (opts & OPT_SHOWLIST) {
showlist(&fio);
if((opts & OPT_OUTQUE) && (opts & OPT_INQUE)){
opts &= ~OPT_OUTQUE;
showlist(&fio);
}
+ } else {
+ if (opts & OPT_IPSTATES)
+ showipstates(fd, &ipsst);
+ else if (opts & OPT_FRSTATES)
+ showfrstates(fd, &ifrst);
+ else
+ showstats(fd, &fio);
}
- else
- showstats(fd, &fio);
return 0;
}
@@ -131,36 +167,46 @@ struct friostat *fp;
perror("ioctl(SIOCGETFF)");
#if SOLARIS
- (void)printf("dropped packets:\tin %ld\tout %ld\n",
+ PRINTF("dropped packets:\tin %lu\tout %lu\n",
fp->f_st[0].fr_drop, fp->f_st[1].fr_drop);
- (void)printf("non-ip packets:\t\tin %ld\tout %ld\n",
+ PRINTF("non-ip packets:\t\tin %lu\tout %lu\n",
fp->f_st[0].fr_notip, fp->f_st[1].fr_notip);
- (void)printf(" bad packets:\t\tin %ld\tout %ld\n",
+ PRINTF(" bad packets:\t\tin %lu\tout %lu\n",
fp->f_st[0].fr_bad, fp->f_st[1].fr_bad);
#endif
- (void)printf(" input packets:\t\tblocked %ld passed %ld nomatch %ld\n",
+ PRINTF(" input packets:\t\tblocked %lu passed %lu nomatch %lu",
fp->f_st[0].fr_block, fp->f_st[0].fr_pass,
fp->f_st[0].fr_nom);
- (void)printf("output packets:\t\tblocked %ld passed %ld nomatch %ld\n",
+ PRINTF(" counted %lu\n", fp->f_st[0].fr_acct);
+ PRINTF("output packets:\t\tblocked %lu passed %lu nomatch %lu",
fp->f_st[1].fr_block, fp->f_st[1].fr_pass,
fp->f_st[1].fr_nom);
- (void)printf(" input packets logged:\tblocked %ld passed %ld\n",
+ PRINTF(" counted %lu\n", fp->f_st[0].fr_acct);
+ PRINTF(" input packets logged:\tblocked %lu passed %lu\n",
fp->f_st[0].fr_bpkl, fp->f_st[0].fr_ppkl);
- (void)printf("output packets logged:\tblocked %ld passed %ld\n",
+ PRINTF("output packets logged:\tblocked %lu passed %lu\n",
fp->f_st[1].fr_bpkl, fp->f_st[1].fr_ppkl);
- (void)printf(" packets logged:\tinput %ld-%ld output %ld-%ld\n",
+ PRINTF(" packets logged:\tinput %lu-%lu output %lu-%lu\n",
fp->f_st[0].fr_pkl, fp->f_st[0].fr_skip,
fp->f_st[1].fr_pkl, fp->f_st[1].fr_skip);
- (void)printf("ICMP replies:\t%ld\tTCP RSTs sent:\t%ld\n",
+ PRINTF("fragment state(in):\tkept %lu\tlost %lu\n",
+ fp->f_st[0].fr_nfr, fp->f_st[0].fr_bnfr);
+ PRINTF("fragment state(out):\tkept %lu\tlost %lu\n",
+ fp->f_st[1].fr_nfr, fp->f_st[1].fr_bnfr);
+ PRINTF("packet state(in):\tkept %lu\tlost %lu\n",
+ fp->f_st[0].fr_ads, fp->f_st[0].fr_bads);
+ PRINTF("packet state(out):\tkept %lu\tlost %lu\n",
+ fp->f_st[1].fr_ads, fp->f_st[1].fr_bads);
+ PRINTF("ICMP replies:\t%lu\tTCP RSTs sent:\t%lu\n",
fp->f_st[0].fr_ret, fp->f_st[1].fr_ret);
- (void)printf("Packet log flags set: (%#x)\n", frf);
+ PRINTF("Packet log flags set: (%#x)\n", frf);
if (frf & FF_LOGPASS)
- printf("\tpackets passed through filter\n");
+ PRINTF("\tpackets passed through filter\n");
if (frf & FF_LOGBLOCK)
- printf("\tpackets blocked by filter\n");
+ PRINTF("\tpackets blocked by filter\n");
if (!frf)
- printf("\tnone\n");
+ PRINTF("\tnone\n");
}
/*
@@ -173,25 +219,33 @@ struct friostat *fiop;
struct frentry *fp = NULL;
int i, set;
- if (opts & OPT_OUTQUE)
- i = F_OUT;
- else if (opts & OPT_INQUE)
- i = F_IN;
- else
- return;
set = fiop->f_active;
if (opts & OPT_INACTIVE)
set = 1 - set;
- fp = (i == F_IN) ? (struct frentry *)fiop->f_fin[set] :
- (struct frentry *)fiop->f_fout[set];
+ if (opts & OPT_ACCNT) {
+ i = F_AC;
+ if (opts & OPT_INQUE)
+ fp = (struct frentry *)fiop->f_acctin[set];
+ else {
+ fp = (struct frentry *)fiop->f_acctout[set];
+ i++;
+ }
+ } else if (opts & OPT_OUTQUE) {
+ i = F_OUT;
+ fp = (struct frentry *)fiop->f_fout[set];
+ } else if (opts & OPT_INQUE) {
+ i = F_IN;
+ fp = (struct frentry *)fiop->f_fin[set];
+ } else
+ return;
if (opts & OPT_VERBOSE)
- (void)fprintf(stderr, "showlist:opts %#x i %d\n", opts, i);
+ FPRINTF(stderr, "showlist:opts %#x i %d\n", opts, i);
if (opts & OPT_VERBOSE)
- printf("fp %#x set %d\n", (u_int)fp, set);
+ PRINTF("fp %#x set %d\n", (u_int)fp, set);
if (!fp) {
- (void)fprintf(stderr, "empty list for filter%s\n",
- (i == F_IN) ? "in" : "out");
+ FPRINTF(stderr, "empty list for %s%s\n",
+ (opts & OPT_INACTIVE) ? "inactive " : "", filters[i]);
return;
}
while (fp) {
@@ -203,10 +257,82 @@ struct friostat *fiop;
if (opts & OPT_OUTQUE)
fp->fr_flags |= FR_OUTQUE;
if (opts & (OPT_HITS|OPT_VERBOSE))
- printf("%d ", fp->fr_hits);
+ PRINTF("%ld ", fp->fr_hits);
+ if (opts & (OPT_ACCNT|OPT_VERBOSE))
+ PRINTF("%ld ", fp->fr_bytes);
printfr(fp);
if (opts & OPT_VERBOSE)
binprint(fp);
fp = fp->fr_next;
}
}
+
+
+static void showipstates(fd, ipsp)
+int fd;
+ips_stat_t *ipsp;
+{
+ ipstate_t *istab[IPSTATE_SIZE], ips;
+ int i;
+
+ PRINTF("IP states added:\n\t%lu TCP\n\t%lu UDP\n\t%lu ICMP\n",
+ ipsp->iss_tcp, ipsp->iss_udp, ipsp->iss_icmp);
+ PRINTF("\t%lu hits\n\t%lu misses\n", ipsp->iss_hits, ipsp->iss_miss);
+ PRINTF("\t%lu maximum\n\t%lu no memory\n",
+ ipsp->iss_max, ipsp->iss_nomem);
+ PRINTF("\t%lu active\n\t%lu expired\n\t%lu closed\n",
+ ipsp->iss_active, ipsp->iss_expire, ipsp->iss_fin);
+ if (kmemcpy((char *)istab, (u_long)ipsp->iss_table, sizeof(istab)))
+ return;
+ for (i = 0; i < IPSTATE_SIZE; i++)
+ while (istab[i]) {
+ if (kmemcpy(&ips, istab[i], sizeof(ips)) == -1)
+ break;
+ PRINTF("%s -> ", inet_ntoa(ips.is_src));
+ PRINTF("%s age %d pass %d pr %d\n",
+ inet_ntoa(ips.is_dst), ips.is_age,
+ ips.is_pass, ips.is_p);
+ if (ips.is_p == IPPROTO_TCP)
+ PRINTF("\t%hu -> %hu %lu:%lu %hu\n",
+ ntohs(ips.is_sport),
+ ntohs(ips.is_dport),
+ ips.is_seq, ips.is_ack, ips.is_win);
+ else if (ips.is_p == IPPROTO_UDP)
+ PRINTF("\t%hu -> %hu\n", ntohs(ips.is_sport),
+ ntohs(ips.is_dport));
+ else if (ips.is_p == IPPROTO_ICMP)
+ PRINTF("\t%hu %hu %d\n", ips.is_icmp.ics_id,
+ ips.is_icmp.ics_seq,
+ ips.is_icmp.ics_type);
+ istab[i] = ips.is_next;
+ }
+}
+
+
+static void showfrstates(fd, ifsp)
+int fd;
+ipfrstat_t *ifsp;
+{
+ struct ipfr *ipfrtab[IPFT_SIZE], ifr;
+ int i;
+
+ PRINTF("IP fragment states:\n\t%lu new\n\t%lu expired\n\t%lu hits\n",
+ ifsp->ifs_new, ifsp->ifs_expire, ifsp->ifs_hits);
+ PRINTF("\t%lu no memory\n\t%lu already exist\n",
+ ifsp->ifs_nomem, ifsp->ifs_exists);
+ PRINTF("\t%lu inuse\n", ifsp->ifs_inuse);
+ if (kmemcpy((char *)ipfrtab, (u_long)ifsp->ifs_table, sizeof(ipfrtab)))
+ return;
+ for (i = 0; i < IPFT_SIZE; i++)
+ while (ipfrtab[i]) {
+ if (kmemcpy(&ifr, (u_long)ipfrtab[i],
+ sizeof(ifr)) == -1)
+ break;
+ PRINTF("%s -> ", inet_ntoa(ifr.ipfr_src));
+ PRINTF("%s %d %d %d %#02x = %#x\n",
+ inet_ntoa(ifr.ipfr_dst), ifr.ipfr_id,
+ ifr.ipfr_ttl, ifr.ipfr_p, ifr.ipfr_tos,
+ ifr.ipfr_pass);
+ ipfrtab[i] = ifr.ipfr_next;
+ }
+}
diff --git a/sbin/ipfstat/ipfstat.8 b/sbin/ipfstat/ipfstat.8
index bfc8b2ae262..1b378541580 100644
--- a/sbin/ipfstat/ipfstat.8
+++ b/sbin/ipfstat/ipfstat.8
@@ -16,20 +16,28 @@ The default behaviour of \fBipfstat\fP
is to retrieve and display the accumulated statistics which have been
accumulated over time as the kernel has put packets through the filter.
.SH OPTIONS
-.IP -o
-display the filter list used for the output side of the kernel IP processing.
-.IP -i
-display the filter list used for the input side of the kernel IP processing.
-.IP -v
-turn verbose mode on. Displays more debugging information.
+.IP -a
+display the accounting filter list and show bytes counted against each rule.
.IP -d <device>
use a device other than \fB/dev/ipl\fP for interfacing with the kernel.
-.IP -I
-swap between retrieving "inactive"/"active" filter list details. For use
-in combination with \fB-i\fP.
+.IP -f
+show fragment state information (statistics) and held state information (in
+the kernel) if any is present.
.IP -h
show per-rule the number of times each one scores a "hit". For use in
combination with \fB-i\fP.
+.IP -i
+display the filter list used for the input side of the kernel IP processing.
+.IP -I
+swap between retrieving "inactive"/"active" filter list details. For use
+in combination with \fB-i\fP.
+.IP -o
+display the filter list used for the output side of the kernel IP processing.
+.IP -s
+show packet/flow state information (statistics) and held state information (in
+the kernel) if any is present.
+.IP -v
+turn verbose mode on. Displays more debugging information.
.SH SYNOPSIS
The role of \fBipfstat\fP is to display current kernel statistics gathered
as a result of applying the filters in place (if any) to packets going in and
diff --git a/sbin/ipfstat/kmem.c b/sbin/ipfstat/kmem.c
index 4c0dbe3b520..159ff8456a1 100644
--- a/sbin/ipfstat/kmem.c
+++ b/sbin/ipfstat/kmem.c
@@ -10,6 +10,7 @@
* returns 0 on success, -1 on error.
*/
+#include <stdio.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
@@ -19,7 +20,7 @@
#define KMEM "/dev/kmem"
#ifndef lint
-static char sccsid[] = "@(#)kmem.c 1.3 10/15/95 (C) 1992 Darren Reed";
+static char sccsid[] = "@(#)kmem.c 1.4 1/12/96 (C) 1992 Darren Reed";
#endif
static int kmemfd = -1;