diff options
Diffstat (limited to 'contrib/ipfilter/fils.c')
-rw-r--r-- | contrib/ipfilter/fils.c | 688 |
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 |