1 /*
2 ** $Id$
3 **
4 ** perf-base.c
5 **
6 ** Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
7 ** Copyright (C) 2002-2013 Sourcefire, Inc.
8 ** Dan Roelker <droelker@sourcefire.com>
9 ** Marc Norton <mnorton@sourcefire.com>
10 **
11 ** This program is free software; you can redistribute it and/or modify
12 ** it under the terms of the GNU General Public License Version 2 as
13 ** published by the Free Software Foundation.  You may not use, modify or
14 ** distribute this program under any other version of the GNU General
15 ** Public License.
16 **
17 ** This program is distributed in the hope that it will be useful,
18 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 ** GNU General Public License for more details.
21 **
22 ** You should have received a copy of the GNU General Public License
23 ** along with this program; if not, write to the Free Software
24 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
25 **
26 **  DESCRIPTION
27 **    The following subroutines are concerned with getting
28 **    basic stats on packet bytes and times that an app
29 **    takes in processing packets.  The times measured are
30 **    kernel and user time for the process.   Real-time
31 **    (wall clock) is also measured to show when processing
32 **    has reached capacity and to measure the true processing
33 **    that the app is currently doing.
34 **
35 **  NOTES
36 **    4.8.02  : Initial Code (DJR,MAN)
37 **    4.22.02 : Added Comments (DJR)
38 **    7.10.02 : Added sfprocpidstats code for SMP linux (DJR)
39 **    8.8.02  : Added stream4 instrumentation (cmg)
40 **    9.1.04  : Removed NO_PKTS, ACCUMULATE/RESET #defines, now we use SFBASE->iReset
41 **              and the permonitor command has 'reset' and 'accrue' commands instead.(MAN)
42 **    10.4.06 : Added UDP Session Stats (SAS)
43 **    4.3.07  : Added stats for TCP sessions (SAS)
44 */
45 
46 #include <time.h>
47 #ifndef WIN32
48 #include <sys/time.h>
49 #include <sys/resource.h>
50 #endif
51 #include <stdlib.h>
52 #include <stdio.h>
53 #include <math.h>
54 #include <sys/types.h>
55 
56 #ifdef HAVE_CONFIG_H
57 #include "config.h"
58 #endif
59 
60 #include "sf_types.h"
61 #include "snort.h"
62 #include "util.h"
63 #include "mpse.h"
64 #include "sfdaq.h"
65 #include "session_api.h"
66 #include "stream_api.h"
67 #include "sf_types.h"
68 #include "snort_bounds.h"
69 
70 
71 static void GetPktDropStats(SFBASE *, SFBASE_STATS *);
72 static void DisplayBasePerfStatsConsole(SFBASE_STATS *, int);
73 static int CalculateBasePerfStats(SFBASE *, SFBASE_STATS *, int);
74 static void LogBasePerfStats(SFBASE_STATS *, FILE *);
75 static void GetPacketsPerSecond(SFBASE *, SFBASE_STATS *, SYSTIMES *, int);
76 static void GetMbitsPerSecond(SFBASE *, SFBASE_STATS *, SYSTIMES *, int);
77 static int GetProcessingTime(SYSTIMES *, SFBASE *);
78 static void GetEventsPerSecond(SFBASE *, SFBASE_STATS *, SYSTIMES *);
79 static void GetuSecondsPerPacket(SFBASE *, SFBASE_STATS *, SYSTIMES *);
80 static void GetCPUTime(SFBASE *, SFBASE_STATS *, SYSTIMES *);
81 
82 
83 //We should never output NaN or Infitity
zeroFpException(double in)84 static inline double zeroFpException(double in)
85 {
86 //FIXME WIN32 -vc++6 does NOT provide the function |isnan() |  nor |isinf()| - VJR 7/22/15
87 //  (see also:http://stackoverflow.com/questions/2249110/how-do-i-make-a-portable-isnan-isinf-function)
88 #ifndef WIN32
89     if (isnan(in) || isinf(in))
90         return 0.0;
91 #endif
92     return in;
93 }
94 
95 /*
96 **  NAME
97 **    InitBaseStats
98 **  DESCRIPTION
99 **    Initializes structs and variables for the next performance
100 **    sample.
101 **
102 **  FORMAL INPUTS
103 **    SFBASE * -- pointer to structure to initialize
104 **
105 **  FORMAL OUTPUTS
106 **    int -- 0 is successful
107 */
InitBaseStats(SFBASE * sfBase)108 int InitBaseStats(SFBASE *sfBase)
109 {
110     int todRet = -1;
111     struct timeval tvTime;
112 
113 #ifndef WIN32
114 #ifndef LINUX_SMP
115     struct rusage  rusage;
116     int rusageRet = -1;
117 #endif
118 
119 #ifdef LINUX_SMP
120     todRet = gettimeofday(&tvTime, NULL);
121 #else
122 
123     rusageRet = getrusage(RUSAGE_SELF, &rusage);
124     todRet = gettimeofday(&tvTime, NULL);
125 
126     if (rusageRet >= 0)
127     {
128         sfBase->usertime_sec   = (double)rusage.ru_utime.tv_sec +
129                                  ((double)rusage.ru_utime.tv_usec * 1.0e-6);
130         sfBase->systemtime_sec = (double)rusage.ru_stime.tv_sec +
131                                  ((double)rusage.ru_stime.tv_usec * 1.0e-6);
132     }
133     else
134     {
135         sfBase->usertime_sec = 0;
136         sfBase->systemtime_sec = 0;
137     }
138 
139 #endif  /* !LINUX_SMP */
140 #else
141     sfBase->usertime_sec = 0;
142     sfBase->systemtime_sec = 0;
143     todRet = gettimeofday(&tvTime, NULL);
144 #endif  /* !WIN32 */
145 
146     if(todRet >= 0)
147     {
148         sfBase->realtime_sec = (double)tvTime.tv_sec +
149                                ((double)tvTime.tv_usec * 1.0e-6);
150     }
151     else
152     {
153         sfBase->realtime_sec = 0;
154     }
155 
156     sfBase->total_blocked_packets = 0;
157     sfBase->total_injected_packets = 0;
158     sfBase->total_wire_packets = 0;
159     sfBase->total_ipfragmented_packets = 0;
160     sfBase->total_ipreassembled_packets = 0;
161     sfBase->total_packets = 0;
162     sfBase->total_rebuilt_packets = 0;
163 
164     sfBase->total_wire_bytes = 0;
165     sfBase->total_ipfragmented_bytes = 0;
166     sfBase->total_ipreassembled_bytes = 0;
167     sfBase->total_bytes = 0;
168     sfBase->total_rebuilt_bytes = 0;
169     sfBase->total_blocked_bytes = 0;
170 
171     sfBase->iNewSessions = 0;
172     sfBase->iDeletedSessions = 0;
173 
174     sfBase->iStreamFlushes = 0;
175     sfBase->iStreamFaults = 0;
176     sfBase->iStreamTimeouts = 0;
177     //sfBase->iMaxSessions = 0;
178     //sfBase->iMaxSessionsInterval = 0;
179     //sfBase->iMidStreamSessions = 0;
180     //sfBase->iClosedSessions = 0;
181     //sfBase->iPrunedSessions = 0;
182     //sfBase->iDroppedAsyncSessions = 0;
183     //sfBase->iSessionsInitializing = 0;
184     //sfBase->iSessionsEstablished = 0;
185     //sfBase->iSessionsClosing = 0;
186 
187     sfBase->iFragCreates = 0;
188     sfBase->iFragCompletes = 0;
189     sfBase->iFragInserts = 0;
190     sfBase->iFragDeletes = 0;
191     sfBase->iFragAutoFrees = 0;
192     sfBase->iFragFlushes = 0;
193     sfBase->iFragTimeouts = 0;
194     sfBase->iFragFaults = 0;
195 
196 #ifdef NORMALIZER
197     {
198         int i = 0;
199         for ( i = 0; i < PERF_COUNT_MAX; i++ )
200         {
201             sfBase->iPegs[i][NORM_MODE_ON] = 0;
202             sfBase->iPegs[i][NORM_MODE_WOULDA] = 0;
203         }
204     }
205 #endif
206 
207     sfBase->iNewUDPSessions = 0;
208     sfBase->iDeletedUDPSessions = 0;
209 
210     //sfBase->iAttributeHosts = 0;
211     //sfBase->iAttributeReloads = 0;
212     sfBase->total_mpls_packets = 0;
213     sfBase->total_mpls_bytes = 0;
214     sfBase->total_blocked_mpls_packets = 0;
215     sfBase->total_blocked_mpls_bytes = 0;
216 
217     sfBase->total_tcp_filtered_packets = 0;
218     sfBase->total_udp_filtered_packets = 0;
219 
220     sfBase->frag3_mem_in_use = 0;
221     sfBase->stream5_mem_in_use = 0;
222     sfBase->total_iAlerts = 0;
223 
224     return 0;
225 }
226 
227 /*
228 **  NAME
229 **    UpdateBaseStats
230 **
231 **  DESCRIPTION
232 **    Simple update of stats.
233 **
234 **  FORMAL INPUTS
235 **    SFBASE * - structure to update
236 **    int      - length of packet payload in bytes
237 **
238 **  FORMAL OUTPUTS
239 **    int - 0 is successful
240 **
241 **  Add in Ethernet Overhead - assume a standerd Ethernet service
242 **
243 **   Ethernet Frame
244 **   ---------------
245 **           | <-----------   PCAP Packet  --------> |
246 **   Preamble  Dest Mac  Src Mac   Type      Payload   CRC        IFG
247 ** | 8 bytes | 6 Bytes | 6 Bytes | 2-Bytes | 46-1500 | 4 Bytes |  12      |
248 **
249 ** Len = PCAP Packet + 4 bytes for CRC
250 ** Overhead = 20 bytes
251 ** Min on the wire == 84 bytes
252 ** Min Size of PCAP packet = 60 bytes (84 - 20 overhead - 4 CRC)
253 **
254 ** Len is the amount of user data being sent.  This will be less then
255 ** actual wire-speed, because of the interframe gap (96 bits) and preamble
256 ** (8 bytes).
257 **
258 ** A 60 byte minimum packet uses 672 bits (60 bytes + 4 CRC), this limits a
259 ** 1000 Mbit network to 1.488 Million packets with a bandwidth of 760
260 ** Mbits.  The lost 240 Mbits is due to interframe gap (96 bits) and preamble
261 ** (8 bytes).
262 **
263 ** Even if the actual data is only 40 bytes per packet (ie, an empty
264 ** TCP ACK), wire data is still 64 bytes per packet, even though actual
265 ** packet size is 40 bytes.  Bandwith drops to 480 Mbits.
266 **
267 ** This explains why when a network goes over 50% capactiy you are closer to
268 ** the edge than you realize, depending on the traffic profile.  At 75% you
269 ** are at the limit of your network, if you can get there.
270 **
271 ** bool rebuilt determines whether the packet is rebuilt or not.  We keep
272 ** separate statistics between wire pkts and rebuilt pkts.
273 **
274 */
UpdateBaseStats(SFBASE * sfBase,Packet * p,bool rebuilt)275 void UpdateBaseStats(SFBASE *sfBase, Packet *p, bool rebuilt)
276 {
277     uint32_t len = p->pkth->caplen;
278 
279     if (!rebuilt)
280     {
281         // For SYN to SYN/ACK counts to help determine if traffic is asynchronous
282         if ((p->tcph != NULL) && (p->tcph->th_flags & TH_SYN))
283         {
284             if (p->tcph->th_flags & TH_ACK)
285                 sfBase->iSynAcks++;
286             else
287                 sfBase->iSyns++;
288         }
289 
290         len += 4; /* for the CRC */
291     }
292 
293     /* Includes wire, IP reassembled & TCP rebuilt packets
294      * that make it to the application layer. */
295     sfBase->total_packets++;
296     sfBase->total_bytes += len;
297 }
298 
299 /*
300 **  NAME
301 **    UpdateWireStats
302 **
303 **  DESCRIPTION
304 **    Simple update of stats for "on the wire".
305 **
306 **  FORMAL INPUTS
307 **    SFBASE * - structure to update
308 **    int      - length of packet payload in bytes
309 **
310 **  FORMAL OUTPUTS
311 **    none
312 */
UpdateWireStats(SFBASE * sfBase,int len,int dropped,int inject)313 void UpdateWireStats(SFBASE *sfBase, int len, int dropped, int inject)
314 {
315     sfBase->total_wire_packets++;
316 
317     len += 4; /* for the CRC */
318     sfBase->total_wire_bytes += len;
319 
320     if( dropped )
321     {
322       sfBase->total_blocked_packets++;
323       sfBase->total_blocked_bytes += len;
324     }
325     if ( inject )
326         sfBase->total_injected_packets++;
327 }
328 
UpdateMPLSStats(SFBASE * sfBase,int len,int dropped)329 void UpdateMPLSStats(SFBASE *sfBase, int len, int dropped)
330 {
331 #ifdef MPLS
332     sfBase->total_mpls_packets++;
333 
334     len += 4; /* for the CRC */
335     sfBase->total_mpls_bytes += len;
336 
337     if( dropped )
338     {
339         sfBase->total_blocked_mpls_packets++;
340         sfBase->total_blocked_mpls_bytes += len;
341     }
342 #endif
343 }
344 
345 /*
346 **  NAME
347 **    UpdateIPFragStats
348 **
349 **  DESCRIPTION
350 **    Simple update of stats for IP fragmented packets
351 **
352 **  FORMAL INPUTS
353 **    SFBASE * - structure to update
354 **    int      - length of packet payload in bytes
355 **
356 **  FORMAL OUTPUTS
357 **    none
358 */
UpdateIPFragStats(SFBASE * sfBase,int len)359 void UpdateIPFragStats(SFBASE *sfBase, int len)
360 {
361     sfBase->total_ipfragmented_packets++;
362 
363     len += 4; /* for the CRC */
364     sfBase->total_ipfragmented_bytes += len;
365 }
366 
367 /*
368 **  NAME
369 **    UpdateIPReassStats
370 **
371 **  DESCRIPTION
372 **    Simple update of stats for IP reassembled packets
373 **
374 **  FORMAL INPUTS
375 **    SFBASE * - structure to update
376 **    int      - length of packet payload in bytes
377 **
378 **  FORMAL OUTPUTS
379 **    none
380 */
UpdateIPReassStats(SFBASE * sfBase,int len)381 void UpdateIPReassStats(SFBASE *sfBase, int len)
382 {
383     sfBase->total_ipreassembled_bytes += len;
384     sfBase->total_ipreassembled_packets++;
385 }
386 
UpdateStreamReassStats(SFBASE * sfBase,int len)387 void UpdateStreamReassStats(SFBASE *sfBase, int len)
388 {
389     sfBase->total_rebuilt_bytes += len;
390     sfBase->total_rebuilt_packets++;
391 }
392 
393 /**API to update stats for packets discarded due to
394  * TCP/UDP port/service based filtering.
395  *
396  * @param sfBase - pointer to accumulated stats
397  */
UpdateFilteredPacketStats(SFBASE * sfBase,IpProto proto)398 void UpdateFilteredPacketStats(SFBASE *sfBase, IpProto proto)
399 {
400     switch (proto)
401     {
402         case IPPROTO_TCP:
403             sfBase->total_tcp_filtered_packets++;
404             break;
405         case IPPROTO_UDP:
406             sfBase->total_udp_filtered_packets++;
407             break;
408         default:
409             //coding error
410             ;
411     }
412 }
413 /*
414 **  NAME
415 **    AddStreamSession
416 **
417 **  DESCRIPTION
418 **    Add a session count
419 **
420 **  FORMAL INPUTS
421 **    SFBASE * - ptr to update.
422 **
423 **  FORMAL OUTPUTS
424 **    int - 0 is successful
425 */
426 
AddStreamSession(SFBASE * sfBase,uint32_t flags)427 int AddStreamSession(SFBASE *sfBase, uint32_t flags)
428 {
429     sfBase->iTotalSessions++;
430     sfBase->iNewSessions++;
431 
432     if (flags & SSNFLAG_MIDSTREAM)
433         sfBase->iMidStreamSessions++;
434 
435     if(sfBase->iTotalSessions > sfBase->iMaxSessions)
436         sfBase->iMaxSessions = sfBase->iTotalSessions;
437 
438     if(sfBase->iTotalSessions > sfBase->iMaxSessionsInterval)
439         sfBase->iMaxSessionsInterval = sfBase->iTotalSessions;
440 
441     return 0;
442 }
443 
444 /*
445 **  NAME
446 **    CloseStreamSession
447 **
448 **  DESCRIPTION
449 **    Add a session count
450 **
451 **  FORMAL INPUTS
452 **    SFBASE * - ptr to update.
453 **
454 **  FORMAL OUTPUTS
455 **    int - 0 is successful
456 */
457 
CloseStreamSession(SFBASE * sfBase,char flags)458 int CloseStreamSession(SFBASE *sfBase, char flags)
459 {
460     if (flags & SESSION_CLOSED_NORMALLY)
461         sfBase->iClosedSessions++;
462     else{
463         if (flags & SESSION_CLOSED_TIMEDOUT)
464             sfBase->iStreamTimeouts++;
465         if (flags & SESSION_CLOSED_PRUNED)
466             sfBase->iPrunedSessions++;
467         if (flags & SESSION_CLOSED_ASYNC)
468             sfBase->iDroppedAsyncSessions++;
469     }
470     return 0;
471 }
472 
473 /*
474 **  NAME
475 **    RemoveStreamSession
476 **
477 **  DESCRIPTION
478 **    Add a session count
479 **
480 **  FORMAL INPUTS
481 **    SFBASE * - ptr to update.
482 **
483 **  FORMAL OUTPUTS
484 **    int - 0 is successful
485 */
486 
RemoveStreamSession(SFBASE * sfBase)487 int RemoveStreamSession(SFBASE *sfBase)
488 {
489     sfBase->iTotalSessions--;
490     sfBase->iDeletedSessions++;
491     return 0;
492 }
493 
494 /*
495 **  NAME
496 **    AddUDPSession
497 **
498 **  DESCRIPTION
499 **    Add a session count
500 **
501 **  FORMAL INPUTS
502 **    SFBASE * - ptr to update.
503 **
504 **  FORMAL OUTPUTS
505 **    int - 0 is successful
506 */
AddUDPSession(SFBASE * sfBase)507 int AddUDPSession(SFBASE *sfBase)
508 {
509     sfBase->iTotalUDPSessions++;
510     sfBase->iNewUDPSessions++;
511 
512     if(sfBase->iTotalUDPSessions > sfBase->iMaxUDPSessions)
513         sfBase->iMaxUDPSessions = sfBase->iTotalUDPSessions;
514 
515     return 0;
516 }
517 
518 /*
519 **  NAME
520 **    RemoveUDPSession
521 **
522 **  DESCRIPTION
523 **    Add a session count
524 **
525 **  FORMAL INPUTS
526 **    SFBASE * - ptr to update.
527 **
528 **  FORMAL OUTPUTS
529 **    int - 0 is successful
530 */
531 
RemoveUDPSession(SFBASE * sfBase)532 int RemoveUDPSession(SFBASE *sfBase)
533 {
534     sfBase->iTotalUDPSessions--;
535     sfBase->iDeletedUDPSessions++;
536     return 0;
537 }
538 
539 /*
540 **  NAME
541 **    ProcessBaseStats
542 **
543 **  DESCRIPTION
544 **    Main function to process Base Stats.
545 **
546 **  FORMAL INPUTS
547 **    SFBASE * - ptr to update.
548 **
549 **  FORMAL OUTPUTS
550 **    int - 0 is successful
551 */
ProcessBaseStats(SFBASE * sfBase,FILE * fh,int console,int max_stats)552 void ProcessBaseStats(SFBASE *sfBase, FILE *fh, int console, int max_stats)
553 {
554     SFBASE_STATS sfBaseStats;
555 
556     if (fh  || console)
557     {
558         if (CalculateBasePerfStats(sfBase, &sfBaseStats, max_stats))
559             return;
560 
561         if (console)
562             DisplayBasePerfStatsConsole(&sfBaseStats, max_stats);
563 
564         if (fh)
565             LogBasePerfStats(&sfBaseStats, fh);
566     }
567 }
568 
GetProcessingTime(SYSTIMES * Systimes,SFBASE * sfBase)569 static int GetProcessingTime(SYSTIMES *Systimes, SFBASE *sfBase)
570 {
571     int todRet = -1;
572     struct timeval tvTime;
573 #ifdef LINUX_SMP
574 
575     if(sfProcessProcPidStats(&(sfBase->sfProcPidStats)))
576         return -1;
577     todRet = gettimeofday(&tvTime, NULL);
578 #else
579     struct rusage  rusage;
580     int rusageRet;
581 #ifndef WIN32
582     rusageRet = getrusage(RUSAGE_SELF, &rusage);
583 #else
584     rusageRet = -1;
585 #endif  /* !WIN32 */
586     todRet = gettimeofday(&tvTime, NULL);
587 
588     if (rusageRet < 0)
589     {
590         rusage.ru_utime.tv_sec = 0;
591         rusage.ru_utime.tv_usec = 0;
592         rusage.ru_stime.tv_sec = 0;
593         rusage.ru_stime.tv_usec = 0;
594     }
595     Systimes->usertime   = ((double)rusage.ru_utime.tv_sec +
596                            ((double)rusage.ru_utime.tv_usec * 1.0e-6)) -
597                            sfBase->usertime_sec;
598     Systimes->systemtime = ((double)rusage.ru_stime.tv_sec +
599                            ((double)rusage.ru_stime.tv_usec * 1.0e-6)) -
600                            sfBase->systemtime_sec;
601     Systimes->totaltime  = Systimes->usertime + Systimes->systemtime;
602 #endif  /* LINUX_SMP */
603 
604     if (todRet < 0)
605     {
606         return todRet;
607     }
608 
609     Systimes->realtime =  ((double)tvTime.tv_sec +
610                           ((double)tvTime.tv_usec * 1.0e-6)) -
611                           sfBase->realtime_sec;
612     return 0;
613 }
614 
GetEventsPerSecond(SFBASE * sfBase,SFBASE_STATS * sfBaseStats,SYSTIMES * Systimes)615 static void GetEventsPerSecond(SFBASE *sfBase, SFBASE_STATS *sfBaseStats,
616         SYSTIMES *Systimes)
617 {
618     sfBaseStats->alerts_per_second =
619         (double)(pc.alert_pkts - sfBase->iAlerts) / Systimes->realtime;
620 
621     sfBase->iAlerts = pc.alert_pkts;
622 
623     sfBaseStats->total_alerts_per_second =
624         (double)(pc.total_alert_pkts - sfBase->total_iAlerts) / Systimes->realtime;
625 
626     sfBase->total_iAlerts = pc.total_alert_pkts;
627 
628     sfBaseStats->total_sessions = sfBase->iTotalSessions;
629     sfBaseStats->max_sessions = sfBase->iMaxSessions;
630 
631     sfBaseStats->syns_per_second =
632         (double)(sfBase->iSyns) / Systimes->realtime;
633 
634     sfBaseStats->synacks_per_second =
635         (double)(sfBase->iSynAcks) / Systimes->realtime;
636 
637     sfBaseStats->deleted_sessions_per_second =
638         (double)(sfBase->iDeletedSessions) / Systimes->realtime;
639 
640     sfBaseStats->new_sessions_per_second =
641         (double)(sfBase->iNewSessions) / Systimes->realtime;
642 
643     sfBaseStats->tcp_sessions_midstream_per_second =
644         (double)(sfBase->iMidStreamSessions) / Systimes->realtime;
645 
646     sfBaseStats->tcp_sessions_closed_per_second =
647         (double)(sfBase->iClosedSessions) / Systimes->realtime;
648 
649     sfBaseStats->tcp_sessions_timedout_per_second =
650         (double)(sfBase->iStreamTimeouts) / Systimes->realtime;
651 
652     sfBaseStats->tcp_sessions_pruned_per_second =
653         (double)(sfBase->iPrunedSessions) / Systimes->realtime;
654 
655     sfBaseStats->tcp_sessions_dropped_async_per_second =
656         (double)(sfBase->iDroppedAsyncSessions) / Systimes->realtime;
657 
658     sfBaseStats->max_tcp_sessions_interval = sfBase->iMaxSessionsInterval;
659 
660     sfBaseStats->stream_flushes_per_second =
661         (double)sfBase->iStreamFlushes / Systimes->realtime;
662 
663     sfBaseStats->stream_faults = sfBase->iStreamFaults;
664     sfBaseStats->stream_timeouts = sfBase->iStreamTimeouts;
665     sfBaseStats->curr_tcp_sessions_initializing = sfBase->iSessionsInitializing;
666     sfBaseStats->curr_tcp_sessions_established = sfBase->iSessionsEstablished;
667     sfBaseStats->curr_tcp_sessions_closing = sfBase->iSessionsClosing;
668 
669     sfBaseStats->frag_creates_per_second =
670         (double)sfBase->iFragCreates / Systimes->realtime;
671 
672     sfBaseStats->frag_completes_per_second =
673         (double)sfBase->iFragCompletes / Systimes->realtime;
674 
675     sfBaseStats->frag_inserts_per_second =
676         (double)sfBase->iFragInserts / Systimes->realtime;
677 
678     sfBaseStats->frag_deletes_per_second =
679         (double)sfBase->iFragDeletes / Systimes->realtime;
680 
681     sfBaseStats->frag_autofrees_per_second =
682         (double)sfBase->iFragAutoFrees / Systimes->realtime;
683 
684     sfBaseStats->frag_flushes_per_second =
685         (double)sfBase->iFragFlushes / Systimes->realtime;
686 
687     sfBaseStats->max_frags = sfBase->iMaxFrags;
688     sfBaseStats->current_frags = sfBase->iCurrentFrags;
689     sfBaseStats->frag_timeouts = sfBase->iFragTimeouts;
690     sfBaseStats->frag_faults = sfBase->iFragFaults;
691 
692     sfBase->iSyns = 0;
693     sfBase->iSynAcks = 0;
694     sfBase->iNewSessions = 0;
695     sfBase->iDeletedSessions = 0;
696 
697     sfBase->iStreamFlushes = 0;
698     sfBase->iStreamFaults = 0;
699     sfBase->iStreamTimeouts = 0;
700 
701     sfBase->iFragCreates = 0;
702     sfBase->iFragCompletes = 0;
703     sfBase->iFragInserts = 0;
704     sfBase->iFragDeletes = 0;
705     sfBase->iFragAutoFrees = 0;
706     sfBase->iFragFlushes = 0;
707     sfBase->iFragTimeouts = 0;
708     sfBase->iFragFaults = 0;
709 
710 #ifdef NORMALIZER
711     {
712         int i = 0;
713         for ( i = 0; i < PERF_COUNT_MAX; i++ )
714         {
715             sfBase->iPegs[i][NORM_MODE_ON] = 0;
716             sfBase->iPegs[i][NORM_MODE_WOULDA] = 0;
717         }
718     }
719 #endif
720 
721     sfBaseStats->total_udp_sessions = sfBase->iTotalUDPSessions;
722     sfBaseStats->max_udp_sessions = sfBase->iMaxUDPSessions;
723     sfBaseStats->deleted_udp_sessions_per_second =
724         (double)(sfBase->iDeletedUDPSessions) / Systimes->realtime;
725 
726     sfBaseStats->new_udp_sessions_per_second =
727         (double)(sfBase->iNewUDPSessions) / Systimes->realtime;
728 
729     sfBase->iNewUDPSessions = 0;
730     sfBase->iDeletedUDPSessions = 0;
731 
732     sfBase->iMaxSessionsInterval = sfBase->iTotalSessions;
733     sfBase->iMidStreamSessions = 0;
734     sfBase->iClosedSessions = 0;
735     sfBase->iPrunedSessions = 0;
736     sfBase->iDroppedAsyncSessions = 0;
737 }
738 
GetPacketsPerSecond(SFBASE * sfBase,SFBASE_STATS * sfBaseStats,SYSTIMES * Systimes,int max_stats)739 static void GetPacketsPerSecond(SFBASE *sfBase, SFBASE_STATS *sfBaseStats,
740         SYSTIMES *Systimes, int max_stats)
741 {
742     sfBaseStats->kpackets_per_sec.realtime   =
743         (double)((double)sfBase->total_packets / 1000) / Systimes->realtime;
744 
745     if (max_stats)
746     {
747         sfBaseStats->kpackets_per_sec.usertime   =
748             (double)((double)sfBase->total_packets / 1000) /
749             Systimes->usertime;
750         sfBaseStats->kpackets_per_sec.systemtime =
751             (double)((double)sfBase->total_packets / 1000) /
752             Systimes->systemtime;
753         sfBaseStats->kpackets_per_sec.totaltime  =
754             (double)((double)sfBase->total_packets / 1000) /
755             Systimes->totaltime;
756     }
757 
758     sfBaseStats->kpackets_wire_per_sec.realtime   =
759         (double)((double)sfBase->total_wire_packets / 1000) / Systimes->realtime;
760 
761     if (max_stats)
762     {
763         sfBaseStats->kpackets_wire_per_sec.usertime   =
764             (double)((double)sfBase->total_wire_packets / 1000) /
765             Systimes->usertime;
766         sfBaseStats->kpackets_wire_per_sec.systemtime =
767             (double)((double)sfBase->total_wire_packets / 1000) /
768             Systimes->systemtime;
769         sfBaseStats->kpackets_wire_per_sec.totaltime  =
770             (double)((double)sfBase->total_wire_packets / 1000) /
771             Systimes->totaltime;
772     }
773 
774     sfBaseStats->kpackets_ipfrag_per_sec.realtime   =
775         (double)((double)sfBase->total_ipfragmented_packets / 1000) / Systimes->realtime;
776 
777     if (max_stats)
778     {
779         sfBaseStats->kpackets_ipfrag_per_sec.usertime   =
780             (double)((double)sfBase->total_ipfragmented_packets / 1000) /
781             Systimes->usertime;
782         sfBaseStats->kpackets_ipfrag_per_sec.systemtime =
783             (double)((double)sfBase->total_ipfragmented_packets / 1000) /
784             Systimes->systemtime;
785         sfBaseStats->kpackets_ipfrag_per_sec.totaltime  =
786             (double)((double)sfBase->total_ipfragmented_packets / 1000) /
787             Systimes->totaltime;
788     }
789 
790     sfBaseStats->kpackets_ipreass_per_sec.realtime   =
791         (double)((double)sfBase->total_ipreassembled_packets / 1000) / Systimes->realtime;
792 
793     if (max_stats)
794     {
795         sfBaseStats->kpackets_ipreass_per_sec.usertime   =
796             (double)((double)sfBase->total_ipreassembled_packets / 1000) /
797             Systimes->usertime;
798         sfBaseStats->kpackets_ipreass_per_sec.systemtime =
799             (double)((double)sfBase->total_ipreassembled_packets / 1000) /
800             Systimes->systemtime;
801         sfBaseStats->kpackets_ipreass_per_sec.totaltime  =
802             (double)((double)sfBase->total_ipreassembled_packets / 1000) /
803             Systimes->totaltime;
804     }
805 
806     sfBaseStats->kpackets_rebuilt_per_sec.realtime   =
807         (double)((double)sfBase->total_rebuilt_packets / 1000) / Systimes->realtime;
808 
809     if (max_stats)
810     {
811         sfBaseStats->kpackets_rebuilt_per_sec.usertime   =
812             (double)((double)sfBase->total_rebuilt_packets / 1000) /
813             Systimes->usertime;
814         sfBaseStats->kpackets_rebuilt_per_sec.systemtime =
815             (double)((double)sfBase->total_rebuilt_packets / 1000) /
816             Systimes->systemtime;
817         sfBaseStats->kpackets_rebuilt_per_sec.totaltime  =
818             (double)((double)sfBase->total_rebuilt_packets / 1000) /
819             Systimes->totaltime;
820     }
821 
822     sfBaseStats->kpackets_per_sec_mpls.realtime   =
823         (double)((double)sfBase->total_mpls_packets / 1000) / Systimes->realtime;
824 
825     if (max_stats)
826     {
827         sfBaseStats->kpackets_per_sec_mpls.usertime   =
828             (double)((double)sfBase->total_mpls_packets / 1000) /
829             Systimes->usertime;
830         sfBaseStats->kpackets_per_sec_mpls.systemtime =
831             (double)((double)sfBase->total_mpls_packets / 1000) /
832             Systimes->systemtime;
833         sfBaseStats->kpackets_per_sec_mpls.totaltime  =
834             (double)((double)sfBase->total_mpls_packets / 1000) /
835             Systimes->totaltime;
836     }
837 }
838 
GetuSecondsPerPacket(SFBASE * sfBase,SFBASE_STATS * sfBaseStats,SYSTIMES * Systimes)839 static void GetuSecondsPerPacket(SFBASE *sfBase, SFBASE_STATS *sfBaseStats,
840         SYSTIMES *Systimes)
841 {
842     if(sfBase->total_packets)
843     {
844         sfBaseStats->usecs_per_packet.usertime   = (Systimes->usertime * 1.0e6) /
845             (double)sfBase->total_packets;
846         sfBaseStats->usecs_per_packet.systemtime = (Systimes->systemtime * 1.0e6) /
847             (double)sfBase->total_packets;
848         sfBaseStats->usecs_per_packet.totaltime  = (Systimes->totaltime * 1.0e6) /
849             (double)sfBase->total_packets;
850         sfBaseStats->usecs_per_packet.realtime   = (Systimes->realtime * 1.0e6) /
851             (double)sfBase->total_packets;
852     }
853 }
854 
GetMbitsPerSecond(SFBASE * sfBase,SFBASE_STATS * sfBaseStats,SYSTIMES * Systimes,int max_stats)855 static void GetMbitsPerSecond(SFBASE *sfBase, SFBASE_STATS *sfBaseStats,
856         SYSTIMES *Systimes, int max_stats)
857 {
858     /*
859     **  These Mbits stats are for the Snort Maximum Performance stats
860     **  that can't reliably be gotten from Linux SMP kernels.  So
861     **  we don't do them.
862     */
863     if (max_stats)
864     {
865         sfBaseStats->mbits_per_sec.usertime   = ((double)
866                                                 (sfBase->total_bytes<<3) *
867                                                 1.0e-6) /
868                                                 Systimes->usertime;
869         sfBaseStats->mbits_per_sec.systemtime = ((double)
870                                                 (sfBase->total_bytes<<3) *
871                                                 1.0e-6) /
872                                                 Systimes->systemtime;
873         sfBaseStats->mbits_per_sec.totaltime  = ((double)
874                                                 (sfBase->total_bytes<<3) *
875                                                 1.0e-6) /
876                                                 Systimes->totaltime;
877     }
878 
879     sfBaseStats->mbits_per_sec.realtime   = ((double)(sfBase->total_bytes<<3) *
880                                              1.0e-6) /
881                                             Systimes->realtime;
882     sfBaseStats->wire_mbits_per_sec.realtime   =
883                                     ((double)(sfBase->total_wire_bytes<<3) *
884                                     1.0e-6) /
885                                     Systimes->realtime;
886     sfBaseStats->rebuilt_mbits_per_sec.realtime   =
887                                     ((double)(sfBase->total_rebuilt_bytes<<3) *
888                                     1.0e-6) /
889                                     Systimes->realtime;
890 
891     sfBaseStats->ipfrag_mbits_per_sec.realtime   =
892                                     ((double)(sfBase->total_ipfragmented_bytes<<3) *
893                                     1.0e-6) /
894                                     Systimes->realtime;
895 
896     sfBaseStats->ipreass_mbits_per_sec.realtime   =
897                                     ((double)(sfBase->total_ipreassembled_bytes<<3) *
898                                     1.0e-6) /
899                                     Systimes->realtime;
900     sfBaseStats->mpls_mbits_per_sec.realtime   =
901                                     ((double)(sfBase->total_mpls_bytes<<3) *
902                                     1.0e-6) /
903                                     Systimes->realtime;
904 }
905 
GetCPUTime(SFBASE * sfBase,SFBASE_STATS * sfBaseStats,SYSTIMES * Systimes)906 static void GetCPUTime(SFBASE *sfBase, SFBASE_STATS *sfBaseStats, SYSTIMES *Systimes)
907 {
908 #ifndef LINUX_SMP
909     unsigned char needToNormalize = 0;
910     sfBaseStats->user_cpu_time   = (Systimes->usertime   /
911                                    Systimes->realtime) * 100;
912     sfBaseStats->system_cpu_time = (Systimes->systemtime /
913                                    Systimes->realtime) * 100;
914     sfBaseStats->idle_cpu_time   = ((Systimes->realtime -
915                                      Systimes->totaltime) /
916                                      Systimes->realtime) * 100;
917 
918     /* percentages can be < 0 because of a small variance between
919      * when the snapshot is taken of the CPU times and snapshot of
920      * the real time.  So these are just a safe-guard to normalize
921      * the data so we see positive values.
922      */
923     if (sfBaseStats->user_cpu_time < 0)
924     {
925         sfBaseStats->user_cpu_time = 0;
926         needToNormalize = 1;
927     }
928     if (sfBaseStats->system_cpu_time < 0)
929     {
930         sfBaseStats->system_cpu_time = 0;
931         needToNormalize = 1;
932     }
933     if (sfBaseStats->idle_cpu_time < 0)
934     {
935         sfBaseStats->idle_cpu_time = 0;
936         needToNormalize = 1;
937     }
938 
939     if (needToNormalize)
940     {
941         double totalPercent = sfBaseStats->user_cpu_time +
942                               sfBaseStats->system_cpu_time +
943                               sfBaseStats->idle_cpu_time;
944 
945 
946         sfBaseStats->user_cpu_time = (sfBaseStats->user_cpu_time /
947                                       totalPercent) * 100;
948         sfBaseStats->system_cpu_time = ( sfBaseStats->system_cpu_time /
949                                       totalPercent) * 100;
950         sfBaseStats->idle_cpu_time = ( sfBaseStats->idle_cpu_time /
951                                       totalPercent) * 100;
952 
953     }
954 #endif
955 }
956 
957 
958 /*
959 **  NAME
960 **    CalculateBasePerfStats
961 **
962 **  DESCRIPTION
963 **    This is the main function that calculates the stats. Stats
964 **    that we caculate are:
965 **      *uSecs per Packet
966 **      *Packets per Second
967 **      *Mbits per Second
968 **      *Average bytes per Packet
969 **      *CPU Time
970 **      *Dropped Packets
971 **    These statistics are processed and then stored in the
972 **    SFBASE_STATS structure.  This allows output functions to
973 **    be easily formed and inserted.
974 **    NOTE: We can break up these statistics into functions for easier
975 **    reading.
976 **
977 **  FORMAL INPUTS
978 **    SFBASE *       - ptr to performance struct
979 **    SFBASE_STATS * - ptr to struct to fill in performance stats
980 **    int            - do max stats
981 **
982 **  FORMAL OUTPUTS
983 **    int - 0 is successful
984 */
CalculateBasePerfStats(SFBASE * sfBase,SFBASE_STATS * sfBaseStats,int max_stats)985 static int CalculateBasePerfStats(SFBASE *sfBase, SFBASE_STATS *sfBaseStats, int max_stats)
986 {
987     SYSTIMES       Systimes;
988     time_t   clock;
989 
990 #ifdef LINUX_SMP
991 
992     /*
993     **  We also give sfBaseStats access to the CPU usage
994     **  contained in sfProcPidStats.  This way we don't need
995     **  to complicate sfBaseStats further.
996     */
997     sfBaseStats->sfProcPidStats = &(sfBase->sfProcPidStats);
998 
999 #endif
1000     if(GetProcessingTime(&Systimes, sfBase))
1001         return -1;
1002 
1003     sfBaseStats->total_blocked_packets = sfBase->total_blocked_packets;
1004     sfBaseStats->total_injected_packets = sfBase->total_injected_packets;
1005     sfBaseStats->total_mpls_packets = sfBase->total_mpls_packets;
1006     sfBaseStats->total_mpls_bytes = sfBase->total_mpls_bytes;
1007     sfBaseStats->total_blocked_mpls_packets = sfBase->total_blocked_mpls_packets;
1008     sfBaseStats->total_blocked_mpls_bytes = sfBase->total_blocked_mpls_bytes;
1009 
1010     sfBaseStats->total_tcp_filtered_packets = sfBase->total_tcp_filtered_packets;
1011     sfBaseStats->total_udp_filtered_packets = sfBase->total_udp_filtered_packets;
1012 
1013 #ifdef NORMALIZER
1014     {
1015         int iCtr;
1016         for ( iCtr = 0; iCtr < PERF_COUNT_MAX; iCtr++ )
1017         {
1018             sfBaseStats->pegs[iCtr][NORM_MODE_ON] = sfBase->iPegs[iCtr][NORM_MODE_ON];
1019             sfBaseStats->pegs[iCtr][NORM_MODE_WOULDA] = sfBase->iPegs[iCtr][NORM_MODE_WOULDA];
1020         }
1021     }
1022 #endif
1023 
1024     /*
1025     **  Avg. bytes per Packet
1026     */
1027     if (sfBase->total_packets > 0)
1028         sfBaseStats->avg_bytes_per_packet = zeroFpException(
1029                 (int)((double)(sfBase->total_bytes) /
1030                 (double)(sfBase->total_packets)));
1031     else
1032         sfBaseStats->avg_bytes_per_packet = 0;
1033 
1034     if (sfBase->total_wire_packets > 0)
1035         sfBaseStats->avg_bytes_per_wire_packet = zeroFpException(
1036                 (int)((double)(sfBase->total_wire_bytes) /
1037                 (double)(sfBase->total_wire_packets)));
1038     else
1039         sfBaseStats->avg_bytes_per_wire_packet = 0;
1040 
1041     if (sfBase->total_ipfragmented_packets > 0)
1042         sfBaseStats->avg_bytes_per_ipfrag_packet = zeroFpException(
1043                 (int)((double)(sfBase->total_ipfragmented_bytes) /
1044                 (double)(sfBase->total_ipfragmented_packets)));
1045     else
1046         sfBaseStats->avg_bytes_per_ipfrag_packet = 0;
1047 
1048     if (sfBase->total_ipreassembled_packets > 0)
1049         sfBaseStats->avg_bytes_per_ipreass_packet = zeroFpException(
1050                 (int)((double)(sfBase->total_ipreassembled_bytes) /
1051                 (double)(sfBase->total_ipreassembled_packets)));
1052     else
1053         sfBaseStats->avg_bytes_per_ipreass_packet = 0;
1054 
1055     if (sfBase->total_rebuilt_packets > 0)
1056         sfBaseStats->avg_bytes_per_rebuilt_packet = zeroFpException(
1057                 (int)((double)(sfBase->total_rebuilt_bytes) /
1058                 (double)(sfBase->total_rebuilt_packets)));
1059     else
1060         sfBaseStats->avg_bytes_per_rebuilt_packet = 0;
1061 
1062     if (sfBase->total_mpls_packets > 0)
1063         sfBaseStats->avg_bytes_per_mpls_packet = zeroFpException(
1064                 (int)((double)(sfBase->total_mpls_bytes) /
1065                 (double)(sfBase->total_mpls_packets)));
1066     else
1067         sfBaseStats->avg_bytes_per_mpls_packet = 0;
1068 
1069     /*
1070     **  CPU time
1071     */
1072     GetCPUTime(sfBase, sfBaseStats, &Systimes);
1073 
1074     /*
1075     **  Get Dropped Packets
1076     */
1077     GetPktDropStats(sfBase, sfBaseStats);
1078 
1079     /*
1080     **  Total packets
1081     */
1082     sfBaseStats->total_packets = sfBase->total_wire_packets;
1083 
1084     /*
1085     *   Pattern Matching Performance in Real and User time
1086     */
1087     sfBaseStats->patmatch_percent = zeroFpException(100.0 * mpseGetPatByteCount() /
1088                                     sfBase->total_wire_bytes);
1089 
1090     mpseResetByteCount();
1091 
1092     if (max_stats)
1093     {
1094         /*
1095         **  uSeconds per Packet
1096         **  user, system, total time
1097         */
1098         GetuSecondsPerPacket(sfBase, sfBaseStats, &Systimes);
1099     }
1100 
1101     /*
1102     **  Mbits per sec
1103     **  user, system, total time
1104     */
1105     GetMbitsPerSecond(sfBase, sfBaseStats, &Systimes, max_stats);
1106 
1107     /*
1108     **  EventsPerSecond
1109     **  We get the information from the global variable
1110     **  PacketCount.
1111     */
1112     GetEventsPerSecond(sfBase, sfBaseStats, &Systimes);
1113 
1114     /*
1115     **  Packets per seconds
1116     **  user, system, total time
1117     */
1118     GetPacketsPerSecond(sfBase, sfBaseStats, &Systimes, max_stats);
1119 
1120     /*
1121     ** Attribute Table counters
1122     **
1123     */
1124     sfBaseStats->current_attribute_hosts = sfBase->iAttributeHosts;
1125     sfBaseStats->attribute_table_reloads = sfBase->iAttributeReloads;
1126 
1127     sfBaseStats->frag3_mem_in_use = sfBase->frag3_mem_in_use;
1128     sfBaseStats->stream5_mem_in_use = sfBase->stream5_mem_in_use;
1129 
1130     /*
1131     **  Set the date string for print out
1132     */
1133     if (sfBase->time)
1134     {
1135         clock = sfBase->time;
1136     }
1137     else
1138     {
1139         time(&clock);
1140     }
1141     sfBaseStats->time = clock;
1142 
1143     return 0;
1144 }
1145 
1146 /*
1147 **  NAME
1148 **    GetPktDropStats
1149 **
1150 **  DESCRIPTION
1151 **    Gets the packet drop statisitics from DAQ.
1152 **
1153 **  FORMAL INPUT
1154 **    SFBASE *       - ptr to struct
1155 **    SFBASE_STATS * - ptr to struct to fill in with perf stats
1156 **
1157 **  FORMAL OUTPUT
1158 **    void return
1159 */
GetPktDropStats(SFBASE * sfBase,SFBASE_STATS * sfBaseStats)1160 static void GetPktDropStats(SFBASE *sfBase, SFBASE_STATS *sfBaseStats)
1161 {
1162     uint64_t recv, drop, sum;
1163 
1164     if (ScReadMode())
1165     {
1166         recv = pc.total_from_daq;
1167         drop = 0;
1168     }
1169     else
1170     {
1171         const DAQ_Stats_t* ps = DAQ_GetStats();
1172         recv = ps->hw_packets_received;
1173         drop = ps->hw_packets_dropped;
1174         if (perfmon_config->base_reset)
1175         {
1176             if (recv < sfBase->pkt_stats.pkts_recv)
1177                 sfBase->pkt_stats.pkts_recv = 0;
1178 
1179             if (drop < sfBase->pkt_stats.pkts_drop)
1180                 sfBase->pkt_stats.pkts_drop = 0;
1181         }
1182     }
1183 
1184     if (perfmon_config->base_reset)
1185     {
1186         sfBaseStats->pkt_stats.pkts_recv = recv - sfBase->pkt_stats.pkts_recv;
1187         sfBaseStats->pkt_stats.pkts_drop = drop - sfBase->pkt_stats.pkts_drop;
1188     }
1189     else
1190     {
1191         sfBaseStats->pkt_stats.pkts_recv = recv;
1192         sfBaseStats->pkt_stats.pkts_drop = drop;
1193     }
1194 
1195     sum = sfBaseStats->pkt_stats.pkts_recv
1196         + sfBaseStats->pkt_stats.pkts_drop;
1197 
1198     if ( !sum )
1199         sfBaseStats->pkt_drop_percent = 0.0;
1200 
1201     else
1202         sfBaseStats->pkt_drop_percent = zeroFpException(
1203             ((double)sfBaseStats->pkt_stats.pkts_drop / (double)sum) * 100.0);
1204 
1205     /*
1206     **  Reset sfBase stats for next go round.
1207     */
1208     sfBase->pkt_stats.pkts_recv = recv;
1209     sfBase->pkt_stats.pkts_drop = drop;
1210 }
1211 
1212 /*
1213  *
1214  *   Log Base Per Stats to File
1215  *
1216  * unixtime(in secs since epoch)
1217  * %pkts dropped
1218  * mbits/sec (wire)
1219  * alerts/sec
1220  * K-Packets/Sec (wire)
1221  * Avg Bytes/Pkt  (wire)
1222  * %bytes pattern matched
1223  * syns/sec
1224  * synacks/sec
1225  * new-sessions/sec (tcp stream cache)
1226  * del-sessions/sec (tcp stream cache)
1227  * total-sessions open (tcp stream cache)
1228  * max-sessions, lifetime (tcp stream cache)
1229  * streamflushes/sec
1230  * streamfaults/sec
1231  * streamtimeouts
1232  * fragcreates/sec
1233  * fragcompletes/sec
1234  * fraginserts/sec
1235  * fragdeletes/sec
1236  * fragflushes/sec
1237  * current-frags open (frag cache)
1238  * max-frags (frag cache)
1239  * fragtimeouts
1240  * fragfaults
1241  * num cpus (following triple is repeated for each CPU)
1242  * %user-cpu usage
1243  * %sys-cpu usage
1244  * %idle-cpu usage
1245  * mbits/sec (wire)
1246  * mbits/sec (ip fragmented)
1247  * mbits/sec (ip reassembled)
1248  * mbits/sec (tcp stream rebuilt)
1249  * mbits/sec (app layer)
1250  * Avg Bytes/Pkt  (wire)
1251  * Avg Bytes/Pkt  (ip fragmented)
1252  * Avg Bytes/Pkt  (ip reassembled)
1253  * Avg Bytes/Pkt  (tcp stream rebuilt)
1254  * Avg Bytes/Pkt  (app layer)
1255  * K-Packets/Sec (wire)
1256  * K-Packets/Sec (ip fragmented)
1257  * K-Packets/Sec (ip reassembled)
1258  * K-Packets/Sec (tcp stream rebuilt)
1259  * K-Packets/Sec (app layer)
1260  * Pkts recieved
1261  * Pkts dropped
1262  * Blocked-KPackets  (wire)
1263  * udp-sessions
1264  * max-udp-sessions
1265  * del-udp-sessions/sec (udp stream cache)
1266  * new-udp-sessions/sec (udp stream cache)
1267  * max-sessions, interval (tcp stream cache)
1268  * curr-tcp-sessions-initializing (tcp stream cache, of total-sessions open)
1269  * curr-tcp-sessions-established (tcp stream cache, of total-sessions open)
1270  * curr-tcp-sessions-closing (tcp stream cache, of total-sessions open)
1271  * tcp-sessions-mistream/sec (tcp stream cache, of new-sessions/sec)
1272  * tcp-sessions-closed/sec (tcp stream cache, of del-sessions/sec)
1273  * tcp-sessions-timedout/sec (tcp stream cache, of del-sessions/sec)
1274  * tcp-sessions-pruned/sec (tcp stream cache, of del-sessions/sec)
1275  * tcp-sessions-dropped_async/sec (tcp stream cache, of del-sessions/sec)
1276  * hosts in attribute table
1277  * attribute table reloads
1278  *
1279  */
1280 
1281 // IMPORTANT - whatever changes you make here, please be sure
1282 // they are reflected in the LogBasePerfHeader() below!
LogBasePerfStats(SFBASE_STATS * sfBaseStats,FILE * fh)1283 static void LogBasePerfStats(SFBASE_STATS *sfBaseStats,  FILE * fh )
1284 {
1285     double sys=0.0,usr=0.0,idle=0.0;
1286     int iCtr = 0;
1287     long start, size = 0;
1288     size_t wrote;
1289     // Oversized buffer; For perspective, the column header is only 1905 + 1 ('\n') characters long.
1290     static char buff[4096];
1291 
1292     if (fh == NULL)
1293         return;
1294 
1295     if ( (start = ftell(fh)) < 0 )
1296         return;
1297 
1298     memset(buff, 0, sizeof(buff));
1299 
1300     size = SafeSnprintf(buff, sizeof(buff),
1301         "%lu,%.3f,%.3f,%.3f,%.3f,%d,%.3f,",
1302         (unsigned long)sfBaseStats->time,
1303         sfBaseStats->pkt_drop_percent,
1304         sfBaseStats->wire_mbits_per_sec.realtime,
1305         sfBaseStats->alerts_per_second,
1306         sfBaseStats->kpackets_wire_per_sec.realtime,
1307         sfBaseStats->avg_bytes_per_wire_packet,
1308         sfBaseStats->patmatch_percent);
1309 
1310     /* Session estimation statistics */
1311 
1312     size += SafeSnprintf(buff + size, sizeof(buff) - size,
1313         "%.3f,%.3f,%.3f,%.3f," CSVu64 CSVu64,
1314         sfBaseStats->syns_per_second,
1315         sfBaseStats->synacks_per_second,
1316         sfBaseStats->new_sessions_per_second,
1317         sfBaseStats->deleted_sessions_per_second,
1318         sfBaseStats->total_sessions,
1319         sfBaseStats->max_sessions);
1320 
1321 
1322     size += SafeSnprintf(buff + size, sizeof(buff) - size,
1323         "%.3f," CSVu64 CSVu64,
1324         sfBaseStats->stream_flushes_per_second,
1325         sfBaseStats->stream_faults,
1326         sfBaseStats->stream_timeouts);
1327 
1328     size += SafeSnprintf(buff + size, sizeof(buff) - size,
1329         "%.3f,%.3f,%.3f,%.3f,%.3f,%.3f," CSVu64 CSVu64 CSVu64 CSVu64,
1330         sfBaseStats->frag_creates_per_second,
1331         sfBaseStats->frag_completes_per_second,
1332         sfBaseStats->frag_inserts_per_second,
1333         sfBaseStats->frag_deletes_per_second,
1334         sfBaseStats->frag_autofrees_per_second,
1335         sfBaseStats->frag_flushes_per_second,
1336         sfBaseStats->current_frags,
1337         sfBaseStats->max_frags,
1338         sfBaseStats->frag_timeouts,
1339         sfBaseStats->frag_faults);
1340 
1341     /* CPU STATS - at the end of output record */
1342 #ifdef LINUX_SMP
1343     /* First the number of CPUs */
1344     size += SafeSnprintf(buff + size, sizeof(buff) - size,
1345         "%d,", sfBaseStats->sfProcPidStats->iCPUs);
1346 
1347     /* Next, stats for each CPU (a triple) */
1348     for(iCtr = 0; iCtr < sfBaseStats->sfProcPidStats->iCPUs; iCtr++)
1349     {
1350         usr= sfBaseStats->sfProcPidStats->SysCPUs[iCtr].user;
1351         sys= sfBaseStats->sfProcPidStats->SysCPUs[iCtr].sys;
1352         idle= sfBaseStats->sfProcPidStats->SysCPUs[iCtr].idle;
1353 
1354         size += SafeSnprintf(buff + size, sizeof(buff) - size,
1355             "%.3f,%.3f,%.3f,",usr,sys,idle);
1356     }
1357 
1358 #else
1359 
1360     usr=sfBaseStats->user_cpu_time;
1361     sys=sfBaseStats->system_cpu_time;
1362     idle=sfBaseStats->idle_cpu_time;
1363 
1364     /* 1 CPU hardcoded */
1365     size += SafeSnprintf(buff + size, sizeof(buff) - size,
1366         "1,%.3f,%.3f,%.3f,",usr,sys,idle);
1367 
1368 #endif
1369 
1370     /* Status for MBits/s, Bytes/Pkt, KPkts/s for each of
1371      * wire, IP Fragmented, IP Reassembled, Stream Reassembled,
1372      * App Layer (data that reaches protocol decoders). */
1373     size += SafeSnprintf(buff + size, sizeof(buff) - size,
1374         "%.3f,%.3f,%.3f,%.3f,%.3f,",
1375         sfBaseStats->wire_mbits_per_sec.realtime,
1376         sfBaseStats->ipfrag_mbits_per_sec.realtime,
1377         sfBaseStats->ipreass_mbits_per_sec.realtime,
1378         sfBaseStats->rebuilt_mbits_per_sec.realtime,
1379         sfBaseStats->mbits_per_sec.realtime);
1380 
1381     size += SafeSnprintf(buff + size, sizeof(buff) - size,
1382         "%d,%d,%d,%d,%d,",
1383         sfBaseStats->avg_bytes_per_wire_packet,
1384         sfBaseStats->avg_bytes_per_ipfrag_packet,
1385         sfBaseStats->avg_bytes_per_ipreass_packet,
1386         sfBaseStats->avg_bytes_per_rebuilt_packet,
1387         sfBaseStats->avg_bytes_per_packet);
1388 
1389     size += SafeSnprintf(buff + size, sizeof(buff) - size,
1390         "%.3f,%.3f,%.3f,%.3f,%.3f,",
1391         sfBaseStats->kpackets_wire_per_sec.realtime,
1392         sfBaseStats->kpackets_ipfrag_per_sec.realtime,
1393         sfBaseStats->kpackets_ipreass_per_sec.realtime,
1394         sfBaseStats->kpackets_rebuilt_per_sec.realtime,
1395         sfBaseStats->kpackets_per_sec.realtime);
1396 
1397     size += SafeSnprintf(buff + size, sizeof(buff) - size,
1398         CSVu64,sfBaseStats->pkt_stats.pkts_recv);
1399 
1400     size += SafeSnprintf(buff + size, sizeof(buff) - size,
1401         CSVu64, sfBaseStats->pkt_stats.pkts_drop);
1402 
1403     size += SafeSnprintf(buff + size, sizeof(buff) - size,
1404         CSVu64, sfBaseStats->total_blocked_packets);
1405 
1406     size += SafeSnprintf(buff + size, sizeof(buff) - size,
1407         "%.3f,%.3f," CSVu64 CSVu64,
1408         sfBaseStats->new_udp_sessions_per_second,
1409         sfBaseStats->deleted_udp_sessions_per_second,
1410         sfBaseStats->total_udp_sessions,
1411         sfBaseStats->max_udp_sessions);
1412 
1413     size += SafeSnprintf(buff + size, sizeof(buff) - size,
1414         CSVu64 CSVu64 CSVu64 CSVu64 "%.3f,%.3f,%.3f,%.3f,%.3f,",
1415         sfBaseStats->max_tcp_sessions_interval,
1416         sfBaseStats->curr_tcp_sessions_initializing,
1417         sfBaseStats->curr_tcp_sessions_established,
1418         sfBaseStats->curr_tcp_sessions_closing,
1419         sfBaseStats->tcp_sessions_midstream_per_second,
1420         sfBaseStats->tcp_sessions_closed_per_second,
1421         sfBaseStats->tcp_sessions_timedout_per_second,
1422         sfBaseStats->tcp_sessions_pruned_per_second,
1423         sfBaseStats->tcp_sessions_dropped_async_per_second);
1424 
1425     size += SafeSnprintf(buff + size, sizeof(buff) - size,
1426         CSVu64 CSVu64,
1427         sfBaseStats->current_attribute_hosts,
1428         sfBaseStats->attribute_table_reloads);
1429 
1430     size += SafeSnprintf(buff + size, sizeof(buff) - size,
1431         "%.3f,%d,%.3f,", sfBaseStats->mpls_mbits_per_sec.realtime,
1432         sfBaseStats->avg_bytes_per_mpls_packet,
1433         sfBaseStats->kpackets_per_sec_mpls.realtime);
1434 
1435     size += SafeSnprintf(buff + size, sizeof(buff) - size,
1436         CSVu64 CSVu64,
1437         sfBaseStats->total_tcp_filtered_packets,
1438         sfBaseStats->total_udp_filtered_packets);
1439 
1440 #ifdef NORMALIZER
1441     size += SafeSnprintf(buff + size, sizeof(buff) - size,
1442         "%d,",
1443         PERF_COUNT_MAX);
1444     for ( iCtr = 0; iCtr < PERF_COUNT_MAX; iCtr++ )
1445         size += SafeSnprintf(buff + size, sizeof(buff) - size,
1446             CSVu64, sfBaseStats->pegs[iCtr][NORM_MODE_ON]);
1447     for ( iCtr = 0; iCtr < PERF_COUNT_MAX; iCtr++ )
1448         size += SafeSnprintf(buff + size, sizeof(buff) - size,
1449             CSVu64, sfBaseStats->pegs[iCtr][NORM_MODE_WOULDA]);
1450 #endif
1451 
1452     size += SafeSnprintf(buff + size, sizeof(buff) - size,
1453         CSVu64, sfBaseStats->total_injected_packets);
1454     size += SafeSnprintf(buff + size, sizeof(buff) - size,
1455         CSVu64, sfBaseStats->frag3_mem_in_use);
1456     size += SafeSnprintf(buff + size, sizeof(buff) - size,
1457         CSVu64, sfBaseStats->stream5_mem_in_use);
1458 
1459     size += SafeSnprintf(buff + size, sizeof(buff) - size,
1460         "%.3f", sfBaseStats->total_alerts_per_second);
1461 
1462     size += SafeSnprintf(buff + size, sizeof(buff) - size, "\n");
1463 
1464     // Write to file. On error, reset the file position and inform the user.
1465     wrote = fwrite(buff, size, 1, fh);
1466 
1467     if (wrote != 1)
1468     {
1469         WarningMessage("%s: Failed to write stats\n", __FUNCTION__);
1470 
1471         // fseek to adjust offset; ftruncate doesn't do that for us.
1472         if (fseek(fh, start, SEEK_SET))
1473         {
1474             WarningMessage("%s: Failed to adjust offset\n", __FUNCTION__);
1475         }
1476         ftruncate(fileno(fh), start);
1477     }
1478 
1479     fflush(fh);
1480 }
1481 
1482 #ifdef NORMALIZER
1483 static const char* iNames[PERF_COUNT_MAX] = {
1484     "ip4::trim",
1485     "ip4::tos",
1486     "ip4::df",
1487     "ip4::rf",
1488     "ip4::ttl",
1489     "ip4::opts",
1490     "icmp4::echo",
1491     "ip6::ttl",
1492     "ip6::opts",
1493     "icmp6::echo",
1494     "tcp::syn_opt",
1495     "tcp::opt",
1496     "tcp::pad",
1497     "tcp::rsv",
1498     "tcp::ns",
1499     "tcp::urp",
1500     "tcp::ecn_pkt",
1501     "tcp::ecn_ssn",
1502     "tcp::ts_ecr",
1503     "tcp::ts_nop",
1504     "tcp::ips_data",
1505     "tcp::block",
1506     "tcp::req_urg",
1507     "tcp::req_pay",
1508     "tcp::req_urp",
1509     "tcp::trim_syn",
1510     "tcp::trim_rst",
1511     "tcp::trim_win",
1512     "tcp::trim_mss",
1513 };
1514 #endif
1515 
1516 // IMPORTANT - whatever changes you make here, please be sure
1517 // they correspond to the LogBasePerfStats() above!
LogBasePerfHeader(FILE * fh)1518 void LogBasePerfHeader (FILE* fh)
1519 {
1520     int iCtr, iCPUs;
1521     if( !fh ) return;
1522 
1523     fprintf(fh,
1524         "#%s,%s,%s,%s,%s,%s,%s",
1525         "time",
1526         "pkt_drop_percent",
1527         "wire_mbits_per_sec.realtime",
1528         "alerts_per_second",
1529         "kpackets_wire_per_sec.realtime",
1530         "avg_bytes_per_wire_packet",
1531         "patmatch_percent");
1532 
1533     /* Session estimation statistics */
1534 
1535     fprintf(fh,
1536         ",%s,%s,%s,%s,%s,%s",
1537         "syns_per_second",
1538         "synacks_per_second",
1539         "new_sessions_per_second",
1540         "deleted_sessions_per_second",
1541         "total_sessions",
1542         "max_sessions");
1543 
1544     fprintf(fh,
1545         ",%s,%s,%s",
1546         "stream_flushes_per_second",
1547         "stream_faults",
1548         "stream_timeouts");
1549 
1550     fprintf(fh,
1551         ",%s,%s,%s,%s,%s,%s,%s,%s,%s,%s",
1552         "frag_creates_per_second",
1553         "frag_completes_per_second",
1554         "frag_inserts_per_second",
1555         "frag_deletes_per_second",
1556         "frag_autofrees_per_second",
1557         "frag_flushes_per_second",
1558         "current_frags",
1559         "max_frags",
1560         "frag_timeouts",
1561         "frag_faults");
1562 
1563     /* First the number of CPUs */
1564     fprintf(fh,
1565         ",%s", "iCPUs");
1566 
1567 #ifdef LINUX_SMP
1568     iCPUs = sfBase.sfProcPidStats.iCPUs;
1569 #else
1570     iCPUs = 1;
1571 #endif
1572     /* Next, stats for each CPU (a triple) */
1573     for ( iCtr = 0; iCtr < iCPUs; iCtr++ )
1574     {
1575         fprintf(fh,
1576             ",%s[%d],%s[%d],%s[%d]",
1577             "usr",iCtr,"sys",iCtr,"idle",iCtr);
1578     }
1579 
1580     /* Status for MBits/s, Bytes/Pkt, KPkts/s for each of
1581      * wire, IP Fragmented, IP Reassembled, Stream Reassembled,
1582      * App Layer (data that reaches protocol decoders). */
1583     fprintf(fh,
1584         ",%s,%s,%s,%s,%s",
1585         "wire_mbits_per_sec.realtime",
1586         "ipfrag_mbits_per_sec.realtime",
1587         "ipreass_mbits_per_sec.realtime",
1588         "rebuilt_mbits_per_sec.realtime",
1589         "mbits_per_sec.realtime");
1590 
1591     fprintf(fh,
1592         ",%s,%s,%s,%s,%s",
1593         "avg_bytes_per_wire_packet",
1594         "avg_bytes_per_ipfrag_packet",
1595         "avg_bytes_per_ipreass_packet",
1596         "avg_bytes_per_rebuilt_packet",
1597         "avg_bytes_per_packet");
1598 
1599     fprintf(fh,
1600         ",%s,%s,%s,%s,%s",
1601         "kpackets_wire_per_sec.realtime",
1602         "kpackets_ipfrag_per_sec.realtime",
1603         "kpackets_ipreass_per_sec.realtime",
1604         "kpackets_rebuilt_per_sec.realtime",
1605         "kpackets_per_sec.realtime");
1606 
1607     fprintf(fh,
1608         ",%s,%s,%s",
1609         "pkt_stats.pkts_recv",
1610         "pkt_stats.pkts_drop",
1611         "total_blocked_verdicts");
1612 
1613     fprintf(fh,
1614         ",%s,%s,%s,%s",
1615         "new_udp_sessions_per_second",
1616         "deleted_udp_sessions_per_second",
1617         "total_udp_sessions",
1618         "max_udp_sessions");
1619 
1620     fprintf(fh,
1621         ",%s,%s,%s,%s,%s,%s,%s,%s,%s",
1622         "max_tcp_sessions_interval",
1623         "curr_tcp_sessions_initializing",
1624         "curr_tcp_sessions_established",
1625         "curr_tcp_sessions_closing",
1626         "tcp_sessions_midstream_per_second",
1627         "tcp_sessions_closed_per_second",
1628         "tcp_sessions_timedout_per_second",
1629         "tcp_sessions_pruned_per_second",
1630         "tcp_sessions_dropped_async_per_second");
1631 
1632     fprintf(fh,
1633         ",%s,%s",
1634         "current_attribute_hosts",
1635         "attribute_table_reloads");
1636 
1637     fprintf(fh,
1638         ",%s,%s,%s", "mpls_mbits_per_sec.realtime",
1639         "avg_bytes_per_mpls_packet",
1640         "kpackets_per_sec_mpls.realtime");
1641 
1642     fprintf(fh,
1643         ",%s,%s",
1644         "total_tcp_filtered_packets",
1645         "total_udp_filtered_packets");
1646 
1647 #ifdef NORMALIZER
1648     fprintf(fh, ",num_normalizations");
1649     for ( iCtr = 0; iCtr < PERF_COUNT_MAX; iCtr++ )
1650         fprintf(fh, ",%s", iNames[iCtr]);
1651     for ( iCtr = 0; iCtr < PERF_COUNT_MAX; iCtr++ )
1652         fprintf(fh, ",would_%s", iNames[iCtr]);
1653 #endif
1654 
1655     fprintf(fh,
1656         ",%s,%s,%s",
1657         "total_injected_packets",
1658         "frag3_mem_in_use",
1659         "stream5_mem_in_use");
1660 
1661     fprintf(fh, ",%s",
1662         "total_alerts_per_second");
1663 
1664     fprintf(fh,"\n");
1665     fflush(fh);
1666 }
1667 
1668 /*
1669 **  NAME
1670 **    DisplayBasePerfStats
1671 **
1672 **  DESCRIPTION
1673 **    Output Function.  We can easily code multiple output buffers
1674 **    because all that is received is a SFBASE_STATS struct which
1675 **    holds all the information to output.  This current output
1676 **    function just prints to stdout.
1677 **
1678 **  FORMAL INPUTS
1679 **    SFBASE_STATS * - struct with perf information
1680 **    int            - flags for output
1681 **
1682 **  FORMAL OUTPUTS
1683 **    void return
1684 */
DisplayBasePerfStatsConsole(SFBASE_STATS * sfBaseStats,int max_stats)1685 static void DisplayBasePerfStatsConsole(SFBASE_STATS *sfBaseStats, int max_stats)
1686 {
1687     int iCtr = 0;
1688 
1689     LogMessage("\n");
1690     LogMessage("\n");
1691     LogMessage("Snort Realtime Performance  : %s--------------------------\n",
1692                ctime(&sfBaseStats->time));
1693 
1694     LogMessage("Pkts Recv:   " STDu64 "\n", sfBaseStats->pkt_stats.pkts_recv);
1695 
1696     LogMessage("Pkts Drop:   " STDu64 "\n", sfBaseStats->pkt_stats.pkts_drop);
1697 
1698     LogMessage("%% Dropped:   %.3f%%\n", sfBaseStats->pkt_drop_percent);
1699 
1700     LogMessage("Block Verdict:     " STDu64 "\n", sfBaseStats->total_blocked_packets);
1701     LogMessage("Injected:    " STDu64 "\n", sfBaseStats->total_injected_packets);
1702     LogMessage("Pkts Filtered TCP:     " STDu64 "\n", sfBaseStats->total_tcp_filtered_packets);
1703     LogMessage("Pkts Filtered UDP:     " STDu64 "\n\n", sfBaseStats->total_udp_filtered_packets);
1704 
1705     LogMessage("Mbits/Sec:   %.3f (wire)\n",
1706             sfBaseStats->wire_mbits_per_sec.realtime);
1707 #ifdef MPLS
1708     LogMessage("Mbits/Sec:   %.3f (mpls)\n",
1709                 sfBaseStats->mpls_mbits_per_sec.realtime);
1710 #endif
1711     LogMessage("Mbits/Sec:   %.3f (ip fragmented)\n",
1712             sfBaseStats->ipfrag_mbits_per_sec.realtime);
1713     LogMessage("Mbits/Sec:   %.3f (ip reassembled)\n",
1714             sfBaseStats->ipreass_mbits_per_sec.realtime);
1715     LogMessage("Mbits/Sec:   %.3f (tcp rebuilt)\n",
1716             sfBaseStats->rebuilt_mbits_per_sec.realtime);
1717     LogMessage("Mbits/Sec:   %.3f (app layer)\n\n",
1718             sfBaseStats->mbits_per_sec.realtime);
1719 
1720     LogMessage("Bytes/Pkt:   %d (wire)\n",
1721         sfBaseStats->avg_bytes_per_wire_packet);
1722 #ifdef MPLS
1723     LogMessage("Bytes/Pkt:   %d (mpls)\n",
1724         sfBaseStats->avg_bytes_per_mpls_packet);
1725 #endif
1726     LogMessage("Bytes/Pkt:   %d (ip fragmented)\n",
1727         sfBaseStats->avg_bytes_per_ipfrag_packet);
1728     LogMessage("Bytes/Pkt:   %d (ip reassembled)\n",
1729         sfBaseStats->avg_bytes_per_ipreass_packet);
1730     LogMessage("Bytes/Pkt:   %d (tcp rebuilt)\n",
1731         sfBaseStats->avg_bytes_per_rebuilt_packet);
1732     LogMessage("Bytes/Pkt:   %d (app layer)\n\n",
1733         sfBaseStats->avg_bytes_per_packet);
1734 
1735     LogMessage("KPkts/Sec:   %.3f (wire)\n",
1736         sfBaseStats->kpackets_wire_per_sec.realtime);
1737 #ifdef MPLS
1738     LogMessage("KPkts/Sec:   %.3f (mpls)\n",
1739         sfBaseStats->kpackets_per_sec_mpls.realtime);
1740 #endif
1741     LogMessage("KPkts/Sec:   %.3f (ip fragmented)\n",
1742         sfBaseStats->kpackets_ipfrag_per_sec.realtime);
1743     LogMessage("KPkts/Sec:   %.3f (ip reassembled)\n",
1744         sfBaseStats->kpackets_ipreass_per_sec.realtime);
1745     LogMessage("KPkts/Sec:   %.3f (tcp rebuilt)\n",
1746         sfBaseStats->kpackets_rebuilt_per_sec.realtime);
1747     LogMessage("KPkts/Sec:   %.3f (app layer)\n\n",
1748         sfBaseStats->kpackets_per_sec.realtime);
1749 
1750     LogMessage("PatMatch:    %.3f%%\n\n",  sfBaseStats->patmatch_percent);
1751 
1752     /*
1753     **  The following ifdefs are for CPU stats dealing with multiple
1754     **  CPUs in Linux.  Snort will show user, system and idle time for
1755     **  each CPU.  The methods of calculating this are different though,
1756     **  since getrusage is broken for multiple CPUs in Linux.  We get the
1757     **  CPU stats instead from the proc filesystem on Linux.
1758     */
1759 #ifdef LINUX_SMP
1760 
1761     for(iCtr = 0; iCtr < sfBaseStats->sfProcPidStats->iCPUs; iCtr++)
1762     {
1763     LogMessage("CPU%d Usage:  %.3f%% (user)  %.3f%% (sys)  %.3f%% (idle)\n",
1764                 iCtr,
1765                 sfBaseStats->sfProcPidStats->SysCPUs[iCtr].user,
1766                 sfBaseStats->sfProcPidStats->SysCPUs[iCtr].sys,
1767                 sfBaseStats->sfProcPidStats->SysCPUs[iCtr].idle);
1768     }
1769     printf("\n");
1770 
1771 #else
1772 
1773     LogMessage("CPU Usage:   %.3f%% (user)  %.3f%% (sys)  %.3f%% (idle)\n\n",
1774                 sfBaseStats->user_cpu_time,
1775                 sfBaseStats->system_cpu_time,
1776                 sfBaseStats->idle_cpu_time);
1777 
1778 #endif
1779 
1780     /*
1781     **  Shows the number of snort alerts per second.
1782     */
1783     LogMessage("Alerts/Sec             :  %.3f\n",   sfBaseStats->alerts_per_second);
1784 
1785     /* Session estimation statistics */
1786     LogMessage("Syns/Sec               :  %.3f\n", sfBaseStats->syns_per_second);
1787     LogMessage("Syn-Acks/Sec           :  %.3f\n", sfBaseStats->synacks_per_second);
1788     LogMessage("New Cached Sessions/Sec:  %.3f\n", sfBaseStats->new_sessions_per_second);
1789     LogMessage("Midstream Sessions/Sec :  %.3f\n", sfBaseStats->tcp_sessions_midstream_per_second);
1790     LogMessage("Cached Sessions Del/Sec:  %.3f\n", sfBaseStats->deleted_sessions_per_second);
1791     LogMessage("Closed Sessions/Sec    :  %.3f\n", sfBaseStats->tcp_sessions_closed_per_second);
1792     LogMessage("TimedOut Sessions/Sec  :  %.3f\n", sfBaseStats->tcp_sessions_timedout_per_second);
1793     LogMessage("Pruned Sessions/Sec    :  %.3f\n", sfBaseStats->tcp_sessions_pruned_per_second);
1794     LogMessage("Dropped Async Ssns/Sec :  %.3f\n", sfBaseStats->tcp_sessions_dropped_async_per_second);
1795 
1796     LogMessage("Current Cached Sessions:  " STDu64 "\n", sfBaseStats->total_sessions);
1797     LogMessage("Sessions Initializing  :  " STDu64 "\n", sfBaseStats->curr_tcp_sessions_initializing);
1798     LogMessage("Sessions Established   :  " STDu64 "\n", sfBaseStats->curr_tcp_sessions_established);
1799     LogMessage("Sessions Closing       :  " STDu64 "\n", sfBaseStats->curr_tcp_sessions_closing);
1800     LogMessage("Max Cached Sessions    :  " STDu64 "\n", sfBaseStats->max_sessions);
1801     LogMessage("Max Sessions (interval):  " STDu64 "\n", sfBaseStats->max_tcp_sessions_interval);
1802 
1803     /* more instrumentation for stream4/frag2 */
1804     LogMessage("Stream Flushes/Sec     :  %.3f\n", sfBaseStats->stream_flushes_per_second);
1805     LogMessage("Stream Cache Faults/Sec:  " STDu64 "\n", sfBaseStats->stream_faults);
1806     LogMessage("Stream Cache Timeouts  :  " STDu64 "\n", sfBaseStats->stream_timeouts);
1807 
1808     LogMessage("Frag Creates()s/Sec    :  %.3f\n", sfBaseStats->frag_creates_per_second);
1809     LogMessage("Frag Completes()s/Sec  :  %.3f\n", sfBaseStats->frag_completes_per_second);
1810     LogMessage("Frag Inserts()s/Sec    :  %.3f\n", sfBaseStats->frag_inserts_per_second);
1811     LogMessage("Frag Deletes/Sec       :  %.3f\n", sfBaseStats->frag_deletes_per_second);
1812     LogMessage("Frag AutoFrees/Sec     :  %.3f\n", sfBaseStats->frag_autofrees_per_second);
1813     LogMessage("Frag Flushes/Sec       :  %.3f\n", sfBaseStats->frag_flushes_per_second);
1814 
1815     LogMessage("Current Cached Frags   :  " STDu64 "\n", sfBaseStats->current_frags);
1816     LogMessage("Max Cached Frags       :  " STDu64 "\n", sfBaseStats->max_frags);
1817     LogMessage("Frag Timeouts          :  " STDu64 "\n", sfBaseStats->frag_timeouts);
1818     LogMessage("Frag Faults            :  " STDu64 "\n\n", sfBaseStats->frag_faults);
1819 
1820     LogMessage("New Cached UDP Ssns/Sec:  %.3f\n", sfBaseStats->new_udp_sessions_per_second);
1821     LogMessage("Cached UDP Ssns Del/Sec:  %.3f\n", sfBaseStats->deleted_udp_sessions_per_second);
1822 
1823     LogMessage("Current Cached UDP Ssns:  " STDu64 "\n", sfBaseStats->total_udp_sessions);
1824     LogMessage("Max Cached UDP Ssns    :  " STDu64 "\n\n", sfBaseStats->max_udp_sessions);
1825 
1826 #ifdef TARGET_BASED
1827     LogMessage("Attribute Table Hosts  :  " STDu64 "\n", sfBaseStats->current_attribute_hosts);
1828     LogMessage("Attribute Table Reloads:  " STDu64 "\n\n", sfBaseStats->attribute_table_reloads);
1829 #endif
1830 
1831 #ifdef NORMALIZER
1832     LogMessage("Number of Normalizations  :  %d\n", PERF_COUNT_MAX);
1833     for ( iCtr = 0; iCtr < PERF_COUNT_MAX; iCtr++ )
1834     {
1835         LogMessage("%-26s:  " STDu64 "\n",
1836             iNames[iCtr], sfBaseStats->pegs[iCtr][NORM_MODE_ON]);
1837         LogMessage("Would %-20s:  " STDu64 "\n",
1838             iNames[iCtr], sfBaseStats->pegs[iCtr][NORM_MODE_WOULDA]);
1839     }
1840 #endif
1841     LogMessage("\n");
1842 
1843     /*
1844     **  Snort Maximum Performance Statistics
1845     **  These statistics calculate the maximum performance that
1846     **  snort could attain by using the getrusage numbers.  We've
1847     **  seen in testing that these numbers come close to the actual
1848     **  throughput for Mbits/Sec and Pkt/Sec.  But note that these
1849     **  are not hard numbers and rigorous testing is necessary to
1850     **  establish snort performance on any hardware setting.
1851     */
1852     if (max_stats)
1853     {
1854 
1855         LogMessage("Snort Maximum Performance\n");
1856         LogMessage("-------------------------\n\n");
1857 
1858         LogMessage("Mbits/Second\n");
1859         LogMessage("----------------\n");
1860         LogMessage("Snort:       %.3f\n",sfBaseStats->mbits_per_sec.usertime);
1861         LogMessage("Sniffing:    %.3f\n",sfBaseStats->mbits_per_sec.systemtime);
1862         LogMessage("Combined:    %.3f\n\n",sfBaseStats->mbits_per_sec.totaltime);
1863 
1864 
1865         LogMessage("uSeconds/Pkt\n");
1866         LogMessage("----------------\n");
1867         LogMessage("Snort:       %.3f\n",sfBaseStats->usecs_per_packet.usertime);
1868         LogMessage("Sniffing:    %.3f\n",sfBaseStats->usecs_per_packet.systemtime);
1869         LogMessage("Combined:    %.3f\n\n",sfBaseStats->usecs_per_packet.totaltime);
1870 
1871         LogMessage("KPkts/Second\n");
1872         LogMessage("------------------\n");
1873         LogMessage("Snort:       %.3f\n",sfBaseStats->kpackets_per_sec.usertime);
1874         LogMessage("Sniffing:    %.3f\n",sfBaseStats->kpackets_per_sec.systemtime);
1875         LogMessage("Combined:    %.3f\n\n",sfBaseStats->kpackets_per_sec.totaltime);
1876     }
1877 }
1878 
1879 
1880