10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * Copyright (C) 1993-2001, 2003 by Darren Reed. 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * See the IPFILTER.LICENCE file for details on licencing. 50Sstevel@tonic-gate * 6*6518Sjojemann * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 70Sstevel@tonic-gate * Use is subject to license terms. 80Sstevel@tonic-gate */ 90Sstevel@tonic-gate 100Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 110Sstevel@tonic-gate 120Sstevel@tonic-gate #ifdef __FreeBSD__ 130Sstevel@tonic-gate # ifndef __FreeBSD_cc_version 140Sstevel@tonic-gate # include <osreldate.h> 150Sstevel@tonic-gate # else 160Sstevel@tonic-gate # if __FreeBSD_cc_version < 430000 170Sstevel@tonic-gate # include <osreldate.h> 180Sstevel@tonic-gate # endif 190Sstevel@tonic-gate # endif 200Sstevel@tonic-gate #endif 210Sstevel@tonic-gate #include <sys/ioctl.h> 220Sstevel@tonic-gate #include <fcntl.h> 232393Syz155240 #ifdef linux 242393Syz155240 # include <linux/a.out.h> 252393Syz155240 #else 262393Syz155240 # include <nlist.h> 272393Syz155240 #endif 280Sstevel@tonic-gate #include <ctype.h> 292393Syz155240 #if defined(sun) && (defined(__svr4__) || defined(__SVR4)) 302393Syz155240 # include <stddef.h> 312393Syz155240 #endif 320Sstevel@tonic-gate #include "ipf.h" 332393Syz155240 #include "netinet/ipl.h" 340Sstevel@tonic-gate #if defined(STATETOP) 350Sstevel@tonic-gate # if defined(_BSDI_VERSION) 362393Syz155240 # undef STATETOP 370Sstevel@tonic-gate # endif 380Sstevel@tonic-gate # if defined(__FreeBSD__) && \ 390Sstevel@tonic-gate (!defined(__FreeBSD_version) || (__FreeBSD_version < 430000)) 400Sstevel@tonic-gate # undef STATETOP 410Sstevel@tonic-gate # endif 420Sstevel@tonic-gate # if defined(__NetBSD_Version__) && (__NetBSD_Version__ < 105000000) 430Sstevel@tonic-gate # undef STATETOP 440Sstevel@tonic-gate # endif 450Sstevel@tonic-gate # if defined(sun) 460Sstevel@tonic-gate # if defined(__svr4__) || defined(__SVR4) 470Sstevel@tonic-gate # include <sys/select.h> 480Sstevel@tonic-gate # else 490Sstevel@tonic-gate # undef STATETOP /* NOT supported on SunOS4 */ 500Sstevel@tonic-gate # endif 510Sstevel@tonic-gate # endif 520Sstevel@tonic-gate #endif 530Sstevel@tonic-gate #if defined(STATETOP) && !defined(linux) 540Sstevel@tonic-gate # include <netinet/ip_var.h> 550Sstevel@tonic-gate # include <netinet/tcp_fsm.h> 560Sstevel@tonic-gate #endif 570Sstevel@tonic-gate #ifdef STATETOP 582393Syz155240 # include <ctype.h> 592393Syz155240 # include <signal.h> 600Sstevel@tonic-gate # if SOLARIS || defined(__NetBSD__) || defined(_BSDI_VERSION) || \ 610Sstevel@tonic-gate defined(__sgi) 620Sstevel@tonic-gate # ifdef ERR 630Sstevel@tonic-gate # undef ERR 640Sstevel@tonic-gate # endif 652393Syz155240 # undef ISASCII 662393Syz155240 # undef ISPRINT 670Sstevel@tonic-gate # include <curses.h> 680Sstevel@tonic-gate # else /* SOLARIS */ 690Sstevel@tonic-gate # include <ncurses.h> 700Sstevel@tonic-gate # endif /* SOLARIS */ 710Sstevel@tonic-gate #endif /* STATETOP */ 720Sstevel@tonic-gate #include "kmem.h" 730Sstevel@tonic-gate #if defined(__NetBSD__) || (__OpenBSD__) 740Sstevel@tonic-gate # include <paths.h> 750Sstevel@tonic-gate #endif 760Sstevel@tonic-gate 770Sstevel@tonic-gate #if !defined(lint) 780Sstevel@tonic-gate static const char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-2000 Darren Reed"; 792393Syz155240 static const char rcsid[] = "@(#)$Id: ipfstat.c,v 1.44.2.12 2005/06/12 07:18:46 darrenr Exp $"; 800Sstevel@tonic-gate #endif 810Sstevel@tonic-gate 820Sstevel@tonic-gate #ifdef __hpux 830Sstevel@tonic-gate # define nlist nlist64 840Sstevel@tonic-gate #endif 850Sstevel@tonic-gate 860Sstevel@tonic-gate extern char *optarg; 870Sstevel@tonic-gate extern int optind; 882393Syz155240 extern int opterr; 890Sstevel@tonic-gate 900Sstevel@tonic-gate #define PRINTF (void)printf 910Sstevel@tonic-gate #define FPRINTF (void)fprintf 920Sstevel@tonic-gate static char *filters[4] = { "ipfilter(in)", "ipfilter(out)", 930Sstevel@tonic-gate "ipacct(in)", "ipacct(out)" }; 940Sstevel@tonic-gate static int state_logging = -1; 950Sstevel@tonic-gate 960Sstevel@tonic-gate int opts = 0; 970Sstevel@tonic-gate int use_inet6 = 0; 980Sstevel@tonic-gate int live_kernel = 1; 990Sstevel@tonic-gate int state_fd = -1; 1000Sstevel@tonic-gate int ipf_fd = -1; 1010Sstevel@tonic-gate 1020Sstevel@tonic-gate #ifdef STATETOP 1030Sstevel@tonic-gate #define STSTRSIZE 80 1040Sstevel@tonic-gate #define STGROWSIZE 16 1050Sstevel@tonic-gate #define HOSTNMLEN 40 1060Sstevel@tonic-gate 1070Sstevel@tonic-gate #define STSORT_PR 0 1080Sstevel@tonic-gate #define STSORT_PKTS 1 1090Sstevel@tonic-gate #define STSORT_BYTES 2 1100Sstevel@tonic-gate #define STSORT_TTL 3 1110Sstevel@tonic-gate #define STSORT_SRCIP 4 1122393Syz155240 #define STSORT_SRCPT 5 1132393Syz155240 #define STSORT_DSTIP 6 1142393Syz155240 #define STSORT_DSTPT 7 1152393Syz155240 #define STSORT_MAX STSORT_DSTPT 1160Sstevel@tonic-gate #define STSORT_DEFAULT STSORT_BYTES 1170Sstevel@tonic-gate 1180Sstevel@tonic-gate 1190Sstevel@tonic-gate typedef struct statetop { 1200Sstevel@tonic-gate i6addr_t st_src; 1210Sstevel@tonic-gate i6addr_t st_dst; 1220Sstevel@tonic-gate u_short st_sport; 1230Sstevel@tonic-gate u_short st_dport; 1240Sstevel@tonic-gate u_char st_p; 1252393Syz155240 u_char st_v; 1260Sstevel@tonic-gate u_char st_state[2]; 1270Sstevel@tonic-gate U_QUAD_T st_pkts; 1280Sstevel@tonic-gate U_QUAD_T st_bytes; 1290Sstevel@tonic-gate u_long st_age; 1300Sstevel@tonic-gate } statetop_t; 1310Sstevel@tonic-gate #endif 1320Sstevel@tonic-gate 1332393Syz155240 int main __P((int, char *[])); 1342393Syz155240 1350Sstevel@tonic-gate static void showstats __P((friostat_t *, u_32_t)); 1360Sstevel@tonic-gate static void showfrstates __P((ipfrstat_t *)); 1370Sstevel@tonic-gate static void showlist __P((friostat_t *)); 1380Sstevel@tonic-gate static void showipstates __P((ips_stat_t *)); 1390Sstevel@tonic-gate static void showauthstates __P((fr_authstat_t *)); 1400Sstevel@tonic-gate static void showgroups __P((friostat_t *)); 1412393Syz155240 static void usage __P((char *)); 1423448Sdh155122 static void printlivelist __P((int, int, frentry_t *, char *, char *)); 1433448Sdh155122 static void printdeadlist __P((int, int, frentry_t *, char *, char *)); 1440Sstevel@tonic-gate static void printlist __P((frentry_t *, char *)); 1452393Syz155240 static void parse_ipportstr __P((const char *, i6addr_t *, int *)); 1460Sstevel@tonic-gate static void ipfstate_live __P((char *, friostat_t **, ips_stat_t **, 1470Sstevel@tonic-gate ipfrstat_t **, fr_authstat_t **, u_32_t *)); 1480Sstevel@tonic-gate static void ipfstate_dead __P((char *, friostat_t **, ips_stat_t **, 1490Sstevel@tonic-gate ipfrstat_t **, fr_authstat_t **, u_32_t *)); 1500Sstevel@tonic-gate #ifdef STATETOP 1512393Syz155240 static void topipstates __P((i6addr_t, i6addr_t, int, int, int, 1522393Syz155240 int, int, int)); 1532393Syz155240 static void sig_break __P((int)); 1542393Syz155240 static void sig_resize __P((int)); 1552393Syz155240 static char *getip __P((int, i6addr_t *)); 1560Sstevel@tonic-gate static char *ttl_to_string __P((long)); 1570Sstevel@tonic-gate static int sort_p __P((const void *, const void *)); 1580Sstevel@tonic-gate static int sort_pkts __P((const void *, const void *)); 1590Sstevel@tonic-gate static int sort_bytes __P((const void *, const void *)); 1600Sstevel@tonic-gate static int sort_ttl __P((const void *, const void *)); 1610Sstevel@tonic-gate static int sort_srcip __P((const void *, const void *)); 1622393Syz155240 static int sort_srcpt __P((const void *, const void *)); 1630Sstevel@tonic-gate static int sort_dstip __P((const void *, const void *)); 1642393Syz155240 static int sort_dstpt __P((const void *, const void *)); 1650Sstevel@tonic-gate #endif 1660Sstevel@tonic-gate 1670Sstevel@tonic-gate 1682393Syz155240 static void usage(name) 1690Sstevel@tonic-gate char *name; 1700Sstevel@tonic-gate { 1710Sstevel@tonic-gate #ifdef USE_INET6 1722393Syz155240 fprintf(stderr, "Usage: %s [-6aAdfghIilnoRsv]\n", name); 1730Sstevel@tonic-gate #else 1742393Syz155240 fprintf(stderr, "Usage: %s [-aAdfghIilnoRsv]\n", name); 1750Sstevel@tonic-gate #endif 1762393Syz155240 fprintf(stderr, " %s [-M corefile] [-N symbol-list]\n", name); 1772393Syz155240 #ifdef USE_INET6 1782393Syz155240 fprintf(stderr, " %s -t [-6C] ", name); 1792393Syz155240 #else 1802393Syz155240 fprintf(stderr, " %s -t [-C] ", name); 1812393Syz155240 #endif 1822393Syz155240 fprintf(stderr, "[-D destination address] [-P protocol] [-S source address] [-T refresh time]\n"); 1830Sstevel@tonic-gate exit(1); 1840Sstevel@tonic-gate } 1850Sstevel@tonic-gate 1860Sstevel@tonic-gate 1870Sstevel@tonic-gate int main(argc,argv) 1880Sstevel@tonic-gate int argc; 1890Sstevel@tonic-gate char *argv[]; 1900Sstevel@tonic-gate { 1910Sstevel@tonic-gate fr_authstat_t frauthst; 1920Sstevel@tonic-gate fr_authstat_t *frauthstp = &frauthst; 1930Sstevel@tonic-gate friostat_t fio; 1940Sstevel@tonic-gate friostat_t *fiop = &fio; 1950Sstevel@tonic-gate ips_stat_t ipsst; 1960Sstevel@tonic-gate ips_stat_t *ipsstp = &ipsst; 1970Sstevel@tonic-gate ipfrstat_t ifrst; 1980Sstevel@tonic-gate ipfrstat_t *ifrstp = &ifrst; 1990Sstevel@tonic-gate char *device = IPL_NAME, *memf = NULL; 2002393Syz155240 char *options, *kern = NULL; 2010Sstevel@tonic-gate int c, myoptind; 2020Sstevel@tonic-gate 2030Sstevel@tonic-gate int protocol = -1; /* -1 = wild card for any protocol */ 2040Sstevel@tonic-gate int refreshtime = 1; /* default update time */ 2050Sstevel@tonic-gate int sport = -1; /* -1 = wild card for any source port */ 2060Sstevel@tonic-gate int dport = -1; /* -1 = wild card for any dest port */ 2070Sstevel@tonic-gate int topclosed = 0; /* do not show closed tcp sessions */ 2082393Syz155240 i6addr_t saddr, daddr; 2090Sstevel@tonic-gate u_32_t frf; 2100Sstevel@tonic-gate 2112393Syz155240 #ifdef USE_INET6 2122393Syz155240 options = "6aACdfghIilnostvD:M:N:P:RS:T:"; 2132393Syz155240 #else 2142393Syz155240 options = "aACdfghIilnostvD:M:N:P:RS:T:"; 2152393Syz155240 #endif 2162393Syz155240 2172393Syz155240 saddr.in4.s_addr = INADDR_ANY; /* default any v4 source addr */ 2182393Syz155240 daddr.in4.s_addr = INADDR_ANY; /* default any v4 dest addr */ 2192393Syz155240 #ifdef USE_INET6 2202393Syz155240 saddr.in6 = in6addr_any; /* default any v6 source addr */ 2212393Syz155240 daddr.in6 = in6addr_any; /* default any v6 dest addr */ 2222393Syz155240 #endif 2232393Syz155240 2242393Syz155240 /* Don't warn about invalid flags when we run getopt for the 1st time */ 2252393Syz155240 opterr = 0; 2260Sstevel@tonic-gate 2270Sstevel@tonic-gate /* 2280Sstevel@tonic-gate * Parse these two arguments now lest there be any buffer overflows 2290Sstevel@tonic-gate * in the parsing of the rest. 2300Sstevel@tonic-gate */ 2310Sstevel@tonic-gate myoptind = optind; 2322393Syz155240 while ((c = getopt(argc, argv, options)) != -1) { 2330Sstevel@tonic-gate switch (c) 2340Sstevel@tonic-gate { 2350Sstevel@tonic-gate case 'M' : 2360Sstevel@tonic-gate memf = optarg; 2370Sstevel@tonic-gate live_kernel = 0; 2380Sstevel@tonic-gate break; 2390Sstevel@tonic-gate case 'N' : 2400Sstevel@tonic-gate kern = optarg; 2410Sstevel@tonic-gate live_kernel = 0; 2420Sstevel@tonic-gate break; 2430Sstevel@tonic-gate } 2442393Syz155240 } 2450Sstevel@tonic-gate optind = myoptind; 2460Sstevel@tonic-gate 2470Sstevel@tonic-gate if (live_kernel == 1) { 2480Sstevel@tonic-gate if ((state_fd = open(IPSTATE_NAME, O_RDONLY)) == -1) { 2492393Syz155240 perror("open(IPSTATE_NAME)"); 2500Sstevel@tonic-gate exit(-1); 2510Sstevel@tonic-gate } 2520Sstevel@tonic-gate if ((ipf_fd = open(device, O_RDONLY)) == -1) { 2532393Syz155240 fprintf(stderr, "open(%s)", device); 2542393Syz155240 perror(""); 2550Sstevel@tonic-gate exit(-1); 2560Sstevel@tonic-gate } 2570Sstevel@tonic-gate } 2580Sstevel@tonic-gate 2592393Syz155240 if (kern != NULL || memf != NULL) { 2600Sstevel@tonic-gate (void)setgid(getgid()); 2610Sstevel@tonic-gate (void)setreuid(getuid(), getuid()); 2623448Sdh155122 if (openkmem(kern, memf) == -1) 2633448Sdh155122 exit(-1); 2640Sstevel@tonic-gate } 2650Sstevel@tonic-gate 2662393Syz155240 if (live_kernel == 1) 2672393Syz155240 (void) checkrev(device); 2680Sstevel@tonic-gate (void)setgid(getgid()); 2690Sstevel@tonic-gate (void)setreuid(getuid(), getuid()); 2700Sstevel@tonic-gate 2712393Syz155240 opterr = 1; 2722393Syz155240 2732393Syz155240 while ((c = getopt(argc, argv, options)) != -1) 2740Sstevel@tonic-gate { 2750Sstevel@tonic-gate switch (c) 2760Sstevel@tonic-gate { 2770Sstevel@tonic-gate #ifdef USE_INET6 2780Sstevel@tonic-gate case '6' : 2790Sstevel@tonic-gate use_inet6 = 1; 2800Sstevel@tonic-gate break; 2810Sstevel@tonic-gate #endif 2820Sstevel@tonic-gate case 'a' : 2830Sstevel@tonic-gate opts |= OPT_ACCNT|OPT_SHOWLIST; 2840Sstevel@tonic-gate break; 2850Sstevel@tonic-gate case 'A' : 2860Sstevel@tonic-gate opts |= OPT_AUTHSTATS; 2870Sstevel@tonic-gate break; 2880Sstevel@tonic-gate case 'C' : 2890Sstevel@tonic-gate topclosed = 1; 2900Sstevel@tonic-gate break; 2910Sstevel@tonic-gate case 'd' : 2920Sstevel@tonic-gate opts |= OPT_DEBUG; 2930Sstevel@tonic-gate break; 2940Sstevel@tonic-gate case 'D' : 2950Sstevel@tonic-gate parse_ipportstr(optarg, &daddr, &dport); 2960Sstevel@tonic-gate break; 2970Sstevel@tonic-gate case 'f' : 2980Sstevel@tonic-gate opts |= OPT_FRSTATES; 2990Sstevel@tonic-gate break; 3000Sstevel@tonic-gate case 'g' : 3010Sstevel@tonic-gate opts |= OPT_GROUPS; 3020Sstevel@tonic-gate break; 3030Sstevel@tonic-gate case 'h' : 3040Sstevel@tonic-gate opts |= OPT_HITS; 3050Sstevel@tonic-gate break; 3060Sstevel@tonic-gate case 'i' : 3070Sstevel@tonic-gate opts |= OPT_INQUE|OPT_SHOWLIST; 3080Sstevel@tonic-gate break; 3090Sstevel@tonic-gate case 'I' : 3100Sstevel@tonic-gate opts |= OPT_INACTIVE; 3110Sstevel@tonic-gate break; 3120Sstevel@tonic-gate case 'l' : 3130Sstevel@tonic-gate opts |= OPT_SHOWLIST; 3140Sstevel@tonic-gate break; 3150Sstevel@tonic-gate case 'M' : 3160Sstevel@tonic-gate break; 3170Sstevel@tonic-gate case 'N' : 3180Sstevel@tonic-gate break; 3190Sstevel@tonic-gate case 'n' : 3200Sstevel@tonic-gate opts |= OPT_SHOWLINENO; 3210Sstevel@tonic-gate break; 3220Sstevel@tonic-gate case 'o' : 3230Sstevel@tonic-gate opts |= OPT_OUTQUE|OPT_SHOWLIST; 3240Sstevel@tonic-gate break; 3250Sstevel@tonic-gate case 'P' : 3262393Syz155240 protocol = getproto(optarg); 3272393Syz155240 if (protocol == -1) { 3282393Syz155240 fprintf(stderr, "%s: Invalid protocol: %s\n", 3290Sstevel@tonic-gate argv[0], optarg); 3300Sstevel@tonic-gate exit(-2); 3310Sstevel@tonic-gate } 3320Sstevel@tonic-gate break; 3332393Syz155240 case 'R' : 3342393Syz155240 opts |= OPT_NORESOLVE; 3352393Syz155240 break; 3360Sstevel@tonic-gate case 's' : 3370Sstevel@tonic-gate opts |= OPT_IPSTATES; 3380Sstevel@tonic-gate break; 3390Sstevel@tonic-gate case 'S' : 3400Sstevel@tonic-gate parse_ipportstr(optarg, &saddr, &sport); 3410Sstevel@tonic-gate break; 3420Sstevel@tonic-gate case 't' : 3430Sstevel@tonic-gate #ifdef STATETOP 3440Sstevel@tonic-gate opts |= OPT_STATETOP; 3450Sstevel@tonic-gate break; 3460Sstevel@tonic-gate #else 3470Sstevel@tonic-gate fprintf(stderr, 3482393Syz155240 "%s: state top facility not compiled in\n", 3490Sstevel@tonic-gate argv[0]); 3500Sstevel@tonic-gate exit(-2); 3510Sstevel@tonic-gate #endif 3520Sstevel@tonic-gate case 'T' : 3530Sstevel@tonic-gate if (!sscanf(optarg, "%d", &refreshtime) || 3540Sstevel@tonic-gate (refreshtime <= 0)) { 3550Sstevel@tonic-gate fprintf(stderr, 3562393Syz155240 "%s: Invalid refreshtime < 1 : %s\n", 3570Sstevel@tonic-gate argv[0], optarg); 3580Sstevel@tonic-gate exit(-2); 3590Sstevel@tonic-gate } 3600Sstevel@tonic-gate break; 3610Sstevel@tonic-gate case 'v' : 3620Sstevel@tonic-gate opts |= OPT_VERBOSE; 3630Sstevel@tonic-gate opts |= OPT_UNDEF; 3640Sstevel@tonic-gate break; 3650Sstevel@tonic-gate default : 3662393Syz155240 usage(argv[0]); 3670Sstevel@tonic-gate break; 3680Sstevel@tonic-gate } 3690Sstevel@tonic-gate } 3700Sstevel@tonic-gate 3710Sstevel@tonic-gate if (live_kernel == 1) { 3720Sstevel@tonic-gate bzero((char *)&fio, sizeof(fio)); 3730Sstevel@tonic-gate bzero((char *)&ipsst, sizeof(ipsst)); 3740Sstevel@tonic-gate bzero((char *)&ifrst, sizeof(ifrst)); 3750Sstevel@tonic-gate 3760Sstevel@tonic-gate ipfstate_live(device, &fiop, &ipsstp, &ifrstp, 3770Sstevel@tonic-gate &frauthstp, &frf); 3780Sstevel@tonic-gate } else 3790Sstevel@tonic-gate ipfstate_dead(kern, &fiop, &ipsstp, &ifrstp, &frauthstp, &frf); 3800Sstevel@tonic-gate 3810Sstevel@tonic-gate if (opts & OPT_IPSTATES) { 3820Sstevel@tonic-gate showipstates(ipsstp); 3830Sstevel@tonic-gate } else if (opts & OPT_SHOWLIST) { 3840Sstevel@tonic-gate showlist(fiop); 3850Sstevel@tonic-gate if ((opts & OPT_OUTQUE) && (opts & OPT_INQUE)){ 3860Sstevel@tonic-gate opts &= ~OPT_OUTQUE; 3870Sstevel@tonic-gate showlist(fiop); 3880Sstevel@tonic-gate } 3892393Syz155240 } else if (opts & OPT_FRSTATES) 3902393Syz155240 showfrstates(ifrstp); 3910Sstevel@tonic-gate #ifdef STATETOP 3922393Syz155240 else if (opts & OPT_STATETOP) 3932393Syz155240 topipstates(saddr, daddr, sport, dport, protocol, 3942393Syz155240 use_inet6 ? 6 : 4, refreshtime, topclosed); 3950Sstevel@tonic-gate #endif 3962393Syz155240 else if (opts & OPT_AUTHSTATS) 3972393Syz155240 showauthstates(frauthstp); 3982393Syz155240 else if (opts & OPT_GROUPS) 3992393Syz155240 showgroups(fiop); 4002393Syz155240 else 4012393Syz155240 showstats(fiop, frf); 4022393Syz155240 4030Sstevel@tonic-gate return 0; 4040Sstevel@tonic-gate } 4050Sstevel@tonic-gate 4060Sstevel@tonic-gate 4070Sstevel@tonic-gate /* 4080Sstevel@tonic-gate * Fill in the stats structures from the live kernel, using a combination 4090Sstevel@tonic-gate * of ioctl's and copying directly from kernel memory. 4100Sstevel@tonic-gate */ 4110Sstevel@tonic-gate static void ipfstate_live(device, fiopp, ipsstpp, ifrstpp, frauthstpp, frfp) 4120Sstevel@tonic-gate char *device; 4130Sstevel@tonic-gate friostat_t **fiopp; 4140Sstevel@tonic-gate ips_stat_t **ipsstpp; 4150Sstevel@tonic-gate ipfrstat_t **ifrstpp; 4160Sstevel@tonic-gate fr_authstat_t **frauthstpp; 4170Sstevel@tonic-gate u_32_t *frfp; 4180Sstevel@tonic-gate { 4190Sstevel@tonic-gate ipfobj_t ipfo; 4200Sstevel@tonic-gate 4210Sstevel@tonic-gate if (checkrev(device) == -1) { 4220Sstevel@tonic-gate fprintf(stderr, "User/kernel version check failed\n"); 4230Sstevel@tonic-gate exit(1); 4240Sstevel@tonic-gate } 4250Sstevel@tonic-gate 4260Sstevel@tonic-gate if ((opts & OPT_AUTHSTATS) == 0) { 4270Sstevel@tonic-gate bzero((caddr_t)&ipfo, sizeof(ipfo)); 4280Sstevel@tonic-gate ipfo.ipfo_rev = IPFILTER_VERSION; 4290Sstevel@tonic-gate ipfo.ipfo_size = sizeof(friostat_t); 4300Sstevel@tonic-gate ipfo.ipfo_ptr = (void *)*fiopp; 4310Sstevel@tonic-gate ipfo.ipfo_type = IPFOBJ_IPFSTAT; 4320Sstevel@tonic-gate 4330Sstevel@tonic-gate if (ioctl(ipf_fd, SIOCGETFS, &ipfo) == -1) { 4340Sstevel@tonic-gate perror("ioctl(ipf:SIOCGETFS)"); 4350Sstevel@tonic-gate exit(-1); 4360Sstevel@tonic-gate } 4370Sstevel@tonic-gate 4380Sstevel@tonic-gate if (ioctl(ipf_fd, SIOCGETFF, frfp) == -1) 4390Sstevel@tonic-gate perror("ioctl(SIOCGETFF)"); 4400Sstevel@tonic-gate } 4410Sstevel@tonic-gate 4420Sstevel@tonic-gate if ((opts & OPT_IPSTATES) != 0) { 4430Sstevel@tonic-gate 4440Sstevel@tonic-gate bzero((caddr_t)&ipfo, sizeof(ipfo)); 4450Sstevel@tonic-gate ipfo.ipfo_rev = IPFILTER_VERSION; 4460Sstevel@tonic-gate ipfo.ipfo_size = sizeof(ips_stat_t); 4470Sstevel@tonic-gate ipfo.ipfo_ptr = (void *)*ipsstpp; 4480Sstevel@tonic-gate ipfo.ipfo_type = IPFOBJ_STATESTAT; 4490Sstevel@tonic-gate 4500Sstevel@tonic-gate if ((ioctl(state_fd, SIOCGETFS, &ipfo) == -1)) { 4510Sstevel@tonic-gate perror("ioctl(state:SIOCGETFS)"); 4520Sstevel@tonic-gate exit(-1); 4530Sstevel@tonic-gate } 4540Sstevel@tonic-gate if (ioctl(state_fd, SIOCGETLG, &state_logging) == -1) { 4550Sstevel@tonic-gate perror("ioctl(state:SIOCGETLG)"); 4560Sstevel@tonic-gate exit(-1); 4570Sstevel@tonic-gate } 4580Sstevel@tonic-gate } 4590Sstevel@tonic-gate 4600Sstevel@tonic-gate if ((opts & OPT_FRSTATES) != 0) { 4610Sstevel@tonic-gate bzero((caddr_t)&ipfo, sizeof(ipfo)); 4620Sstevel@tonic-gate ipfo.ipfo_rev = IPFILTER_VERSION; 4630Sstevel@tonic-gate ipfo.ipfo_size = sizeof(ipfrstat_t); 4640Sstevel@tonic-gate ipfo.ipfo_ptr = (void *)*ifrstpp; 4650Sstevel@tonic-gate ipfo.ipfo_type = IPFOBJ_FRAGSTAT; 4660Sstevel@tonic-gate 4670Sstevel@tonic-gate if (ioctl(ipf_fd, SIOCGFRST, &ipfo) == -1) { 4680Sstevel@tonic-gate perror("ioctl(SIOCGFRST)"); 4690Sstevel@tonic-gate exit(-1); 4700Sstevel@tonic-gate } 4710Sstevel@tonic-gate } 4720Sstevel@tonic-gate 4730Sstevel@tonic-gate if (opts & OPT_VERBOSE) 4740Sstevel@tonic-gate PRINTF("opts %#x name %s\n", opts, device); 4750Sstevel@tonic-gate 4760Sstevel@tonic-gate if ((opts & OPT_AUTHSTATS) != 0) { 4770Sstevel@tonic-gate if (ipf_fd >= 0) { 4780Sstevel@tonic-gate close(ipf_fd); 4790Sstevel@tonic-gate ipf_fd = -1; 4800Sstevel@tonic-gate } 4810Sstevel@tonic-gate device = IPAUTH_NAME; 4820Sstevel@tonic-gate if ((ipf_fd = open(device, O_RDONLY)) == -1) { 4830Sstevel@tonic-gate perror("open"); 4840Sstevel@tonic-gate exit(-1); 4850Sstevel@tonic-gate } 4860Sstevel@tonic-gate 4870Sstevel@tonic-gate bzero((caddr_t)&ipfo, sizeof(ipfo)); 4880Sstevel@tonic-gate ipfo.ipfo_rev = IPFILTER_VERSION; 4890Sstevel@tonic-gate ipfo.ipfo_size = sizeof(fr_authstat_t); 4900Sstevel@tonic-gate ipfo.ipfo_ptr = (void *)*frauthstpp; 4910Sstevel@tonic-gate ipfo.ipfo_type = IPFOBJ_AUTHSTAT; 4920Sstevel@tonic-gate 4930Sstevel@tonic-gate if (ioctl(ipf_fd, SIOCATHST, &ipfo) == -1) { 4940Sstevel@tonic-gate perror("ioctl(SIOCATHST)"); 4950Sstevel@tonic-gate exit(-1); 4960Sstevel@tonic-gate } 4970Sstevel@tonic-gate } 4980Sstevel@tonic-gate } 4990Sstevel@tonic-gate 5000Sstevel@tonic-gate 5010Sstevel@tonic-gate /* 5020Sstevel@tonic-gate * Build up the stats structures from data held in the "core" memory. 5030Sstevel@tonic-gate * This is mainly useful when looking at data in crash dumps and ioctl's 5040Sstevel@tonic-gate * just won't work any more. 5050Sstevel@tonic-gate */ 5060Sstevel@tonic-gate static void ipfstate_dead(kernel, fiopp, ipsstpp, ifrstpp, frauthstpp, frfp) 5070Sstevel@tonic-gate char *kernel; 5080Sstevel@tonic-gate friostat_t **fiopp; 5090Sstevel@tonic-gate ips_stat_t **ipsstpp; 5100Sstevel@tonic-gate ipfrstat_t **ifrstpp; 5110Sstevel@tonic-gate fr_authstat_t **frauthstpp; 5120Sstevel@tonic-gate u_32_t *frfp; 5130Sstevel@tonic-gate { 5140Sstevel@tonic-gate static fr_authstat_t frauthst, *frauthstp; 5150Sstevel@tonic-gate static ips_stat_t ipsst, *ipsstp; 5160Sstevel@tonic-gate static ipfrstat_t ifrst, *ifrstp; 5170Sstevel@tonic-gate static friostat_t fio, *fiop; 5180Sstevel@tonic-gate int temp; 5190Sstevel@tonic-gate 5200Sstevel@tonic-gate void *rules[2][2]; 5210Sstevel@tonic-gate struct nlist deadlist[43] = { 5220Sstevel@tonic-gate { "fr_authstats" }, /* 0 */ 5230Sstevel@tonic-gate { "fae_list" }, 5240Sstevel@tonic-gate { "ipauth" }, 5250Sstevel@tonic-gate { "fr_authlist" }, 5260Sstevel@tonic-gate { "fr_authstart" }, 5270Sstevel@tonic-gate { "fr_authend" }, /* 5 */ 5280Sstevel@tonic-gate { "fr_authnext" }, 5290Sstevel@tonic-gate { "fr_auth" }, 5300Sstevel@tonic-gate { "fr_authused" }, 5310Sstevel@tonic-gate { "fr_authsize" }, 5320Sstevel@tonic-gate { "fr_defaultauthage" }, /* 10 */ 5330Sstevel@tonic-gate { "fr_authpkts" }, 5340Sstevel@tonic-gate { "fr_auth_lock" }, 5350Sstevel@tonic-gate { "frstats" }, 5360Sstevel@tonic-gate { "ips_stats" }, 5370Sstevel@tonic-gate { "ips_num" }, /* 15 */ 5380Sstevel@tonic-gate { "ips_wild" }, 5390Sstevel@tonic-gate { "ips_list" }, 5400Sstevel@tonic-gate { "ips_table" }, 5410Sstevel@tonic-gate { "fr_statemax" }, 5420Sstevel@tonic-gate { "fr_statesize" }, /* 20 */ 5430Sstevel@tonic-gate { "fr_state_doflush" }, 5440Sstevel@tonic-gate { "fr_state_lock" }, 5450Sstevel@tonic-gate { "ipfr_heads" }, 5460Sstevel@tonic-gate { "ipfr_nattab" }, 5470Sstevel@tonic-gate { "ipfr_stats" }, /* 25 */ 5480Sstevel@tonic-gate { "ipfr_inuse" }, 5490Sstevel@tonic-gate { "fr_ipfrttl" }, 5500Sstevel@tonic-gate { "fr_frag_lock" }, 5510Sstevel@tonic-gate { "ipfr_timer_id" }, 5520Sstevel@tonic-gate { "fr_nat_lock" }, /* 30 */ 5530Sstevel@tonic-gate { "ipfilter" }, 5540Sstevel@tonic-gate { "ipfilter6" }, 5550Sstevel@tonic-gate { "ipacct" }, 5560Sstevel@tonic-gate { "ipacct6" }, 5570Sstevel@tonic-gate { "ipl_frouteok" }, /* 35 */ 5580Sstevel@tonic-gate { "fr_running" }, 5590Sstevel@tonic-gate { "ipfgroups" }, 5600Sstevel@tonic-gate { "fr_active" }, 5610Sstevel@tonic-gate { "fr_pass" }, 5620Sstevel@tonic-gate { "fr_flags" }, /* 40 */ 5630Sstevel@tonic-gate { "ipstate_logging" }, 5640Sstevel@tonic-gate { NULL } 5650Sstevel@tonic-gate }; 5660Sstevel@tonic-gate 5670Sstevel@tonic-gate 5680Sstevel@tonic-gate frauthstp = &frauthst; 5690Sstevel@tonic-gate ipsstp = &ipsst; 5700Sstevel@tonic-gate ifrstp = &ifrst; 5710Sstevel@tonic-gate fiop = &fio; 5720Sstevel@tonic-gate 5730Sstevel@tonic-gate *frfp = 0; 5740Sstevel@tonic-gate *fiopp = fiop; 5750Sstevel@tonic-gate *ipsstpp = ipsstp; 5760Sstevel@tonic-gate *ifrstpp = ifrstp; 5770Sstevel@tonic-gate *frauthstpp = frauthstp; 5780Sstevel@tonic-gate 5790Sstevel@tonic-gate bzero((char *)fiop, sizeof(*fiop)); 5800Sstevel@tonic-gate bzero((char *)ipsstp, sizeof(*ipsstp)); 5810Sstevel@tonic-gate bzero((char *)ifrstp, sizeof(*ifrstp)); 5820Sstevel@tonic-gate bzero((char *)frauthstp, sizeof(*frauthstp)); 5830Sstevel@tonic-gate 5840Sstevel@tonic-gate if (nlist(kernel, deadlist) == -1) { 5850Sstevel@tonic-gate fprintf(stderr, "nlist error\n"); 5860Sstevel@tonic-gate return; 5870Sstevel@tonic-gate } 5880Sstevel@tonic-gate 5890Sstevel@tonic-gate /* 5900Sstevel@tonic-gate * This is for SIOCGETFF. 5910Sstevel@tonic-gate */ 5920Sstevel@tonic-gate kmemcpy((char *)frfp, (u_long)deadlist[40].n_value, sizeof(*frfp)); 5930Sstevel@tonic-gate 5940Sstevel@tonic-gate /* 5950Sstevel@tonic-gate * f_locks is a combination of the lock variable from each part of 5960Sstevel@tonic-gate * ipfilter (state, auth, nat, fragments). 5970Sstevel@tonic-gate */ 5980Sstevel@tonic-gate kmemcpy((char *)fiop, (u_long)deadlist[13].n_value, sizeof(*fiop)); 5990Sstevel@tonic-gate kmemcpy((char *)&fiop->f_locks[0], (u_long)deadlist[22].n_value, 6000Sstevel@tonic-gate sizeof(fiop->f_locks[0])); 6010Sstevel@tonic-gate kmemcpy((char *)&fiop->f_locks[0], (u_long)deadlist[30].n_value, 6020Sstevel@tonic-gate sizeof(fiop->f_locks[1])); 6030Sstevel@tonic-gate kmemcpy((char *)&fiop->f_locks[2], (u_long)deadlist[28].n_value, 6040Sstevel@tonic-gate sizeof(fiop->f_locks[2])); 6050Sstevel@tonic-gate kmemcpy((char *)&fiop->f_locks[3], (u_long)deadlist[12].n_value, 6060Sstevel@tonic-gate sizeof(fiop->f_locks[3])); 6070Sstevel@tonic-gate 6080Sstevel@tonic-gate /* 6090Sstevel@tonic-gate * Get pointers to each list of rules (active, inactive, in, out) 6100Sstevel@tonic-gate */ 6110Sstevel@tonic-gate kmemcpy((char *)&rules, (u_long)deadlist[31].n_value, sizeof(rules)); 6120Sstevel@tonic-gate fiop->f_fin[0] = rules[0][0]; 6130Sstevel@tonic-gate fiop->f_fin[1] = rules[0][1]; 6140Sstevel@tonic-gate fiop->f_fout[0] = rules[1][0]; 6150Sstevel@tonic-gate fiop->f_fout[1] = rules[1][1]; 6160Sstevel@tonic-gate 6170Sstevel@tonic-gate /* 6180Sstevel@tonic-gate * Same for IPv6, except make them null if support for it is not 6190Sstevel@tonic-gate * being compiled in. 6200Sstevel@tonic-gate */ 6210Sstevel@tonic-gate #ifdef USE_INET6 6220Sstevel@tonic-gate kmemcpy((char *)&rules, (u_long)deadlist[32].n_value, sizeof(rules)); 6230Sstevel@tonic-gate fiop->f_fin6[0] = rules[0][0]; 6240Sstevel@tonic-gate fiop->f_fin6[1] = rules[0][1]; 6250Sstevel@tonic-gate fiop->f_fout6[0] = rules[1][0]; 6260Sstevel@tonic-gate fiop->f_fout6[1] = rules[1][1]; 6270Sstevel@tonic-gate #else 6280Sstevel@tonic-gate fiop->f_fin6[0] = NULL; 6290Sstevel@tonic-gate fiop->f_fin6[1] = NULL; 6300Sstevel@tonic-gate fiop->f_fout6[0] = NULL; 6310Sstevel@tonic-gate fiop->f_fout6[1] = NULL; 6320Sstevel@tonic-gate #endif 6330Sstevel@tonic-gate 6340Sstevel@tonic-gate /* 6350Sstevel@tonic-gate * Now get accounting rules pointers. 6360Sstevel@tonic-gate */ 6370Sstevel@tonic-gate kmemcpy((char *)&rules, (u_long)deadlist[33].n_value, sizeof(rules)); 6380Sstevel@tonic-gate fiop->f_acctin[0] = rules[0][0]; 6390Sstevel@tonic-gate fiop->f_acctin[1] = rules[0][1]; 6400Sstevel@tonic-gate fiop->f_acctout[0] = rules[1][0]; 6410Sstevel@tonic-gate fiop->f_acctout[1] = rules[1][1]; 6420Sstevel@tonic-gate 6430Sstevel@tonic-gate #ifdef USE_INET6 6440Sstevel@tonic-gate kmemcpy((char *)&rules, (u_long)deadlist[34].n_value, sizeof(rules)); 6450Sstevel@tonic-gate fiop->f_acctin6[0] = rules[0][0]; 6460Sstevel@tonic-gate fiop->f_acctin6[1] = rules[0][1]; 6470Sstevel@tonic-gate fiop->f_acctout6[0] = rules[1][0]; 6480Sstevel@tonic-gate fiop->f_acctout6[1] = rules[1][1]; 6490Sstevel@tonic-gate #else 6500Sstevel@tonic-gate fiop->f_acctin6[0] = NULL; 6510Sstevel@tonic-gate fiop->f_acctin6[1] = NULL; 6520Sstevel@tonic-gate fiop->f_acctout6[0] = NULL; 6530Sstevel@tonic-gate fiop->f_acctout6[1] = NULL; 6540Sstevel@tonic-gate #endif 6550Sstevel@tonic-gate 6560Sstevel@tonic-gate /* 6570Sstevel@tonic-gate * A collection of "global" variables used inside the kernel which 6580Sstevel@tonic-gate * are all collected in friostat_t via ioctl. 6590Sstevel@tonic-gate */ 6600Sstevel@tonic-gate kmemcpy((char *)&fiop->f_froute, (u_long)deadlist[35].n_value, 6610Sstevel@tonic-gate sizeof(fiop->f_froute)); 6620Sstevel@tonic-gate kmemcpy((char *)&fiop->f_running, (u_long)deadlist[36].n_value, 6630Sstevel@tonic-gate sizeof(fiop->f_running)); 6640Sstevel@tonic-gate kmemcpy((char *)&fiop->f_groups, (u_long)deadlist[37].n_value, 6650Sstevel@tonic-gate sizeof(fiop->f_groups)); 6660Sstevel@tonic-gate kmemcpy((char *)&fiop->f_active, (u_long)deadlist[38].n_value, 6670Sstevel@tonic-gate sizeof(fiop->f_active)); 6680Sstevel@tonic-gate kmemcpy((char *)&fiop->f_defpass, (u_long)deadlist[39].n_value, 6690Sstevel@tonic-gate sizeof(fiop->f_defpass)); 6700Sstevel@tonic-gate 6710Sstevel@tonic-gate /* 6720Sstevel@tonic-gate * Build up the state information stats structure. 6730Sstevel@tonic-gate */ 6740Sstevel@tonic-gate kmemcpy((char *)ipsstp, (u_long)deadlist[14].n_value, sizeof(*ipsstp)); 6750Sstevel@tonic-gate kmemcpy((char *)&temp, (u_long)deadlist[15].n_value, sizeof(temp)); 6760Sstevel@tonic-gate ipsstp->iss_active = temp; 6770Sstevel@tonic-gate ipsstp->iss_table = (void *)deadlist[18].n_value; 6780Sstevel@tonic-gate ipsstp->iss_list = (void *)deadlist[17].n_value; 6790Sstevel@tonic-gate 6800Sstevel@tonic-gate /* 6810Sstevel@tonic-gate * Build up the authentiation information stats structure. 6820Sstevel@tonic-gate */ 6830Sstevel@tonic-gate kmemcpy((char *)frauthstp, (u_long)deadlist[0].n_value, 6840Sstevel@tonic-gate sizeof(*frauthstp)); 6850Sstevel@tonic-gate frauthstp->fas_faelist = (void *)deadlist[1].n_value; 6860Sstevel@tonic-gate 6870Sstevel@tonic-gate /* 6880Sstevel@tonic-gate * Build up the fragment information stats structure. 6890Sstevel@tonic-gate */ 6900Sstevel@tonic-gate kmemcpy((char *)ifrstp, (u_long)deadlist[25].n_value, 6910Sstevel@tonic-gate sizeof(*ifrstp)); 6920Sstevel@tonic-gate ifrstp->ifs_table = (void *)deadlist[23].n_value; 6930Sstevel@tonic-gate ifrstp->ifs_nattab = (void *)deadlist[24].n_value; 6940Sstevel@tonic-gate kmemcpy((char *)&ifrstp->ifs_inuse, (u_long)deadlist[26].n_value, 6950Sstevel@tonic-gate sizeof(ifrstp->ifs_inuse)); 6960Sstevel@tonic-gate 6970Sstevel@tonic-gate /* 6980Sstevel@tonic-gate * Get logging on/off switches 6990Sstevel@tonic-gate */ 7000Sstevel@tonic-gate kmemcpy((char *)&state_logging, (u_long)deadlist[41].n_value, 7010Sstevel@tonic-gate sizeof(state_logging)); 7020Sstevel@tonic-gate } 7030Sstevel@tonic-gate 7040Sstevel@tonic-gate 7050Sstevel@tonic-gate /* 7060Sstevel@tonic-gate * Display the kernel stats for packets blocked and passed and other 7070Sstevel@tonic-gate * associated running totals which are kept. 7080Sstevel@tonic-gate */ 7090Sstevel@tonic-gate static void showstats(fp, frf) 7100Sstevel@tonic-gate struct friostat *fp; 7110Sstevel@tonic-gate u_32_t frf; 7120Sstevel@tonic-gate { 7130Sstevel@tonic-gate 7140Sstevel@tonic-gate PRINTF("bad packets:\t\tin %lu\tout %lu\n", 7150Sstevel@tonic-gate fp->f_st[0].fr_bad, fp->f_st[1].fr_bad); 7160Sstevel@tonic-gate #ifdef USE_INET6 7170Sstevel@tonic-gate PRINTF(" IPv6 packets:\t\tin %lu out %lu\n", 7180Sstevel@tonic-gate fp->f_st[0].fr_ipv6, fp->f_st[1].fr_ipv6); 7190Sstevel@tonic-gate #endif 7200Sstevel@tonic-gate PRINTF(" input packets:\t\tblocked %lu passed %lu nomatch %lu", 7210Sstevel@tonic-gate fp->f_st[0].fr_block, fp->f_st[0].fr_pass, 7220Sstevel@tonic-gate fp->f_st[0].fr_nom); 7232393Syz155240 PRINTF(" counted %lu short %lu\n", 7240Sstevel@tonic-gate fp->f_st[0].fr_acct, fp->f_st[0].fr_short); 7250Sstevel@tonic-gate PRINTF("output packets:\t\tblocked %lu passed %lu nomatch %lu", 7260Sstevel@tonic-gate fp->f_st[1].fr_block, fp->f_st[1].fr_pass, 7270Sstevel@tonic-gate fp->f_st[1].fr_nom); 7282393Syz155240 PRINTF(" counted %lu short %lu\n", 7290Sstevel@tonic-gate fp->f_st[1].fr_acct, fp->f_st[1].fr_short); 7300Sstevel@tonic-gate PRINTF(" input packets logged:\tblocked %lu passed %lu\n", 7310Sstevel@tonic-gate fp->f_st[0].fr_bpkl, fp->f_st[0].fr_ppkl); 7320Sstevel@tonic-gate PRINTF("output packets logged:\tblocked %lu passed %lu\n", 7330Sstevel@tonic-gate fp->f_st[1].fr_bpkl, fp->f_st[1].fr_ppkl); 7340Sstevel@tonic-gate PRINTF(" packets logged:\tinput %lu output %lu\n", 7350Sstevel@tonic-gate fp->f_st[0].fr_pkl, fp->f_st[1].fr_pkl); 7360Sstevel@tonic-gate PRINTF(" log failures:\t\tinput %lu output %lu\n", 7370Sstevel@tonic-gate fp->f_st[0].fr_skip, fp->f_st[1].fr_skip); 7382393Syz155240 PRINTF("fragment state(in):\tkept %lu\tlost %lu\tnot fragmented %lu\n", 7392393Syz155240 fp->f_st[0].fr_nfr, fp->f_st[0].fr_bnfr, 7402393Syz155240 fp->f_st[0].fr_cfr); 7412393Syz155240 PRINTF("fragment state(out):\tkept %lu\tlost %lu\tnot fragmented %lu\n", 7422393Syz155240 fp->f_st[1].fr_nfr, fp->f_st[1].fr_bnfr, 7432393Syz155240 fp->f_st[0].fr_cfr); 7440Sstevel@tonic-gate PRINTF("packet state(in):\tkept %lu\tlost %lu\n", 7450Sstevel@tonic-gate fp->f_st[0].fr_ads, fp->f_st[0].fr_bads); 7460Sstevel@tonic-gate PRINTF("packet state(out):\tkept %lu\tlost %lu\n", 7470Sstevel@tonic-gate fp->f_st[1].fr_ads, fp->f_st[1].fr_bads); 7480Sstevel@tonic-gate PRINTF("ICMP replies:\t%lu\tTCP RSTs sent:\t%lu\n", 7490Sstevel@tonic-gate fp->f_st[0].fr_ret, fp->f_st[1].fr_ret); 7500Sstevel@tonic-gate PRINTF("Invalid source(in):\t%lu\n", fp->f_st[0].fr_badsrc); 7510Sstevel@tonic-gate PRINTF("Result cache hits(in):\t%lu\t(out):\t%lu\n", 7520Sstevel@tonic-gate fp->f_st[0].fr_chit, fp->f_st[1].fr_chit); 7530Sstevel@tonic-gate PRINTF("IN Pullups succeeded:\t%lu\tfailed:\t%lu\n", 7540Sstevel@tonic-gate fp->f_st[0].fr_pull[0], fp->f_st[0].fr_pull[1]); 7550Sstevel@tonic-gate PRINTF("OUT Pullups succeeded:\t%lu\tfailed:\t%lu\n", 7560Sstevel@tonic-gate fp->f_st[1].fr_pull[0], fp->f_st[1].fr_pull[1]); 7570Sstevel@tonic-gate PRINTF("Fastroute successes:\t%lu\tfailures:\t%lu\n", 7580Sstevel@tonic-gate fp->f_froute[0], fp->f_froute[1]); 7590Sstevel@tonic-gate PRINTF("TCP cksum fails(in):\t%lu\t(out):\t%lu\n", 7600Sstevel@tonic-gate fp->f_st[0].fr_tcpbad, fp->f_st[1].fr_tcpbad); 7610Sstevel@tonic-gate PRINTF("IPF Ticks:\t%lu\n", fp->f_ticks); 7620Sstevel@tonic-gate 7630Sstevel@tonic-gate PRINTF("Packet log flags set: (%#x)\n", frf); 7640Sstevel@tonic-gate if (frf & FF_LOGPASS) 7650Sstevel@tonic-gate PRINTF("\tpackets passed through filter\n"); 7660Sstevel@tonic-gate if (frf & FF_LOGBLOCK) 7670Sstevel@tonic-gate PRINTF("\tpackets blocked by filter\n"); 7680Sstevel@tonic-gate if (frf & FF_LOGNOMATCH) 7690Sstevel@tonic-gate PRINTF("\tpackets not matched by filter\n"); 7700Sstevel@tonic-gate if (!frf) 7710Sstevel@tonic-gate PRINTF("\tnone\n"); 7720Sstevel@tonic-gate } 7730Sstevel@tonic-gate 7740Sstevel@tonic-gate 7750Sstevel@tonic-gate /* 7760Sstevel@tonic-gate * Print out a list of rules from the kernel, starting at the one passed. 7770Sstevel@tonic-gate */ 7783448Sdh155122 static void printlivelist(out, set, fp, group, comment) 7793448Sdh155122 int out, set; 7800Sstevel@tonic-gate frentry_t *fp; 7813448Sdh155122 char *group, *comment; 7820Sstevel@tonic-gate { 7833448Sdh155122 frgroup_t *grtop, *grtail, *g; 7840Sstevel@tonic-gate struct frentry fb, *fg; 785*6518Sjojemann int n; 7863448Sdh155122 ipfruleiter_t rule; 7873448Sdh155122 ipfobj_t obj; 7883448Sdh155122 7893448Sdh155122 fb.fr_next = fp; 7903448Sdh155122 n = 0; 7910Sstevel@tonic-gate 7923448Sdh155122 grtop = NULL; 7933448Sdh155122 grtail = NULL; 7943448Sdh155122 rule.iri_ver = use_inet6? AF_INET6 : AF_INET; 7953448Sdh155122 rule.iri_inout = out; 7963448Sdh155122 rule.iri_active = set; 7975417Sjojemann rule.iri_nrules = 1; 7983448Sdh155122 rule.iri_rule = &fb; 7993448Sdh155122 if (group != NULL) 8003448Sdh155122 strncpy(rule.iri_group, group, FR_GROUPLEN); 8013448Sdh155122 else 8023448Sdh155122 rule.iri_group[0] = '\0'; 8033448Sdh155122 8043448Sdh155122 bzero((char *)&obj, sizeof(obj)); 8053448Sdh155122 obj.ipfo_rev = IPFILTER_VERSION; 8063448Sdh155122 obj.ipfo_type = IPFOBJ_IPFITER; 8073448Sdh155122 obj.ipfo_size = sizeof(rule); 8083448Sdh155122 obj.ipfo_ptr = &rule; 8093448Sdh155122 8103448Sdh155122 do { 8113448Sdh155122 u_long array[1000]; 8123448Sdh155122 8133448Sdh155122 memset(array, 0xff, sizeof(array)); 8143448Sdh155122 fp = (frentry_t *)array; 8153448Sdh155122 rule.iri_rule = fp; 8163448Sdh155122 if (ioctl(ipf_fd, SIOCIPFITER, &obj) == -1) { 8173448Sdh155122 perror("ioctl(SIOCIPFITER)"); 8180Sstevel@tonic-gate return; 8190Sstevel@tonic-gate } 8203448Sdh155122 if (fp->fr_data != NULL) 8213448Sdh155122 fp->fr_data = (char *)fp + sizeof(*fp); 8223448Sdh155122 8233448Sdh155122 n++; 8243448Sdh155122 8250Sstevel@tonic-gate if (opts & (OPT_HITS|OPT_VERBOSE)) 8260Sstevel@tonic-gate #ifdef USE_QUAD_T 8270Sstevel@tonic-gate PRINTF("%qu ", (unsigned long long) fp->fr_hits); 8280Sstevel@tonic-gate #else 8290Sstevel@tonic-gate PRINTF("%lu ", fp->fr_hits); 8300Sstevel@tonic-gate #endif 8310Sstevel@tonic-gate if (opts & (OPT_ACCNT|OPT_VERBOSE)) 8320Sstevel@tonic-gate #ifdef USE_QUAD_T 8330Sstevel@tonic-gate PRINTF("%qu ", (unsigned long long) fp->fr_bytes); 8340Sstevel@tonic-gate #else 8350Sstevel@tonic-gate PRINTF("%lu ", fp->fr_bytes); 8360Sstevel@tonic-gate #endif 8370Sstevel@tonic-gate if (opts & OPT_SHOWLINENO) 8380Sstevel@tonic-gate PRINTF("@%d ", n); 8390Sstevel@tonic-gate 8400Sstevel@tonic-gate printfr(fp, ioctl); 8412393Syz155240 if (opts & OPT_DEBUG) { 8420Sstevel@tonic-gate binprint(fp, sizeof(*fp)); 8430Sstevel@tonic-gate if (fp->fr_data != NULL && fp->fr_dsize > 0) 8440Sstevel@tonic-gate binprint(fp->fr_data, fp->fr_dsize); 8450Sstevel@tonic-gate } 8463448Sdh155122 8473448Sdh155122 if (fp->fr_grhead[0] != '\0') { 8483448Sdh155122 g = calloc(1, sizeof(*g)); 8493448Sdh155122 8503448Sdh155122 if (g != NULL) { 8513448Sdh155122 strncpy(g->fg_name, fp->fr_grhead, 8523448Sdh155122 FR_GROUPLEN); 8533448Sdh155122 if (grtop == NULL) { 8543448Sdh155122 grtop = g; 8553448Sdh155122 grtail = g; 8563448Sdh155122 } else { 8573448Sdh155122 grtail->fg_next = g; 8583448Sdh155122 grtail = g; 8593448Sdh155122 } 8603448Sdh155122 } 8613448Sdh155122 } 8623448Sdh155122 } while (fp->fr_next != NULL); 8633448Sdh155122 8643448Sdh155122 while ((g = grtop) != NULL) { 8653448Sdh155122 printlivelist(out, set, NULL, g->fg_name, comment); 8663448Sdh155122 grtop = g->fg_next; 8673448Sdh155122 free(g); 8683448Sdh155122 } 8693448Sdh155122 } 8703448Sdh155122 8713448Sdh155122 8723448Sdh155122 static void printdeadlist(out, set, fp, group, comment) 8733448Sdh155122 int out, set; 8743448Sdh155122 frentry_t *fp; 8753448Sdh155122 char *group, *comment; 8763448Sdh155122 { 8773448Sdh155122 frgroup_t *grtop, *grtail, *g; 8783448Sdh155122 struct frentry fb, *fg; 8793448Sdh155122 char *data; 8803448Sdh155122 u_32_t type; 8813448Sdh155122 int n; 8823448Sdh155122 8833448Sdh155122 fb.fr_next = fp; 8843448Sdh155122 n = 0; 8853448Sdh155122 grtop = NULL; 8863448Sdh155122 grtail = NULL; 8873448Sdh155122 8883448Sdh155122 do { 8893448Sdh155122 fp = fb.fr_next; 8903448Sdh155122 if (kmemcpy((char *)&fb, (u_long)fb.fr_next, 8913448Sdh155122 sizeof(fb)) == -1) { 8923448Sdh155122 perror("kmemcpy"); 8933448Sdh155122 return; 8943448Sdh155122 } 8953448Sdh155122 8963448Sdh155122 data = NULL; 8973448Sdh155122 type = fb.fr_type & ~FR_T_BUILTIN; 8983448Sdh155122 if (type == FR_T_IPF || type == FR_T_BPFOPC) { 8993448Sdh155122 if (fb.fr_dsize) { 9003448Sdh155122 data = malloc(fb.fr_dsize); 9013448Sdh155122 9023448Sdh155122 if (kmemcpy(data, (u_long)fb.fr_data, 9033448Sdh155122 fb.fr_dsize) == -1) { 9043448Sdh155122 perror("kmemcpy"); 9053448Sdh155122 return; 9063448Sdh155122 } 9073448Sdh155122 fb.fr_data = data; 9083448Sdh155122 } 9093448Sdh155122 } 9103448Sdh155122 9113448Sdh155122 n++; 9123448Sdh155122 9133448Sdh155122 if (opts & (OPT_HITS|OPT_VERBOSE)) 9143448Sdh155122 #ifdef USE_QUAD_T 9153448Sdh155122 PRINTF("%qu ", (unsigned long long) fb.fr_hits); 9163448Sdh155122 #else 9173448Sdh155122 PRINTF("%lu ", fb.fr_hits); 9183448Sdh155122 #endif 9193448Sdh155122 if (opts & (OPT_ACCNT|OPT_VERBOSE)) 9203448Sdh155122 #ifdef USE_QUAD_T 9213448Sdh155122 PRINTF("%qu ", (unsigned long long) fb.fr_bytes); 9223448Sdh155122 #else 9233448Sdh155122 PRINTF("%lu ", fb.fr_bytes); 9243448Sdh155122 #endif 9253448Sdh155122 if (opts & OPT_SHOWLINENO) 9263448Sdh155122 PRINTF("@%d ", n); 9273448Sdh155122 9283448Sdh155122 printfr(fp, ioctl); 9293448Sdh155122 if (opts & OPT_DEBUG) { 9303448Sdh155122 binprint(fp, sizeof(*fp)); 9313448Sdh155122 if (fb.fr_data != NULL && fb.fr_dsize > 0) 9323448Sdh155122 binprint(fb.fr_data, fb.fr_dsize); 9333448Sdh155122 } 9340Sstevel@tonic-gate if (data != NULL) 9350Sstevel@tonic-gate free(data); 9363448Sdh155122 if (fb.fr_grhead[0] != '\0') { 9373448Sdh155122 g = calloc(1, sizeof(*g)); 9383448Sdh155122 9393448Sdh155122 if (g != NULL) { 9403448Sdh155122 strncpy(g->fg_name, fb.fr_grhead, 9413448Sdh155122 FR_GROUPLEN); 9423448Sdh155122 if (grtop == NULL) { 9433448Sdh155122 grtop = g; 9443448Sdh155122 grtail = g; 9453448Sdh155122 } else { 9463448Sdh155122 grtail->fg_next = g; 9473448Sdh155122 grtail = g; 9483448Sdh155122 } 9493448Sdh155122 } 9500Sstevel@tonic-gate } 9510Sstevel@tonic-gate if (type == FR_T_CALLFUNC) { 9523448Sdh155122 printdeadlist(out, set, fb.fr_data, group, 9533448Sdh155122 "# callfunc: "); 9540Sstevel@tonic-gate } 9553448Sdh155122 } while (fb.fr_next != NULL); 9563448Sdh155122 9573448Sdh155122 while ((g = grtop) != NULL) { 9583448Sdh155122 printdeadlist(out, set, NULL, g->fg_name, comment); 9593448Sdh155122 grtop = g->fg_next; 9603448Sdh155122 free(g); 9610Sstevel@tonic-gate } 9620Sstevel@tonic-gate } 9630Sstevel@tonic-gate 9643448Sdh155122 9650Sstevel@tonic-gate /* 9660Sstevel@tonic-gate * print out all of the asked for rule sets, using the stats struct as 9670Sstevel@tonic-gate * the base from which to get the pointers. 9680Sstevel@tonic-gate */ 9690Sstevel@tonic-gate static void showlist(fiop) 9700Sstevel@tonic-gate struct friostat *fiop; 9710Sstevel@tonic-gate { 9720Sstevel@tonic-gate struct frentry *fp = NULL; 9730Sstevel@tonic-gate int i, set; 9740Sstevel@tonic-gate 9750Sstevel@tonic-gate set = fiop->f_active; 9760Sstevel@tonic-gate if (opts & OPT_INACTIVE) 9770Sstevel@tonic-gate set = 1 - set; 9780Sstevel@tonic-gate if (opts & OPT_ACCNT) { 9790Sstevel@tonic-gate #ifdef USE_INET6 9800Sstevel@tonic-gate if ((use_inet6) && (opts & OPT_OUTQUE)) { 9810Sstevel@tonic-gate i = F_ACOUT; 9820Sstevel@tonic-gate fp = (struct frentry *)fiop->f_acctout6[set]; 9830Sstevel@tonic-gate } else if ((use_inet6) && (opts & OPT_INQUE)) { 9840Sstevel@tonic-gate i = F_ACIN; 9850Sstevel@tonic-gate fp = (struct frentry *)fiop->f_acctin6[set]; 9860Sstevel@tonic-gate } else 9870Sstevel@tonic-gate #endif 9880Sstevel@tonic-gate if (opts & OPT_OUTQUE) { 9890Sstevel@tonic-gate i = F_ACOUT; 9900Sstevel@tonic-gate fp = (struct frentry *)fiop->f_acctout[set]; 9910Sstevel@tonic-gate } else if (opts & OPT_INQUE) { 9920Sstevel@tonic-gate i = F_ACIN; 9930Sstevel@tonic-gate fp = (struct frentry *)fiop->f_acctin[set]; 9940Sstevel@tonic-gate } else { 9950Sstevel@tonic-gate FPRINTF(stderr, "No -i or -o given with -a\n"); 9960Sstevel@tonic-gate return; 9970Sstevel@tonic-gate } 9980Sstevel@tonic-gate } else { 9990Sstevel@tonic-gate #ifdef USE_INET6 10000Sstevel@tonic-gate if ((use_inet6) && (opts & OPT_OUTQUE)) { 10010Sstevel@tonic-gate i = F_OUT; 10020Sstevel@tonic-gate fp = (struct frentry *)fiop->f_fout6[set]; 10030Sstevel@tonic-gate } else if ((use_inet6) && (opts & OPT_INQUE)) { 10040Sstevel@tonic-gate i = F_IN; 10050Sstevel@tonic-gate fp = (struct frentry *)fiop->f_fin6[set]; 10060Sstevel@tonic-gate } else 10070Sstevel@tonic-gate #endif 10080Sstevel@tonic-gate if (opts & OPT_OUTQUE) { 10090Sstevel@tonic-gate i = F_OUT; 10100Sstevel@tonic-gate fp = (struct frentry *)fiop->f_fout[set]; 10110Sstevel@tonic-gate } else if (opts & OPT_INQUE) { 10120Sstevel@tonic-gate i = F_IN; 10130Sstevel@tonic-gate fp = (struct frentry *)fiop->f_fin[set]; 10140Sstevel@tonic-gate } else 10150Sstevel@tonic-gate return; 10160Sstevel@tonic-gate } 10170Sstevel@tonic-gate if (opts & OPT_VERBOSE) 10180Sstevel@tonic-gate FPRINTF(stderr, "showlist:opts %#x i %d\n", opts, i); 10190Sstevel@tonic-gate 10200Sstevel@tonic-gate if (opts & OPT_VERBOSE) 10210Sstevel@tonic-gate PRINTF("fp %p set %d\n", fp, set); 10220Sstevel@tonic-gate if (!fp) { 10230Sstevel@tonic-gate FPRINTF(stderr, "empty list for %s%s\n", 10240Sstevel@tonic-gate (opts & OPT_INACTIVE) ? "inactive " : "", filters[i]); 10250Sstevel@tonic-gate return; 10260Sstevel@tonic-gate } 10273448Sdh155122 if (live_kernel == 1) 10283448Sdh155122 printlivelist(i, set, fp, NULL, NULL); 10293448Sdh155122 else 10303448Sdh155122 printdeadlist(i, set, fp, NULL, NULL); 10310Sstevel@tonic-gate } 10320Sstevel@tonic-gate 10330Sstevel@tonic-gate 10340Sstevel@tonic-gate /* 10350Sstevel@tonic-gate * Display ipfilter stateful filtering information 10360Sstevel@tonic-gate */ 10370Sstevel@tonic-gate static void showipstates(ipsp) 10380Sstevel@tonic-gate ips_stat_t *ipsp; 10390Sstevel@tonic-gate { 10400Sstevel@tonic-gate u_long minlen, maxlen, totallen, *buckets; 10410Sstevel@tonic-gate int i, sz; 10420Sstevel@tonic-gate 10430Sstevel@tonic-gate sz = sizeof(*buckets) * ipsp->iss_statesize; 10440Sstevel@tonic-gate buckets = (u_long *)malloc(sz); 10451448Sschuster if (buckets == NULL) { 10461448Sschuster perror("malloc"); 10471448Sschuster exit(1); 10481448Sschuster } 10490Sstevel@tonic-gate if (kmemcpy((char *)buckets, (u_long)ipsp->iss_bucketlen, sz)) { 10500Sstevel@tonic-gate free(buckets); 10510Sstevel@tonic-gate return; 10520Sstevel@tonic-gate } 10530Sstevel@tonic-gate 10540Sstevel@tonic-gate /* 10550Sstevel@tonic-gate * If a list of states hasn't been asked for, only print out stats 10560Sstevel@tonic-gate */ 10570Sstevel@tonic-gate if (!(opts & OPT_SHOWLIST)) { 10580Sstevel@tonic-gate PRINTF("IP states added:\n\t%lu TCP\n\t%lu UDP\n\t%lu ICMP\n", 10590Sstevel@tonic-gate ipsp->iss_tcp, ipsp->iss_udp, ipsp->iss_icmp); 10600Sstevel@tonic-gate PRINTF("\t%lu hits\n\t%lu misses\n", ipsp->iss_hits, 10610Sstevel@tonic-gate ipsp->iss_miss); 10620Sstevel@tonic-gate PRINTF("\t%lu maximum\n\t%lu no memory\n\t%lu max bucket\n", 10630Sstevel@tonic-gate ipsp->iss_max, ipsp->iss_nomem, ipsp->iss_bucketfull); 10642393Syz155240 PRINTF("\t%lu maximum\n\t%lu no memory\n\t%lu bkts in use\n", 10652393Syz155240 ipsp->iss_max, ipsp->iss_nomem, ipsp->iss_inuse); 10660Sstevel@tonic-gate PRINTF("\t%lu active\n\t%lu expired\n\t%lu closed\n", 10670Sstevel@tonic-gate ipsp->iss_active, ipsp->iss_expire, ipsp->iss_fin); 10680Sstevel@tonic-gate 10690Sstevel@tonic-gate PRINTF("State logging %sabled\n", 10700Sstevel@tonic-gate state_logging ? "en" : "dis"); 10710Sstevel@tonic-gate 10720Sstevel@tonic-gate PRINTF("\nState table bucket statistics:\n"); 10730Sstevel@tonic-gate PRINTF("\t%lu in use\t\n", ipsp->iss_inuse); 10740Sstevel@tonic-gate 10750Sstevel@tonic-gate minlen = ipsp->iss_max; 10760Sstevel@tonic-gate totallen = 0; 10770Sstevel@tonic-gate maxlen = 0; 10780Sstevel@tonic-gate 10790Sstevel@tonic-gate for (i = 0; i < ipsp->iss_statesize; i++) { 10800Sstevel@tonic-gate if (buckets[i] > maxlen) 10810Sstevel@tonic-gate maxlen = buckets[i]; 10820Sstevel@tonic-gate if (buckets[i] < minlen) 10830Sstevel@tonic-gate minlen = buckets[i]; 10840Sstevel@tonic-gate totallen += buckets[i]; 10850Sstevel@tonic-gate } 10860Sstevel@tonic-gate 10870Sstevel@tonic-gate PRINTF("\t%2.2f%% bucket usage\n\t%lu minimal length\n", 10880Sstevel@tonic-gate ((float)ipsp->iss_inuse / ipsp->iss_statesize) * 100.0, 10890Sstevel@tonic-gate minlen); 10900Sstevel@tonic-gate PRINTF("\t%lu maximal length\n\t%.3f average length\n", 10910Sstevel@tonic-gate maxlen, 10920Sstevel@tonic-gate ipsp->iss_inuse ? (float) totallen/ ipsp->iss_inuse : 10930Sstevel@tonic-gate 0.0); 10940Sstevel@tonic-gate 10950Sstevel@tonic-gate #define ENTRIES_PER_LINE 5 10960Sstevel@tonic-gate 10970Sstevel@tonic-gate if (opts & OPT_VERBOSE) { 10980Sstevel@tonic-gate PRINTF("\nCurrent bucket sizes :\n"); 10990Sstevel@tonic-gate for (i = 0; i < ipsp->iss_statesize; i++) { 11002393Syz155240 if ((i % ENTRIES_PER_LINE) == 0) 11010Sstevel@tonic-gate PRINTF("\t"); 11020Sstevel@tonic-gate PRINTF("%4d -> %4lu", i, buckets[i]); 11030Sstevel@tonic-gate if ((i % ENTRIES_PER_LINE) == 11042393Syz155240 (ENTRIES_PER_LINE - 1)) 11050Sstevel@tonic-gate PRINTF("\n"); 11062393Syz155240 else 11070Sstevel@tonic-gate PRINTF(" "); 11080Sstevel@tonic-gate } 11090Sstevel@tonic-gate PRINTF("\n"); 11100Sstevel@tonic-gate } 11110Sstevel@tonic-gate PRINTF("\n"); 11120Sstevel@tonic-gate 11130Sstevel@tonic-gate free(buckets); 11140Sstevel@tonic-gate return; 11150Sstevel@tonic-gate } 11160Sstevel@tonic-gate 11170Sstevel@tonic-gate /* 11180Sstevel@tonic-gate * Print out all the state information currently held in the kernel. 11190Sstevel@tonic-gate */ 11200Sstevel@tonic-gate while (ipsp->iss_list != NULL) { 11212393Syz155240 ipsp->iss_list = printstate(ipsp->iss_list, opts, 11222393Syz155240 ipsp->iss_ticks); 11230Sstevel@tonic-gate } 11240Sstevel@tonic-gate 11250Sstevel@tonic-gate free(buckets); 11260Sstevel@tonic-gate } 11270Sstevel@tonic-gate 11280Sstevel@tonic-gate 11290Sstevel@tonic-gate #ifdef STATETOP 11302393Syz155240 static int handle_resize = 0, handle_break = 0; 11312393Syz155240 11322393Syz155240 static void topipstates(saddr, daddr, sport, dport, protocol, ver, 11330Sstevel@tonic-gate refreshtime, topclosed) 11342393Syz155240 i6addr_t saddr; 11352393Syz155240 i6addr_t daddr; 11360Sstevel@tonic-gate int sport; 11370Sstevel@tonic-gate int dport; 11380Sstevel@tonic-gate int protocol; 11392393Syz155240 int ver; 11400Sstevel@tonic-gate int refreshtime; 11410Sstevel@tonic-gate int topclosed; 11420Sstevel@tonic-gate { 11430Sstevel@tonic-gate char str1[STSTRSIZE], str2[STSTRSIZE], str3[STSTRSIZE], str4[STSTRSIZE]; 11440Sstevel@tonic-gate int maxtsentries = 0, reverse = 0, sorting = STSORT_DEFAULT; 11452393Syz155240 int i, j, winy, tsentry, maxx, maxy, redraw = 0, ret = 0; 11462393Syz155240 int len, srclen, dstlen, forward = 1, c = 0; 11470Sstevel@tonic-gate ips_stat_t ipsst, *ipsstp = &ipsst; 11480Sstevel@tonic-gate statetop_t *tstable = NULL, *tp; 11492393Syz155240 const char *errstr = ""; 11500Sstevel@tonic-gate ipstate_t ips; 11510Sstevel@tonic-gate ipfobj_t ipfo; 11522393Syz155240 struct timeval selecttimeout; 11530Sstevel@tonic-gate char hostnm[HOSTNMLEN]; 11540Sstevel@tonic-gate struct protoent *proto; 11550Sstevel@tonic-gate fd_set readfd; 11560Sstevel@tonic-gate time_t t; 11570Sstevel@tonic-gate 11582393Syz155240 /* install signal handlers */ 11592393Syz155240 signal(SIGINT, sig_break); 11602393Syz155240 signal(SIGQUIT, sig_break); 11612393Syz155240 signal(SIGTERM, sig_break); 11622393Syz155240 signal(SIGWINCH, sig_resize); 11632393Syz155240 11640Sstevel@tonic-gate /* init ncurses stuff */ 11650Sstevel@tonic-gate initscr(); 11660Sstevel@tonic-gate cbreak(); 11670Sstevel@tonic-gate noecho(); 11682393Syz155240 curs_set(0); 11692393Syz155240 timeout(0); 11702393Syz155240 getmaxyx(stdscr, maxy, maxx); 11710Sstevel@tonic-gate 11720Sstevel@tonic-gate /* init hostname */ 11730Sstevel@tonic-gate gethostname(hostnm, sizeof(hostnm) - 1); 11740Sstevel@tonic-gate hostnm[sizeof(hostnm) - 1] = '\0'; 11752393Syz155240 11760Sstevel@tonic-gate /* init ipfobj_t stuff */ 11770Sstevel@tonic-gate bzero((caddr_t)&ipfo, sizeof(ipfo)); 11780Sstevel@tonic-gate ipfo.ipfo_rev = IPFILTER_VERSION; 11790Sstevel@tonic-gate ipfo.ipfo_size = sizeof(*ipsstp); 11800Sstevel@tonic-gate ipfo.ipfo_ptr = (void *)ipsstp; 11810Sstevel@tonic-gate ipfo.ipfo_type = IPFOBJ_STATESTAT; 11820Sstevel@tonic-gate 11830Sstevel@tonic-gate /* repeat until user aborts */ 11840Sstevel@tonic-gate while ( 1 ) { 11850Sstevel@tonic-gate 11860Sstevel@tonic-gate /* get state table */ 11870Sstevel@tonic-gate bzero((char *)&ipsst, sizeof(ipsst)); 11880Sstevel@tonic-gate if ((ioctl(state_fd, SIOCGETFS, &ipfo) == -1)) { 11892393Syz155240 errstr = "ioctl(SIOCGETFS)"; 11902393Syz155240 ret = -1; 11912393Syz155240 goto out; 11920Sstevel@tonic-gate } 11930Sstevel@tonic-gate 11940Sstevel@tonic-gate /* clear the history */ 11950Sstevel@tonic-gate tsentry = -1; 11960Sstevel@tonic-gate 11972393Syz155240 /* reset max str len */ 11982393Syz155240 srclen = dstlen = 0; 11992393Syz155240 12000Sstevel@tonic-gate /* read the state table and store in tstable */ 12012393Syz155240 for (; ipsstp->iss_list; ipsstp->iss_list = ips.is_next) { 12022393Syz155240 12030Sstevel@tonic-gate if (kmemcpy((char *)&ips, (u_long)ipsstp->iss_list, 12040Sstevel@tonic-gate sizeof(ips))) 12050Sstevel@tonic-gate break; 12062393Syz155240 12072393Syz155240 if (ips.is_v != ver) 12082393Syz155240 continue; 12090Sstevel@tonic-gate 12102393Syz155240 /* check v4 src/dest addresses */ 12112393Syz155240 if (ips.is_v == 4) { 12122393Syz155240 if ((saddr.in4.s_addr != INADDR_ANY && 12132393Syz155240 saddr.in4.s_addr != ips.is_saddr) || 12142393Syz155240 (daddr.in4.s_addr != INADDR_ANY && 12152393Syz155240 daddr.in4.s_addr != ips.is_daddr)) 12162393Syz155240 continue; 12172393Syz155240 } 12182393Syz155240 #ifdef USE_INET6 12192393Syz155240 /* check v6 src/dest addresses */ 12202393Syz155240 if (ips.is_v == 6) { 12212393Syz155240 if ((IP6_NEQ(&saddr, &in6addr_any) && 12222393Syz155240 IP6_NEQ(&saddr, &ips.is_src)) || 12232393Syz155240 (IP6_NEQ(&daddr, &in6addr_any) && 12242393Syz155240 IP6_NEQ(&daddr, &ips.is_dst))) 12252393Syz155240 continue; 12262393Syz155240 } 12272393Syz155240 #endif 12282393Syz155240 /* check protocol */ 12292393Syz155240 if (protocol > 0 && protocol != ips.is_p) 12302393Syz155240 continue; 12312393Syz155240 12322393Syz155240 /* check ports if protocol is TCP or UDP */ 12332393Syz155240 if (((ips.is_p == IPPROTO_TCP) || 12342393Syz155240 (ips.is_p == IPPROTO_UDP)) && 12352393Syz155240 (((sport > 0) && (htons(sport) != ips.is_sport)) || 12362393Syz155240 ((dport > 0) && (htons(dport) != ips.is_dport)))) 12372393Syz155240 continue; 12382393Syz155240 12392393Syz155240 /* show closed TCP sessions ? */ 12402393Syz155240 if ((topclosed == 0) && (ips.is_p == IPPROTO_TCP) && 12412393Syz155240 (ips.is_state[0] >= IPF_TCPS_LAST_ACK) && 12422393Syz155240 (ips.is_state[1] >= IPF_TCPS_LAST_ACK)) 12432393Syz155240 continue; 12440Sstevel@tonic-gate 12452393Syz155240 /* 12462393Syz155240 * if necessary make room for this state 12472393Syz155240 * entry 12482393Syz155240 */ 12492393Syz155240 tsentry++; 12502393Syz155240 if (!maxtsentries || tsentry == maxtsentries) { 12512393Syz155240 maxtsentries += STGROWSIZE; 12522393Syz155240 tstable = realloc(tstable, 12532393Syz155240 maxtsentries * sizeof(statetop_t)); 12542393Syz155240 if (tstable == NULL) { 12552393Syz155240 perror("realloc"); 12562393Syz155240 exit(-1); 12570Sstevel@tonic-gate } 12582393Syz155240 } 12590Sstevel@tonic-gate 12602393Syz155240 /* get max src/dest address string length */ 12612393Syz155240 len = strlen(getip(ips.is_v, &ips.is_src)); 12622393Syz155240 if (srclen < len) 12632393Syz155240 srclen = len; 12642393Syz155240 len = strlen(getip(ips.is_v, &ips.is_dst)); 12652393Syz155240 if (dstlen < len) 12662393Syz155240 dstlen = len; 12670Sstevel@tonic-gate 12682393Syz155240 /* fill structure */ 12692393Syz155240 tp = tstable + tsentry; 12702393Syz155240 tp->st_src = ips.is_src; 12712393Syz155240 tp->st_dst = ips.is_dst; 12722393Syz155240 tp->st_p = ips.is_p; 12732393Syz155240 tp->st_v = ips.is_v; 12742393Syz155240 tp->st_state[0] = ips.is_state[0]; 12752393Syz155240 tp->st_state[1] = ips.is_state[1]; 12762393Syz155240 if (forward) { 12772393Syz155240 tp->st_pkts = ips.is_pkts[0]+ips.is_pkts[1]; 12782393Syz155240 tp->st_bytes = ips.is_bytes[0]+ips.is_bytes[1]; 12792393Syz155240 } else { 12802393Syz155240 tp->st_pkts = ips.is_pkts[2]+ips.is_pkts[3]; 12812393Syz155240 tp->st_bytes = ips.is_bytes[2]+ips.is_bytes[3]; 12822393Syz155240 } 12832393Syz155240 tp->st_age = ips.is_die - ipsstp->iss_ticks; 12842393Syz155240 if ((ips.is_p == IPPROTO_TCP) || 12852393Syz155240 (ips.is_p == IPPROTO_UDP)) { 12862393Syz155240 tp->st_sport = ips.is_sport; 12872393Syz155240 tp->st_dport = ips.is_dport; 12880Sstevel@tonic-gate } 12890Sstevel@tonic-gate } 12900Sstevel@tonic-gate 12910Sstevel@tonic-gate 12920Sstevel@tonic-gate /* sort the array */ 12932393Syz155240 if (tsentry != -1) { 12940Sstevel@tonic-gate switch (sorting) 12950Sstevel@tonic-gate { 12960Sstevel@tonic-gate case STSORT_PR: 12970Sstevel@tonic-gate qsort(tstable, tsentry + 1, 12980Sstevel@tonic-gate sizeof(statetop_t), sort_p); 12990Sstevel@tonic-gate break; 13000Sstevel@tonic-gate case STSORT_PKTS: 13010Sstevel@tonic-gate qsort(tstable, tsentry + 1, 13020Sstevel@tonic-gate sizeof(statetop_t), sort_pkts); 13030Sstevel@tonic-gate break; 13040Sstevel@tonic-gate case STSORT_BYTES: 13050Sstevel@tonic-gate qsort(tstable, tsentry + 1, 13060Sstevel@tonic-gate sizeof(statetop_t), sort_bytes); 13070Sstevel@tonic-gate break; 13080Sstevel@tonic-gate case STSORT_TTL: 13090Sstevel@tonic-gate qsort(tstable, tsentry + 1, 13100Sstevel@tonic-gate sizeof(statetop_t), sort_ttl); 13110Sstevel@tonic-gate break; 13120Sstevel@tonic-gate case STSORT_SRCIP: 13130Sstevel@tonic-gate qsort(tstable, tsentry + 1, 13140Sstevel@tonic-gate sizeof(statetop_t), sort_srcip); 13150Sstevel@tonic-gate break; 13162393Syz155240 case STSORT_SRCPT: 13172393Syz155240 qsort(tstable, tsentry +1, 13182393Syz155240 sizeof(statetop_t), sort_srcpt); 13192393Syz155240 break; 13200Sstevel@tonic-gate case STSORT_DSTIP: 13210Sstevel@tonic-gate qsort(tstable, tsentry + 1, 13220Sstevel@tonic-gate sizeof(statetop_t), sort_dstip); 13230Sstevel@tonic-gate break; 13242393Syz155240 case STSORT_DSTPT: 13252393Syz155240 qsort(tstable, tsentry + 1, 13262393Syz155240 sizeof(statetop_t), sort_dstpt); 13272393Syz155240 break; 13280Sstevel@tonic-gate default: 13290Sstevel@tonic-gate break; 13300Sstevel@tonic-gate } 13312393Syz155240 } 13322393Syz155240 13332393Syz155240 /* handle window resizes */ 13342393Syz155240 if (handle_resize) { 13352393Syz155240 endwin(); 13362393Syz155240 initscr(); 13372393Syz155240 cbreak(); 13382393Syz155240 noecho(); 13392393Syz155240 curs_set(0); 13402393Syz155240 timeout(0); 13412393Syz155240 getmaxyx(stdscr, maxy, maxx); 13422393Syz155240 redraw = 1; 13432393Syz155240 handle_resize = 0; 13442393Syz155240 } 13452393Syz155240 13462393Syz155240 /* stop program? */ 13472393Syz155240 if (handle_break) 13482393Syz155240 break; 13490Sstevel@tonic-gate 13500Sstevel@tonic-gate /* print title */ 13510Sstevel@tonic-gate erase(); 13520Sstevel@tonic-gate attron(A_BOLD); 13532393Syz155240 winy = 0; 13542393Syz155240 move(winy,0); 13550Sstevel@tonic-gate sprintf(str1, "%s - %s - state top", hostnm, IPL_VERSION); 13560Sstevel@tonic-gate for (j = 0 ; j < (maxx - 8 - strlen(str1)) / 2; j++) 13570Sstevel@tonic-gate printw(" "); 13580Sstevel@tonic-gate printw("%s", str1); 13590Sstevel@tonic-gate attroff(A_BOLD); 13600Sstevel@tonic-gate 13610Sstevel@tonic-gate /* just for fun add a clock */ 13622393Syz155240 move(winy, maxx - 8); 13630Sstevel@tonic-gate t = time(NULL); 13640Sstevel@tonic-gate strftime(str1, 80, "%T", localtime(&t)); 13650Sstevel@tonic-gate printw("%s\n", str1); 13660Sstevel@tonic-gate 13670Sstevel@tonic-gate /* 13682393Syz155240 * print the display filters, this is placed in the loop, 13690Sstevel@tonic-gate * because someday I might add code for changing these 13700Sstevel@tonic-gate * while the programming is running :-) 13710Sstevel@tonic-gate */ 13720Sstevel@tonic-gate if (sport >= 0) 13732393Syz155240 sprintf(str1, "%s,%d", getip(ver, &saddr), sport); 13740Sstevel@tonic-gate else 13752393Syz155240 sprintf(str1, "%s", getip(ver, &saddr)); 13760Sstevel@tonic-gate 13770Sstevel@tonic-gate if (dport >= 0) 13782393Syz155240 sprintf(str2, "%s,%d", getip(ver, &daddr), dport); 13790Sstevel@tonic-gate else 13802393Syz155240 sprintf(str2, "%s", getip(ver, &daddr)); 13810Sstevel@tonic-gate 13820Sstevel@tonic-gate if (protocol < 0) 13830Sstevel@tonic-gate strcpy(str3, "any"); 13840Sstevel@tonic-gate else if ((proto = getprotobynumber(protocol)) != NULL) 13852393Syz155240 sprintf(str3, "%s", proto->p_name); 13860Sstevel@tonic-gate else 13870Sstevel@tonic-gate sprintf(str3, "%d", protocol); 13880Sstevel@tonic-gate 13890Sstevel@tonic-gate switch (sorting) 13900Sstevel@tonic-gate { 13910Sstevel@tonic-gate case STSORT_PR: 13920Sstevel@tonic-gate sprintf(str4, "proto"); 13930Sstevel@tonic-gate break; 13940Sstevel@tonic-gate case STSORT_PKTS: 13950Sstevel@tonic-gate sprintf(str4, "# pkts"); 13960Sstevel@tonic-gate break; 13970Sstevel@tonic-gate case STSORT_BYTES: 13980Sstevel@tonic-gate sprintf(str4, "# bytes"); 13990Sstevel@tonic-gate break; 14000Sstevel@tonic-gate case STSORT_TTL: 14010Sstevel@tonic-gate sprintf(str4, "ttl"); 14020Sstevel@tonic-gate break; 14030Sstevel@tonic-gate case STSORT_SRCIP: 14042393Syz155240 sprintf(str4, "src ip"); 14052393Syz155240 break; 14062393Syz155240 case STSORT_SRCPT: 14072393Syz155240 sprintf(str4, "src port"); 14080Sstevel@tonic-gate break; 14090Sstevel@tonic-gate case STSORT_DSTIP: 14102393Syz155240 sprintf(str4, "dest ip"); 14112393Syz155240 break; 14122393Syz155240 case STSORT_DSTPT: 14132393Syz155240 sprintf(str4, "dest port"); 14140Sstevel@tonic-gate break; 14150Sstevel@tonic-gate default: 14160Sstevel@tonic-gate sprintf(str4, "unknown"); 14170Sstevel@tonic-gate break; 14180Sstevel@tonic-gate } 14190Sstevel@tonic-gate 14200Sstevel@tonic-gate if (reverse) 14210Sstevel@tonic-gate strcat(str4, " (reverse)"); 14220Sstevel@tonic-gate 14232393Syz155240 winy += 2; 14242393Syz155240 move(winy,0); 14252393Syz155240 printw("Src: %s, Dest: %s, Proto: %s, Sorted by: %s\n\n", 14260Sstevel@tonic-gate str1, str2, str3, str4); 14270Sstevel@tonic-gate 14282393Syz155240 /* 14292393Syz155240 * For an IPv4 IP address we need at most 15 characters, 14302393Syz155240 * 4 tuples of 3 digits, separated by 3 dots. Enforce this 14312393Syz155240 * length, so the colums do not change positions based 14322393Syz155240 * on the size of the IP address. This length makes the 14332393Syz155240 * output fit in a 80 column terminal. 14342393Syz155240 * We are lacking a good solution for IPv6 addresses (that 14352393Syz155240 * can be longer that 15 characters), so we do not enforce 14362393Syz155240 * a maximum on the IP field size. 14372393Syz155240 */ 14382393Syz155240 if (srclen < 15) 14392393Syz155240 srclen = 15; 14402393Syz155240 if (dstlen < 15) 14412393Syz155240 dstlen = 15; 14422393Syz155240 14430Sstevel@tonic-gate /* print column description */ 14442393Syz155240 winy += 2; 14452393Syz155240 move(winy,0); 14460Sstevel@tonic-gate attron(A_BOLD); 14472393Syz155240 printw("%-*s %-*s %3s %4s %7s %9s %9s\n", 14482393Syz155240 srclen + 6, "Source IP", dstlen + 6, "Destination IP", 14492393Syz155240 "ST", "PR", "#pkts", "#bytes", "ttl"); 14500Sstevel@tonic-gate attroff(A_BOLD); 14510Sstevel@tonic-gate 14520Sstevel@tonic-gate /* print all the entries */ 14530Sstevel@tonic-gate tp = tstable; 14540Sstevel@tonic-gate if (reverse) 14550Sstevel@tonic-gate tp += tsentry; 14560Sstevel@tonic-gate 14570Sstevel@tonic-gate if (tsentry > maxy - 6) 14580Sstevel@tonic-gate tsentry = maxy - 6; 14590Sstevel@tonic-gate for (i = 0; i <= tsentry; i++) { 14600Sstevel@tonic-gate /* print src/dest and port */ 14610Sstevel@tonic-gate if ((tp->st_p == IPPROTO_TCP) || 14620Sstevel@tonic-gate (tp->st_p == IPPROTO_UDP)) { 14630Sstevel@tonic-gate sprintf(str1, "%s,%hu", 14642393Syz155240 getip(tp->st_v, &tp->st_src), 14650Sstevel@tonic-gate ntohs(tp->st_sport)); 14660Sstevel@tonic-gate sprintf(str2, "%s,%hu", 14672393Syz155240 getip(tp->st_v, &tp->st_dst), 14680Sstevel@tonic-gate ntohs(tp->st_dport)); 14690Sstevel@tonic-gate } else { 14702393Syz155240 sprintf(str1, "%s", getip(tp->st_v, 14712393Syz155240 &tp->st_src)); 14722393Syz155240 sprintf(str2, "%s", getip(tp->st_v, 14732393Syz155240 &tp->st_dst)); 14740Sstevel@tonic-gate } 14752393Syz155240 winy++; 14762393Syz155240 move(winy, 0); 14772393Syz155240 printw("%-*s %-*s", srclen + 6, str1, dstlen + 6, str2); 14780Sstevel@tonic-gate 14790Sstevel@tonic-gate /* print state */ 14800Sstevel@tonic-gate sprintf(str1, "%X/%X", tp->st_state[0], 14810Sstevel@tonic-gate tp->st_state[1]); 14820Sstevel@tonic-gate printw(" %3s", str1); 14830Sstevel@tonic-gate 14842393Syz155240 /* print protocol */ 14850Sstevel@tonic-gate proto = getprotobynumber(tp->st_p); 14860Sstevel@tonic-gate if (proto) { 14870Sstevel@tonic-gate strncpy(str1, proto->p_name, 4); 14880Sstevel@tonic-gate str1[4] = '\0'; 14890Sstevel@tonic-gate } else { 14900Sstevel@tonic-gate sprintf(str1, "%d", tp->st_p); 14910Sstevel@tonic-gate } 14922393Syz155240 /* just print icmp for IPv6-ICMP */ 14932393Syz155240 if (tp->st_p == IPPROTO_ICMPV6) 14942393Syz155240 strcpy(str1, "icmp"); 14950Sstevel@tonic-gate printw(" %4s", str1); 14962393Syz155240 14972393Syz155240 /* print #pkt/#bytes */ 14980Sstevel@tonic-gate #ifdef USE_QUAD_T 14990Sstevel@tonic-gate printw(" %7qu %9qu", (unsigned long long) tp->st_pkts, 15000Sstevel@tonic-gate (unsigned long long) tp->st_bytes); 15010Sstevel@tonic-gate #else 15020Sstevel@tonic-gate printw(" %7lu %9lu", tp->st_pkts, tp->st_bytes); 15030Sstevel@tonic-gate #endif 15040Sstevel@tonic-gate printw(" %9s", ttl_to_string(tp->st_age)); 15050Sstevel@tonic-gate 15060Sstevel@tonic-gate if (reverse) 15070Sstevel@tonic-gate tp--; 15080Sstevel@tonic-gate else 15090Sstevel@tonic-gate tp++; 15100Sstevel@tonic-gate } 15110Sstevel@tonic-gate 15120Sstevel@tonic-gate /* screen data structure is filled, now update the screen */ 15130Sstevel@tonic-gate if (redraw) 15140Sstevel@tonic-gate clearok(stdscr,1); 15150Sstevel@tonic-gate 15162393Syz155240 if (refresh() == ERR) 15172393Syz155240 break; 15180Sstevel@tonic-gate if (redraw) { 15190Sstevel@tonic-gate clearok(stdscr,0); 15200Sstevel@tonic-gate redraw = 0; 15210Sstevel@tonic-gate } 15220Sstevel@tonic-gate 15230Sstevel@tonic-gate /* wait for key press or a 1 second time out period */ 15240Sstevel@tonic-gate selecttimeout.tv_sec = refreshtime; 15250Sstevel@tonic-gate selecttimeout.tv_usec = 0; 15260Sstevel@tonic-gate FD_ZERO(&readfd); 15270Sstevel@tonic-gate FD_SET(0, &readfd); 15280Sstevel@tonic-gate select(1, &readfd, NULL, NULL, &selecttimeout); 15290Sstevel@tonic-gate 15300Sstevel@tonic-gate /* if key pressed, read all waiting keys */ 15310Sstevel@tonic-gate if (FD_ISSET(0, &readfd)) { 15320Sstevel@tonic-gate c = wgetch(stdscr); 15330Sstevel@tonic-gate if (c == ERR) 15340Sstevel@tonic-gate continue; 15350Sstevel@tonic-gate 15362393Syz155240 if (ISALPHA(c) && ISUPPER(c)) 15372393Syz155240 c = TOLOWER(c); 15382393Syz155240 if (c == 'l') { 15390Sstevel@tonic-gate redraw = 1; 15402393Syz155240 } else if (c == 'q') { 15411448Sschuster break; 15422393Syz155240 } else if (c == 'r') { 15430Sstevel@tonic-gate reverse = !reverse; 15442393Syz155240 } else if (c == 'b') { 15452393Syz155240 forward = 0; 15462393Syz155240 } else if (c == 'f') { 15472393Syz155240 forward = 1; 15482393Syz155240 } else if (c == 's') { 15492393Syz155240 if (++sorting > STSORT_MAX) 15500Sstevel@tonic-gate sorting = 0; 15510Sstevel@tonic-gate } 15520Sstevel@tonic-gate } 15530Sstevel@tonic-gate } /* while */ 15540Sstevel@tonic-gate 15552393Syz155240 out: 15560Sstevel@tonic-gate printw("\n"); 15574985San207044 refresh(); 15580Sstevel@tonic-gate endwin(); 15592393Syz155240 free(tstable); 15602393Syz155240 if (ret != 0) 15612393Syz155240 perror(errstr); 15620Sstevel@tonic-gate } 15630Sstevel@tonic-gate #endif 15640Sstevel@tonic-gate 15650Sstevel@tonic-gate 15660Sstevel@tonic-gate /* 15670Sstevel@tonic-gate * Show fragment cache information that's held in the kernel. 15680Sstevel@tonic-gate */ 15690Sstevel@tonic-gate static void showfrstates(ifsp) 15700Sstevel@tonic-gate ipfrstat_t *ifsp; 15710Sstevel@tonic-gate { 15720Sstevel@tonic-gate struct ipfr *ipfrtab[IPFT_SIZE], ifr; 15730Sstevel@tonic-gate int i; 15740Sstevel@tonic-gate 15750Sstevel@tonic-gate /* 15760Sstevel@tonic-gate * print out the numeric statistics 15770Sstevel@tonic-gate */ 15780Sstevel@tonic-gate PRINTF("IP fragment states:\n\t%lu new\n\t%lu expired\n\t%lu hits\n", 15790Sstevel@tonic-gate ifsp->ifs_new, ifsp->ifs_expire, ifsp->ifs_hits); 15802393Syz155240 PRINTF("\t%lu retrans\n\t%lu too short\n", 15812393Syz155240 ifsp->ifs_retrans0, ifsp->ifs_short); 15820Sstevel@tonic-gate PRINTF("\t%lu no memory\n\t%lu already exist\n", 15830Sstevel@tonic-gate ifsp->ifs_nomem, ifsp->ifs_exists); 15840Sstevel@tonic-gate PRINTF("\t%lu inuse\n", ifsp->ifs_inuse); 15850Sstevel@tonic-gate if (kmemcpy((char *)ipfrtab, (u_long)ifsp->ifs_table, sizeof(ipfrtab))) 15860Sstevel@tonic-gate return; 15870Sstevel@tonic-gate 15880Sstevel@tonic-gate /* 15890Sstevel@tonic-gate * Print out the contents (if any) of the fragment cache table. 15900Sstevel@tonic-gate */ 15912393Syz155240 PRINTF("\n"); 15920Sstevel@tonic-gate for (i = 0; i < IPFT_SIZE; i++) 15932393Syz155240 while (ipfrtab[i] != NULL) { 15940Sstevel@tonic-gate if (kmemcpy((char *)&ifr, (u_long)ipfrtab[i], 15950Sstevel@tonic-gate sizeof(ifr)) == -1) 15960Sstevel@tonic-gate break; 15972393Syz155240 printfraginfo("", &ifr); 15980Sstevel@tonic-gate ipfrtab[i] = ifr.ipfr_next; 15990Sstevel@tonic-gate } 16002393Syz155240 /* 16012393Syz155240 * Print out the contents (if any) of the NAT fragment cache table. 16022393Syz155240 */ 16030Sstevel@tonic-gate if (kmemcpy((char *)ipfrtab, (u_long)ifsp->ifs_nattab,sizeof(ipfrtab))) 16040Sstevel@tonic-gate return; 16050Sstevel@tonic-gate for (i = 0; i < IPFT_SIZE; i++) 16062393Syz155240 while (ipfrtab[i] != NULL) { 16070Sstevel@tonic-gate if (kmemcpy((char *)&ifr, (u_long)ipfrtab[i], 16080Sstevel@tonic-gate sizeof(ifr)) == -1) 16090Sstevel@tonic-gate break; 16102393Syz155240 printfraginfo("NAT: ", &ifr); 16110Sstevel@tonic-gate ipfrtab[i] = ifr.ipfr_next; 16120Sstevel@tonic-gate } 16130Sstevel@tonic-gate } 16140Sstevel@tonic-gate 16150Sstevel@tonic-gate 16160Sstevel@tonic-gate /* 16170Sstevel@tonic-gate * Show stats on how auth within IPFilter has been used 16180Sstevel@tonic-gate */ 16190Sstevel@tonic-gate static void showauthstates(asp) 16200Sstevel@tonic-gate fr_authstat_t *asp; 16210Sstevel@tonic-gate { 16220Sstevel@tonic-gate frauthent_t *frap, fra; 16230Sstevel@tonic-gate 16240Sstevel@tonic-gate #ifdef USE_QUAD_T 16250Sstevel@tonic-gate printf("Authorisation hits: %qu\tmisses %qu\n", 16260Sstevel@tonic-gate (unsigned long long) asp->fas_hits, 16270Sstevel@tonic-gate (unsigned long long) asp->fas_miss); 16280Sstevel@tonic-gate #else 16290Sstevel@tonic-gate printf("Authorisation hits: %ld\tmisses %ld\n", asp->fas_hits, 16300Sstevel@tonic-gate asp->fas_miss); 16310Sstevel@tonic-gate #endif 16320Sstevel@tonic-gate printf("nospace %ld\nadded %ld\nsendfail %ld\nsendok %ld\n", 16330Sstevel@tonic-gate asp->fas_nospace, asp->fas_added, asp->fas_sendfail, 16340Sstevel@tonic-gate asp->fas_sendok); 16350Sstevel@tonic-gate printf("queok %ld\nquefail %ld\nexpire %ld\n", 16360Sstevel@tonic-gate asp->fas_queok, asp->fas_quefail, asp->fas_expire); 16370Sstevel@tonic-gate 16380Sstevel@tonic-gate frap = asp->fas_faelist; 16390Sstevel@tonic-gate while (frap) { 16400Sstevel@tonic-gate if (kmemcpy((char *)&fra, (u_long)frap, sizeof(fra)) == -1) 16410Sstevel@tonic-gate break; 16420Sstevel@tonic-gate 16430Sstevel@tonic-gate printf("age %ld\t", fra.fae_age); 16440Sstevel@tonic-gate printfr(&fra.fae_fr, ioctl); 16450Sstevel@tonic-gate frap = fra.fae_next; 16460Sstevel@tonic-gate } 16470Sstevel@tonic-gate } 16480Sstevel@tonic-gate 16490Sstevel@tonic-gate 16500Sstevel@tonic-gate /* 16510Sstevel@tonic-gate * Display groups used for each of filter rules, accounting rules and 16520Sstevel@tonic-gate * authentication, separately. 16530Sstevel@tonic-gate */ 16540Sstevel@tonic-gate static void showgroups(fiop) 16550Sstevel@tonic-gate struct friostat *fiop; 16560Sstevel@tonic-gate { 16570Sstevel@tonic-gate static char *gnames[3] = { "Filter", "Accounting", "Authentication" }; 16582393Syz155240 static int gnums[3] = { IPL_LOGIPF, IPL_LOGCOUNT, IPL_LOGAUTH }; 16590Sstevel@tonic-gate frgroup_t *fp, grp; 16600Sstevel@tonic-gate int on, off, i; 16610Sstevel@tonic-gate 16620Sstevel@tonic-gate on = fiop->f_active; 16630Sstevel@tonic-gate off = 1 - on; 16640Sstevel@tonic-gate 16650Sstevel@tonic-gate for (i = 0; i < 3; i++) { 16660Sstevel@tonic-gate printf("%s groups (active):\n", gnames[i]); 16672393Syz155240 for (fp = fiop->f_groups[gnums[i]][on]; fp != NULL; 16682393Syz155240 fp = grp.fg_next) 16690Sstevel@tonic-gate if (kmemcpy((char *)&grp, (u_long)fp, sizeof(grp))) 16700Sstevel@tonic-gate break; 16710Sstevel@tonic-gate else 16720Sstevel@tonic-gate printf("%s\n", grp.fg_name); 16730Sstevel@tonic-gate printf("%s groups (inactive):\n", gnames[i]); 16742393Syz155240 for (fp = fiop->f_groups[gnums[i]][off]; fp != NULL; 16752393Syz155240 fp = grp.fg_next) 16760Sstevel@tonic-gate if (kmemcpy((char *)&grp, (u_long)fp, sizeof(grp))) 16770Sstevel@tonic-gate break; 16780Sstevel@tonic-gate else 16790Sstevel@tonic-gate printf("%s\n", grp.fg_name); 16800Sstevel@tonic-gate } 16810Sstevel@tonic-gate } 16820Sstevel@tonic-gate 16830Sstevel@tonic-gate static void parse_ipportstr(argument, ip, port) 16840Sstevel@tonic-gate const char *argument; 16852393Syz155240 i6addr_t *ip; 16860Sstevel@tonic-gate int *port; 16870Sstevel@tonic-gate { 16880Sstevel@tonic-gate char *s, *comma; 16892393Syz155240 int ok = 0; 16900Sstevel@tonic-gate 16910Sstevel@tonic-gate /* make working copy of argument, Theoretically you must be able 16920Sstevel@tonic-gate * to write to optarg, but that seems very ugly to me.... 16930Sstevel@tonic-gate */ 16940Sstevel@tonic-gate s = strdup(argument); 16950Sstevel@tonic-gate if (s == NULL) 16960Sstevel@tonic-gate return; 16970Sstevel@tonic-gate 16980Sstevel@tonic-gate /* get port */ 16990Sstevel@tonic-gate if ((comma = strchr(s, ',')) != NULL) { 17000Sstevel@tonic-gate if (!strcasecmp(comma + 1, "any")) { 17010Sstevel@tonic-gate *port = -1; 17020Sstevel@tonic-gate } else if (!sscanf(comma + 1, "%d", port) || 17030Sstevel@tonic-gate (*port < 0) || (*port > 65535)) { 17040Sstevel@tonic-gate fprintf(stderr, "Invalid port specfication in %s\n", 17050Sstevel@tonic-gate argument); 17060Sstevel@tonic-gate free(s); 17070Sstevel@tonic-gate exit(-2); 17080Sstevel@tonic-gate } 17090Sstevel@tonic-gate *comma = '\0'; 17100Sstevel@tonic-gate } 17110Sstevel@tonic-gate 17120Sstevel@tonic-gate 17130Sstevel@tonic-gate /* get ip address */ 17140Sstevel@tonic-gate if (!strcasecmp(s, "any")) { 17152393Syz155240 ip->in4.s_addr = INADDR_ANY; 17162393Syz155240 #ifdef USE_INET6 17172393Syz155240 ip->in6 = in6addr_any; 17182393Syz155240 } else if (use_inet6 && inet_pton(AF_INET6, s, &ip->in6)) { 17192393Syz155240 ok = 1; 17202393Syz155240 #endif 17212393Syz155240 } else if (inet_aton(s, &ip->in4)) 17222393Syz155240 ok = 1; 17232393Syz155240 17242393Syz155240 if (ok == 0) { 17250Sstevel@tonic-gate fprintf(stderr, "Invalid IP address: %s\n", s); 17260Sstevel@tonic-gate free(s); 17270Sstevel@tonic-gate exit(-2); 17280Sstevel@tonic-gate } 17290Sstevel@tonic-gate 17300Sstevel@tonic-gate /* free allocated memory */ 17310Sstevel@tonic-gate free(s); 17320Sstevel@tonic-gate } 17330Sstevel@tonic-gate 17340Sstevel@tonic-gate 17350Sstevel@tonic-gate #ifdef STATETOP 17362393Syz155240 static void sig_resize(s) 17372393Syz155240 int s; 17382393Syz155240 { 17392393Syz155240 handle_resize = 1; 17402393Syz155240 } 17412393Syz155240 17422393Syz155240 static void sig_break(s) 17432393Syz155240 int s; 17442393Syz155240 { 17452393Syz155240 handle_break = 1; 17462393Syz155240 } 17472393Syz155240 17482393Syz155240 static char *getip(v, addr) 17492393Syz155240 int v; 17502393Syz155240 i6addr_t *addr; 17512393Syz155240 { 17522393Syz155240 #ifdef USE_INET6 17532393Syz155240 static char hostbuf[MAXHOSTNAMELEN+1]; 17542393Syz155240 #endif 17552393Syz155240 17562393Syz155240 if (v == 4) 17572393Syz155240 return inet_ntoa(addr->in4); 17582393Syz155240 17592393Syz155240 #ifdef USE_INET6 17602393Syz155240 (void) inet_ntop(AF_INET6, &addr->in6, hostbuf, sizeof(hostbuf) - 1); 17612393Syz155240 hostbuf[MAXHOSTNAMELEN] = '\0'; 17622393Syz155240 return hostbuf; 17632393Syz155240 #else 17642393Syz155240 return "IPv6"; 17652393Syz155240 #endif 17662393Syz155240 } 17672393Syz155240 17680Sstevel@tonic-gate 17690Sstevel@tonic-gate static char *ttl_to_string(ttl) 17700Sstevel@tonic-gate long int ttl; 17710Sstevel@tonic-gate { 17722393Syz155240 static char ttlbuf[STSTRSIZE]; 17730Sstevel@tonic-gate int hours, minutes, seconds; 17740Sstevel@tonic-gate 17750Sstevel@tonic-gate /* ttl is in half seconds */ 17760Sstevel@tonic-gate ttl /= 2; 17770Sstevel@tonic-gate 17780Sstevel@tonic-gate hours = ttl / 3600; 17790Sstevel@tonic-gate ttl = ttl % 3600; 17800Sstevel@tonic-gate minutes = ttl / 60; 17810Sstevel@tonic-gate seconds = ttl % 60; 17820Sstevel@tonic-gate 17832393Syz155240 if (hours > 0) 17840Sstevel@tonic-gate sprintf(ttlbuf, "%2d:%02d:%02d", hours, minutes, seconds); 17850Sstevel@tonic-gate else 17860Sstevel@tonic-gate sprintf(ttlbuf, "%2d:%02d", minutes, seconds); 17870Sstevel@tonic-gate return ttlbuf; 17880Sstevel@tonic-gate } 17890Sstevel@tonic-gate 17900Sstevel@tonic-gate 17910Sstevel@tonic-gate static int sort_pkts(a, b) 17920Sstevel@tonic-gate const void *a; 17930Sstevel@tonic-gate const void *b; 17940Sstevel@tonic-gate { 17950Sstevel@tonic-gate 17960Sstevel@tonic-gate register const statetop_t *ap = a; 17970Sstevel@tonic-gate register const statetop_t *bp = b; 17980Sstevel@tonic-gate 17990Sstevel@tonic-gate if (ap->st_pkts == bp->st_pkts) 18000Sstevel@tonic-gate return 0; 18010Sstevel@tonic-gate else if (ap->st_pkts < bp->st_pkts) 18020Sstevel@tonic-gate return 1; 18030Sstevel@tonic-gate return -1; 18040Sstevel@tonic-gate } 18050Sstevel@tonic-gate 18060Sstevel@tonic-gate 18070Sstevel@tonic-gate static int sort_bytes(a, b) 18080Sstevel@tonic-gate const void *a; 18090Sstevel@tonic-gate const void *b; 18100Sstevel@tonic-gate { 18110Sstevel@tonic-gate register const statetop_t *ap = a; 18120Sstevel@tonic-gate register const statetop_t *bp = b; 18130Sstevel@tonic-gate 18140Sstevel@tonic-gate if (ap->st_bytes == bp->st_bytes) 18150Sstevel@tonic-gate return 0; 18160Sstevel@tonic-gate else if (ap->st_bytes < bp->st_bytes) 18170Sstevel@tonic-gate return 1; 18180Sstevel@tonic-gate return -1; 18190Sstevel@tonic-gate } 18200Sstevel@tonic-gate 18210Sstevel@tonic-gate 18220Sstevel@tonic-gate static int sort_p(a, b) 18230Sstevel@tonic-gate const void *a; 18240Sstevel@tonic-gate const void *b; 18250Sstevel@tonic-gate { 18260Sstevel@tonic-gate register const statetop_t *ap = a; 18270Sstevel@tonic-gate register const statetop_t *bp = b; 18280Sstevel@tonic-gate 18290Sstevel@tonic-gate if (ap->st_p == bp->st_p) 18300Sstevel@tonic-gate return 0; 18310Sstevel@tonic-gate else if (ap->st_p < bp->st_p) 18320Sstevel@tonic-gate return 1; 18330Sstevel@tonic-gate return -1; 18340Sstevel@tonic-gate } 18350Sstevel@tonic-gate 18360Sstevel@tonic-gate 18370Sstevel@tonic-gate static int sort_ttl(a, b) 18380Sstevel@tonic-gate const void *a; 18390Sstevel@tonic-gate const void *b; 18400Sstevel@tonic-gate { 18410Sstevel@tonic-gate register const statetop_t *ap = a; 18420Sstevel@tonic-gate register const statetop_t *bp = b; 18430Sstevel@tonic-gate 18440Sstevel@tonic-gate if (ap->st_age == bp->st_age) 18450Sstevel@tonic-gate return 0; 18460Sstevel@tonic-gate else if (ap->st_age < bp->st_age) 18470Sstevel@tonic-gate return 1; 18480Sstevel@tonic-gate return -1; 18490Sstevel@tonic-gate } 18500Sstevel@tonic-gate 18510Sstevel@tonic-gate static int sort_srcip(a, b) 18520Sstevel@tonic-gate const void *a; 18530Sstevel@tonic-gate const void *b; 18540Sstevel@tonic-gate { 18550Sstevel@tonic-gate register const statetop_t *ap = a; 18560Sstevel@tonic-gate register const statetop_t *bp = b; 18570Sstevel@tonic-gate 18582393Syz155240 #ifdef USE_INET6 18592393Syz155240 if (use_inet6) { 18602393Syz155240 if (IP6_EQ(&ap->st_src, &bp->st_src)) 18612393Syz155240 return 0; 18622393Syz155240 else if (IP6_GT(&ap->st_src, &bp->st_src)) 18632393Syz155240 return 1; 18642393Syz155240 } else 18652393Syz155240 #endif 18662393Syz155240 { 18672393Syz155240 if (ntohl(ap->st_src.in4.s_addr) == 18682393Syz155240 ntohl(bp->st_src.in4.s_addr)) 18692393Syz155240 return 0; 18702393Syz155240 else if (ntohl(ap->st_src.in4.s_addr) > 18712393Syz155240 ntohl(bp->st_src.in4.s_addr)) 18722393Syz155240 return 1; 18732393Syz155240 } 18742393Syz155240 return -1; 18752393Syz155240 } 18762393Syz155240 18772393Syz155240 static int sort_srcpt(a, b) 18782393Syz155240 const void *a; 18792393Syz155240 const void *b; 18802393Syz155240 { 18812393Syz155240 register const statetop_t *ap = a; 18822393Syz155240 register const statetop_t *bp = b; 18832393Syz155240 18842393Syz155240 if (htons(ap->st_sport) == htons(bp->st_sport)) 18850Sstevel@tonic-gate return 0; 18862393Syz155240 else if (htons(ap->st_sport) > htons(bp->st_sport)) 18870Sstevel@tonic-gate return 1; 18880Sstevel@tonic-gate return -1; 18890Sstevel@tonic-gate } 18900Sstevel@tonic-gate 18910Sstevel@tonic-gate static int sort_dstip(a, b) 18920Sstevel@tonic-gate const void *a; 18930Sstevel@tonic-gate const void *b; 18940Sstevel@tonic-gate { 18950Sstevel@tonic-gate register const statetop_t *ap = a; 18960Sstevel@tonic-gate register const statetop_t *bp = b; 18970Sstevel@tonic-gate 18982393Syz155240 #ifdef USE_INET6 18992393Syz155240 if (use_inet6) { 19002393Syz155240 if (IP6_EQ(&ap->st_dst, &bp->st_dst)) 19012393Syz155240 return 0; 19022393Syz155240 else if (IP6_GT(&ap->st_dst, &bp->st_dst)) 19032393Syz155240 return 1; 19042393Syz155240 } else 19052393Syz155240 #endif 19062393Syz155240 { 19072393Syz155240 if (ntohl(ap->st_dst.in4.s_addr) == 19082393Syz155240 ntohl(bp->st_dst.in4.s_addr)) 19092393Syz155240 return 0; 19102393Syz155240 else if (ntohl(ap->st_dst.in4.s_addr) > 19112393Syz155240 ntohl(bp->st_dst.in4.s_addr)) 19122393Syz155240 return 1; 19132393Syz155240 } 19142393Syz155240 return -1; 19152393Syz155240 } 19162393Syz155240 19172393Syz155240 static int sort_dstpt(a, b) 19182393Syz155240 const void *a; 19192393Syz155240 const void *b; 19202393Syz155240 { 19212393Syz155240 register const statetop_t *ap = a; 19222393Syz155240 register const statetop_t *bp = b; 19232393Syz155240 19242393Syz155240 if (htons(ap->st_dport) == htons(bp->st_dport)) 19250Sstevel@tonic-gate return 0; 19262393Syz155240 else if (htons(ap->st_dport) > htons(bp->st_dport)) 19270Sstevel@tonic-gate return 1; 19280Sstevel@tonic-gate return -1; 19290Sstevel@tonic-gate } 19302393Syz155240 19310Sstevel@tonic-gate #endif 1932