#include #include #include #include #include #include #include #include #include "array.h" #include "intcnt.h" extern "C" { #include "error.h" } #include "utils.h" #define MINUTE_STEP 5 /* interval for displaying per-minute info */ #define SECOND_STEP 5 /* interval for displaying per-second info */ class procdata { public: intcnt month; intcnt dayofmonth; intcnt hour; intcnt minute; intcnt second; time_t prevts; intcnt freqs; char *procname; }; procdata **procs = NULL; int nprocs = 0; char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; time_t gen_time_t(int year, int month, int day, int hour, int minute, int seconds) { struct tm then; memset(&then, 0x00, sizeof(then)); then.tm_year = year; then.tm_mon = month; then.tm_mday = day; then.tm_hour = hour; then.tm_min = minute; then.tm_sec = seconds; return mktime(&then); } int split_line(char *in, int *year, int *month, int *day, int *hour, int *minute, int *seconds, char **proc, char **line) { char rc = 0; char *fields[6]; char *copy = mystrdup(in); int loop; /* format: * Mmm dd hh:mm:ss host proc[pid]: line * examples: * Oct 24 14:44:46 muur snort: spp_portscan: PORTSCAN DETECTED to port 4365 from 195.241.135.194 (STEALTH) * Oct 24 14:44:52 muur smbd[3059]: [2003/10/24 14:44:52, 0] smbd/oplock_linux.c:linux_init_kernel_oplocks(287) */ /* split line up into fields */ fields[0] = copy; for(;;) { char *dummy; for(loop=1; loop<6; loop++) { dummy = strchr(fields[loop-1] + 1, ' '); if (!dummy) { rc = -1; break; } *dummy = 0x00; dummy++; while(*dummy == ' ') dummy++; fields[loop] = dummy; } if (rc == -1) break; /* year unknown */ *year = 0; /* month */ for(*month=0; *month < 12; (*month)++) { if (strcmp(fields[0], months[*month]) == 0) break; } if (*month == 12) { rc = -1; break; } /* day */ *day = atoi(fields[1]); /* time */ *hour = atoi(fields[2]); *minute = atoi(&fields[2][3]); *seconds = atoi(&fields[2][6]); /* procname */ dummy = strchr(fields[4], '['); if (dummy) *dummy = 0x00; dummy = strchr(fields[4], ':'); if (dummy) *dummy = 0x00; *proc = mystrdup(fields[4]); /* description */ *line = mystrdup(©[fields[5] - fields[0]]); break; } free(copy); return rc; } int process_line(char *in) { int rc = 0; char *proc = NULL, *line = NULL; time_t now = time(NULL); struct tm *curtm = localtime(&now); for(;;) { int year, month, day, hour, minute, seconds; time_t curts; procdata *curproc = NULL; int loop; /* ignore '-- MARK --' lines */ if (strcmp(&in[strlen(in) - 10], "-- MARK --") == 0) break; /* ignore "last message repeated x times" lines */ if (strstr(in, "last message repeated ") != NULL && strcmp(&in[strlen(in) - 6], " times") == 0) break; /* split line in fields */ if (split_line(in, &year, &month, &day, &hour, &minute, &seconds, &proc, &line) != 0) { rc = -1; break; } /* gen timestamp */ year = curtm -> tm_year; curts = gen_time_t(year, month, day, hour, minute, seconds); /* update statistics if already known */ for(loop=0; loop procname, proc) == 0) { curproc = procs[loop]; /* calculate most popular interval */ (curproc -> freqs).add(curts - curproc -> prevts); curproc -> prevts = curts; break; } } /* add if new */ if (loop == nprocs) { nprocs++; procs = (procdata **)myrealloc(procs, nprocs * sizeof(procdata *), "procdata *"); procs[nprocs - 1] = new procdata; if (!procs[nprocs-1]) error_exit("cannot allocate procdata object"); curproc = procs[nprocs - 1]; curproc -> prevts = curts; curproc -> procname = strdup(proc); } (curproc -> month).add(month); (curproc -> dayofmonth).add(day); (curproc -> hour).add(hour); (curproc -> minute).add(minute); (curproc -> second).add(seconds); break; } free(proc); free(line); return rc; } void secondstostring(time_t ts, char *to) { sprintf(to, "%02d:%02d:%02d", ts / 3600, (ts / 60) % 60, ts % 60); } void show_frequency_tables(void) { int loop; printf("

