📄 perf-base.c
字号:
/*** $Id$**** perf-base.c**** Copyright (C) 2002 Sourcefire,Inc** Dan Roelker <droelker@sourcefire.com>** Marc Norton <mnorton@sourcefire.com>**** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License Version 2 as** published by the Free Software Foundation. You may not use, modify or** distribute this program under any other version of the GNU General** Public License.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the** GNU General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.**** DESCRIPTION** The following subroutines are concerned with getting** basic stats on packet bytes and times that an app** takes in processing packets. The times measured are** kernel and user time for the process. Real-time** (wall clock) is also measured to show when processing** has reached capacity and to measure the true processing ** that the app is currently doing.**** NOTES** 4.8.02 : Initial Code (DJR,MAN)** 4.22.02 : Added Comments (DJR)** 7.10.02 : Added sfprocpidstats code for SMP linux (DJR)** 8.8.02 : Added stream4 instrumentation (cmg)** 9.1.04 : Removed NO_PKTS, ACCUMULATE/RESET #defines, now we use SFBASE->iReset** and the permonitor command has 'reset' and 'accrue' commands instead.(MAN)** 10.4.06 : Added UDP Session Stats (SAS)** 4.3.07 : Added stats for TCP sessions (SAS)*/#include <time.h>#ifndef WIN32#include <sys/time.h>#include <sys/resource.h>#endif#include <stdlib.h>#include <stdio.h>#include <sys/types.h>#include "snort.h"#include "inline.h"#include "util.h"#include "mpse.h"#include "stream_api.h"#include "sf_types.h"int GetPktDropStats(SFBASE *sfBase, SFBASE_STATS *sfBaseStats);int DisplayBasePerfStatsConsole(SFBASE_STATS *sfBaseStats, int iFlags);int CalculateBasePerfStats(SFBASE *sfPerf, SFBASE_STATS *sfBaseStats);int LogBasePerfStats(SFBASE_STATS *sfBaseStats, FILE * fh );/*** NAME** InitBaseStats** DESCRIPTION** Initializes structs and variables for the next performance** sample.**** FORMAL INPUTS** SFBASE * -- pointer to structure to initialize** ** FORMAL OUTPUTS** int -- 0 is successful*/ int InitBaseStats(SFBASE *sfBase){ int todRet = -1; struct timeval tvTime;#ifndef WIN32#ifndef LINUX_SMP struct rusage rusage; int rusageRet = -1;#endif #ifdef LINUX_SMP static int first_time = 0; if(!first_time) { sfInitProcPidStats(&(sfBase->sfProcPidStats)); first_time = 1; } todRet = gettimeofday(&tvTime, NULL);#else rusageRet = getrusage(RUSAGE_SELF, &rusage); todRet = gettimeofday(&tvTime, NULL); if (rusageRet >= 0) { sfBase->usertime_sec = (double)rusage.ru_utime.tv_sec + ((double)rusage.ru_utime.tv_usec * 1.0e-6); sfBase->systemtime_sec = (double)rusage.ru_stime.tv_sec + ((double)rusage.ru_stime.tv_usec * 1.0e-6); } else { sfBase->usertime_sec = 0; sfBase->systemtime_sec = 0; }#endif /* !LINUX_SMP */#else sfBase->usertime_sec = 0; sfBase->systemtime_sec = 0; todRet = gettimeofday(&tvTime, NULL);#endif /* !WIN32 */ if(todRet >= 0) { sfBase->realtime_sec = (double)tvTime.tv_sec + ((double)tvTime.tv_usec * 1.0e-6); } else { sfBase->realtime_sec = 0; } sfBase->total_blocked_packets = 0; sfBase->total_wire_packets = 0; sfBase->total_ipfragmented_packets = 0; sfBase->total_ipreassembled_packets = 0; sfBase->total_packets = 0; sfBase->total_rebuilt_packets = 0; sfBase->total_wire_bytes = 0; sfBase->total_ipfragmented_bytes = 0; sfBase->total_ipreassembled_bytes = 0; sfBase->total_bytes = 0; sfBase->total_rebuilt_bytes = 0; sfBase->total_blocked_bytes = 0; sfBase->iNewSessions = 0; sfBase->iDeletedSessions = 0; sfBase->iStreamFlushes = 0; sfBase->iStreamFaults = 0; sfBase->iStreamTimeouts = 0; //sfBase->iMaxSessions = 0; //sfBase->iMaxSessionsInterval = 0; //sfBase->iMidStreamSessions = 0; //sfBase->iClosedSessions = 0; //sfBase->iPrunedSessions = 0; //sfBase->iDroppedAsyncSessions = 0; //sfBase->iSessionsInitializing = 0; //sfBase->iSessionsEstablished = 0; //sfBase->iSessionsClosing = 0; sfBase->iFragCreates = 0; sfBase->iFragCompletes = 0; sfBase->iFragInserts = 0; sfBase->iFragDeletes = 0; sfBase->iFragAutoFrees = 0; sfBase->iFragFlushes = 0; sfBase->iFragTimeouts = 0; sfBase->iFragFaults = 0; sfBase->iNewUDPSessions = 0; sfBase->iDeletedUDPSessions = 0; //sfBase->iAttributeHosts = 0; //sfBase->iAttributeReloads = 0; return 0;}/*** NAME** UpdateBaseStats**** DESCRIPTION** Simple update of stats.**** FORMAL INPUTS** SFBASE * - structure to update** int - length of packet payload in bytes**** FORMAL OUTPUTS** int - 0 is successful**** Add in Ethernet Overhead - assume a standerd Ethernet service**** Ethernet Frame** ---------------** | <----------- PCAP Packet --------> |** Preamble Dest Mac Src Mac Type Payload CRC IFG** | 8 bytes | 6 Bytes | 6 Bytes | 2-Bytes | 46-1500 | 4 Bytes | 12 |**** Len = PCAP Packet + 4 bytes for CRC** Overhead = 20 bytes** Min on the wire == 84 bytes** Min Size of PCAP packet = 60 bytes (84 - 20 overhead - 4 CRC)**** Len is the amount of user data being sent. This will be less then** actual wire-speed, because of the interframe gap (96 bits) and preamble** (8 bytes).**** A 60 byte minimum packet uses 672 bits (60 bytes + 4 CRC), this limits a** 1000 Mbit network to 1.488 Million packets with a bandwidth of 760** Mbits. The lost 240 Mbits is due to interframe gap (96 bits) and preamble** (8 bytes).**** Even if the actual data is only 40 bytes per packet (ie, an empty** TCP ACK), wire data is still 64 bytes per packet, even though actual** packet size is 40 bytes. Bandwith drops to 480 Mbits. **** This explains why when a network goes over 50% capactiy you are closer to** the edge than you realize, depending on the traffic profile. At 75% you ** are at the limit of your network, if you can get there.**** iRebuiltPkt determines whether the packet is rebuilt or not. We keep** separate statistics between wire pkts and rebuilt pkts.***/int UpdateBaseStats(SFBASE *sfBase, int len, int iRebuiltPkt){ /* If rebuilt, count info for TCP rebuilt packet */ if(iRebuiltPkt) { sfBase->total_rebuilt_bytes += len; sfBase->total_rebuilt_packets++; } else { len += 4; /* for the CRC */ } /* Includes wire, IP reassembled & TCP rebuilt packets * that make it to the application layer. */ sfBase->total_packets++; sfBase->total_bytes += len; return 0;}/*** NAME** UpdateWireStats**** DESCRIPTION** Simple update of stats for "on the wire".**** FORMAL INPUTS** SFBASE * - structure to update** int - length of packet payload in bytes**** FORMAL OUTPUTS** none*/void UpdateWireStats(SFBASE *sfBase, int len){ sfBase->total_wire_packets++; len += 4; /* for the CRC */ sfBase->total_wire_bytes += len; if( InlineWasPacketDropped() ) { sfBase->total_blocked_packets++; sfBase->total_blocked_bytes += len; }}/*** NAME** UpdateIPFragStats**** DESCRIPTION** Simple update of stats for IP fragmented packets**** FORMAL INPUTS** SFBASE * - structure to update** int - length of packet payload in bytes**** FORMAL OUTPUTS** none*/void UpdateIPFragStats(SFBASE *sfBase, int len){ sfBase->total_ipfragmented_packets++; len += 4; /* for the CRC */ sfBase->total_wire_bytes += len; sfBase->total_ipfragmented_bytes += len;}/*** NAME** UpdateIPReassStats**** DESCRIPTION** Simple update of stats for IP reassembled packets**** FORMAL INPUTS** SFBASE * - structure to update** int - length of packet payload in bytes**** FORMAL OUTPUTS** none*/void UpdateIPReassStats(SFBASE *sfBase, int len){ sfBase->total_ipreassembled_packets++; len += 4; /* for the CRC */ sfBase->total_wire_bytes += len; sfBase->total_ipreassembled_bytes += len;}/*** NAME** AddStreamSession**** DESCRIPTION** Add a session count**** FORMAL INPUTS** SFBASE * - ptr to update.**** FORMAL OUTPUTS** int - 0 is successful*/int AddStreamSession(SFBASE *sfBase, u_int32_t flags){ sfBase->iTotalSessions++; sfBase->iNewSessions++; if (flags & SSNFLAG_MIDSTREAM) sfBase->iMidStreamSessions++; if(sfBase->iTotalSessions > sfBase->iMaxSessions) sfBase->iMaxSessions = sfBase->iTotalSessions; if(sfBase->iTotalSessions > sfBase->iMaxSessionsInterval) sfBase->iMaxSessionsInterval = sfBase->iTotalSessions; return 0;}/*** NAME** CloseStreamSession**** DESCRIPTION** Add a session count**** FORMAL INPUTS** SFBASE * - ptr to update.**** FORMAL OUTPUTS** int - 0 is successful
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -