1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * Copyright (C) 1993-2001, 2003 by Darren Reed. 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * See the IPFILTER.LICENCE file for details on licencing. 5*7c478bd9Sstevel@tonic-gate * 6*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 7*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 8*7c478bd9Sstevel@tonic-gate */ 9*7c478bd9Sstevel@tonic-gate 10*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 11*7c478bd9Sstevel@tonic-gate 12*7c478bd9Sstevel@tonic-gate #ifdef __FreeBSD__ 13*7c478bd9Sstevel@tonic-gate # ifndef __FreeBSD_cc_version 14*7c478bd9Sstevel@tonic-gate # include <osreldate.h> 15*7c478bd9Sstevel@tonic-gate # else 16*7c478bd9Sstevel@tonic-gate # if __FreeBSD_cc_version < 430000 17*7c478bd9Sstevel@tonic-gate # include <osreldate.h> 18*7c478bd9Sstevel@tonic-gate # endif 19*7c478bd9Sstevel@tonic-gate # endif 20*7c478bd9Sstevel@tonic-gate #endif 21*7c478bd9Sstevel@tonic-gate #include <sys/ioctl.h> 22*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 23*7c478bd9Sstevel@tonic-gate #include <nlist.h> 24*7c478bd9Sstevel@tonic-gate #include <ctype.h> 25*7c478bd9Sstevel@tonic-gate #include <stddef.h> 26*7c478bd9Sstevel@tonic-gate #include "ipf.h" 27*7c478bd9Sstevel@tonic-gate #include "ipl.h" 28*7c478bd9Sstevel@tonic-gate #if defined(STATETOP) 29*7c478bd9Sstevel@tonic-gate # if defined(_BSDI_VERSION) 30*7c478bd9Sstevel@tonic-gate # undef STATETOP) 31*7c478bd9Sstevel@tonic-gate # endif 32*7c478bd9Sstevel@tonic-gate # if defined(__FreeBSD__) && \ 33*7c478bd9Sstevel@tonic-gate (!defined(__FreeBSD_version) || (__FreeBSD_version < 430000)) 34*7c478bd9Sstevel@tonic-gate # undef STATETOP 35*7c478bd9Sstevel@tonic-gate # endif 36*7c478bd9Sstevel@tonic-gate # if defined(__NetBSD_Version__) && (__NetBSD_Version__ < 105000000) 37*7c478bd9Sstevel@tonic-gate # undef STATETOP 38*7c478bd9Sstevel@tonic-gate # endif 39*7c478bd9Sstevel@tonic-gate # if defined(sun) 40*7c478bd9Sstevel@tonic-gate # if defined(__svr4__) || defined(__SVR4) 41*7c478bd9Sstevel@tonic-gate # include <sys/select.h> 42*7c478bd9Sstevel@tonic-gate # else 43*7c478bd9Sstevel@tonic-gate # undef STATETOP /* NOT supported on SunOS4 */ 44*7c478bd9Sstevel@tonic-gate # endif 45*7c478bd9Sstevel@tonic-gate # endif 46*7c478bd9Sstevel@tonic-gate #endif 47*7c478bd9Sstevel@tonic-gate #if defined(STATETOP) && !defined(linux) 48*7c478bd9Sstevel@tonic-gate # include <netinet/ip_var.h> 49*7c478bd9Sstevel@tonic-gate # include <netinet/tcp_fsm.h> 50*7c478bd9Sstevel@tonic-gate #endif 51*7c478bd9Sstevel@tonic-gate #ifdef STATETOP 52*7c478bd9Sstevel@tonic-gate #if SOLARIS2 >= 10 53*7c478bd9Sstevel@tonic-gate # include "ipl.h" 54*7c478bd9Sstevel@tonic-gate #else 55*7c478bd9Sstevel@tonic-gate # include "netinet/ipl.h" 56*7c478bd9Sstevel@tonic-gate #endif 57*7c478bd9Sstevel@tonic-gate # if SOLARIS || defined(__NetBSD__) || defined(_BSDI_VERSION) || \ 58*7c478bd9Sstevel@tonic-gate defined(__sgi) 59*7c478bd9Sstevel@tonic-gate # ifdef ERR 60*7c478bd9Sstevel@tonic-gate # undef ERR 61*7c478bd9Sstevel@tonic-gate # endif 62*7c478bd9Sstevel@tonic-gate # include <curses.h> 63*7c478bd9Sstevel@tonic-gate # else /* SOLARIS */ 64*7c478bd9Sstevel@tonic-gate # include <ncurses.h> 65*7c478bd9Sstevel@tonic-gate # endif /* SOLARIS */ 66*7c478bd9Sstevel@tonic-gate #endif /* STATETOP */ 67*7c478bd9Sstevel@tonic-gate #include "kmem.h" 68*7c478bd9Sstevel@tonic-gate #if defined(__NetBSD__) || (__OpenBSD__) 69*7c478bd9Sstevel@tonic-gate # include <paths.h> 70*7c478bd9Sstevel@tonic-gate #endif 71*7c478bd9Sstevel@tonic-gate 72*7c478bd9Sstevel@tonic-gate #if !defined(lint) 73*7c478bd9Sstevel@tonic-gate static const char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-2000 Darren Reed"; 74*7c478bd9Sstevel@tonic-gate static const char rcsid[] = "@(#)$Id: ipfstat.c,v 1.28 2003/07/01 01:03:04 darrenr Exp $"; 75*7c478bd9Sstevel@tonic-gate #endif 76*7c478bd9Sstevel@tonic-gate 77*7c478bd9Sstevel@tonic-gate #ifdef __hpux 78*7c478bd9Sstevel@tonic-gate # define nlist nlist64 79*7c478bd9Sstevel@tonic-gate #endif 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate extern char *optarg; 82*7c478bd9Sstevel@tonic-gate extern int optind; 83*7c478bd9Sstevel@tonic-gate 84*7c478bd9Sstevel@tonic-gate #define PRINTF (void)printf 85*7c478bd9Sstevel@tonic-gate #define FPRINTF (void)fprintf 86*7c478bd9Sstevel@tonic-gate #define F_IN 0 87*7c478bd9Sstevel@tonic-gate #define F_OUT 1 88*7c478bd9Sstevel@tonic-gate #define F_ACIN 2 89*7c478bd9Sstevel@tonic-gate #define F_ACOUT 3 90*7c478bd9Sstevel@tonic-gate static char *filters[4] = { "ipfilter(in)", "ipfilter(out)", 91*7c478bd9Sstevel@tonic-gate "ipacct(in)", "ipacct(out)" }; 92*7c478bd9Sstevel@tonic-gate static int state_logging = -1; 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate int opts = 0; 95*7c478bd9Sstevel@tonic-gate int use_inet6 = 0; 96*7c478bd9Sstevel@tonic-gate int live_kernel = 1; 97*7c478bd9Sstevel@tonic-gate int state_fd = -1; 98*7c478bd9Sstevel@tonic-gate int ipf_fd = -1; 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate #ifdef STATETOP 101*7c478bd9Sstevel@tonic-gate #define STSTRSIZE 80 102*7c478bd9Sstevel@tonic-gate #define STGROWSIZE 16 103*7c478bd9Sstevel@tonic-gate #define HOSTNMLEN 40 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate #define STSORT_PR 0 106*7c478bd9Sstevel@tonic-gate #define STSORT_PKTS 1 107*7c478bd9Sstevel@tonic-gate #define STSORT_BYTES 2 108*7c478bd9Sstevel@tonic-gate #define STSORT_TTL 3 109*7c478bd9Sstevel@tonic-gate #define STSORT_SRCIP 4 110*7c478bd9Sstevel@tonic-gate #define STSORT_DSTIP 5 111*7c478bd9Sstevel@tonic-gate #define STSORT_MAX STSORT_DSTIP 112*7c478bd9Sstevel@tonic-gate #define STSORT_DEFAULT STSORT_BYTES 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate typedef struct statetop { 116*7c478bd9Sstevel@tonic-gate i6addr_t st_src; 117*7c478bd9Sstevel@tonic-gate i6addr_t st_dst; 118*7c478bd9Sstevel@tonic-gate u_short st_sport; 119*7c478bd9Sstevel@tonic-gate u_short st_dport; 120*7c478bd9Sstevel@tonic-gate u_char st_p; 121*7c478bd9Sstevel@tonic-gate u_char st_state[2]; 122*7c478bd9Sstevel@tonic-gate U_QUAD_T st_pkts; 123*7c478bd9Sstevel@tonic-gate U_QUAD_T st_bytes; 124*7c478bd9Sstevel@tonic-gate u_long st_age; 125*7c478bd9Sstevel@tonic-gate } statetop_t; 126*7c478bd9Sstevel@tonic-gate #endif 127*7c478bd9Sstevel@tonic-gate 128*7c478bd9Sstevel@tonic-gate extern int main __P((int, char *[])); 129*7c478bd9Sstevel@tonic-gate static void showstats __P((friostat_t *, u_32_t)); 130*7c478bd9Sstevel@tonic-gate static void showfrstates __P((ipfrstat_t *)); 131*7c478bd9Sstevel@tonic-gate static void showlist __P((friostat_t *)); 132*7c478bd9Sstevel@tonic-gate static void showipstates __P((ips_stat_t *)); 133*7c478bd9Sstevel@tonic-gate static void showauthstates __P((fr_authstat_t *)); 134*7c478bd9Sstevel@tonic-gate static void showgroups __P((friostat_t *)); 135*7c478bd9Sstevel@tonic-gate static void Usage __P((char *)); 136*7c478bd9Sstevel@tonic-gate static void printlist __P((frentry_t *, char *)); 137*7c478bd9Sstevel@tonic-gate static void parse_ipportstr __P((const char *, struct in_addr *, int *)); 138*7c478bd9Sstevel@tonic-gate static void ipfstate_live __P((char *, friostat_t **, ips_stat_t **, 139*7c478bd9Sstevel@tonic-gate ipfrstat_t **, fr_authstat_t **, u_32_t *)); 140*7c478bd9Sstevel@tonic-gate static void ipfstate_dead __P((char *, friostat_t **, ips_stat_t **, 141*7c478bd9Sstevel@tonic-gate ipfrstat_t **, fr_authstat_t **, u_32_t *)); 142*7c478bd9Sstevel@tonic-gate #ifdef STATETOP 143*7c478bd9Sstevel@tonic-gate static void topipstates __P((struct in_addr, struct in_addr, int, int, int, int, int)); 144*7c478bd9Sstevel@tonic-gate static char *ttl_to_string __P((long)); 145*7c478bd9Sstevel@tonic-gate static int sort_p __P((const void *, const void *)); 146*7c478bd9Sstevel@tonic-gate static int sort_pkts __P((const void *, const void *)); 147*7c478bd9Sstevel@tonic-gate static int sort_bytes __P((const void *, const void *)); 148*7c478bd9Sstevel@tonic-gate static int sort_ttl __P((const void *, const void *)); 149*7c478bd9Sstevel@tonic-gate static int sort_srcip __P((const void *, const void *)); 150*7c478bd9Sstevel@tonic-gate static int sort_dstip __P((const void *, const void *)); 151*7c478bd9Sstevel@tonic-gate #endif 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate static void Usage(name) 155*7c478bd9Sstevel@tonic-gate char *name; 156*7c478bd9Sstevel@tonic-gate { 157*7c478bd9Sstevel@tonic-gate #ifdef USE_INET6 158*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Usage: %s [-6aAfhIinosv] [-d <device>]\n", name); 159*7c478bd9Sstevel@tonic-gate #else 160*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Usage: %s [-aAfhIinosv] [-d <device>]\n", name); 161*7c478bd9Sstevel@tonic-gate #endif 162*7c478bd9Sstevel@tonic-gate fprintf(stderr, "\t\t[-M corefile] [-N symbol-list]\n"); 163*7c478bd9Sstevel@tonic-gate fprintf(stderr, " %s -t [-S source address] [-D destination address] [-P protocol] [-T refreshtime] [-C] [-d <device>]\n", name); 164*7c478bd9Sstevel@tonic-gate exit(1); 165*7c478bd9Sstevel@tonic-gate } 166*7c478bd9Sstevel@tonic-gate 167*7c478bd9Sstevel@tonic-gate 168*7c478bd9Sstevel@tonic-gate int main(argc,argv) 169*7c478bd9Sstevel@tonic-gate int argc; 170*7c478bd9Sstevel@tonic-gate char *argv[]; 171*7c478bd9Sstevel@tonic-gate { 172*7c478bd9Sstevel@tonic-gate fr_authstat_t frauthst; 173*7c478bd9Sstevel@tonic-gate fr_authstat_t *frauthstp = &frauthst; 174*7c478bd9Sstevel@tonic-gate friostat_t fio; 175*7c478bd9Sstevel@tonic-gate friostat_t *fiop = &fio; 176*7c478bd9Sstevel@tonic-gate ips_stat_t ipsst; 177*7c478bd9Sstevel@tonic-gate ips_stat_t *ipsstp = &ipsst; 178*7c478bd9Sstevel@tonic-gate ipfrstat_t ifrst; 179*7c478bd9Sstevel@tonic-gate ipfrstat_t *ifrstp = &ifrst; 180*7c478bd9Sstevel@tonic-gate char *device = IPL_NAME, *memf = NULL; 181*7c478bd9Sstevel@tonic-gate char *kern = NULL; 182*7c478bd9Sstevel@tonic-gate int c, myoptind; 183*7c478bd9Sstevel@tonic-gate struct protoent *proto; 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate int protocol = -1; /* -1 = wild card for any protocol */ 186*7c478bd9Sstevel@tonic-gate int refreshtime = 1; /* default update time */ 187*7c478bd9Sstevel@tonic-gate int sport = -1; /* -1 = wild card for any source port */ 188*7c478bd9Sstevel@tonic-gate int dport = -1; /* -1 = wild card for any dest port */ 189*7c478bd9Sstevel@tonic-gate int topclosed = 0; /* do not show closed tcp sessions */ 190*7c478bd9Sstevel@tonic-gate struct in_addr saddr, daddr; 191*7c478bd9Sstevel@tonic-gate u_32_t frf; 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate saddr.s_addr = INADDR_ANY; /* default any source addr */ 194*7c478bd9Sstevel@tonic-gate daddr.s_addr = INADDR_ANY; /* default any dest addr */ 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate /* 197*7c478bd9Sstevel@tonic-gate * Parse these two arguments now lest there be any buffer overflows 198*7c478bd9Sstevel@tonic-gate * in the parsing of the rest. 199*7c478bd9Sstevel@tonic-gate */ 200*7c478bd9Sstevel@tonic-gate myoptind = optind; 201*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "6aACdfghIilnostvD:M:N:P:S:T:")) != -1) 202*7c478bd9Sstevel@tonic-gate switch (c) 203*7c478bd9Sstevel@tonic-gate { 204*7c478bd9Sstevel@tonic-gate case 'M' : 205*7c478bd9Sstevel@tonic-gate memf = optarg; 206*7c478bd9Sstevel@tonic-gate live_kernel = 0; 207*7c478bd9Sstevel@tonic-gate break; 208*7c478bd9Sstevel@tonic-gate case 'N' : 209*7c478bd9Sstevel@tonic-gate kern = optarg; 210*7c478bd9Sstevel@tonic-gate live_kernel = 0; 211*7c478bd9Sstevel@tonic-gate break; 212*7c478bd9Sstevel@tonic-gate } 213*7c478bd9Sstevel@tonic-gate optind = myoptind; 214*7c478bd9Sstevel@tonic-gate 215*7c478bd9Sstevel@tonic-gate if (live_kernel == 1) { 216*7c478bd9Sstevel@tonic-gate if ((state_fd = open(IPSTATE_NAME, O_RDONLY)) == -1) { 217*7c478bd9Sstevel@tonic-gate perror("open"); 218*7c478bd9Sstevel@tonic-gate exit(-1); 219*7c478bd9Sstevel@tonic-gate } 220*7c478bd9Sstevel@tonic-gate if ((ipf_fd = open(device, O_RDONLY)) == -1) { 221*7c478bd9Sstevel@tonic-gate perror("open"); 222*7c478bd9Sstevel@tonic-gate exit(-1); 223*7c478bd9Sstevel@tonic-gate } 224*7c478bd9Sstevel@tonic-gate } 225*7c478bd9Sstevel@tonic-gate 226*7c478bd9Sstevel@tonic-gate if (kern != NULL || memf != NULL) 227*7c478bd9Sstevel@tonic-gate { 228*7c478bd9Sstevel@tonic-gate (void)setgid(getgid()); 229*7c478bd9Sstevel@tonic-gate (void)setreuid(getuid(), getuid()); 230*7c478bd9Sstevel@tonic-gate } 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate if (openkmem(kern, memf) == -1) 233*7c478bd9Sstevel@tonic-gate exit(-1); 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate (void)setgid(getgid()); 236*7c478bd9Sstevel@tonic-gate (void)setreuid(getuid(), getuid()); 237*7c478bd9Sstevel@tonic-gate 238*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "6aACdfghIilnostvD:M:N:P:S:T:")) != -1) 239*7c478bd9Sstevel@tonic-gate { 240*7c478bd9Sstevel@tonic-gate switch (c) 241*7c478bd9Sstevel@tonic-gate { 242*7c478bd9Sstevel@tonic-gate #ifdef USE_INET6 243*7c478bd9Sstevel@tonic-gate case '6' : 244*7c478bd9Sstevel@tonic-gate use_inet6 = 1; 245*7c478bd9Sstevel@tonic-gate break; 246*7c478bd9Sstevel@tonic-gate #endif 247*7c478bd9Sstevel@tonic-gate case 'a' : 248*7c478bd9Sstevel@tonic-gate opts |= OPT_ACCNT|OPT_SHOWLIST; 249*7c478bd9Sstevel@tonic-gate break; 250*7c478bd9Sstevel@tonic-gate case 'A' : 251*7c478bd9Sstevel@tonic-gate opts |= OPT_AUTHSTATS; 252*7c478bd9Sstevel@tonic-gate break; 253*7c478bd9Sstevel@tonic-gate case 'C' : 254*7c478bd9Sstevel@tonic-gate topclosed = 1; 255*7c478bd9Sstevel@tonic-gate break; 256*7c478bd9Sstevel@tonic-gate case 'd' : 257*7c478bd9Sstevel@tonic-gate opts |= OPT_DEBUG; 258*7c478bd9Sstevel@tonic-gate break; 259*7c478bd9Sstevel@tonic-gate case 'D' : 260*7c478bd9Sstevel@tonic-gate parse_ipportstr(optarg, &daddr, &dport); 261*7c478bd9Sstevel@tonic-gate break; 262*7c478bd9Sstevel@tonic-gate case 'f' : 263*7c478bd9Sstevel@tonic-gate opts |= OPT_FRSTATES; 264*7c478bd9Sstevel@tonic-gate break; 265*7c478bd9Sstevel@tonic-gate case 'g' : 266*7c478bd9Sstevel@tonic-gate opts |= OPT_GROUPS; 267*7c478bd9Sstevel@tonic-gate break; 268*7c478bd9Sstevel@tonic-gate case 'h' : 269*7c478bd9Sstevel@tonic-gate opts |= OPT_HITS; 270*7c478bd9Sstevel@tonic-gate break; 271*7c478bd9Sstevel@tonic-gate case 'i' : 272*7c478bd9Sstevel@tonic-gate opts |= OPT_INQUE|OPT_SHOWLIST; 273*7c478bd9Sstevel@tonic-gate break; 274*7c478bd9Sstevel@tonic-gate case 'I' : 275*7c478bd9Sstevel@tonic-gate opts |= OPT_INACTIVE; 276*7c478bd9Sstevel@tonic-gate break; 277*7c478bd9Sstevel@tonic-gate case 'l' : 278*7c478bd9Sstevel@tonic-gate opts |= OPT_SHOWLIST; 279*7c478bd9Sstevel@tonic-gate break; 280*7c478bd9Sstevel@tonic-gate case 'M' : 281*7c478bd9Sstevel@tonic-gate break; 282*7c478bd9Sstevel@tonic-gate case 'N' : 283*7c478bd9Sstevel@tonic-gate break; 284*7c478bd9Sstevel@tonic-gate case 'n' : 285*7c478bd9Sstevel@tonic-gate opts |= OPT_SHOWLINENO; 286*7c478bd9Sstevel@tonic-gate break; 287*7c478bd9Sstevel@tonic-gate case 'o' : 288*7c478bd9Sstevel@tonic-gate opts |= OPT_OUTQUE|OPT_SHOWLIST; 289*7c478bd9Sstevel@tonic-gate break; 290*7c478bd9Sstevel@tonic-gate case 'P' : 291*7c478bd9Sstevel@tonic-gate if ((proto = getprotobyname(optarg)) != NULL) { 292*7c478bd9Sstevel@tonic-gate protocol = proto->p_proto; 293*7c478bd9Sstevel@tonic-gate } else if (!sscanf(optarg, "%d", &protocol) || 294*7c478bd9Sstevel@tonic-gate (protocol < 0)) { 295*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s : Invalid protocol: %s\n", 296*7c478bd9Sstevel@tonic-gate argv[0], optarg); 297*7c478bd9Sstevel@tonic-gate exit(-2); 298*7c478bd9Sstevel@tonic-gate } 299*7c478bd9Sstevel@tonic-gate break; 300*7c478bd9Sstevel@tonic-gate case 's' : 301*7c478bd9Sstevel@tonic-gate opts |= OPT_IPSTATES; 302*7c478bd9Sstevel@tonic-gate break; 303*7c478bd9Sstevel@tonic-gate case 'S' : 304*7c478bd9Sstevel@tonic-gate parse_ipportstr(optarg, &saddr, &sport); 305*7c478bd9Sstevel@tonic-gate break; 306*7c478bd9Sstevel@tonic-gate case 't' : 307*7c478bd9Sstevel@tonic-gate #ifdef STATETOP 308*7c478bd9Sstevel@tonic-gate opts |= OPT_STATETOP; 309*7c478bd9Sstevel@tonic-gate break; 310*7c478bd9Sstevel@tonic-gate #else 311*7c478bd9Sstevel@tonic-gate fprintf(stderr, 312*7c478bd9Sstevel@tonic-gate "%s : state top facility not compiled in\n", 313*7c478bd9Sstevel@tonic-gate argv[0]); 314*7c478bd9Sstevel@tonic-gate exit(-2); 315*7c478bd9Sstevel@tonic-gate #endif 316*7c478bd9Sstevel@tonic-gate case 'T' : 317*7c478bd9Sstevel@tonic-gate if (!sscanf(optarg, "%d", &refreshtime) || 318*7c478bd9Sstevel@tonic-gate (refreshtime <= 0)) { 319*7c478bd9Sstevel@tonic-gate fprintf(stderr, 320*7c478bd9Sstevel@tonic-gate "%s : Invalid refreshtime < 1 : %s\n", 321*7c478bd9Sstevel@tonic-gate argv[0], optarg); 322*7c478bd9Sstevel@tonic-gate exit(-2); 323*7c478bd9Sstevel@tonic-gate } 324*7c478bd9Sstevel@tonic-gate break; 325*7c478bd9Sstevel@tonic-gate case 'v' : 326*7c478bd9Sstevel@tonic-gate opts |= OPT_VERBOSE; 327*7c478bd9Sstevel@tonic-gate opts |= OPT_UNDEF; 328*7c478bd9Sstevel@tonic-gate break; 329*7c478bd9Sstevel@tonic-gate default : 330*7c478bd9Sstevel@tonic-gate Usage(argv[0]); 331*7c478bd9Sstevel@tonic-gate break; 332*7c478bd9Sstevel@tonic-gate } 333*7c478bd9Sstevel@tonic-gate } 334*7c478bd9Sstevel@tonic-gate 335*7c478bd9Sstevel@tonic-gate if (live_kernel == 1) { 336*7c478bd9Sstevel@tonic-gate bzero((char *)&fio, sizeof(fio)); 337*7c478bd9Sstevel@tonic-gate bzero((char *)&ipsst, sizeof(ipsst)); 338*7c478bd9Sstevel@tonic-gate bzero((char *)&ifrst, sizeof(ifrst)); 339*7c478bd9Sstevel@tonic-gate 340*7c478bd9Sstevel@tonic-gate ipfstate_live(device, &fiop, &ipsstp, &ifrstp, 341*7c478bd9Sstevel@tonic-gate &frauthstp, &frf); 342*7c478bd9Sstevel@tonic-gate } else 343*7c478bd9Sstevel@tonic-gate ipfstate_dead(kern, &fiop, &ipsstp, &ifrstp, &frauthstp, &frf); 344*7c478bd9Sstevel@tonic-gate 345*7c478bd9Sstevel@tonic-gate if (opts & OPT_IPSTATES) { 346*7c478bd9Sstevel@tonic-gate showipstates(ipsstp); 347*7c478bd9Sstevel@tonic-gate } else if (opts & OPT_SHOWLIST) { 348*7c478bd9Sstevel@tonic-gate showlist(fiop); 349*7c478bd9Sstevel@tonic-gate if ((opts & OPT_OUTQUE) && (opts & OPT_INQUE)){ 350*7c478bd9Sstevel@tonic-gate opts &= ~OPT_OUTQUE; 351*7c478bd9Sstevel@tonic-gate showlist(fiop); 352*7c478bd9Sstevel@tonic-gate } 353*7c478bd9Sstevel@tonic-gate } else { 354*7c478bd9Sstevel@tonic-gate if (opts & OPT_FRSTATES) 355*7c478bd9Sstevel@tonic-gate showfrstates(ifrstp); 356*7c478bd9Sstevel@tonic-gate #ifdef STATETOP 357*7c478bd9Sstevel@tonic-gate else if (opts & OPT_STATETOP) 358*7c478bd9Sstevel@tonic-gate topipstates(saddr, daddr, sport, dport, 359*7c478bd9Sstevel@tonic-gate protocol, refreshtime, topclosed); 360*7c478bd9Sstevel@tonic-gate #endif 361*7c478bd9Sstevel@tonic-gate else if (opts & OPT_AUTHSTATS) 362*7c478bd9Sstevel@tonic-gate showauthstates(frauthstp); 363*7c478bd9Sstevel@tonic-gate else if (opts & OPT_GROUPS) 364*7c478bd9Sstevel@tonic-gate showgroups(fiop); 365*7c478bd9Sstevel@tonic-gate else 366*7c478bd9Sstevel@tonic-gate showstats(fiop, frf); 367*7c478bd9Sstevel@tonic-gate } 368*7c478bd9Sstevel@tonic-gate return 0; 369*7c478bd9Sstevel@tonic-gate } 370*7c478bd9Sstevel@tonic-gate 371*7c478bd9Sstevel@tonic-gate 372*7c478bd9Sstevel@tonic-gate /* 373*7c478bd9Sstevel@tonic-gate * Fill in the stats structures from the live kernel, using a combination 374*7c478bd9Sstevel@tonic-gate * of ioctl's and copying directly from kernel memory. 375*7c478bd9Sstevel@tonic-gate */ 376*7c478bd9Sstevel@tonic-gate static void ipfstate_live(device, fiopp, ipsstpp, ifrstpp, frauthstpp, frfp) 377*7c478bd9Sstevel@tonic-gate char *device; 378*7c478bd9Sstevel@tonic-gate friostat_t **fiopp; 379*7c478bd9Sstevel@tonic-gate ips_stat_t **ipsstpp; 380*7c478bd9Sstevel@tonic-gate ipfrstat_t **ifrstpp; 381*7c478bd9Sstevel@tonic-gate fr_authstat_t **frauthstpp; 382*7c478bd9Sstevel@tonic-gate u_32_t *frfp; 383*7c478bd9Sstevel@tonic-gate { 384*7c478bd9Sstevel@tonic-gate ipfobj_t ipfo; 385*7c478bd9Sstevel@tonic-gate 386*7c478bd9Sstevel@tonic-gate if (checkrev(device) == -1) { 387*7c478bd9Sstevel@tonic-gate fprintf(stderr, "User/kernel version check failed\n"); 388*7c478bd9Sstevel@tonic-gate exit(1); 389*7c478bd9Sstevel@tonic-gate } 390*7c478bd9Sstevel@tonic-gate 391*7c478bd9Sstevel@tonic-gate if ((opts & OPT_AUTHSTATS) == 0) { 392*7c478bd9Sstevel@tonic-gate bzero((caddr_t)&ipfo, sizeof(ipfo)); 393*7c478bd9Sstevel@tonic-gate ipfo.ipfo_rev = IPFILTER_VERSION; 394*7c478bd9Sstevel@tonic-gate ipfo.ipfo_size = sizeof(friostat_t); 395*7c478bd9Sstevel@tonic-gate ipfo.ipfo_ptr = (void *)*fiopp; 396*7c478bd9Sstevel@tonic-gate ipfo.ipfo_type = IPFOBJ_IPFSTAT; 397*7c478bd9Sstevel@tonic-gate 398*7c478bd9Sstevel@tonic-gate if (ioctl(ipf_fd, SIOCGETFS, &ipfo) == -1) { 399*7c478bd9Sstevel@tonic-gate perror("ioctl(ipf:SIOCGETFS)"); 400*7c478bd9Sstevel@tonic-gate exit(-1); 401*7c478bd9Sstevel@tonic-gate } 402*7c478bd9Sstevel@tonic-gate 403*7c478bd9Sstevel@tonic-gate if (ioctl(ipf_fd, SIOCGETFF, frfp) == -1) 404*7c478bd9Sstevel@tonic-gate perror("ioctl(SIOCGETFF)"); 405*7c478bd9Sstevel@tonic-gate } 406*7c478bd9Sstevel@tonic-gate 407*7c478bd9Sstevel@tonic-gate if ((opts & OPT_IPSTATES) != 0) { 408*7c478bd9Sstevel@tonic-gate 409*7c478bd9Sstevel@tonic-gate bzero((caddr_t)&ipfo, sizeof(ipfo)); 410*7c478bd9Sstevel@tonic-gate ipfo.ipfo_rev = IPFILTER_VERSION; 411*7c478bd9Sstevel@tonic-gate ipfo.ipfo_size = sizeof(ips_stat_t); 412*7c478bd9Sstevel@tonic-gate ipfo.ipfo_ptr = (void *)*ipsstpp; 413*7c478bd9Sstevel@tonic-gate ipfo.ipfo_type = IPFOBJ_STATESTAT; 414*7c478bd9Sstevel@tonic-gate 415*7c478bd9Sstevel@tonic-gate if ((ioctl(state_fd, SIOCGETFS, &ipfo) == -1)) { 416*7c478bd9Sstevel@tonic-gate perror("ioctl(state:SIOCGETFS)"); 417*7c478bd9Sstevel@tonic-gate exit(-1); 418*7c478bd9Sstevel@tonic-gate } 419*7c478bd9Sstevel@tonic-gate if (ioctl(state_fd, SIOCGETLG, &state_logging) == -1) { 420*7c478bd9Sstevel@tonic-gate perror("ioctl(state:SIOCGETLG)"); 421*7c478bd9Sstevel@tonic-gate exit(-1); 422*7c478bd9Sstevel@tonic-gate } 423*7c478bd9Sstevel@tonic-gate } 424*7c478bd9Sstevel@tonic-gate 425*7c478bd9Sstevel@tonic-gate if ((opts & OPT_FRSTATES) != 0) { 426*7c478bd9Sstevel@tonic-gate bzero((caddr_t)&ipfo, sizeof(ipfo)); 427*7c478bd9Sstevel@tonic-gate ipfo.ipfo_rev = IPFILTER_VERSION; 428*7c478bd9Sstevel@tonic-gate ipfo.ipfo_size = sizeof(ipfrstat_t); 429*7c478bd9Sstevel@tonic-gate ipfo.ipfo_ptr = (void *)*ifrstpp; 430*7c478bd9Sstevel@tonic-gate ipfo.ipfo_type = IPFOBJ_FRAGSTAT; 431*7c478bd9Sstevel@tonic-gate 432*7c478bd9Sstevel@tonic-gate if (ioctl(ipf_fd, SIOCGFRST, &ipfo) == -1) { 433*7c478bd9Sstevel@tonic-gate perror("ioctl(SIOCGFRST)"); 434*7c478bd9Sstevel@tonic-gate exit(-1); 435*7c478bd9Sstevel@tonic-gate } 436*7c478bd9Sstevel@tonic-gate } 437*7c478bd9Sstevel@tonic-gate 438*7c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 439*7c478bd9Sstevel@tonic-gate PRINTF("opts %#x name %s\n", opts, device); 440*7c478bd9Sstevel@tonic-gate 441*7c478bd9Sstevel@tonic-gate if ((opts & OPT_AUTHSTATS) != 0) { 442*7c478bd9Sstevel@tonic-gate if (ipf_fd >= 0) { 443*7c478bd9Sstevel@tonic-gate close(ipf_fd); 444*7c478bd9Sstevel@tonic-gate ipf_fd = -1; 445*7c478bd9Sstevel@tonic-gate } 446*7c478bd9Sstevel@tonic-gate device = IPAUTH_NAME; 447*7c478bd9Sstevel@tonic-gate if ((ipf_fd = open(device, O_RDONLY)) == -1) { 448*7c478bd9Sstevel@tonic-gate perror("open"); 449*7c478bd9Sstevel@tonic-gate exit(-1); 450*7c478bd9Sstevel@tonic-gate } 451*7c478bd9Sstevel@tonic-gate 452*7c478bd9Sstevel@tonic-gate bzero((caddr_t)&ipfo, sizeof(ipfo)); 453*7c478bd9Sstevel@tonic-gate ipfo.ipfo_rev = IPFILTER_VERSION; 454*7c478bd9Sstevel@tonic-gate ipfo.ipfo_size = sizeof(fr_authstat_t); 455*7c478bd9Sstevel@tonic-gate ipfo.ipfo_ptr = (void *)*frauthstpp; 456*7c478bd9Sstevel@tonic-gate ipfo.ipfo_type = IPFOBJ_AUTHSTAT; 457*7c478bd9Sstevel@tonic-gate 458*7c478bd9Sstevel@tonic-gate if (ioctl(ipf_fd, SIOCATHST, &ipfo) == -1) { 459*7c478bd9Sstevel@tonic-gate perror("ioctl(SIOCATHST)"); 460*7c478bd9Sstevel@tonic-gate exit(-1); 461*7c478bd9Sstevel@tonic-gate } 462*7c478bd9Sstevel@tonic-gate } 463*7c478bd9Sstevel@tonic-gate } 464*7c478bd9Sstevel@tonic-gate 465*7c478bd9Sstevel@tonic-gate 466*7c478bd9Sstevel@tonic-gate /* 467*7c478bd9Sstevel@tonic-gate * Build up the stats structures from data held in the "core" memory. 468*7c478bd9Sstevel@tonic-gate * This is mainly useful when looking at data in crash dumps and ioctl's 469*7c478bd9Sstevel@tonic-gate * just won't work any more. 470*7c478bd9Sstevel@tonic-gate */ 471*7c478bd9Sstevel@tonic-gate static void ipfstate_dead(kernel, fiopp, ipsstpp, ifrstpp, frauthstpp, frfp) 472*7c478bd9Sstevel@tonic-gate char *kernel; 473*7c478bd9Sstevel@tonic-gate friostat_t **fiopp; 474*7c478bd9Sstevel@tonic-gate ips_stat_t **ipsstpp; 475*7c478bd9Sstevel@tonic-gate ipfrstat_t **ifrstpp; 476*7c478bd9Sstevel@tonic-gate fr_authstat_t **frauthstpp; 477*7c478bd9Sstevel@tonic-gate u_32_t *frfp; 478*7c478bd9Sstevel@tonic-gate { 479*7c478bd9Sstevel@tonic-gate static fr_authstat_t frauthst, *frauthstp; 480*7c478bd9Sstevel@tonic-gate static ips_stat_t ipsst, *ipsstp; 481*7c478bd9Sstevel@tonic-gate static ipfrstat_t ifrst, *ifrstp; 482*7c478bd9Sstevel@tonic-gate static friostat_t fio, *fiop; 483*7c478bd9Sstevel@tonic-gate int temp; 484*7c478bd9Sstevel@tonic-gate 485*7c478bd9Sstevel@tonic-gate void *rules[2][2]; 486*7c478bd9Sstevel@tonic-gate struct nlist deadlist[43] = { 487*7c478bd9Sstevel@tonic-gate { "fr_authstats" }, /* 0 */ 488*7c478bd9Sstevel@tonic-gate { "fae_list" }, 489*7c478bd9Sstevel@tonic-gate { "ipauth" }, 490*7c478bd9Sstevel@tonic-gate { "fr_authlist" }, 491*7c478bd9Sstevel@tonic-gate { "fr_authstart" }, 492*7c478bd9Sstevel@tonic-gate { "fr_authend" }, /* 5 */ 493*7c478bd9Sstevel@tonic-gate { "fr_authnext" }, 494*7c478bd9Sstevel@tonic-gate { "fr_auth" }, 495*7c478bd9Sstevel@tonic-gate { "fr_authused" }, 496*7c478bd9Sstevel@tonic-gate { "fr_authsize" }, 497*7c478bd9Sstevel@tonic-gate { "fr_defaultauthage" }, /* 10 */ 498*7c478bd9Sstevel@tonic-gate { "fr_authpkts" }, 499*7c478bd9Sstevel@tonic-gate { "fr_auth_lock" }, 500*7c478bd9Sstevel@tonic-gate { "frstats" }, 501*7c478bd9Sstevel@tonic-gate { "ips_stats" }, 502*7c478bd9Sstevel@tonic-gate { "ips_num" }, /* 15 */ 503*7c478bd9Sstevel@tonic-gate { "ips_wild" }, 504*7c478bd9Sstevel@tonic-gate { "ips_list" }, 505*7c478bd9Sstevel@tonic-gate { "ips_table" }, 506*7c478bd9Sstevel@tonic-gate { "fr_statemax" }, 507*7c478bd9Sstevel@tonic-gate { "fr_statesize" }, /* 20 */ 508*7c478bd9Sstevel@tonic-gate { "fr_state_doflush" }, 509*7c478bd9Sstevel@tonic-gate { "fr_state_lock" }, 510*7c478bd9Sstevel@tonic-gate { "ipfr_heads" }, 511*7c478bd9Sstevel@tonic-gate { "ipfr_nattab" }, 512*7c478bd9Sstevel@tonic-gate { "ipfr_stats" }, /* 25 */ 513*7c478bd9Sstevel@tonic-gate { "ipfr_inuse" }, 514*7c478bd9Sstevel@tonic-gate { "fr_ipfrttl" }, 515*7c478bd9Sstevel@tonic-gate { "fr_frag_lock" }, 516*7c478bd9Sstevel@tonic-gate { "ipfr_timer_id" }, 517*7c478bd9Sstevel@tonic-gate { "fr_nat_lock" }, /* 30 */ 518*7c478bd9Sstevel@tonic-gate { "ipfilter" }, 519*7c478bd9Sstevel@tonic-gate { "ipfilter6" }, 520*7c478bd9Sstevel@tonic-gate { "ipacct" }, 521*7c478bd9Sstevel@tonic-gate { "ipacct6" }, 522*7c478bd9Sstevel@tonic-gate { "ipl_frouteok" }, /* 35 */ 523*7c478bd9Sstevel@tonic-gate { "fr_running" }, 524*7c478bd9Sstevel@tonic-gate { "ipfgroups" }, 525*7c478bd9Sstevel@tonic-gate { "fr_active" }, 526*7c478bd9Sstevel@tonic-gate { "fr_pass" }, 527*7c478bd9Sstevel@tonic-gate { "fr_flags" }, /* 40 */ 528*7c478bd9Sstevel@tonic-gate { "ipstate_logging" }, 529*7c478bd9Sstevel@tonic-gate { NULL } 530*7c478bd9Sstevel@tonic-gate }; 531*7c478bd9Sstevel@tonic-gate 532*7c478bd9Sstevel@tonic-gate 533*7c478bd9Sstevel@tonic-gate frauthstp = &frauthst; 534*7c478bd9Sstevel@tonic-gate ipsstp = &ipsst; 535*7c478bd9Sstevel@tonic-gate ifrstp = &ifrst; 536*7c478bd9Sstevel@tonic-gate fiop = &fio; 537*7c478bd9Sstevel@tonic-gate 538*7c478bd9Sstevel@tonic-gate *frfp = 0; 539*7c478bd9Sstevel@tonic-gate *fiopp = fiop; 540*7c478bd9Sstevel@tonic-gate *ipsstpp = ipsstp; 541*7c478bd9Sstevel@tonic-gate *ifrstpp = ifrstp; 542*7c478bd9Sstevel@tonic-gate *frauthstpp = frauthstp; 543*7c478bd9Sstevel@tonic-gate 544*7c478bd9Sstevel@tonic-gate bzero((char *)fiop, sizeof(*fiop)); 545*7c478bd9Sstevel@tonic-gate bzero((char *)ipsstp, sizeof(*ipsstp)); 546*7c478bd9Sstevel@tonic-gate bzero((char *)ifrstp, sizeof(*ifrstp)); 547*7c478bd9Sstevel@tonic-gate bzero((char *)frauthstp, sizeof(*frauthstp)); 548*7c478bd9Sstevel@tonic-gate 549*7c478bd9Sstevel@tonic-gate if (nlist(kernel, deadlist) == -1) { 550*7c478bd9Sstevel@tonic-gate fprintf(stderr, "nlist error\n"); 551*7c478bd9Sstevel@tonic-gate return; 552*7c478bd9Sstevel@tonic-gate } 553*7c478bd9Sstevel@tonic-gate 554*7c478bd9Sstevel@tonic-gate /* 555*7c478bd9Sstevel@tonic-gate * This is for SIOCGETFF. 556*7c478bd9Sstevel@tonic-gate */ 557*7c478bd9Sstevel@tonic-gate kmemcpy((char *)frfp, (u_long)deadlist[40].n_value, sizeof(*frfp)); 558*7c478bd9Sstevel@tonic-gate 559*7c478bd9Sstevel@tonic-gate /* 560*7c478bd9Sstevel@tonic-gate * f_locks is a combination of the lock variable from each part of 561*7c478bd9Sstevel@tonic-gate * ipfilter (state, auth, nat, fragments). 562*7c478bd9Sstevel@tonic-gate */ 563*7c478bd9Sstevel@tonic-gate kmemcpy((char *)fiop, (u_long)deadlist[13].n_value, sizeof(*fiop)); 564*7c478bd9Sstevel@tonic-gate kmemcpy((char *)&fiop->f_locks[0], (u_long)deadlist[22].n_value, 565*7c478bd9Sstevel@tonic-gate sizeof(fiop->f_locks[0])); 566*7c478bd9Sstevel@tonic-gate kmemcpy((char *)&fiop->f_locks[0], (u_long)deadlist[30].n_value, 567*7c478bd9Sstevel@tonic-gate sizeof(fiop->f_locks[1])); 568*7c478bd9Sstevel@tonic-gate kmemcpy((char *)&fiop->f_locks[2], (u_long)deadlist[28].n_value, 569*7c478bd9Sstevel@tonic-gate sizeof(fiop->f_locks[2])); 570*7c478bd9Sstevel@tonic-gate kmemcpy((char *)&fiop->f_locks[3], (u_long)deadlist[12].n_value, 571*7c478bd9Sstevel@tonic-gate sizeof(fiop->f_locks[3])); 572*7c478bd9Sstevel@tonic-gate 573*7c478bd9Sstevel@tonic-gate /* 574*7c478bd9Sstevel@tonic-gate * Get pointers to each list of rules (active, inactive, in, out) 575*7c478bd9Sstevel@tonic-gate */ 576*7c478bd9Sstevel@tonic-gate kmemcpy((char *)&rules, (u_long)deadlist[31].n_value, sizeof(rules)); 577*7c478bd9Sstevel@tonic-gate fiop->f_fin[0] = rules[0][0]; 578*7c478bd9Sstevel@tonic-gate fiop->f_fin[1] = rules[0][1]; 579*7c478bd9Sstevel@tonic-gate fiop->f_fout[0] = rules[1][0]; 580*7c478bd9Sstevel@tonic-gate fiop->f_fout[1] = rules[1][1]; 581*7c478bd9Sstevel@tonic-gate 582*7c478bd9Sstevel@tonic-gate /* 583*7c478bd9Sstevel@tonic-gate * Same for IPv6, except make them null if support for it is not 584*7c478bd9Sstevel@tonic-gate * being compiled in. 585*7c478bd9Sstevel@tonic-gate */ 586*7c478bd9Sstevel@tonic-gate #ifdef USE_INET6 587*7c478bd9Sstevel@tonic-gate kmemcpy((char *)&rules, (u_long)deadlist[32].n_value, sizeof(rules)); 588*7c478bd9Sstevel@tonic-gate fiop->f_fin6[0] = rules[0][0]; 589*7c478bd9Sstevel@tonic-gate fiop->f_fin6[1] = rules[0][1]; 590*7c478bd9Sstevel@tonic-gate fiop->f_fout6[0] = rules[1][0]; 591*7c478bd9Sstevel@tonic-gate fiop->f_fout6[1] = rules[1][1]; 592*7c478bd9Sstevel@tonic-gate #else 593*7c478bd9Sstevel@tonic-gate fiop->f_fin6[0] = NULL; 594*7c478bd9Sstevel@tonic-gate fiop->f_fin6[1] = NULL; 595*7c478bd9Sstevel@tonic-gate fiop->f_fout6[0] = NULL; 596*7c478bd9Sstevel@tonic-gate fiop->f_fout6[1] = NULL; 597*7c478bd9Sstevel@tonic-gate #endif 598*7c478bd9Sstevel@tonic-gate 599*7c478bd9Sstevel@tonic-gate /* 600*7c478bd9Sstevel@tonic-gate * Now get accounting rules pointers. 601*7c478bd9Sstevel@tonic-gate */ 602*7c478bd9Sstevel@tonic-gate kmemcpy((char *)&rules, (u_long)deadlist[33].n_value, sizeof(rules)); 603*7c478bd9Sstevel@tonic-gate fiop->f_acctin[0] = rules[0][0]; 604*7c478bd9Sstevel@tonic-gate fiop->f_acctin[1] = rules[0][1]; 605*7c478bd9Sstevel@tonic-gate fiop->f_acctout[0] = rules[1][0]; 606*7c478bd9Sstevel@tonic-gate fiop->f_acctout[1] = rules[1][1]; 607*7c478bd9Sstevel@tonic-gate 608*7c478bd9Sstevel@tonic-gate #ifdef USE_INET6 609*7c478bd9Sstevel@tonic-gate kmemcpy((char *)&rules, (u_long)deadlist[34].n_value, sizeof(rules)); 610*7c478bd9Sstevel@tonic-gate fiop->f_acctin6[0] = rules[0][0]; 611*7c478bd9Sstevel@tonic-gate fiop->f_acctin6[1] = rules[0][1]; 612*7c478bd9Sstevel@tonic-gate fiop->f_acctout6[0] = rules[1][0]; 613*7c478bd9Sstevel@tonic-gate fiop->f_acctout6[1] = rules[1][1]; 614*7c478bd9Sstevel@tonic-gate #else 615*7c478bd9Sstevel@tonic-gate fiop->f_acctin6[0] = NULL; 616*7c478bd9Sstevel@tonic-gate fiop->f_acctin6[1] = NULL; 617*7c478bd9Sstevel@tonic-gate fiop->f_acctout6[0] = NULL; 618*7c478bd9Sstevel@tonic-gate fiop->f_acctout6[1] = NULL; 619*7c478bd9Sstevel@tonic-gate #endif 620*7c478bd9Sstevel@tonic-gate 621*7c478bd9Sstevel@tonic-gate /* 622*7c478bd9Sstevel@tonic-gate * A collection of "global" variables used inside the kernel which 623*7c478bd9Sstevel@tonic-gate * are all collected in friostat_t via ioctl. 624*7c478bd9Sstevel@tonic-gate */ 625*7c478bd9Sstevel@tonic-gate kmemcpy((char *)&fiop->f_froute, (u_long)deadlist[35].n_value, 626*7c478bd9Sstevel@tonic-gate sizeof(fiop->f_froute)); 627*7c478bd9Sstevel@tonic-gate kmemcpy((char *)&fiop->f_running, (u_long)deadlist[36].n_value, 628*7c478bd9Sstevel@tonic-gate sizeof(fiop->f_running)); 629*7c478bd9Sstevel@tonic-gate kmemcpy((char *)&fiop->f_groups, (u_long)deadlist[37].n_value, 630*7c478bd9Sstevel@tonic-gate sizeof(fiop->f_groups)); 631*7c478bd9Sstevel@tonic-gate kmemcpy((char *)&fiop->f_active, (u_long)deadlist[38].n_value, 632*7c478bd9Sstevel@tonic-gate sizeof(fiop->f_active)); 633*7c478bd9Sstevel@tonic-gate kmemcpy((char *)&fiop->f_defpass, (u_long)deadlist[39].n_value, 634*7c478bd9Sstevel@tonic-gate sizeof(fiop->f_defpass)); 635*7c478bd9Sstevel@tonic-gate 636*7c478bd9Sstevel@tonic-gate /* 637*7c478bd9Sstevel@tonic-gate * Build up the state information stats structure. 638*7c478bd9Sstevel@tonic-gate */ 639*7c478bd9Sstevel@tonic-gate kmemcpy((char *)ipsstp, (u_long)deadlist[14].n_value, sizeof(*ipsstp)); 640*7c478bd9Sstevel@tonic-gate kmemcpy((char *)&temp, (u_long)deadlist[15].n_value, sizeof(temp)); 641*7c478bd9Sstevel@tonic-gate ipsstp->iss_active = temp; 642*7c478bd9Sstevel@tonic-gate ipsstp->iss_table = (void *)deadlist[18].n_value; 643*7c478bd9Sstevel@tonic-gate ipsstp->iss_list = (void *)deadlist[17].n_value; 644*7c478bd9Sstevel@tonic-gate 645*7c478bd9Sstevel@tonic-gate /* 646*7c478bd9Sstevel@tonic-gate * Build up the authentiation information stats structure. 647*7c478bd9Sstevel@tonic-gate */ 648*7c478bd9Sstevel@tonic-gate kmemcpy((char *)frauthstp, (u_long)deadlist[0].n_value, 649*7c478bd9Sstevel@tonic-gate sizeof(*frauthstp)); 650*7c478bd9Sstevel@tonic-gate frauthstp->fas_faelist = (void *)deadlist[1].n_value; 651*7c478bd9Sstevel@tonic-gate 652*7c478bd9Sstevel@tonic-gate /* 653*7c478bd9Sstevel@tonic-gate * Build up the fragment information stats structure. 654*7c478bd9Sstevel@tonic-gate */ 655*7c478bd9Sstevel@tonic-gate kmemcpy((char *)ifrstp, (u_long)deadlist[25].n_value, 656*7c478bd9Sstevel@tonic-gate sizeof(*ifrstp)); 657*7c478bd9Sstevel@tonic-gate ifrstp->ifs_table = (void *)deadlist[23].n_value; 658*7c478bd9Sstevel@tonic-gate ifrstp->ifs_nattab = (void *)deadlist[24].n_value; 659*7c478bd9Sstevel@tonic-gate kmemcpy((char *)&ifrstp->ifs_inuse, (u_long)deadlist[26].n_value, 660*7c478bd9Sstevel@tonic-gate sizeof(ifrstp->ifs_inuse)); 661*7c478bd9Sstevel@tonic-gate 662*7c478bd9Sstevel@tonic-gate /* 663*7c478bd9Sstevel@tonic-gate * Get logging on/off switches 664*7c478bd9Sstevel@tonic-gate */ 665*7c478bd9Sstevel@tonic-gate kmemcpy((char *)&state_logging, (u_long)deadlist[41].n_value, 666*7c478bd9Sstevel@tonic-gate sizeof(state_logging)); 667*7c478bd9Sstevel@tonic-gate } 668*7c478bd9Sstevel@tonic-gate 669*7c478bd9Sstevel@tonic-gate 670*7c478bd9Sstevel@tonic-gate /* 671*7c478bd9Sstevel@tonic-gate * Display the kernel stats for packets blocked and passed and other 672*7c478bd9Sstevel@tonic-gate * associated running totals which are kept. 673*7c478bd9Sstevel@tonic-gate */ 674*7c478bd9Sstevel@tonic-gate static void showstats(fp, frf) 675*7c478bd9Sstevel@tonic-gate struct friostat *fp; 676*7c478bd9Sstevel@tonic-gate u_32_t frf; 677*7c478bd9Sstevel@tonic-gate { 678*7c478bd9Sstevel@tonic-gate 679*7c478bd9Sstevel@tonic-gate PRINTF("bad packets:\t\tin %lu\tout %lu\n", 680*7c478bd9Sstevel@tonic-gate fp->f_st[0].fr_bad, fp->f_st[1].fr_bad); 681*7c478bd9Sstevel@tonic-gate #ifdef USE_INET6 682*7c478bd9Sstevel@tonic-gate PRINTF(" IPv6 packets:\t\tin %lu out %lu\n", 683*7c478bd9Sstevel@tonic-gate fp->f_st[0].fr_ipv6, fp->f_st[1].fr_ipv6); 684*7c478bd9Sstevel@tonic-gate #endif 685*7c478bd9Sstevel@tonic-gate PRINTF(" input packets:\t\tblocked %lu passed %lu nomatch %lu", 686*7c478bd9Sstevel@tonic-gate fp->f_st[0].fr_block, fp->f_st[0].fr_pass, 687*7c478bd9Sstevel@tonic-gate fp->f_st[0].fr_nom); 688*7c478bd9Sstevel@tonic-gate PRINTF(" counted %lu short %lu\n", 689*7c478bd9Sstevel@tonic-gate fp->f_st[0].fr_acct, fp->f_st[0].fr_short); 690*7c478bd9Sstevel@tonic-gate PRINTF("output packets:\t\tblocked %lu passed %lu nomatch %lu", 691*7c478bd9Sstevel@tonic-gate fp->f_st[1].fr_block, fp->f_st[1].fr_pass, 692*7c478bd9Sstevel@tonic-gate fp->f_st[1].fr_nom); 693*7c478bd9Sstevel@tonic-gate PRINTF(" counted %lu short %lu\n", 694*7c478bd9Sstevel@tonic-gate fp->f_st[1].fr_acct, fp->f_st[1].fr_short); 695*7c478bd9Sstevel@tonic-gate PRINTF(" input packets logged:\tblocked %lu passed %lu\n", 696*7c478bd9Sstevel@tonic-gate fp->f_st[0].fr_bpkl, fp->f_st[0].fr_ppkl); 697*7c478bd9Sstevel@tonic-gate PRINTF("output packets logged:\tblocked %lu passed %lu\n", 698*7c478bd9Sstevel@tonic-gate fp->f_st[1].fr_bpkl, fp->f_st[1].fr_ppkl); 699*7c478bd9Sstevel@tonic-gate PRINTF(" packets logged:\tinput %lu output %lu\n", 700*7c478bd9Sstevel@tonic-gate fp->f_st[0].fr_pkl, fp->f_st[1].fr_pkl); 701*7c478bd9Sstevel@tonic-gate PRINTF(" log failures:\t\tinput %lu output %lu\n", 702*7c478bd9Sstevel@tonic-gate fp->f_st[0].fr_skip, fp->f_st[1].fr_skip); 703*7c478bd9Sstevel@tonic-gate PRINTF("fragment state(in):\tkept %lu\tlost %lu\n", 704*7c478bd9Sstevel@tonic-gate fp->f_st[0].fr_nfr, fp->f_st[0].fr_bnfr); 705*7c478bd9Sstevel@tonic-gate PRINTF("fragment state(out):\tkept %lu\tlost %lu\n", 706*7c478bd9Sstevel@tonic-gate fp->f_st[1].fr_nfr, fp->f_st[1].fr_bnfr); 707*7c478bd9Sstevel@tonic-gate PRINTF("packet state(in):\tkept %lu\tlost %lu\n", 708*7c478bd9Sstevel@tonic-gate fp->f_st[0].fr_ads, fp->f_st[0].fr_bads); 709*7c478bd9Sstevel@tonic-gate PRINTF("packet state(out):\tkept %lu\tlost %lu\n", 710*7c478bd9Sstevel@tonic-gate fp->f_st[1].fr_ads, fp->f_st[1].fr_bads); 711*7c478bd9Sstevel@tonic-gate PRINTF("ICMP replies:\t%lu\tTCP RSTs sent:\t%lu\n", 712*7c478bd9Sstevel@tonic-gate fp->f_st[0].fr_ret, fp->f_st[1].fr_ret); 713*7c478bd9Sstevel@tonic-gate PRINTF("Invalid source(in):\t%lu\n", fp->f_st[0].fr_badsrc); 714*7c478bd9Sstevel@tonic-gate PRINTF("Result cache hits(in):\t%lu\t(out):\t%lu\n", 715*7c478bd9Sstevel@tonic-gate fp->f_st[0].fr_chit, fp->f_st[1].fr_chit); 716*7c478bd9Sstevel@tonic-gate PRINTF("IN Pullups succeeded:\t%lu\tfailed:\t%lu\n", 717*7c478bd9Sstevel@tonic-gate fp->f_st[0].fr_pull[0], fp->f_st[0].fr_pull[1]); 718*7c478bd9Sstevel@tonic-gate PRINTF("OUT Pullups succeeded:\t%lu\tfailed:\t%lu\n", 719*7c478bd9Sstevel@tonic-gate fp->f_st[1].fr_pull[0], fp->f_st[1].fr_pull[1]); 720*7c478bd9Sstevel@tonic-gate PRINTF("Fastroute successes:\t%lu\tfailures:\t%lu\n", 721*7c478bd9Sstevel@tonic-gate fp->f_froute[0], fp->f_froute[1]); 722*7c478bd9Sstevel@tonic-gate PRINTF("TCP cksum fails(in):\t%lu\t(out):\t%lu\n", 723*7c478bd9Sstevel@tonic-gate fp->f_st[0].fr_tcpbad, fp->f_st[1].fr_tcpbad); 724*7c478bd9Sstevel@tonic-gate PRINTF("IPF Ticks:\t%lu\n", fp->f_ticks); 725*7c478bd9Sstevel@tonic-gate 726*7c478bd9Sstevel@tonic-gate PRINTF("Packet log flags set: (%#x)\n", frf); 727*7c478bd9Sstevel@tonic-gate if (frf & FF_LOGPASS) 728*7c478bd9Sstevel@tonic-gate PRINTF("\tpackets passed through filter\n"); 729*7c478bd9Sstevel@tonic-gate if (frf & FF_LOGBLOCK) 730*7c478bd9Sstevel@tonic-gate PRINTF("\tpackets blocked by filter\n"); 731*7c478bd9Sstevel@tonic-gate if (frf & FF_LOGNOMATCH) 732*7c478bd9Sstevel@tonic-gate PRINTF("\tpackets not matched by filter\n"); 733*7c478bd9Sstevel@tonic-gate if (!frf) 734*7c478bd9Sstevel@tonic-gate PRINTF("\tnone\n"); 735*7c478bd9Sstevel@tonic-gate } 736*7c478bd9Sstevel@tonic-gate 737*7c478bd9Sstevel@tonic-gate 738*7c478bd9Sstevel@tonic-gate /* 739*7c478bd9Sstevel@tonic-gate * Print out a list of rules from the kernel, starting at the one passed. 740*7c478bd9Sstevel@tonic-gate */ 741*7c478bd9Sstevel@tonic-gate static void printlist(fp, comment) 742*7c478bd9Sstevel@tonic-gate frentry_t *fp; 743*7c478bd9Sstevel@tonic-gate char *comment; 744*7c478bd9Sstevel@tonic-gate { 745*7c478bd9Sstevel@tonic-gate struct frentry fb, *fg; 746*7c478bd9Sstevel@tonic-gate char *data; 747*7c478bd9Sstevel@tonic-gate u_32_t type; 748*7c478bd9Sstevel@tonic-gate int n; 749*7c478bd9Sstevel@tonic-gate 750*7c478bd9Sstevel@tonic-gate for (n = 1; fp; n++) { 751*7c478bd9Sstevel@tonic-gate if (kmemcpy((char *)&fb, (u_long)fp, sizeof(fb)) == -1) { 752*7c478bd9Sstevel@tonic-gate perror("kmemcpy"); 753*7c478bd9Sstevel@tonic-gate return; 754*7c478bd9Sstevel@tonic-gate } 755*7c478bd9Sstevel@tonic-gate fp = &fb; 756*7c478bd9Sstevel@tonic-gate if (opts & (OPT_HITS|OPT_VERBOSE)) 757*7c478bd9Sstevel@tonic-gate #ifdef USE_QUAD_T 758*7c478bd9Sstevel@tonic-gate PRINTF("%qu ", (unsigned long long) fp->fr_hits); 759*7c478bd9Sstevel@tonic-gate #else 760*7c478bd9Sstevel@tonic-gate PRINTF("%lu ", fp->fr_hits); 761*7c478bd9Sstevel@tonic-gate #endif 762*7c478bd9Sstevel@tonic-gate if (opts & (OPT_ACCNT|OPT_VERBOSE)) 763*7c478bd9Sstevel@tonic-gate #ifdef USE_QUAD_T 764*7c478bd9Sstevel@tonic-gate PRINTF("%qu ", (unsigned long long) fp->fr_bytes); 765*7c478bd9Sstevel@tonic-gate #else 766*7c478bd9Sstevel@tonic-gate PRINTF("%lu ", fp->fr_bytes); 767*7c478bd9Sstevel@tonic-gate #endif 768*7c478bd9Sstevel@tonic-gate if (opts & OPT_SHOWLINENO) 769*7c478bd9Sstevel@tonic-gate PRINTF("@%d ", n); 770*7c478bd9Sstevel@tonic-gate data = NULL; 771*7c478bd9Sstevel@tonic-gate type = fp->fr_type & ~FR_T_BUILTIN; 772*7c478bd9Sstevel@tonic-gate if (type == FR_T_IPF || type == FR_T_BPFOPC) { 773*7c478bd9Sstevel@tonic-gate if (fp->fr_dsize) { 774*7c478bd9Sstevel@tonic-gate data = malloc(fp->fr_dsize); 775*7c478bd9Sstevel@tonic-gate 776*7c478bd9Sstevel@tonic-gate if (kmemcpy(data, (u_long)fp->fr_data, 777*7c478bd9Sstevel@tonic-gate fp->fr_dsize) == -1) { 778*7c478bd9Sstevel@tonic-gate perror("kmemcpy"); 779*7c478bd9Sstevel@tonic-gate return; 780*7c478bd9Sstevel@tonic-gate } 781*7c478bd9Sstevel@tonic-gate fp->fr_data = data; 782*7c478bd9Sstevel@tonic-gate } 783*7c478bd9Sstevel@tonic-gate } 784*7c478bd9Sstevel@tonic-gate 785*7c478bd9Sstevel@tonic-gate printfr(fp, ioctl); 786*7c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) { 787*7c478bd9Sstevel@tonic-gate binprint(fp, sizeof(*fp)); 788*7c478bd9Sstevel@tonic-gate if (fp->fr_data != NULL && fp->fr_dsize > 0) 789*7c478bd9Sstevel@tonic-gate binprint(fp->fr_data, fp->fr_dsize); 790*7c478bd9Sstevel@tonic-gate } 791*7c478bd9Sstevel@tonic-gate if (data != NULL) 792*7c478bd9Sstevel@tonic-gate free(data); 793*7c478bd9Sstevel@tonic-gate if (fp->fr_grp != NULL) { 794*7c478bd9Sstevel@tonic-gate if (!kmemcpy((char *)&fg, (u_long)fp->fr_grp, 795*7c478bd9Sstevel@tonic-gate sizeof(fg))) 796*7c478bd9Sstevel@tonic-gate printlist(fg, comment); 797*7c478bd9Sstevel@tonic-gate } 798*7c478bd9Sstevel@tonic-gate if (type == FR_T_CALLFUNC) { 799*7c478bd9Sstevel@tonic-gate printlist(fp->fr_data, "# callfunc: "); 800*7c478bd9Sstevel@tonic-gate } 801*7c478bd9Sstevel@tonic-gate fp = fp->fr_next; 802*7c478bd9Sstevel@tonic-gate } 803*7c478bd9Sstevel@tonic-gate } 804*7c478bd9Sstevel@tonic-gate 805*7c478bd9Sstevel@tonic-gate /* 806*7c478bd9Sstevel@tonic-gate * print out all of the asked for rule sets, using the stats struct as 807*7c478bd9Sstevel@tonic-gate * the base from which to get the pointers. 808*7c478bd9Sstevel@tonic-gate */ 809*7c478bd9Sstevel@tonic-gate static void showlist(fiop) 810*7c478bd9Sstevel@tonic-gate struct friostat *fiop; 811*7c478bd9Sstevel@tonic-gate { 812*7c478bd9Sstevel@tonic-gate struct frentry *fp = NULL; 813*7c478bd9Sstevel@tonic-gate int i, set; 814*7c478bd9Sstevel@tonic-gate 815*7c478bd9Sstevel@tonic-gate set = fiop->f_active; 816*7c478bd9Sstevel@tonic-gate if (opts & OPT_INACTIVE) 817*7c478bd9Sstevel@tonic-gate set = 1 - set; 818*7c478bd9Sstevel@tonic-gate if (opts & OPT_ACCNT) { 819*7c478bd9Sstevel@tonic-gate #ifdef USE_INET6 820*7c478bd9Sstevel@tonic-gate if ((use_inet6) && (opts & OPT_OUTQUE)) { 821*7c478bd9Sstevel@tonic-gate i = F_ACOUT; 822*7c478bd9Sstevel@tonic-gate fp = (struct frentry *)fiop->f_acctout6[set]; 823*7c478bd9Sstevel@tonic-gate } else if ((use_inet6) && (opts & OPT_INQUE)) { 824*7c478bd9Sstevel@tonic-gate i = F_ACIN; 825*7c478bd9Sstevel@tonic-gate fp = (struct frentry *)fiop->f_acctin6[set]; 826*7c478bd9Sstevel@tonic-gate } else 827*7c478bd9Sstevel@tonic-gate #endif 828*7c478bd9Sstevel@tonic-gate if (opts & OPT_OUTQUE) { 829*7c478bd9Sstevel@tonic-gate i = F_ACOUT; 830*7c478bd9Sstevel@tonic-gate fp = (struct frentry *)fiop->f_acctout[set]; 831*7c478bd9Sstevel@tonic-gate } else if (opts & OPT_INQUE) { 832*7c478bd9Sstevel@tonic-gate i = F_ACIN; 833*7c478bd9Sstevel@tonic-gate fp = (struct frentry *)fiop->f_acctin[set]; 834*7c478bd9Sstevel@tonic-gate } else { 835*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, "No -i or -o given with -a\n"); 836*7c478bd9Sstevel@tonic-gate return; 837*7c478bd9Sstevel@tonic-gate } 838*7c478bd9Sstevel@tonic-gate } else { 839*7c478bd9Sstevel@tonic-gate #ifdef USE_INET6 840*7c478bd9Sstevel@tonic-gate if ((use_inet6) && (opts & OPT_OUTQUE)) { 841*7c478bd9Sstevel@tonic-gate i = F_OUT; 842*7c478bd9Sstevel@tonic-gate fp = (struct frentry *)fiop->f_fout6[set]; 843*7c478bd9Sstevel@tonic-gate } else if ((use_inet6) && (opts & OPT_INQUE)) { 844*7c478bd9Sstevel@tonic-gate i = F_IN; 845*7c478bd9Sstevel@tonic-gate fp = (struct frentry *)fiop->f_fin6[set]; 846*7c478bd9Sstevel@tonic-gate } else 847*7c478bd9Sstevel@tonic-gate #endif 848*7c478bd9Sstevel@tonic-gate if (opts & OPT_OUTQUE) { 849*7c478bd9Sstevel@tonic-gate i = F_OUT; 850*7c478bd9Sstevel@tonic-gate fp = (struct frentry *)fiop->f_fout[set]; 851*7c478bd9Sstevel@tonic-gate } else if (opts & OPT_INQUE) { 852*7c478bd9Sstevel@tonic-gate i = F_IN; 853*7c478bd9Sstevel@tonic-gate fp = (struct frentry *)fiop->f_fin[set]; 854*7c478bd9Sstevel@tonic-gate } else 855*7c478bd9Sstevel@tonic-gate return; 856*7c478bd9Sstevel@tonic-gate } 857*7c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 858*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, "showlist:opts %#x i %d\n", opts, i); 859*7c478bd9Sstevel@tonic-gate 860*7c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 861*7c478bd9Sstevel@tonic-gate PRINTF("fp %p set %d\n", fp, set); 862*7c478bd9Sstevel@tonic-gate if (!fp) { 863*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, "empty list for %s%s\n", 864*7c478bd9Sstevel@tonic-gate (opts & OPT_INACTIVE) ? "inactive " : "", filters[i]); 865*7c478bd9Sstevel@tonic-gate return; 866*7c478bd9Sstevel@tonic-gate } 867*7c478bd9Sstevel@tonic-gate printlist(fp, NULL); 868*7c478bd9Sstevel@tonic-gate } 869*7c478bd9Sstevel@tonic-gate 870*7c478bd9Sstevel@tonic-gate 871*7c478bd9Sstevel@tonic-gate /* 872*7c478bd9Sstevel@tonic-gate * Display ipfilter stateful filtering information 873*7c478bd9Sstevel@tonic-gate */ 874*7c478bd9Sstevel@tonic-gate static void showipstates(ipsp) 875*7c478bd9Sstevel@tonic-gate ips_stat_t *ipsp; 876*7c478bd9Sstevel@tonic-gate { 877*7c478bd9Sstevel@tonic-gate u_long minlen, maxlen, totallen, *buckets; 878*7c478bd9Sstevel@tonic-gate int i, sz; 879*7c478bd9Sstevel@tonic-gate 880*7c478bd9Sstevel@tonic-gate sz = sizeof(*buckets) * ipsp->iss_statesize; 881*7c478bd9Sstevel@tonic-gate buckets = (u_long *)malloc(sz); 882*7c478bd9Sstevel@tonic-gate if (kmemcpy((char *)buckets, (u_long)ipsp->iss_bucketlen, sz)) { 883*7c478bd9Sstevel@tonic-gate free(buckets); 884*7c478bd9Sstevel@tonic-gate return; 885*7c478bd9Sstevel@tonic-gate } 886*7c478bd9Sstevel@tonic-gate 887*7c478bd9Sstevel@tonic-gate /* 888*7c478bd9Sstevel@tonic-gate * If a list of states hasn't been asked for, only print out stats 889*7c478bd9Sstevel@tonic-gate */ 890*7c478bd9Sstevel@tonic-gate if (!(opts & OPT_SHOWLIST)) { 891*7c478bd9Sstevel@tonic-gate PRINTF("IP states added:\n\t%lu TCP\n\t%lu UDP\n\t%lu ICMP\n", 892*7c478bd9Sstevel@tonic-gate ipsp->iss_tcp, ipsp->iss_udp, ipsp->iss_icmp); 893*7c478bd9Sstevel@tonic-gate PRINTF("\t%lu hits\n\t%lu misses\n", ipsp->iss_hits, 894*7c478bd9Sstevel@tonic-gate ipsp->iss_miss); 895*7c478bd9Sstevel@tonic-gate PRINTF("\t%lu maximum\n\t%lu no memory\n\t%lu max bucket\n", 896*7c478bd9Sstevel@tonic-gate ipsp->iss_max, ipsp->iss_nomem, ipsp->iss_bucketfull); 897*7c478bd9Sstevel@tonic-gate PRINTF("\t%lu active\n\t%lu expired\n\t%lu closed\n", 898*7c478bd9Sstevel@tonic-gate ipsp->iss_active, ipsp->iss_expire, ipsp->iss_fin); 899*7c478bd9Sstevel@tonic-gate 900*7c478bd9Sstevel@tonic-gate PRINTF("State logging %sabled\n", 901*7c478bd9Sstevel@tonic-gate state_logging ? "en" : "dis"); 902*7c478bd9Sstevel@tonic-gate 903*7c478bd9Sstevel@tonic-gate PRINTF("\nState table bucket statistics:\n"); 904*7c478bd9Sstevel@tonic-gate PRINTF("\t%lu in use\t\n", ipsp->iss_inuse); 905*7c478bd9Sstevel@tonic-gate 906*7c478bd9Sstevel@tonic-gate minlen = ipsp->iss_max; 907*7c478bd9Sstevel@tonic-gate totallen = 0; 908*7c478bd9Sstevel@tonic-gate maxlen = 0; 909*7c478bd9Sstevel@tonic-gate 910*7c478bd9Sstevel@tonic-gate for (i = 0; i < ipsp->iss_statesize; i++) { 911*7c478bd9Sstevel@tonic-gate if (buckets[i] > maxlen) 912*7c478bd9Sstevel@tonic-gate maxlen = buckets[i]; 913*7c478bd9Sstevel@tonic-gate if (buckets[i] < minlen) 914*7c478bd9Sstevel@tonic-gate minlen = buckets[i]; 915*7c478bd9Sstevel@tonic-gate totallen += buckets[i]; 916*7c478bd9Sstevel@tonic-gate } 917*7c478bd9Sstevel@tonic-gate 918*7c478bd9Sstevel@tonic-gate PRINTF("\t%2.2f%% bucket usage\n\t%lu minimal length\n", 919*7c478bd9Sstevel@tonic-gate ((float)ipsp->iss_inuse / ipsp->iss_statesize) * 100.0, 920*7c478bd9Sstevel@tonic-gate minlen); 921*7c478bd9Sstevel@tonic-gate PRINTF("\t%lu maximal length\n\t%.3f average length\n", 922*7c478bd9Sstevel@tonic-gate maxlen, 923*7c478bd9Sstevel@tonic-gate ipsp->iss_inuse ? (float) totallen/ ipsp->iss_inuse : 924*7c478bd9Sstevel@tonic-gate 0.0); 925*7c478bd9Sstevel@tonic-gate 926*7c478bd9Sstevel@tonic-gate #define ENTRIES_PER_LINE 5 927*7c478bd9Sstevel@tonic-gate 928*7c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) { 929*7c478bd9Sstevel@tonic-gate PRINTF("\nCurrent bucket sizes :\n"); 930*7c478bd9Sstevel@tonic-gate for (i = 0; i < ipsp->iss_statesize; i++) { 931*7c478bd9Sstevel@tonic-gate if ((i % ENTRIES_PER_LINE) == 0) 932*7c478bd9Sstevel@tonic-gate PRINTF("\t"); 933*7c478bd9Sstevel@tonic-gate PRINTF("%4d -> %4lu", i, buckets[i]); 934*7c478bd9Sstevel@tonic-gate if ((i % ENTRIES_PER_LINE) == 935*7c478bd9Sstevel@tonic-gate (ENTRIES_PER_LINE - 1)) 936*7c478bd9Sstevel@tonic-gate PRINTF("\n"); 937*7c478bd9Sstevel@tonic-gate else 938*7c478bd9Sstevel@tonic-gate PRINTF(" "); 939*7c478bd9Sstevel@tonic-gate } 940*7c478bd9Sstevel@tonic-gate PRINTF("\n"); 941*7c478bd9Sstevel@tonic-gate } 942*7c478bd9Sstevel@tonic-gate PRINTF("\n"); 943*7c478bd9Sstevel@tonic-gate 944*7c478bd9Sstevel@tonic-gate free(buckets); 945*7c478bd9Sstevel@tonic-gate return; 946*7c478bd9Sstevel@tonic-gate } 947*7c478bd9Sstevel@tonic-gate 948*7c478bd9Sstevel@tonic-gate /* 949*7c478bd9Sstevel@tonic-gate * Print out all the state information currently held in the kernel. 950*7c478bd9Sstevel@tonic-gate */ 951*7c478bd9Sstevel@tonic-gate while (ipsp->iss_list != NULL) { 952*7c478bd9Sstevel@tonic-gate ipsp->iss_list = printstate(ipsp->iss_list, opts); 953*7c478bd9Sstevel@tonic-gate } 954*7c478bd9Sstevel@tonic-gate 955*7c478bd9Sstevel@tonic-gate free(buckets); 956*7c478bd9Sstevel@tonic-gate } 957*7c478bd9Sstevel@tonic-gate 958*7c478bd9Sstevel@tonic-gate 959*7c478bd9Sstevel@tonic-gate #ifdef STATETOP 960*7c478bd9Sstevel@tonic-gate static void topipstates(saddr, daddr, sport, dport, protocol, 961*7c478bd9Sstevel@tonic-gate refreshtime, topclosed) 962*7c478bd9Sstevel@tonic-gate struct in_addr saddr; 963*7c478bd9Sstevel@tonic-gate struct in_addr daddr; 964*7c478bd9Sstevel@tonic-gate int sport; 965*7c478bd9Sstevel@tonic-gate int dport; 966*7c478bd9Sstevel@tonic-gate int protocol; 967*7c478bd9Sstevel@tonic-gate int refreshtime; 968*7c478bd9Sstevel@tonic-gate int topclosed; 969*7c478bd9Sstevel@tonic-gate { 970*7c478bd9Sstevel@tonic-gate char str1[STSTRSIZE], str2[STSTRSIZE], str3[STSTRSIZE], str4[STSTRSIZE]; 971*7c478bd9Sstevel@tonic-gate int maxtsentries = 0, reverse = 0, sorting = STSORT_DEFAULT; 972*7c478bd9Sstevel@tonic-gate int i, j, winx, tsentry, maxx, maxy, redraw = 0; 973*7c478bd9Sstevel@tonic-gate ips_stat_t ipsst, *ipsstp = &ipsst; 974*7c478bd9Sstevel@tonic-gate statetop_t *tstable = NULL, *tp; 975*7c478bd9Sstevel@tonic-gate ipstate_t ips; 976*7c478bd9Sstevel@tonic-gate ipfobj_t ipfo; 977*7c478bd9Sstevel@tonic-gate struct timeval selecttimeout; 978*7c478bd9Sstevel@tonic-gate char hostnm[HOSTNMLEN]; 979*7c478bd9Sstevel@tonic-gate struct protoent *proto; 980*7c478bd9Sstevel@tonic-gate fd_set readfd; 981*7c478bd9Sstevel@tonic-gate int c = 0; 982*7c478bd9Sstevel@tonic-gate time_t t; 983*7c478bd9Sstevel@tonic-gate 984*7c478bd9Sstevel@tonic-gate /* init ncurses stuff */ 985*7c478bd9Sstevel@tonic-gate initscr(); 986*7c478bd9Sstevel@tonic-gate cbreak(); 987*7c478bd9Sstevel@tonic-gate noecho(); 988*7c478bd9Sstevel@tonic-gate 989*7c478bd9Sstevel@tonic-gate /* init hostname */ 990*7c478bd9Sstevel@tonic-gate gethostname(hostnm, sizeof(hostnm) - 1); 991*7c478bd9Sstevel@tonic-gate hostnm[sizeof(hostnm) - 1] = '\0'; 992*7c478bd9Sstevel@tonic-gate 993*7c478bd9Sstevel@tonic-gate /* init ipfobj_t stuff */ 994*7c478bd9Sstevel@tonic-gate bzero((caddr_t)&ipfo, sizeof(ipfo)); 995*7c478bd9Sstevel@tonic-gate ipfo.ipfo_rev = IPFILTER_VERSION; 996*7c478bd9Sstevel@tonic-gate ipfo.ipfo_size = sizeof(*ipsstp); 997*7c478bd9Sstevel@tonic-gate ipfo.ipfo_ptr = (void *)ipsstp; 998*7c478bd9Sstevel@tonic-gate ipfo.ipfo_type = IPFOBJ_STATESTAT; 999*7c478bd9Sstevel@tonic-gate 1000*7c478bd9Sstevel@tonic-gate /* repeat until user aborts */ 1001*7c478bd9Sstevel@tonic-gate while ( 1 ) { 1002*7c478bd9Sstevel@tonic-gate 1003*7c478bd9Sstevel@tonic-gate /* get state table */ 1004*7c478bd9Sstevel@tonic-gate bzero((char *)&ipsst, sizeof(ipsst)); 1005*7c478bd9Sstevel@tonic-gate if ((ioctl(state_fd, SIOCGETFS, &ipfo) == -1)) { 1006*7c478bd9Sstevel@tonic-gate perror("ioctl(SIOCGETFS)"); 1007*7c478bd9Sstevel@tonic-gate exit(-1); 1008*7c478bd9Sstevel@tonic-gate } 1009*7c478bd9Sstevel@tonic-gate 1010*7c478bd9Sstevel@tonic-gate /* clear the history */ 1011*7c478bd9Sstevel@tonic-gate tsentry = -1; 1012*7c478bd9Sstevel@tonic-gate 1013*7c478bd9Sstevel@tonic-gate /* read the state table and store in tstable */ 1014*7c478bd9Sstevel@tonic-gate while (ipsstp->iss_list) { 1015*7c478bd9Sstevel@tonic-gate if (kmemcpy((char *)&ips, (u_long)ipsstp->iss_list, 1016*7c478bd9Sstevel@tonic-gate sizeof(ips))) 1017*7c478bd9Sstevel@tonic-gate break; 1018*7c478bd9Sstevel@tonic-gate ipsstp->iss_list = ips.is_next; 1019*7c478bd9Sstevel@tonic-gate 1020*7c478bd9Sstevel@tonic-gate if (((saddr.s_addr == INADDR_ANY) || 1021*7c478bd9Sstevel@tonic-gate (saddr.s_addr == ips.is_saddr)) && 1022*7c478bd9Sstevel@tonic-gate ((daddr.s_addr == INADDR_ANY) || 1023*7c478bd9Sstevel@tonic-gate (daddr.s_addr == ips.is_daddr)) && 1024*7c478bd9Sstevel@tonic-gate ((protocol < 0) || (protocol == ips.is_p)) && 1025*7c478bd9Sstevel@tonic-gate (((ips.is_p != IPPROTO_TCP) && 1026*7c478bd9Sstevel@tonic-gate (ips.is_p != IPPROTO_UDP)) || 1027*7c478bd9Sstevel@tonic-gate (((sport < 0) || 1028*7c478bd9Sstevel@tonic-gate (htons(sport) == ips.is_sport)) && 1029*7c478bd9Sstevel@tonic-gate ((dport < 0) || 1030*7c478bd9Sstevel@tonic-gate (htons(dport) == ips.is_dport)))) && 1031*7c478bd9Sstevel@tonic-gate (topclosed || (ips.is_p != IPPROTO_TCP) || 1032*7c478bd9Sstevel@tonic-gate (ips.is_state[0] < TCPS_LAST_ACK) || 1033*7c478bd9Sstevel@tonic-gate (ips.is_state[1] < TCPS_LAST_ACK))) { 1034*7c478bd9Sstevel@tonic-gate /* 1035*7c478bd9Sstevel@tonic-gate * if necessary make room for this state 1036*7c478bd9Sstevel@tonic-gate * entry 1037*7c478bd9Sstevel@tonic-gate */ 1038*7c478bd9Sstevel@tonic-gate tsentry++; 1039*7c478bd9Sstevel@tonic-gate if (!maxtsentries || 1040*7c478bd9Sstevel@tonic-gate (tsentry == maxtsentries)) { 1041*7c478bd9Sstevel@tonic-gate 1042*7c478bd9Sstevel@tonic-gate maxtsentries += STGROWSIZE; 1043*7c478bd9Sstevel@tonic-gate tstable = realloc(tstable, maxtsentries * sizeof(statetop_t)); 1044*7c478bd9Sstevel@tonic-gate if (!tstable) { 1045*7c478bd9Sstevel@tonic-gate perror("malloc"); 1046*7c478bd9Sstevel@tonic-gate exit(-1); 1047*7c478bd9Sstevel@tonic-gate } 1048*7c478bd9Sstevel@tonic-gate } 1049*7c478bd9Sstevel@tonic-gate 1050*7c478bd9Sstevel@tonic-gate /* fill structure */ 1051*7c478bd9Sstevel@tonic-gate tp = tstable + tsentry; 1052*7c478bd9Sstevel@tonic-gate tp->st_src = ips.is_src; 1053*7c478bd9Sstevel@tonic-gate tp->st_dst = ips.is_dst; 1054*7c478bd9Sstevel@tonic-gate tp->st_p = ips.is_p; 1055*7c478bd9Sstevel@tonic-gate tp->st_state[0] = ips.is_state[0]; 1056*7c478bd9Sstevel@tonic-gate tp->st_state[1] = ips.is_state[1]; 1057*7c478bd9Sstevel@tonic-gate tp->st_pkts = ips.is_pkts[0] + ips.is_pkts[1]; 1058*7c478bd9Sstevel@tonic-gate tp->st_bytes = ips.is_bytes[0] + 1059*7c478bd9Sstevel@tonic-gate ips.is_bytes[1]; 1060*7c478bd9Sstevel@tonic-gate if ((ips.is_p == IPPROTO_TCP) || 1061*7c478bd9Sstevel@tonic-gate (ips.is_p == IPPROTO_UDP)) { 1062*7c478bd9Sstevel@tonic-gate tp->st_sport = ips.is_sport; 1063*7c478bd9Sstevel@tonic-gate tp->st_dport = ips.is_dport; 1064*7c478bd9Sstevel@tonic-gate } 1065*7c478bd9Sstevel@tonic-gate 1066*7c478bd9Sstevel@tonic-gate } 1067*7c478bd9Sstevel@tonic-gate } 1068*7c478bd9Sstevel@tonic-gate 1069*7c478bd9Sstevel@tonic-gate 1070*7c478bd9Sstevel@tonic-gate /* sort the array */ 1071*7c478bd9Sstevel@tonic-gate if (tsentry != -1) 1072*7c478bd9Sstevel@tonic-gate switch (sorting) 1073*7c478bd9Sstevel@tonic-gate { 1074*7c478bd9Sstevel@tonic-gate case STSORT_PR: 1075*7c478bd9Sstevel@tonic-gate qsort(tstable, tsentry + 1, 1076*7c478bd9Sstevel@tonic-gate sizeof(statetop_t), sort_p); 1077*7c478bd9Sstevel@tonic-gate break; 1078*7c478bd9Sstevel@tonic-gate case STSORT_PKTS: 1079*7c478bd9Sstevel@tonic-gate qsort(tstable, tsentry + 1, 1080*7c478bd9Sstevel@tonic-gate sizeof(statetop_t), sort_pkts); 1081*7c478bd9Sstevel@tonic-gate break; 1082*7c478bd9Sstevel@tonic-gate case STSORT_BYTES: 1083*7c478bd9Sstevel@tonic-gate qsort(tstable, tsentry + 1, 1084*7c478bd9Sstevel@tonic-gate sizeof(statetop_t), sort_bytes); 1085*7c478bd9Sstevel@tonic-gate break; 1086*7c478bd9Sstevel@tonic-gate case STSORT_TTL: 1087*7c478bd9Sstevel@tonic-gate qsort(tstable, tsentry + 1, 1088*7c478bd9Sstevel@tonic-gate sizeof(statetop_t), sort_ttl); 1089*7c478bd9Sstevel@tonic-gate break; 1090*7c478bd9Sstevel@tonic-gate case STSORT_SRCIP: 1091*7c478bd9Sstevel@tonic-gate qsort(tstable, tsentry + 1, 1092*7c478bd9Sstevel@tonic-gate sizeof(statetop_t), sort_srcip); 1093*7c478bd9Sstevel@tonic-gate break; 1094*7c478bd9Sstevel@tonic-gate case STSORT_DSTIP: 1095*7c478bd9Sstevel@tonic-gate qsort(tstable, tsentry + 1, 1096*7c478bd9Sstevel@tonic-gate sizeof(statetop_t), sort_dstip); 1097*7c478bd9Sstevel@tonic-gate break; 1098*7c478bd9Sstevel@tonic-gate default: 1099*7c478bd9Sstevel@tonic-gate break; 1100*7c478bd9Sstevel@tonic-gate } 1101*7c478bd9Sstevel@tonic-gate 1102*7c478bd9Sstevel@tonic-gate /* print title */ 1103*7c478bd9Sstevel@tonic-gate erase(); 1104*7c478bd9Sstevel@tonic-gate getmaxyx(stdscr, maxy, maxx); 1105*7c478bd9Sstevel@tonic-gate attron(A_BOLD); 1106*7c478bd9Sstevel@tonic-gate winx = 0; 1107*7c478bd9Sstevel@tonic-gate move(winx,0); 1108*7c478bd9Sstevel@tonic-gate sprintf(str1, "%s - %s - state top", hostnm, IPL_VERSION); 1109*7c478bd9Sstevel@tonic-gate for (j = 0 ; j < (maxx - 8 - strlen(str1)) / 2; j++) 1110*7c478bd9Sstevel@tonic-gate printw(" "); 1111*7c478bd9Sstevel@tonic-gate printw("%s", str1); 1112*7c478bd9Sstevel@tonic-gate attroff(A_BOLD); 1113*7c478bd9Sstevel@tonic-gate 1114*7c478bd9Sstevel@tonic-gate /* just for fun add a clock */ 1115*7c478bd9Sstevel@tonic-gate move(winx, maxx - 8); 1116*7c478bd9Sstevel@tonic-gate t = time(NULL); 1117*7c478bd9Sstevel@tonic-gate strftime(str1, 80, "%T", localtime(&t)); 1118*7c478bd9Sstevel@tonic-gate printw("%s\n", str1); 1119*7c478bd9Sstevel@tonic-gate 1120*7c478bd9Sstevel@tonic-gate /* 1121*7c478bd9Sstevel@tonic-gate * print the display filters, this is placed in the loop, 1122*7c478bd9Sstevel@tonic-gate * because someday I might add code for changing these 1123*7c478bd9Sstevel@tonic-gate * while the programming is running :-) 1124*7c478bd9Sstevel@tonic-gate */ 1125*7c478bd9Sstevel@tonic-gate if (sport >= 0) 1126*7c478bd9Sstevel@tonic-gate sprintf(str1, "%s,%d", inet_ntoa(saddr), sport); 1127*7c478bd9Sstevel@tonic-gate else 1128*7c478bd9Sstevel@tonic-gate sprintf(str1, "%s", inet_ntoa(saddr)); 1129*7c478bd9Sstevel@tonic-gate 1130*7c478bd9Sstevel@tonic-gate if (dport >= 0) 1131*7c478bd9Sstevel@tonic-gate sprintf(str2, "%s,%d", inet_ntoa(daddr), dport); 1132*7c478bd9Sstevel@tonic-gate else 1133*7c478bd9Sstevel@tonic-gate sprintf(str2, "%s", inet_ntoa(daddr)); 1134*7c478bd9Sstevel@tonic-gate 1135*7c478bd9Sstevel@tonic-gate if (protocol < 0) 1136*7c478bd9Sstevel@tonic-gate strcpy(str3, "any"); 1137*7c478bd9Sstevel@tonic-gate else if ((proto = getprotobynumber(protocol)) != NULL) 1138*7c478bd9Sstevel@tonic-gate sprintf(str3, "%s", proto->p_name); 1139*7c478bd9Sstevel@tonic-gate else 1140*7c478bd9Sstevel@tonic-gate sprintf(str3, "%d", protocol); 1141*7c478bd9Sstevel@tonic-gate 1142*7c478bd9Sstevel@tonic-gate switch (sorting) 1143*7c478bd9Sstevel@tonic-gate { 1144*7c478bd9Sstevel@tonic-gate case STSORT_PR: 1145*7c478bd9Sstevel@tonic-gate sprintf(str4, "proto"); 1146*7c478bd9Sstevel@tonic-gate break; 1147*7c478bd9Sstevel@tonic-gate case STSORT_PKTS: 1148*7c478bd9Sstevel@tonic-gate sprintf(str4, "# pkts"); 1149*7c478bd9Sstevel@tonic-gate break; 1150*7c478bd9Sstevel@tonic-gate case STSORT_BYTES: 1151*7c478bd9Sstevel@tonic-gate sprintf(str4, "# bytes"); 1152*7c478bd9Sstevel@tonic-gate break; 1153*7c478bd9Sstevel@tonic-gate case STSORT_TTL: 1154*7c478bd9Sstevel@tonic-gate sprintf(str4, "ttl"); 1155*7c478bd9Sstevel@tonic-gate break; 1156*7c478bd9Sstevel@tonic-gate case STSORT_SRCIP: 1157*7c478bd9Sstevel@tonic-gate sprintf(str4, "srcip"); 1158*7c478bd9Sstevel@tonic-gate break; 1159*7c478bd9Sstevel@tonic-gate case STSORT_DSTIP: 1160*7c478bd9Sstevel@tonic-gate sprintf(str4, "dstip"); 1161*7c478bd9Sstevel@tonic-gate break; 1162*7c478bd9Sstevel@tonic-gate default: 1163*7c478bd9Sstevel@tonic-gate sprintf(str4, "unknown"); 1164*7c478bd9Sstevel@tonic-gate break; 1165*7c478bd9Sstevel@tonic-gate } 1166*7c478bd9Sstevel@tonic-gate 1167*7c478bd9Sstevel@tonic-gate if (reverse) 1168*7c478bd9Sstevel@tonic-gate strcat(str4, " (reverse)"); 1169*7c478bd9Sstevel@tonic-gate 1170*7c478bd9Sstevel@tonic-gate winx += 2; 1171*7c478bd9Sstevel@tonic-gate move(winx,0); 1172*7c478bd9Sstevel@tonic-gate printw("Src = %s Dest = %s Proto = %s Sorted by = %s\n\n", 1173*7c478bd9Sstevel@tonic-gate str1, str2, str3, str4); 1174*7c478bd9Sstevel@tonic-gate 1175*7c478bd9Sstevel@tonic-gate /* print column description */ 1176*7c478bd9Sstevel@tonic-gate winx += 2; 1177*7c478bd9Sstevel@tonic-gate move(winx,0); 1178*7c478bd9Sstevel@tonic-gate attron(A_BOLD); 1179*7c478bd9Sstevel@tonic-gate printw("%-21s %-21s %3s %4s %7s %9s %9s\n", "Source IP", 1180*7c478bd9Sstevel@tonic-gate "Destination IP", "ST", "PR", "#pkts", "#bytes", "ttl"); 1181*7c478bd9Sstevel@tonic-gate attroff(A_BOLD); 1182*7c478bd9Sstevel@tonic-gate 1183*7c478bd9Sstevel@tonic-gate /* print all the entries */ 1184*7c478bd9Sstevel@tonic-gate tp = tstable; 1185*7c478bd9Sstevel@tonic-gate if (reverse) 1186*7c478bd9Sstevel@tonic-gate tp += tsentry; 1187*7c478bd9Sstevel@tonic-gate 1188*7c478bd9Sstevel@tonic-gate if (tsentry > maxy - 6) 1189*7c478bd9Sstevel@tonic-gate tsentry = maxy - 6; 1190*7c478bd9Sstevel@tonic-gate for (i = 0; i <= tsentry; i++) { 1191*7c478bd9Sstevel@tonic-gate /* print src/dest and port */ 1192*7c478bd9Sstevel@tonic-gate if ((tp->st_p == IPPROTO_TCP) || 1193*7c478bd9Sstevel@tonic-gate (tp->st_p == IPPROTO_UDP)) { 1194*7c478bd9Sstevel@tonic-gate sprintf(str1, "%s,%hu", 1195*7c478bd9Sstevel@tonic-gate inet_ntoa(tp->st_src.in4), 1196*7c478bd9Sstevel@tonic-gate ntohs(tp->st_sport)); 1197*7c478bd9Sstevel@tonic-gate sprintf(str2, "%s,%hu", 1198*7c478bd9Sstevel@tonic-gate inet_ntoa(tp->st_dst.in4), 1199*7c478bd9Sstevel@tonic-gate ntohs(tp->st_dport)); 1200*7c478bd9Sstevel@tonic-gate } else { 1201*7c478bd9Sstevel@tonic-gate sprintf(str1, "%s", inet_ntoa(tp->st_src.in4)); 1202*7c478bd9Sstevel@tonic-gate sprintf(str2, "%s", inet_ntoa(tp->st_dst.in4)); 1203*7c478bd9Sstevel@tonic-gate } 1204*7c478bd9Sstevel@tonic-gate winx++; 1205*7c478bd9Sstevel@tonic-gate move(winx, 0); 1206*7c478bd9Sstevel@tonic-gate printw("%-21s %-21s", str1, str2); 1207*7c478bd9Sstevel@tonic-gate 1208*7c478bd9Sstevel@tonic-gate /* print state */ 1209*7c478bd9Sstevel@tonic-gate sprintf(str1, "%X/%X", tp->st_state[0], 1210*7c478bd9Sstevel@tonic-gate tp->st_state[1]); 1211*7c478bd9Sstevel@tonic-gate printw(" %3s", str1); 1212*7c478bd9Sstevel@tonic-gate 1213*7c478bd9Sstevel@tonic-gate /* print proto */ 1214*7c478bd9Sstevel@tonic-gate proto = getprotobynumber(tp->st_p); 1215*7c478bd9Sstevel@tonic-gate if (proto) { 1216*7c478bd9Sstevel@tonic-gate strncpy(str1, proto->p_name, 4); 1217*7c478bd9Sstevel@tonic-gate str1[4] = '\0'; 1218*7c478bd9Sstevel@tonic-gate } else { 1219*7c478bd9Sstevel@tonic-gate sprintf(str1, "%d", tp->st_p); 1220*7c478bd9Sstevel@tonic-gate } 1221*7c478bd9Sstevel@tonic-gate printw(" %4s", str1); 1222*7c478bd9Sstevel@tonic-gate /* print #pkt/#bytes */ 1223*7c478bd9Sstevel@tonic-gate #ifdef USE_QUAD_T 1224*7c478bd9Sstevel@tonic-gate printw(" %7qu %9qu", (unsigned long long) tp->st_pkts, 1225*7c478bd9Sstevel@tonic-gate (unsigned long long) tp->st_bytes); 1226*7c478bd9Sstevel@tonic-gate #else 1227*7c478bd9Sstevel@tonic-gate printw(" %7lu %9lu", tp->st_pkts, tp->st_bytes); 1228*7c478bd9Sstevel@tonic-gate #endif 1229*7c478bd9Sstevel@tonic-gate printw(" %9s", ttl_to_string(tp->st_age)); 1230*7c478bd9Sstevel@tonic-gate 1231*7c478bd9Sstevel@tonic-gate if (reverse) 1232*7c478bd9Sstevel@tonic-gate tp--; 1233*7c478bd9Sstevel@tonic-gate else 1234*7c478bd9Sstevel@tonic-gate tp++; 1235*7c478bd9Sstevel@tonic-gate } 1236*7c478bd9Sstevel@tonic-gate 1237*7c478bd9Sstevel@tonic-gate /* screen data structure is filled, now update the screen */ 1238*7c478bd9Sstevel@tonic-gate if (redraw) 1239*7c478bd9Sstevel@tonic-gate clearok(stdscr,1); 1240*7c478bd9Sstevel@tonic-gate 1241*7c478bd9Sstevel@tonic-gate refresh(); 1242*7c478bd9Sstevel@tonic-gate if (redraw) { 1243*7c478bd9Sstevel@tonic-gate clearok(stdscr,0); 1244*7c478bd9Sstevel@tonic-gate redraw = 0; 1245*7c478bd9Sstevel@tonic-gate } 1246*7c478bd9Sstevel@tonic-gate 1247*7c478bd9Sstevel@tonic-gate /* wait for key press or a 1 second time out period */ 1248*7c478bd9Sstevel@tonic-gate selecttimeout.tv_sec = refreshtime; 1249*7c478bd9Sstevel@tonic-gate selecttimeout.tv_usec = 0; 1250*7c478bd9Sstevel@tonic-gate FD_ZERO(&readfd); 1251*7c478bd9Sstevel@tonic-gate FD_SET(0, &readfd); 1252*7c478bd9Sstevel@tonic-gate select(1, &readfd, NULL, NULL, &selecttimeout); 1253*7c478bd9Sstevel@tonic-gate 1254*7c478bd9Sstevel@tonic-gate /* if key pressed, read all waiting keys */ 1255*7c478bd9Sstevel@tonic-gate if (FD_ISSET(0, &readfd)) { 1256*7c478bd9Sstevel@tonic-gate c = wgetch(stdscr); 1257*7c478bd9Sstevel@tonic-gate if (c == ERR) 1258*7c478bd9Sstevel@tonic-gate continue; 1259*7c478bd9Sstevel@tonic-gate 1260*7c478bd9Sstevel@tonic-gate if (tolower(c) == 'l') { 1261*7c478bd9Sstevel@tonic-gate redraw = 1; 1262*7c478bd9Sstevel@tonic-gate } else if (tolower(c) == 'q') { 1263*7c478bd9Sstevel@tonic-gate nocbreak(); 1264*7c478bd9Sstevel@tonic-gate endwin(); 1265*7c478bd9Sstevel@tonic-gate exit(0); 1266*7c478bd9Sstevel@tonic-gate } else if (tolower(c) == 'r') { 1267*7c478bd9Sstevel@tonic-gate reverse = !reverse; 1268*7c478bd9Sstevel@tonic-gate } else if (tolower(c) == 's') { 1269*7c478bd9Sstevel@tonic-gate sorting++; 1270*7c478bd9Sstevel@tonic-gate if (sorting > STSORT_MAX) 1271*7c478bd9Sstevel@tonic-gate sorting = 0; 1272*7c478bd9Sstevel@tonic-gate } 1273*7c478bd9Sstevel@tonic-gate } 1274*7c478bd9Sstevel@tonic-gate } /* while */ 1275*7c478bd9Sstevel@tonic-gate 1276*7c478bd9Sstevel@tonic-gate printw("\n"); 1277*7c478bd9Sstevel@tonic-gate nocbreak(); 1278*7c478bd9Sstevel@tonic-gate endwin(); 1279*7c478bd9Sstevel@tonic-gate 1280*7c478bd9Sstevel@tonic-gate free(tstable); 1281*7c478bd9Sstevel@tonic-gate } 1282*7c478bd9Sstevel@tonic-gate #endif 1283*7c478bd9Sstevel@tonic-gate 1284*7c478bd9Sstevel@tonic-gate 1285*7c478bd9Sstevel@tonic-gate /* 1286*7c478bd9Sstevel@tonic-gate * Show fragment cache information that's held in the kernel. 1287*7c478bd9Sstevel@tonic-gate */ 1288*7c478bd9Sstevel@tonic-gate static void showfrstates(ifsp) 1289*7c478bd9Sstevel@tonic-gate ipfrstat_t *ifsp; 1290*7c478bd9Sstevel@tonic-gate { 1291*7c478bd9Sstevel@tonic-gate struct ipfr *ipfrtab[IPFT_SIZE], ifr; 1292*7c478bd9Sstevel@tonic-gate frentry_t fr; 1293*7c478bd9Sstevel@tonic-gate int i; 1294*7c478bd9Sstevel@tonic-gate 1295*7c478bd9Sstevel@tonic-gate /* 1296*7c478bd9Sstevel@tonic-gate * print out the numeric statistics 1297*7c478bd9Sstevel@tonic-gate */ 1298*7c478bd9Sstevel@tonic-gate PRINTF("IP fragment states:\n\t%lu new\n\t%lu expired\n\t%lu hits\n", 1299*7c478bd9Sstevel@tonic-gate ifsp->ifs_new, ifsp->ifs_expire, ifsp->ifs_hits); 1300*7c478bd9Sstevel@tonic-gate PRINTF("\t%lu retrans\n\t%lu too short\n", ifsp->ifs_retrans0, ifsp->ifs_short); 1301*7c478bd9Sstevel@tonic-gate PRINTF("\t%lu no memory\n\t%lu already exist\n", 1302*7c478bd9Sstevel@tonic-gate ifsp->ifs_nomem, ifsp->ifs_exists); 1303*7c478bd9Sstevel@tonic-gate PRINTF("\t%lu inuse\n", ifsp->ifs_inuse); 1304*7c478bd9Sstevel@tonic-gate if (kmemcpy((char *)ipfrtab, (u_long)ifsp->ifs_table, sizeof(ipfrtab))) 1305*7c478bd9Sstevel@tonic-gate return; 1306*7c478bd9Sstevel@tonic-gate 1307*7c478bd9Sstevel@tonic-gate /* 1308*7c478bd9Sstevel@tonic-gate * Print out the contents (if any) of the fragment cache table. 1309*7c478bd9Sstevel@tonic-gate */ 1310*7c478bd9Sstevel@tonic-gate for (i = 0; i < IPFT_SIZE; i++) 1311*7c478bd9Sstevel@tonic-gate while (ipfrtab[i]) { 1312*7c478bd9Sstevel@tonic-gate if (kmemcpy((char *)&ifr, (u_long)ipfrtab[i], 1313*7c478bd9Sstevel@tonic-gate sizeof(ifr)) == -1) 1314*7c478bd9Sstevel@tonic-gate break; 1315*7c478bd9Sstevel@tonic-gate PRINTF("%s -> ", hostname(4, &ifr.ipfr_src)); 1316*7c478bd9Sstevel@tonic-gate if (kmemcpy((char *)&fr, (u_long)ifr.ipfr_rule, 1317*7c478bd9Sstevel@tonic-gate sizeof(fr)) == -1) 1318*7c478bd9Sstevel@tonic-gate break; 1319*7c478bd9Sstevel@tonic-gate PRINTF("%s %d %d %d %#02x = %#x\n", 1320*7c478bd9Sstevel@tonic-gate hostname(4, &ifr.ipfr_dst), ifr.ipfr_id, 1321*7c478bd9Sstevel@tonic-gate ifr.ipfr_ttl, ifr.ipfr_p, ifr.ipfr_tos, 1322*7c478bd9Sstevel@tonic-gate fr.fr_flags); 1323*7c478bd9Sstevel@tonic-gate ipfrtab[i] = ifr.ipfr_next; 1324*7c478bd9Sstevel@tonic-gate } 1325*7c478bd9Sstevel@tonic-gate if (kmemcpy((char *)ipfrtab, (u_long)ifsp->ifs_nattab,sizeof(ipfrtab))) 1326*7c478bd9Sstevel@tonic-gate return; 1327*7c478bd9Sstevel@tonic-gate for (i = 0; i < IPFT_SIZE; i++) 1328*7c478bd9Sstevel@tonic-gate while (ipfrtab[i]) { 1329*7c478bd9Sstevel@tonic-gate if (kmemcpy((char *)&ifr, (u_long)ipfrtab[i], 1330*7c478bd9Sstevel@tonic-gate sizeof(ifr)) == -1) 1331*7c478bd9Sstevel@tonic-gate break; 1332*7c478bd9Sstevel@tonic-gate PRINTF("NAT: %s -> ", hostname(4, &ifr.ipfr_src)); 1333*7c478bd9Sstevel@tonic-gate if (kmemcpy((char *)&fr, (u_long)ifr.ipfr_rule, 1334*7c478bd9Sstevel@tonic-gate sizeof(fr)) == -1) 1335*7c478bd9Sstevel@tonic-gate break; 1336*7c478bd9Sstevel@tonic-gate PRINTF("%s %d %d %d %#02x = %#x\n", 1337*7c478bd9Sstevel@tonic-gate hostname(4, &ifr.ipfr_dst), ifr.ipfr_id, 1338*7c478bd9Sstevel@tonic-gate ifr.ipfr_ttl, ifr.ipfr_p, ifr.ipfr_tos, 1339*7c478bd9Sstevel@tonic-gate fr.fr_flags); 1340*7c478bd9Sstevel@tonic-gate ipfrtab[i] = ifr.ipfr_next; 1341*7c478bd9Sstevel@tonic-gate } 1342*7c478bd9Sstevel@tonic-gate } 1343*7c478bd9Sstevel@tonic-gate 1344*7c478bd9Sstevel@tonic-gate 1345*7c478bd9Sstevel@tonic-gate /* 1346*7c478bd9Sstevel@tonic-gate * Show stats on how auth within IPFilter has been used 1347*7c478bd9Sstevel@tonic-gate */ 1348*7c478bd9Sstevel@tonic-gate static void showauthstates(asp) 1349*7c478bd9Sstevel@tonic-gate fr_authstat_t *asp; 1350*7c478bd9Sstevel@tonic-gate { 1351*7c478bd9Sstevel@tonic-gate frauthent_t *frap, fra; 1352*7c478bd9Sstevel@tonic-gate 1353*7c478bd9Sstevel@tonic-gate #ifdef USE_QUAD_T 1354*7c478bd9Sstevel@tonic-gate printf("Authorisation hits: %qu\tmisses %qu\n", 1355*7c478bd9Sstevel@tonic-gate (unsigned long long) asp->fas_hits, 1356*7c478bd9Sstevel@tonic-gate (unsigned long long) asp->fas_miss); 1357*7c478bd9Sstevel@tonic-gate #else 1358*7c478bd9Sstevel@tonic-gate printf("Authorisation hits: %ld\tmisses %ld\n", asp->fas_hits, 1359*7c478bd9Sstevel@tonic-gate asp->fas_miss); 1360*7c478bd9Sstevel@tonic-gate #endif 1361*7c478bd9Sstevel@tonic-gate printf("nospace %ld\nadded %ld\nsendfail %ld\nsendok %ld\n", 1362*7c478bd9Sstevel@tonic-gate asp->fas_nospace, asp->fas_added, asp->fas_sendfail, 1363*7c478bd9Sstevel@tonic-gate asp->fas_sendok); 1364*7c478bd9Sstevel@tonic-gate printf("queok %ld\nquefail %ld\nexpire %ld\n", 1365*7c478bd9Sstevel@tonic-gate asp->fas_queok, asp->fas_quefail, asp->fas_expire); 1366*7c478bd9Sstevel@tonic-gate 1367*7c478bd9Sstevel@tonic-gate frap = asp->fas_faelist; 1368*7c478bd9Sstevel@tonic-gate while (frap) { 1369*7c478bd9Sstevel@tonic-gate if (kmemcpy((char *)&fra, (u_long)frap, sizeof(fra)) == -1) 1370*7c478bd9Sstevel@tonic-gate break; 1371*7c478bd9Sstevel@tonic-gate 1372*7c478bd9Sstevel@tonic-gate printf("age %ld\t", fra.fae_age); 1373*7c478bd9Sstevel@tonic-gate printfr(&fra.fae_fr, ioctl); 1374*7c478bd9Sstevel@tonic-gate frap = fra.fae_next; 1375*7c478bd9Sstevel@tonic-gate } 1376*7c478bd9Sstevel@tonic-gate } 1377*7c478bd9Sstevel@tonic-gate 1378*7c478bd9Sstevel@tonic-gate 1379*7c478bd9Sstevel@tonic-gate /* 1380*7c478bd9Sstevel@tonic-gate * Display groups used for each of filter rules, accounting rules and 1381*7c478bd9Sstevel@tonic-gate * authentication, separately. 1382*7c478bd9Sstevel@tonic-gate */ 1383*7c478bd9Sstevel@tonic-gate static void showgroups(fiop) 1384*7c478bd9Sstevel@tonic-gate struct friostat *fiop; 1385*7c478bd9Sstevel@tonic-gate { 1386*7c478bd9Sstevel@tonic-gate static char *gnames[3] = { "Filter", "Accounting", "Authentication" }; 1387*7c478bd9Sstevel@tonic-gate frgroup_t *fp, grp; 1388*7c478bd9Sstevel@tonic-gate int on, off, i; 1389*7c478bd9Sstevel@tonic-gate 1390*7c478bd9Sstevel@tonic-gate on = fiop->f_active; 1391*7c478bd9Sstevel@tonic-gate off = 1 - on; 1392*7c478bd9Sstevel@tonic-gate 1393*7c478bd9Sstevel@tonic-gate for (i = 0; i < 3; i++) { 1394*7c478bd9Sstevel@tonic-gate printf("%s groups (active):\n", gnames[i]); 1395*7c478bd9Sstevel@tonic-gate for (fp = fiop->f_groups[i][on]; fp; fp = grp.fg_next) 1396*7c478bd9Sstevel@tonic-gate if (kmemcpy((char *)&grp, (u_long)fp, sizeof(grp))) 1397*7c478bd9Sstevel@tonic-gate break; 1398*7c478bd9Sstevel@tonic-gate else 1399*7c478bd9Sstevel@tonic-gate printf("%s\n", grp.fg_name); 1400*7c478bd9Sstevel@tonic-gate printf("%s groups (inactive):\n", gnames[i]); 1401*7c478bd9Sstevel@tonic-gate for (fp = fiop->f_groups[i][off]; fp; fp = grp.fg_next) 1402*7c478bd9Sstevel@tonic-gate if (kmemcpy((char *)&grp, (u_long)fp, sizeof(grp))) 1403*7c478bd9Sstevel@tonic-gate break; 1404*7c478bd9Sstevel@tonic-gate else 1405*7c478bd9Sstevel@tonic-gate printf("%s\n", grp.fg_name); 1406*7c478bd9Sstevel@tonic-gate } 1407*7c478bd9Sstevel@tonic-gate } 1408*7c478bd9Sstevel@tonic-gate 1409*7c478bd9Sstevel@tonic-gate static void parse_ipportstr(argument, ip, port) 1410*7c478bd9Sstevel@tonic-gate const char *argument; 1411*7c478bd9Sstevel@tonic-gate struct in_addr *ip; 1412*7c478bd9Sstevel@tonic-gate int *port; 1413*7c478bd9Sstevel@tonic-gate { 1414*7c478bd9Sstevel@tonic-gate 1415*7c478bd9Sstevel@tonic-gate char *s, *comma; 1416*7c478bd9Sstevel@tonic-gate 1417*7c478bd9Sstevel@tonic-gate /* make working copy of argument, Theoretically you must be able 1418*7c478bd9Sstevel@tonic-gate * to write to optarg, but that seems very ugly to me.... 1419*7c478bd9Sstevel@tonic-gate */ 1420*7c478bd9Sstevel@tonic-gate s = strdup(argument); 1421*7c478bd9Sstevel@tonic-gate if (s == NULL) 1422*7c478bd9Sstevel@tonic-gate return; 1423*7c478bd9Sstevel@tonic-gate 1424*7c478bd9Sstevel@tonic-gate /* get port */ 1425*7c478bd9Sstevel@tonic-gate if ((comma = strchr(s, ',')) != NULL) { 1426*7c478bd9Sstevel@tonic-gate if (!strcasecmp(comma + 1, "any")) { 1427*7c478bd9Sstevel@tonic-gate *port = -1; 1428*7c478bd9Sstevel@tonic-gate } else if (!sscanf(comma + 1, "%d", port) || 1429*7c478bd9Sstevel@tonic-gate (*port < 0) || (*port > 65535)) { 1430*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Invalid port specfication in %s\n", 1431*7c478bd9Sstevel@tonic-gate argument); 1432*7c478bd9Sstevel@tonic-gate free(s); 1433*7c478bd9Sstevel@tonic-gate exit(-2); 1434*7c478bd9Sstevel@tonic-gate } 1435*7c478bd9Sstevel@tonic-gate *comma = '\0'; 1436*7c478bd9Sstevel@tonic-gate } 1437*7c478bd9Sstevel@tonic-gate 1438*7c478bd9Sstevel@tonic-gate 1439*7c478bd9Sstevel@tonic-gate /* get ip address */ 1440*7c478bd9Sstevel@tonic-gate if (!strcasecmp(s, "any")) { 1441*7c478bd9Sstevel@tonic-gate ip->s_addr = INADDR_ANY; 1442*7c478bd9Sstevel@tonic-gate } else if (!inet_aton(s, ip)) { 1443*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Invalid IP address: %s\n", s); 1444*7c478bd9Sstevel@tonic-gate free(s); 1445*7c478bd9Sstevel@tonic-gate exit(-2); 1446*7c478bd9Sstevel@tonic-gate } 1447*7c478bd9Sstevel@tonic-gate 1448*7c478bd9Sstevel@tonic-gate /* free allocated memory */ 1449*7c478bd9Sstevel@tonic-gate free(s); 1450*7c478bd9Sstevel@tonic-gate } 1451*7c478bd9Sstevel@tonic-gate 1452*7c478bd9Sstevel@tonic-gate 1453*7c478bd9Sstevel@tonic-gate #ifdef STATETOP 1454*7c478bd9Sstevel@tonic-gate static char ttlbuf[STSTRSIZE]; 1455*7c478bd9Sstevel@tonic-gate 1456*7c478bd9Sstevel@tonic-gate static char *ttl_to_string(ttl) 1457*7c478bd9Sstevel@tonic-gate long int ttl; 1458*7c478bd9Sstevel@tonic-gate { 1459*7c478bd9Sstevel@tonic-gate 1460*7c478bd9Sstevel@tonic-gate int hours, minutes, seconds; 1461*7c478bd9Sstevel@tonic-gate 1462*7c478bd9Sstevel@tonic-gate /* ttl is in half seconds */ 1463*7c478bd9Sstevel@tonic-gate ttl /= 2; 1464*7c478bd9Sstevel@tonic-gate 1465*7c478bd9Sstevel@tonic-gate hours = ttl / 3600; 1466*7c478bd9Sstevel@tonic-gate ttl = ttl % 3600; 1467*7c478bd9Sstevel@tonic-gate minutes = ttl / 60; 1468*7c478bd9Sstevel@tonic-gate seconds = ttl % 60; 1469*7c478bd9Sstevel@tonic-gate 1470*7c478bd9Sstevel@tonic-gate if (hours > 0 ) 1471*7c478bd9Sstevel@tonic-gate sprintf(ttlbuf, "%2d:%02d:%02d", hours, minutes, seconds); 1472*7c478bd9Sstevel@tonic-gate else 1473*7c478bd9Sstevel@tonic-gate sprintf(ttlbuf, "%2d:%02d", minutes, seconds); 1474*7c478bd9Sstevel@tonic-gate return ttlbuf; 1475*7c478bd9Sstevel@tonic-gate } 1476*7c478bd9Sstevel@tonic-gate 1477*7c478bd9Sstevel@tonic-gate 1478*7c478bd9Sstevel@tonic-gate static int sort_pkts(a, b) 1479*7c478bd9Sstevel@tonic-gate const void *a; 1480*7c478bd9Sstevel@tonic-gate const void *b; 1481*7c478bd9Sstevel@tonic-gate { 1482*7c478bd9Sstevel@tonic-gate 1483*7c478bd9Sstevel@tonic-gate register const statetop_t *ap = a; 1484*7c478bd9Sstevel@tonic-gate register const statetop_t *bp = b; 1485*7c478bd9Sstevel@tonic-gate 1486*7c478bd9Sstevel@tonic-gate if (ap->st_pkts == bp->st_pkts) 1487*7c478bd9Sstevel@tonic-gate return 0; 1488*7c478bd9Sstevel@tonic-gate else if (ap->st_pkts < bp->st_pkts) 1489*7c478bd9Sstevel@tonic-gate return 1; 1490*7c478bd9Sstevel@tonic-gate return -1; 1491*7c478bd9Sstevel@tonic-gate } 1492*7c478bd9Sstevel@tonic-gate 1493*7c478bd9Sstevel@tonic-gate 1494*7c478bd9Sstevel@tonic-gate static int sort_bytes(a, b) 1495*7c478bd9Sstevel@tonic-gate const void *a; 1496*7c478bd9Sstevel@tonic-gate const void *b; 1497*7c478bd9Sstevel@tonic-gate { 1498*7c478bd9Sstevel@tonic-gate register const statetop_t *ap = a; 1499*7c478bd9Sstevel@tonic-gate register const statetop_t *bp = b; 1500*7c478bd9Sstevel@tonic-gate 1501*7c478bd9Sstevel@tonic-gate if (ap->st_bytes == bp->st_bytes) 1502*7c478bd9Sstevel@tonic-gate return 0; 1503*7c478bd9Sstevel@tonic-gate else if (ap->st_bytes < bp->st_bytes) 1504*7c478bd9Sstevel@tonic-gate return 1; 1505*7c478bd9Sstevel@tonic-gate return -1; 1506*7c478bd9Sstevel@tonic-gate } 1507*7c478bd9Sstevel@tonic-gate 1508*7c478bd9Sstevel@tonic-gate 1509*7c478bd9Sstevel@tonic-gate static int sort_p(a, b) 1510*7c478bd9Sstevel@tonic-gate const void *a; 1511*7c478bd9Sstevel@tonic-gate const void *b; 1512*7c478bd9Sstevel@tonic-gate { 1513*7c478bd9Sstevel@tonic-gate register const statetop_t *ap = a; 1514*7c478bd9Sstevel@tonic-gate register const statetop_t *bp = b; 1515*7c478bd9Sstevel@tonic-gate 1516*7c478bd9Sstevel@tonic-gate if (ap->st_p == bp->st_p) 1517*7c478bd9Sstevel@tonic-gate return 0; 1518*7c478bd9Sstevel@tonic-gate else if (ap->st_p < bp->st_p) 1519*7c478bd9Sstevel@tonic-gate return 1; 1520*7c478bd9Sstevel@tonic-gate return -1; 1521*7c478bd9Sstevel@tonic-gate } 1522*7c478bd9Sstevel@tonic-gate 1523*7c478bd9Sstevel@tonic-gate 1524*7c478bd9Sstevel@tonic-gate static int sort_ttl(a, b) 1525*7c478bd9Sstevel@tonic-gate const void *a; 1526*7c478bd9Sstevel@tonic-gate const void *b; 1527*7c478bd9Sstevel@tonic-gate { 1528*7c478bd9Sstevel@tonic-gate register const statetop_t *ap = a; 1529*7c478bd9Sstevel@tonic-gate register const statetop_t *bp = b; 1530*7c478bd9Sstevel@tonic-gate 1531*7c478bd9Sstevel@tonic-gate if (ap->st_age == bp->st_age) 1532*7c478bd9Sstevel@tonic-gate return 0; 1533*7c478bd9Sstevel@tonic-gate else if (ap->st_age < bp->st_age) 1534*7c478bd9Sstevel@tonic-gate return 1; 1535*7c478bd9Sstevel@tonic-gate return -1; 1536*7c478bd9Sstevel@tonic-gate } 1537*7c478bd9Sstevel@tonic-gate 1538*7c478bd9Sstevel@tonic-gate static int sort_srcip(a, b) 1539*7c478bd9Sstevel@tonic-gate const void *a; 1540*7c478bd9Sstevel@tonic-gate const void *b; 1541*7c478bd9Sstevel@tonic-gate { 1542*7c478bd9Sstevel@tonic-gate register const statetop_t *ap = a; 1543*7c478bd9Sstevel@tonic-gate register const statetop_t *bp = b; 1544*7c478bd9Sstevel@tonic-gate 1545*7c478bd9Sstevel@tonic-gate if (ntohl(ap->st_src.in4.s_addr) == ntohl(bp->st_src.in4.s_addr)) 1546*7c478bd9Sstevel@tonic-gate return 0; 1547*7c478bd9Sstevel@tonic-gate else if (ntohl(ap->st_src.in4.s_addr) > ntohl(bp->st_src.in4.s_addr)) 1548*7c478bd9Sstevel@tonic-gate return 1; 1549*7c478bd9Sstevel@tonic-gate return -1; 1550*7c478bd9Sstevel@tonic-gate } 1551*7c478bd9Sstevel@tonic-gate 1552*7c478bd9Sstevel@tonic-gate static int sort_dstip(a, b) 1553*7c478bd9Sstevel@tonic-gate const void *a; 1554*7c478bd9Sstevel@tonic-gate const void *b; 1555*7c478bd9Sstevel@tonic-gate { 1556*7c478bd9Sstevel@tonic-gate register const statetop_t *ap = a; 1557*7c478bd9Sstevel@tonic-gate register const statetop_t *bp = b; 1558*7c478bd9Sstevel@tonic-gate 1559*7c478bd9Sstevel@tonic-gate if (ntohl(ap->st_dst.in4.s_addr) == ntohl(bp->st_dst.in4.s_addr)) 1560*7c478bd9Sstevel@tonic-gate return 0; 1561*7c478bd9Sstevel@tonic-gate else if (ntohl(ap->st_dst.in4.s_addr) > ntohl(bp->st_dst.in4.s_addr)) 1562*7c478bd9Sstevel@tonic-gate return 1; 1563*7c478bd9Sstevel@tonic-gate return -1; 1564*7c478bd9Sstevel@tonic-gate } 1565*7c478bd9Sstevel@tonic-gate #endif 1566