Frequencies

\n"); printf("\n"); printf(""); for(loop=0; loop<5; loop++) printf(""); printf("\n"); for(loop=0; loop", procs[loop]-> procname); procs[loop] -> freqs.sort(); for(loop2=0; loop2 freqs.getn()); loop2++) { char buffer[128]; secondstostring(procs[loop] -> freqs.getvalue(loop2), buffer); printf("", buffer, procs[loop] -> freqs.getcnt(loop2)); } printf("\n"); } printf("
ProcessInterval / Frequency
%s%s / %d
\n"); } void show_topx_tables(void) { int loop; printf("

Top10 tables

\n"); /* count */ printf("

Months

\n"); printf("\n"); printf(""); for(loop=0; loop<5; loop++) printf(""); printf("\n"); for(int month=0; month<12; month++) { array *amonth = new array(1); for(loop=0; loop addstring(procs[loop] -> procname, procs[loop] -> month.getcntfromvalue(month)); amonth -> sort(0); printf("", months[month]); for(loop=0; loop getcounter(loop, 0) == -1) printf(""); else printf("", amonth -> getstring(loop), amonth -> getcounter(loop, 0)); printf("\n"); delete amonth; } printf("
MonthProcess [count]
%s%s [%d]
\n"); printf("
\n"); printf("

Day of month

\n"); printf("\n"); printf(""); for(loop=0; loop<5; loop++) printf(""); printf("\n"); for(int day=0; day<31; day++) { array *adayofmonth = new array(1); for(loop=0; loop addstring(procs[loop] -> procname, procs[loop] -> dayofmonth.getcntfromvalue(day)); adayofmonth -> sort(0); printf("", day + 1); for(loop=0; loop getcounter(loop, 0) == -1) printf(""); else printf("", adayofmonth -> getstring(loop), adayofmonth -> getcounter(loop, 0)); printf("\n"); delete adayofmonth; } printf("
DayProcess [count]
%d%s [%d]
\n"); printf("
\n"); printf("

Hour

\n"); printf("\n"); printf(""); for(loop=0; loop<5; loop++) printf(""); printf("\n"); for(int hour=0; hour<24; hour++) { array *ahour = new array(1); for(loop=0; loop addstring(procs[loop] -> procname, procs[loop] -> hour.getcntfromvalue(hour)); ahour -> sort(0); printf("", hour+1); for(loop=0; loop getcounter(loop, 0) == -1) printf(""); else printf("", ahour -> getstring(loop), ahour -> getcounter(loop, 0)); printf("\n"); delete ahour; } printf("
HourProcess [count]
%d%s [%d]
\n"); printf("
\n"); printf("

Minute

\n"); printf("\n"); printf(""); for(loop=0; loop<5; loop++) printf(""); printf("\n"); for(int minute=0; minute<60; minute += MINUTE_STEP) { array *aminute = new array(1); int dummy; for(dummy=0; dummy addstring(procs[loop] -> procname, procs[loop] -> minute.getcntfromvalue(minute + dummy)); } aminute -> sort(0); printf("", minute); for(loop=0; loop getcounter(loop, 0) == -1) printf(""); else printf("", aminute -> getstring(loop), aminute -> getcounter(loop, 0)); printf("\n"); delete aminute; } printf("
MinuteProcess [count]
%d%s [%d]
\n"); printf("
\n"); /* let's not do per-second, it ain't that intresting */ } int main(int argc, char *argv[]) { int fd = 0; /* open file if filename is given */ if (argc == 2) { fd = open(argv[1], O_RDONLY); if (fd == -1) { fprintf(stderr, "Failed to open file %s, reason: %s\n", argv[1], strerror(errno)); return 1; } } buffered_reader br(fd); /* read & parse logfile */ for(;;) { char *line = br.read_line(); if (!line) /* EOF */ break; (void)process_line(line); free(line); } /* now generate them statistics */ /* show headers */ printf("

"); if (argc == 2) printf("Statistics for '%s'", argv[1]); else printf("Syslog statistics"); printf("

\n"); /* frequency table */ show_frequency_tables(); /* tables per month/year/etc. */ show_topx_tables(); /* show trailer */ printf("
\n"); printf("
\n"); printf("slst, (C) by folkert@vanheusden.com\n"); printf("\n"); return 0; }