1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * Copyright (c) 2018, Joyent, Inc. 28 */ 29 30 #include "statcommon.h" 31 32 #include <sys/types.h> 33 #include <stdlib.h> 34 #include <ctype.h> 35 #include <stdio.h> 36 #include <bsm/audit.h> 37 #include <bsm/libbsm.h> 38 #include <unistd.h> 39 #include <locale.h> 40 41 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 42 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it isn't */ 43 #endif 44 45 46 /* 47 * Display header every HEADER_MOD lines printed 48 */ 49 #define DFLT_HEADER_MOD (20) 50 #define ONEK (1024) 51 52 #define CFLG (0x01) 53 #define HFLG (0x02) 54 #define IFLG (0x04) 55 #define NFLG (0x08) 56 #define VFLG (0x10) 57 58 extern char *optarg; 59 60 static int count; 61 static int flags; 62 static int header_mod = DFLT_HEADER_MOD; 63 static int interval; 64 static uint_t timestamp_fmt = NODATE; 65 66 static void display_stats(); 67 static void eauditon(); 68 static void parse_args(); 69 static void usage_exit(); 70 static int strisdigit(); 71 72 int 73 main(argc, argv) 74 int argc; 75 char **argv; 76 { 77 register int i; 78 au_stat_t s; 79 80 (void) setlocale(LC_ALL, ""); 81 (void) textdomain(TEXT_DOMAIN); 82 83 (void) setbuf(stdout, (char *)0); 84 (void) setbuf(stderr, (char *)0); 85 86 parse_args(argc, argv); 87 88 if (!flags) { 89 eauditon(A_GETSTAT, (caddr_t)&s, NULL); 90 if (timestamp_fmt != NODATE) 91 print_timestamp(timestamp_fmt); 92 display_stats(&s, 0); 93 exit(0); 94 } 95 96 if (flags & VFLG || flags & NFLG) 97 eauditon(A_GETSTAT, (caddr_t)&s, NULL); 98 99 if (flags & VFLG) 100 (void) printf("version = %d\n", s.as_version); 101 102 if (flags & NFLG) 103 (void) printf("number of kernel events = %d\n", s.as_numevent); 104 105 if (!(flags & IFLG)) 106 exit(0); 107 108 /* CSTYLED */ 109 for (i = 0;; i++) { 110 eauditon(A_GETSTAT, (caddr_t)&s, NULL); 111 if (timestamp_fmt != NODATE) 112 print_timestamp(timestamp_fmt); 113 display_stats(&s, i); 114 if ((flags & CFLG) && count) 115 if (i == count - 1) 116 break; 117 (void) sleep(interval); 118 } 119 120 return (0); 121 } 122 123 124 static void 125 display_stats(au_stat_t *s, int cnt) 126 { 127 int offset[12]; /* used to line the header up correctly */ 128 char buf[512]; 129 130 (void) sprintf(buf, 131 "%4u %n%4u %n%4u %n%4u %n%4u %n%4u %n%4u %n%4u %n%4u %n%4u %n%4u %n%4u%n", 132 s->as_generated, &(offset[0]), 133 s->as_nonattrib, &(offset[1]), 134 s->as_kernel, &(offset[2]), 135 s->as_audit, &(offset[3]), 136 s->as_auditctl, &(offset[4]), 137 s->as_enqueue, &(offset[5]), 138 s->as_written, &(offset[6]), 139 s->as_wblocked, &(offset[7]), 140 s->as_rblocked, &(offset[8]), 141 s->as_dropped, &(offset[9]), 142 s->as_totalsize / ONEK, &(offset[10]), 143 s->as_memused / ONEK, &(offset[11])); 144 145 /* print a properly aligned header every HEADER_MOD lines */ 146 if (header_mod && (!cnt || ((timestamp_fmt != NODATE) ? 147 !(cnt % (header_mod / 2)) : !(cnt % header_mod)))) { 148 (void) printf( 149 "%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s\n", 150 offset[0] - 1, "gen", 151 offset[1] - offset[0] - 1, "nona", 152 offset[2] - offset[1] - 1, "kern", 153 offset[3] - offset[2] - 1, "aud", 154 offset[4] - offset[3] - 1, "ctl", 155 offset[5] - offset[4] - 1, "enq", 156 offset[6] - offset[5] - 1, "wrtn", 157 offset[7] - offset[6] - 1, "wblk", 158 offset[8] - offset[7] - 1, "rblk", 159 offset[9] - offset[8] - 1, "drop", 160 offset[10] - offset[9] - 1, "tot", 161 offset[11] - offset[10], "mem"); 162 } 163 164 (void) puts(buf); 165 } 166 167 168 static void 169 eauditon(cmd, data, length) 170 int cmd; 171 caddr_t data; 172 int length; 173 { 174 if (auditon(cmd, data, length) == -1) { 175 perror("auditstat: auditon"); 176 exit(1); 177 } 178 } 179 180 181 static void 182 parse_args(argc, argv) 183 int argc; 184 char **argv; 185 { 186 int c; 187 188 while ((c = getopt(argc, argv, "c:h:i:vnT:")) != -1) { 189 switch (c) { 190 case 'c': 191 if (flags & CFLG) 192 usage_exit(); 193 flags |= CFLG; 194 if (strisdigit(optarg)) { 195 (void) fprintf(stderr, 196 "auditstat: invalid count specified.\n"); 197 exit(1); 198 } 199 count = atoi(optarg); 200 break; 201 case 'h': 202 if (flags & HFLG) 203 usage_exit(); 204 flags |= HFLG; 205 if (strisdigit(optarg)) { 206 (void) fprintf(stderr, 207 "auditstat: invalid header arg specified.\n"); 208 exit(1); 209 } 210 header_mod = atoi(optarg); 211 break; 212 case 'i': 213 if (flags & IFLG) 214 usage_exit(); 215 flags |= IFLG; 216 if (strisdigit(optarg)) { 217 (void) fprintf(stderr, 218 "auditstat: invalid interval specified.\n"); 219 exit(1); 220 } 221 interval = atoi(optarg); 222 break; 223 case 'n': 224 if (flags & NFLG) 225 usage_exit(); 226 flags |= NFLG; 227 break; 228 case 'v': 229 if (flags & VFLG) 230 usage_exit(); 231 flags |= VFLG; 232 break; 233 case 'T': 234 if (optarg) { 235 if (*optarg == 'u') 236 timestamp_fmt = UDATE; 237 else if (*optarg == 'd') 238 timestamp_fmt = DDATE; 239 else 240 usage_exit(); 241 } else { 242 usage_exit(); 243 } 244 break; 245 case '?': 246 default: 247 usage_exit(); 248 break; 249 } 250 } 251 } 252 253 254 static void 255 usage_exit() 256 { 257 (void) fprintf(stderr, 258 "auditstat: usage: auditstat [-c count] [-h lines] " 259 "[-T d|u] [-i interval] [-n] [-v]\n"); 260 exit(1); 261 } 262 263 264 static int 265 strisdigit(s) 266 char *s; 267 { 268 for (; *s; s++) 269 if (!isdigit(*s)) 270 return (1); 271 272 return (0); 273 } 274