aboutsummaryrefslogtreecommitdiff
path: root/contrib/ipfilter/fils.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ipfilter/fils.c')
-rw-r--r--contrib/ipfilter/fils.c688
1 files changed, 410 insertions, 278 deletions
diff --git a/contrib/ipfilter/fils.c b/contrib/ipfilter/fils.c
index 3ed698abb34f..b3bfae2758c6 100644
--- a/contrib/ipfilter/fils.c
+++ b/contrib/ipfilter/fils.c
@@ -12,6 +12,9 @@
# endif
# endif
#endif
+#ifdef __sgi
+# include <sys/ptimers.h>
+#endif
#include <stdio.h>
#include <string.h>
#if !defined(__SVR4) && !defined(__svr4__)
@@ -21,8 +24,24 @@
#include <sys/time.h>
#include <sys/param.h>
#include <sys/file.h>
-#if defined(STATETOP) && defined(sun) && !defined(__svr4__) && !defined(__SVR4)
-#include <sys/select.h>
+#if defined(STATETOP)
+# if defined(_BSDI_VERSION)
+# undef STATETOP)
+# endif
+# if defined(__FreeBSD__) && \
+ (!defined(__FreeBSD_version) || (__FreeBSD_version < 430000))
+# undef STATETOP
+# endif
+# if defined(__NetBSD_Version__) && (__NetBSD_Version__ < 105000000)
+# undef STATETOP
+# endif
+# if defined(sun)
+# if defined(__svr4__) || defined(__SVR4)
+# include <sys/select.h>
+# else
+# undef STATETOP /* NOT supported on SunOS4 */
+# endif
+# endif
#endif
#include <stdlib.h>
#include <unistd.h>
@@ -50,15 +69,16 @@
#include "netinet/ip_compat.h"
#include "netinet/ip_fil.h"
#include "ipf.h"
-#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_frag.h"
#include "netinet/ip_state.h"
+#include "netinet/ip_proxy.h"
#include "netinet/ip_auth.h"
#ifdef STATETOP
# include "netinet/ipl.h"
# include <ctype.h>
-# if SOLARIS
+# if SOLARIS || defined(__NetBSD__) || defined(_BSDI_VERSION) || \
+ defined(__sgi)
# ifdef ERR
# undef ERR
# endif
@@ -74,7 +94,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: fils.c,v 2.21.2.17 2001/07/19 12:24:09 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: fils.c,v 2.21.2.34 2002/02/22 15:32:45 darrenr Exp $";
#endif
extern char *optarg;
@@ -89,9 +109,8 @@ static char *filters[4] = { "ipfilter(in)", "ipfilter(out)",
"ipacct(in)", "ipacct(out)" };
int opts = 0;
-#ifdef USE_INET6
int use_inet6 = 0;
-#endif
+int live_kernel = 1;
#ifdef STATETOP
#define STSTRSIZE 80
@@ -102,7 +121,9 @@ int use_inet6 = 0;
#define STSORT_PKTS 1
#define STSORT_BYTES 2
#define STSORT_TTL 3
-#define STSORT_MAX STSORT_TTL
+#define STSORT_SRCIP 4
+#define STSORT_DSTIP 5
+#define STSORT_MAX STSORT_DSTIP
#define STSORT_DEFAULT STSORT_BYTES
@@ -120,51 +141,33 @@ typedef struct statetop {
#endif
extern int main __P((int, char *[]));
-static void showstats __P((int, friostat_t *));
-static void showfrstates __P((int, ipfrstat_t *));
+static void showstats __P((friostat_t *, u_32_t));
+static void showfrstates __P((ipfrstat_t *));
static void showlist __P((friostat_t *));
-static void showipstates __P((int, ips_stat_t *));
-static void showauthstates __P((int, fr_authstat_t *));
+static void showipstates __P((ips_stat_t *));
+static void showauthstates __P((fr_authstat_t *));
static void showgroups __P((friostat_t *));
static void Usage __P((char *));
static void printlist __P((frentry_t *));
-static char *get_ifname __P((void *));
-static char *hostname __P((int, void *));
static void parse_ipportstr __P((const char *, struct in_addr *, int *));
+static int ipfstate_live __P((char *, friostat_t **, ips_stat_t **,
+ ipfrstat_t **, fr_authstat_t **, u_32_t *));
+static void ipfstate_dead __P((char *, friostat_t **, ips_stat_t **,
+ ipfrstat_t **, fr_authstat_t **, u_32_t *));
#ifdef STATETOP
-static void topipstates __P((int, struct in_addr, struct in_addr, int, int, int, int, int));
+static void topipstates __P((struct in_addr, struct in_addr, int, int, int, int, int));
static char *ttl_to_string __P((long));
static int sort_p __P((const void *, const void *));
static int sort_pkts __P((const void *, const void *));
static int sort_bytes __P((const void *, const void *));
static int sort_ttl __P((const void *, const void *));
+static int sort_srcip __P((const void *, const void *));
+static int sort_dstip __P((const void *, const void *));
#endif
#if SOLARIS
void showqiflist __P((char *));
#endif
-static char *hostname(v, ip)
-int v;
-void *ip;
-{
-#ifdef USE_INET6
- static char hostbuf[MAXHOSTNAMELEN+1];
-#endif
- struct in_addr ipa;
-
- if (v == 4) {
- ipa.s_addr = *(u_32_t *)ip;
- return inet_ntoa(ipa);
- }
-#ifdef USE_INET6
- (void) inet_ntop(AF_INET6, ip, hostbuf, sizeof(hostbuf) - 1);
- hostbuf[MAXHOSTNAMELEN] = '\0';
- return hostbuf;
-#else
- return "IPv6";
-#endif
-}
-
static void Usage(name)
char *name;
@@ -174,11 +177,8 @@ char *name;
#else
fprintf(stderr, "Usage: %s [-aAfhIinosv] [-d <device>]\n", name);
#endif
- fprintf(stderr, "\t\t[-M corefile]");
-#if SOLARIS
- fprintf(stderr, " [-N symbol-list]");
-#endif
- fprintf(stderr, "\n %s -t [-S source address] [-D destination address] [-P protocol] [-T refreshtime] [-C] [-d <device>]\n", name);
+ fprintf(stderr, "\t\t[-M corefile] [-N symbol-list]\n");
+ fprintf(stderr, " %s -t [-S source address] [-D destination address] [-P protocol] [-T refreshtime] [-C] [-d <device>]\n", name);
exit(1);
}
@@ -190,15 +190,13 @@ char *argv[];
fr_authstat_t frauthst;
fr_authstat_t *frauthstp = &frauthst;
friostat_t fio;
- friostat_t *fiop=&fio;
+ friostat_t *fiop = &fio;
ips_stat_t ipsst;
ips_stat_t *ipsstp = &ipsst;
ipfrstat_t ifrst;
ipfrstat_t *ifrstp = &ifrst;
- char *name = NULL, *device = IPL_NAME, *memf = NULL;
-#if SOLARIS
+ char *device = IPL_NAME, *memf = NULL;
char *kern = NULL;
-#endif
int c, fd, myoptind;
struct protoent *proto;
@@ -208,6 +206,8 @@ char *argv[];
int dport = -1; /* -1 = wild card for any dest port */
int topclosed = 0; /* do not show closed tcp sessions */
struct in_addr saddr, daddr;
+ u_32_t frf;
+
saddr.s_addr = INADDR_ANY; /* default any source addr */
daddr.s_addr = INADDR_ANY; /* default any dest addr */
@@ -216,45 +216,33 @@ char *argv[];
* in the parsing of the rest.
*/
myoptind = optind;
-#if SOLARIS
while ((c = getopt(argc, argv, "6aACfghIilnoqstvd:D:M:N:P:S:T:")) != -1)
-#else
- while ((c = getopt(argc, argv, "6aACfghIilnoqstvd:D:M:P:S:T:")) != -1)
-#endif
switch (c)
{
case 'M' :
memf = optarg;
+ live_kernel = 0;
break;
-#if SOLARIS
case 'N' :
kern = optarg;
+ live_kernel = 0;
break;
-#endif
}
optind = myoptind;
-#if SOLARIS
if (kern != NULL || memf != NULL)
-#else
- if (memf != NULL)
-#endif
{
(void)setuid(getuid());
(void)setgid(getgid());
}
- if (openkmem(memf) == -1)
+ if (openkmem(kern, memf) == -1)
exit(-1);
(void)setuid(getuid());
(void)setgid(getgid());
-#if SOLARIS
while ((c = getopt(argc, argv, "6aACfghIilnoqstvd:D:M:N:P:S:T:")) != -1)
-#else
- while ((c = getopt(argc, argv, "6aACfghIilnostvd:D:M:P:S:T:")) != -1)
-#endif
{
switch (c)
{
@@ -265,7 +253,8 @@ char *argv[];
#endif
case 'a' :
opts |= OPT_ACCNT|OPT_SHOWLIST;
- break; case 'A' :
+ break;
+ case 'A' :
device = IPAUTH_NAME;
opts |= OPT_AUTHSTATS;
break;
@@ -316,11 +305,15 @@ char *argv[];
exit(-2);
}
break;
-#if SOLARIS
case 'q' :
+#if SOLARIS
showqiflist(kern);
exit(0);
break;
+#else
+ fprintf(stderr, "-q only availble on Solaris\n");
+ exit(1);
+ break;
#endif
case 's' :
opts |= OPT_IPSTATES;
@@ -356,19 +349,67 @@ char *argv[];
}
}
+ if (live_kernel == 1) {
+ bzero((char *)&fio, sizeof(fio));
+ bzero((char *)&ipsst, sizeof(ipsst));
+ bzero((char *)&ifrst, sizeof(ifrst));
+
+ fd = ipfstate_live(device, &fiop, &ipsstp, &ifrstp,
+ &frauthstp, &frf);
+ } else
+ ipfstate_dead(kern, &fiop, &ipsstp, &ifrstp, &frauthstp, &frf);
+
+ if (opts & OPT_IPSTATES) {
+ showipstates(ipsstp);
+ } else if (opts & OPT_SHOWLIST) {
+ showlist(fiop);
+ if ((opts & OPT_OUTQUE) && (opts & OPT_INQUE)){
+ opts &= ~OPT_OUTQUE;
+ showlist(fiop);
+ }
+ } else {
+ if (opts & OPT_FRSTATES)
+ showfrstates(ifrstp);
+#ifdef STATETOP
+ else if (opts & OPT_STATETOP)
+ topipstates(saddr, daddr, sport, dport,
+ protocol, refreshtime, topclosed);
+#endif
+ else if (opts & OPT_AUTHSTATS)
+ showauthstates(frauthstp);
+ else if (opts & OPT_GROUPS)
+ showgroups(fiop);
+ else
+ showstats(fiop, frf);
+ }
+ return 0;
+}
+
+
+/*
+ * Fill in the stats structures from the live kernel, using a combination
+ * of ioctl's and copying directly from kernel memory.
+ */
+int ipfstate_live(device, fiopp, ipsstpp, ifrstpp, frauthstpp, frfp)
+char *device;
+friostat_t **fiopp;
+ips_stat_t **ipsstpp;
+ipfrstat_t **ifrstpp;
+fr_authstat_t **frauthstpp;
+u_32_t *frfp;
+{
+ int fd;
+
if ((fd = open(device, O_RDONLY)) < 0) {
perror("open");
exit(-1);
}
- bzero((char *)&fio, sizeof(fio));
- bzero((char *)&ipsst, sizeof(ipsst));
- bzero((char *)&ifrst, sizeof(ifrst));
-
- if (!(opts & OPT_AUTHSTATS) && ioctl(fd, SIOCGETFS, &fiop) == -1) {
+ if (!(opts & OPT_AUTHSTATS) && ioctl(fd, SIOCGETFS, fiopp) == -1) {
perror("ioctl(ipf:SIOCGETFS)");
exit(-1);
}
+
if ((opts & OPT_IPSTATES)) {
int sfd = open(IPL_STATE, O_RDONLY);
@@ -376,64 +417,237 @@ char *argv[];
perror("open");
exit(-1);
}
- if ((ioctl(sfd, SIOCGETFS, &ipsstp) == -1)) {
+ if ((ioctl(sfd, SIOCGETFS, ipsstpp) == -1)) {
perror("ioctl(state:SIOCGETFS)");
exit(-1);
}
close(sfd);
}
- if ((opts & OPT_FRSTATES) && (ioctl(fd, SIOCGFRST, &ifrstp) == -1)) {
+ if ((opts & OPT_FRSTATES) && (ioctl(fd, SIOCGFRST, ifrstpp) == -1)) {
perror("ioctl(SIOCGFRST)");
exit(-1);
}
if (opts & OPT_VERBOSE)
- PRINTF("opts %#x name %s\n", opts, name ? name : "<>");
+ PRINTF("opts %#x name %s\n", opts, device);
if ((opts & OPT_AUTHSTATS) &&
- (ioctl(fd, SIOCATHST, &frauthstp) == -1)) {
+ (ioctl(fd, SIOCATHST, frauthstpp) == -1)) {
perror("ioctl(SIOCATHST)");
exit(-1);
}
- if (opts & OPT_IPSTATES) {
- showipstates(fd, ipsstp);
- } else if (opts & OPT_SHOWLIST) {
- showlist(&fio);
- if ((opts & OPT_OUTQUE) && (opts & OPT_INQUE)){
- opts &= ~OPT_OUTQUE;
- showlist(&fio);
- }
- } else {
- if (opts & OPT_FRSTATES)
- showfrstates(fd, ifrstp);
-#ifdef STATETOP
- else if (opts & OPT_STATETOP)
- topipstates(fd, saddr, daddr, sport, dport,
- protocol, refreshtime, topclosed);
-#endif
- else if (opts & OPT_AUTHSTATS)
- showauthstates(fd, frauthstp);
- else if (opts & OPT_GROUPS)
- showgroups(&fio);
- else
- showstats(fd, &fio);
+ if (ioctl(fd, SIOCGETFF, frfp) == -1)
+ perror("ioctl(SIOCGETFF)");
+
+ return fd;
+}
+
+
+/*
+ * Build up the stats structures from data held in the "core" memory.
+ * This is mainly useful when looking at data in crash dumps and ioctl's
+ * just won't work any more.
+ */
+void ipfstate_dead(kernel, fiopp, ipsstpp, ifrstpp, frauthstpp, frfp)
+char *kernel;
+friostat_t **fiopp;
+ips_stat_t **ipsstpp;
+ipfrstat_t **ifrstpp;
+fr_authstat_t **frauthstpp;
+u_32_t *frfp;
+{
+ static fr_authstat_t frauthst, *frauthstp;
+ static ips_stat_t ipsst, *ipsstp;
+ static ipfrstat_t ifrst, *ifrstp;
+ static friostat_t fio, *fiop;
+
+ void *rules[2][2];
+ struct nlist deadlist[42] = {
+ { "fr_authstats" }, /* 0 */
+ { "fae_list" },
+ { "ipauth" },
+ { "fr_authlist" },
+ { "fr_authstart" },
+ { "fr_authend" }, /* 5 */
+ { "fr_authnext" },
+ { "fr_auth" },
+ { "fr_authused" },
+ { "fr_authsize" },
+ { "fr_defaultauthage" }, /* 10 */
+ { "fr_authpkts" },
+ { "fr_auth_lock" },
+ { "frstats" },
+ { "ips_stats" },
+ { "ips_num" }, /* 15 */
+ { "ips_wild" },
+ { "ips_list" },
+ { "ips_table" },
+ { "fr_statemax" },
+ { "fr_statesize" }, /* 20 */
+ { "fr_state_doflush" },
+ { "fr_state_lock" },
+ { "ipfr_heads" },
+ { "ipfr_nattab" },
+ { "ipfr_stats" }, /* 25 */
+ { "ipfr_inuse" },
+ { "fr_ipfrttl" },
+ { "fr_frag_lock" },
+ { "ipfr_timer_id" },
+ { "fr_nat_lock" }, /* 30 */
+ { "ipfilter" },
+ { "ipfilter6" },
+ { "ipacct" },
+ { "ipacct6" },
+ { "ipl_frouteok" }, /* 35 */
+ { "fr_running" },
+ { "ipfgroups" },
+ { "fr_active" },
+ { "fr_pass" },
+ { "fr_flags" }, /* 40 */
+ { NULL }
+ };
+
+
+ frauthstp = &frauthst;
+ ipsstp = &ipsst;
+ ifrstp = &ifrst;
+ fiop = &fio;
+
+ *frfp = 0;
+ *fiopp = fiop;
+ *ipsstpp = ipsstp;
+ *ifrstpp = ifrstp;
+ *frauthstpp = frauthstp;
+
+ bzero((char *)fiop, sizeof(*fiop));
+ bzero((char *)ipsstp, sizeof(*ipsstp));
+ bzero((char *)ifrstp, sizeof(*ifrstp));
+ bzero((char *)frauthstp, sizeof(*frauthstp));
+
+ if (nlist(kernel, deadlist) == -1) {
+ fprintf(stderr, "nlist error\n");
+ return;
}
- return 0;
+
+ /*
+ * This is for SIOCGETFF.
+ */
+ kmemcpy((char *)frfp, (u_long)deadlist[40].n_value, sizeof(*frfp));
+
+ /*
+ * f_locks is a combination of the lock variable from each part of
+ * ipfilter (state, auth, nat, fragments).
+ */
+ kmemcpy((char *)fiop, (u_long)deadlist[13].n_value, sizeof(*fiop));
+ kmemcpy((char *)&fiop->f_locks[0], (u_long)deadlist[22].n_value,
+ sizeof(fiop->f_locks[0]));
+ kmemcpy((char *)&fiop->f_locks[0], (u_long)deadlist[30].n_value,
+ sizeof(fiop->f_locks[1]));
+ kmemcpy((char *)&fiop->f_locks[2], (u_long)deadlist[28].n_value,
+ sizeof(fiop->f_locks[2]));
+ kmemcpy((char *)&fiop->f_locks[3], (u_long)deadlist[12].n_value,
+ sizeof(fiop->f_locks[3]));
+
+ /*
+ * Get pointers to each list of rules (active, inactive, in, out)
+ */
+ kmemcpy((char *)&rules, (u_long)deadlist[31].n_value, sizeof(rules));
+ fiop->f_fin[0] = rules[0][0];
+ fiop->f_fin[1] = rules[0][1];
+ fiop->f_fout[0] = rules[1][0];
+ fiop->f_fout[1] = rules[1][1];
+
+ /*
+ * Same for IPv6, except make them null if support for it is not
+ * being compiled in.
+ */
+#ifdef USE_INET6
+ kmemcpy((char *)&rules, (u_long)deadlist[32].n_value, sizeof(rules));
+ fiop->f_fin6[0] = rules[0][0];
+ fiop->f_fin6[1] = rules[0][1];
+ fiop->f_fout6[0] = rules[1][0];
+ fiop->f_fout6[1] = rules[1][1];
+#else
+ fiop->f_fin6[0] = NULL;
+ fiop->f_fin6[1] = NULL;
+ fiop->f_fout6[0] = NULL;
+ fiop->f_fout6[1] = NULL;
+#endif
+
+ /*
+ * Now get accounting rules pointers.
+ */
+ kmemcpy((char *)&rules, (u_long)deadlist[33].n_value, sizeof(rules));
+ fiop->f_acctin[0] = rules[0][0];
+ fiop->f_acctin[1] = rules[0][1];
+ fiop->f_acctout[0] = rules[1][0];
+ fiop->f_acctout[1] = rules[1][1];
+
+#ifdef USE_INET6
+ kmemcpy((char *)&rules, (u_long)deadlist[34].n_value, sizeof(rules));
+ fiop->f_acctin6[0] = rules[0][0];
+ fiop->f_acctin6[1] = rules[0][1];
+ fiop->f_acctout6[0] = rules[1][0];
+ fiop->f_acctout6[1] = rules[1][1];
+#else
+ fiop->f_acctin6[0] = NULL;
+ fiop->f_acctin6[1] = NULL;
+ fiop->f_acctout6[0] = NULL;
+ fiop->f_acctout6[1] = NULL;
+#endif
+
+ /*
+ * A collection of "global" variables used inside the kernel which
+ * are all collected in friostat_t via ioctl.
+ */
+ kmemcpy((char *)&fiop->f_froute, (u_long)deadlist[35].n_value,
+ sizeof(fiop->f_froute));
+ kmemcpy((char *)&fiop->f_running, (u_long)deadlist[36].n_value,
+ sizeof(fiop->f_running));
+ kmemcpy((char *)&fiop->f_groups, (u_long)deadlist[37].n_value,
+ sizeof(fiop->f_groups));
+ kmemcpy((char *)&fiop->f_active, (u_long)deadlist[38].n_value,
+ sizeof(fiop->f_active));
+ kmemcpy((char *)&fiop->f_defpass, (u_long)deadlist[39].n_value,
+ sizeof(fiop->f_defpass));
+
+ /*
+ * Build up the state information stats structure.
+ */
+ kmemcpy((char *)ipsstp, (u_long)deadlist[14].n_value, sizeof(*ipsstp));
+ kmemcpy((char *)&ipsstp->iss_active, (u_long)deadlist[15].n_value,
+ sizeof(ipsstp->iss_active));
+ ipsstp->iss_table = (void *)deadlist[18].n_value;
+ ipsstp->iss_list = (void *)deadlist[17].n_value;
+
+ /*
+ * Build up the authentiation information stats structure.
+ */
+ kmemcpy((char *)frauthstp, (u_long)deadlist[0].n_value,
+ sizeof(*frauthstp));
+ frauthstp->fas_faelist = (void *)deadlist[1].n_value;
+
+ /*
+ * Build up the fragment information stats structure.
+ */
+ kmemcpy((char *)ifrstp, (u_long)deadlist[25].n_value,
+ sizeof(*ifrstp));
+ ifrstp->ifs_table = (void *)deadlist[23].n_value;
+ ifrstp->ifs_nattab = (void *)deadlist[24].n_value;
+ kmemcpy((char *)&ifrstp->ifs_inuse, (u_long)deadlist[26].n_value,
+ sizeof(ifrstp->ifs_inuse));
}
/*
- * read the kernel stats for packets blocked and passed
+ * Display the kernel stats for packets blocked and passed and other
+ * associated running totals which are kept.
*/
-static void showstats(fd, fp)
-int fd;
+static void showstats(fp, frf)
struct friostat *fp;
+u_32_t frf;
{
- u_32_t frf = 0;
-
- if (ioctl(fd, SIOCGETFF, &frf) == -1)
- perror("ioctl(SIOCGETFF)");
#if SOLARIS
PRINTF("dropped packets:\tin %lu\tout %lu\n",
@@ -505,6 +719,9 @@ struct friostat *fp;
}
+/*
+ * Print out a list of rules from the kernel, starting at the one passed.
+ */
static void printlist(fp)
frentry_t *fp;
{
@@ -543,7 +760,8 @@ frentry_t *fp;
}
/*
- * print out filter rule list
+ * print out all of the asked for rule sets, using the stats struct as
+ * the base from which to get the pointers.
*/
static void showlist(fiop)
struct friostat *fiop;
@@ -598,12 +816,17 @@ struct friostat *fiop;
}
-static void showipstates(fd, ipsp)
-int fd;
+/*
+ * Display ipfilter stateful filtering information
+ */
+static void showipstates(ipsp)
ips_stat_t *ipsp;
{
- ipstate_t *istab[IPSTATE_SIZE], ips;
+ ipstate_t *istab[IPSTATE_SIZE];
+ /*
+ * If a list of states hasn't been asked for, only print out stats
+ */
if (!(opts & OPT_SHOWLIST)) {
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);
@@ -619,116 +842,20 @@ ips_stat_t *ipsp;
if (kmemcpy((char *)istab, (u_long)ipsp->iss_table, sizeof(istab)))
return;
- while (ipsp->iss_list) {
- if (kmemcpy((char *)&ips, (u_long)ipsp->iss_list, sizeof(ips)))
- break;
- ipsp->iss_list = ips.is_next;
- PRINTF("%s -> ", hostname(ips.is_v, &ips.is_src.in4));
- PRINTF("%s ttl %ld pass %#x pr %d state %d/%d\n",
- hostname(ips.is_v, &ips.is_dst.in4),
- ips.is_age, ips.is_pass, ips.is_p,
- ips.is_state[0], ips.is_state[1]);
-#ifdef USE_QUAD_T
- PRINTF("\tpkts %qu bytes %qu",
- (unsigned long long) ips.is_pkts,
- (unsigned long long) ips.is_bytes);
-#else
- PRINTF("\tpkts %ld bytes %ld", ips.is_pkts, ips.is_bytes);
-#endif
- if (ips.is_p == IPPROTO_TCP)
-#if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \
- (__FreeBSD_version >= 220000) || defined(__OpenBSD__)
- PRINTF("\t%hu -> %hu %x:%x %hu:%hu",
- ntohs(ips.is_sport), ntohs(ips.is_dport),
- ips.is_send, ips.is_dend,
- ips.is_maxswin, ips.is_maxdwin);
-#else
- PRINTF("\t%hu -> %hu %x:%x %hu:%hu",
- ntohs(ips.is_sport), ntohs(ips.is_dport),
- ips.is_send, ips.is_dend,
- ips.is_maxswin, ips.is_maxdwin);
-#endif
- else if (ips.is_p == IPPROTO_UDP)
- PRINTF(" %hu -> %hu", ntohs(ips.is_sport),
- ntohs(ips.is_dport));
- else if (ips.is_p == IPPROTO_ICMP
-#ifdef USE_INET6
- || ips.is_p == IPPROTO_ICMPV6
-#endif
- )
- PRINTF(" %hu %hu %d", ips.is_icmp.ics_id,
- ips.is_icmp.ics_seq, ips.is_icmp.ics_type);
-
- PRINTF("\n\t");
-
- if (ips.is_pass & FR_PASS) {
- PRINTF("pass");
- } else if (ips.is_pass & FR_BLOCK) {
- PRINTF("block");
- switch (ips.is_pass & FR_RETMASK)
- {
- case FR_RETICMP :
- PRINTF(" return-icmp");
- break;
- case FR_FAKEICMP :
- PRINTF(" return-icmp-as-dest");
- break;
- case FR_RETRST :
- PRINTF(" return-rst");
- break;
- default :
- break;
- }
- } else if ((ips.is_pass & FR_LOGMASK) == FR_LOG) {
- PRINTF("log");
- if (ips.is_pass & FR_LOGBODY)
- PRINTF(" body");
- if (ips.is_pass & FR_LOGFIRST)
- PRINTF(" first");
- } else if (ips.is_pass & FR_ACCOUNT)
- PRINTF("count");
-
- if (ips.is_pass & FR_OUTQUE)
- PRINTF(" out");
- else
- PRINTF(" in");
-
- if ((ips.is_pass & FR_LOG) != 0) {
- PRINTF(" log");
- if (ips.is_pass & FR_LOGBODY)
- PRINTF(" body");
- if (ips.is_pass & FR_LOGFIRST)
- PRINTF(" first");
- if (ips.is_pass & FR_LOGORBLOCK)
- PRINTF(" or-block");
- }
- if (ips.is_pass & FR_QUICK)
- PRINTF(" quick");
- if (ips.is_pass & FR_KEEPFRAG)
- PRINTF(" keep frags");
- /* a given; no? */
- if (ips.is_pass & FR_KEEPSTATE)
- PRINTF(" keep state");
- PRINTF("\tIPv%d", ips.is_v);
- PRINTF("\n");
-
- PRINTF("\tpkt_flags & %x(%x) = %x,\t",
- ips.is_flags & 0xf, ips.is_flags,
- ips.is_flags >> 4);
- PRINTF("\tpkt_options & %x = %x\n", ips.is_optmsk,
- ips.is_opt);
- PRINTF("\tpkt_security & %x = %x, pkt_auth & %x = %x\n",
- ips.is_secmsk, ips.is_sec, ips.is_authmsk,
- ips.is_auth);
- PRINTF("\tinterfaces: in %s[%p] ",
- get_ifname(ips.is_ifpin), ips.is_ifpin);
- PRINTF("out %s[%p]\n",
- get_ifname(ips.is_ifpout), ips.is_ifpout);
+ /*
+ * Print out all the state information currently held in the kernel.
+ */
+ while (ipsp->iss_list != NULL) {
+ ipsp->iss_list = printstate(ipsp->iss_list, opts);
}
}
#if SOLARIS
+/*
+ * Displays the list of interfaces of which IPFilter has taken control in
+ * Solaris.
+ */
void showqiflist(kern)
char *kern;
{
@@ -737,6 +864,7 @@ char *kern;
{ NULL }
};
qif_t qif, *qf;
+ ill_t ill;
if (kern == NULL)
kern = "/dev/ksyms";
@@ -752,24 +880,27 @@ char *kern;
while (qf) {
if (kmemcpy((char *)&qif, (u_long)qf, sizeof(qif)))
break;
- printf("\tName: %-8s Header Length: %2d SAP: %s (%04x)\n",
+ if (kmemcpy((char *)&ill, (u_long)qif.qf_ill, sizeof(ill)))
+ ill.ill_ppa = -1;
+ printf("Name: %-8s Header Length: %2d SAP: %s (%04x) PPA %d",
qif.qf_name, qif.qf_hl,
#ifdef IP6_DL_SAP
(qif.qf_sap == IP6_DL_SAP) ? "IPv6" : "IPv4"
#else
"IPv4"
#endif
- , qif.qf_sap);
+ , qif.qf_sap, ill.ill_ppa);
+ printf(" %ld %ld", qif.qf_incnt, qif.qf_outcnt);
qf = qif.qf_next;
+ putchar('\n');
}
}
#endif
#ifdef STATETOP
-static void topipstates(fd, saddr, daddr, sport, dport, protocol,
+static void topipstates(saddr, daddr, sport, dport, protocol,
refreshtime, topclosed)
-int fd;
struct in_addr saddr;
struct in_addr daddr;
int sport;
@@ -841,8 +972,8 @@ int topclosed;
((dport < 0) ||
(htons(dport) == ips.is_dport)))) &&
(topclosed || (ips.is_p != IPPROTO_TCP) ||
- (ips.is_state[0] < TCPS_CLOSE_WAIT) ||
- (ips.is_state[1] < TCPS_CLOSE_WAIT))) {
+ (ips.is_state[0] < TCPS_LAST_ACK) ||
+ (ips.is_state[1] < TCPS_LAST_ACK))) {
/*
* if necessary make room for this state
* entry
@@ -899,6 +1030,14 @@ int topclosed;
qsort(tstable, tsentry + 1,
sizeof(statetop_t), sort_ttl);
break;
+ case STSORT_SRCIP:
+ qsort(tstable, tsentry + 1,
+ sizeof(statetop_t), sort_srcip);
+ break;
+ case STSORT_DSTIP:
+ qsort(tstable, tsentry + 1,
+ sizeof(statetop_t), sort_dstip);
+ break;
default:
break;
}
@@ -957,6 +1096,12 @@ int topclosed;
case STSORT_TTL:
sprintf(str4, "ttl");
break;
+ case STSORT_SRCIP:
+ sprintf(str4, "srcip");
+ break;
+ case STSORT_DSTIP:
+ sprintf(str4, "dstip");
+ break;
default:
sprintf(str4, "unknown");
break;
@@ -1079,14 +1224,20 @@ int topclosed;
}
#endif
-static void showfrstates(fd, ifsp)
-int fd;
+
+/*
+ * Show fragment cache information that's held in the kernel.
+ */
+static void showfrstates(ifsp)
ipfrstat_t *ifsp;
{
struct ipfr *ipfrtab[IPFT_SIZE], ifr;
frentry_t fr;
int i;
+ /*
+ * print out the numeric statistics
+ */
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",
@@ -1094,6 +1245,10 @@ ipfrstat_t *ifsp;
PRINTF("\t%lu inuse\n", ifsp->ifs_inuse);
if (kmemcpy((char *)ipfrtab, (u_long)ifsp->ifs_table, sizeof(ipfrtab)))
return;
+
+ /*
+ * Print out the contents (if any) of the fragment cache table.
+ */
for (i = 0; i < IPFT_SIZE; i++)
while (ipfrtab[i]) {
if (kmemcpy((char *)&ifr, (u_long)ipfrtab[i],
@@ -1129,8 +1284,10 @@ ipfrstat_t *ifsp;
}
-static void showauthstates(fd, asp)
-int fd;
+/*
+ * Show stats on how auth within IPFilter has been used
+ */
+static void showauthstates(asp)
fr_authstat_t *asp;
{
frauthent_t *frap, fra;
@@ -1161,63 +1318,10 @@ fr_authstat_t *asp;
}
-static char *get_ifname(ptr)
-void *ptr;
-{
-#if SOLARIS
- char *ifname;
- ill_t ill;
-
- if (ptr == (void *)-1)
- return "!";
- if (ptr == NULL)
- return "-";
-
- if (kmemcpy((char *)&ill, (u_long)ptr, sizeof(ill)) == -1)
- return "X";
- ifname = malloc(ill.ill_name_length + 1);
- if (kmemcpy(ifname, (u_long)ill.ill_name,
- ill.ill_name_length) == -1)
- return "X";
- return ifname;
-#else
-# if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \
- defined(__OpenBSD__)
-#else
- char buf[32];
- int len;
-# endif
- struct ifnet netif;
-
- if (ptr == (void *)-1)
- return "!";
- if (ptr == NULL)
- return "-";
-
- if (kmemcpy((char *)&netif, (u_long)ptr, sizeof(netif)) == -1)
- return "X";
-# if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \
- defined(__OpenBSD__)
- return strdup(netif.if_xname);
-# else
- if (kstrncpy(buf, (u_long)netif.if_name, sizeof(buf)) == -1)
- return "X";
- if (netif.if_unit < 10)
- len = 2;
- else if (netif.if_unit < 1000)
- len = 3;
- else if (netif.if_unit < 10000)
- len = 4;
- else
- len = 5;
- buf[sizeof(buf) - len] = '\0';
- sprintf(buf + strlen(buf), "%d", netif.if_unit % 10000);
- return strdup(buf);
-# endif
-#endif
-}
-
-
+/*
+ * Display groups used for each of filter rules, accounting rules and
+ * authentication, separately.
+ */
static void showgroups(fiop)
struct friostat *fiop;
{
@@ -1370,4 +1474,32 @@ const void *b;
return 1;
return -1;
}
+
+static int sort_srcip(a, b)
+const void *a;
+const void *b;
+{
+ register const statetop_t *ap = a;
+ register const statetop_t *bp = b;
+
+ if (ntohl(ap->st_src.in4.s_addr) == ntohl(bp->st_src.in4.s_addr))
+ return 0;
+ else if (ntohl(ap->st_src.in4.s_addr) > ntohl(bp->st_src.in4.s_addr))
+ return 1;
+ return -1;
+}
+
+static int sort_dstip(a, b)
+const void *a;
+const void *b;
+{
+ register const statetop_t *ap = a;
+ register const statetop_t *bp = b;
+
+ if (ntohl(ap->st_dst.in4.s_addr) == ntohl(bp->st_dst.in4.s_addr))
+ return 0;
+ else if (ntohl(ap->st_dst.in4.s_addr) > ntohl(bp->st_dst.in4.s_addr))
+ return 1;
+ return -1;
+}
#endif