/**************************************************************************** ** ** File: stats.c ** ** Author: Mike Borella ** ** Comments: Statistics collection module ** ** $Id: stats.c,v 1.2 2001/09/07 19:27:02 mborella Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** 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 Library 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. ** *****************************************************************************/ #include "global.h" #include "error.h" #include "stats.h" typedef struct stats { int ip; int udp; int tcp; int ipx; int gre; int icmp; int ipv6; int icmpv6; int ospf; int rsvp; int arp; int ah; int esp; int igmp; } stats_t; stats_t statistics; static int stats_counted_ip = 0; static int stats_counted_udp = 0; static int stats_counted_tcp = 0; static int stats_paused = 0; /* when set, stats will not be counted */ /*---------------------------------------------------------------------------- ** ** stats_ispaused() ** ** Check if stats counting is paused ** **---------------------------------------------------------------------------- */ inline int stats_ispaused(void) { return stats_paused; } /*---------------------------------------------------------------------------- ** ** stats_pause() ** ** Temporarily stop doing stats. Typically used when an ICMP packet is ** encountered so that the encapsulated IP/UDP/TCP headers are not counted. ** **---------------------------------------------------------------------------- */ inline void stats_pause(void) { stats_paused = 1; } /*---------------------------------------------------------------------------- ** ** stats_unpause() ** ** Restart doing stats. Typically used at the begining of processing each ** packet. ** **---------------------------------------------------------------------------- */ inline void stats_unpause(void) { stats_paused = 0; } /*---------------------------------------------------------------------------- ** ** stats_reset() ** **---------------------------------------------------------------------------- */ inline void stats_reset(void) { stats_counted_ip = 0; stats_counted_udp = 0; stats_counted_tcp = 0; } /*---------------------------------------------------------------------------- ** ** stats_init() ** **---------------------------------------------------------------------------- */ inline void stats_init(void) { memset(&statistics, 0, sizeof(stats_t)); } /*---------------------------------------------------------------------------- ** ** stats_update() ** **---------------------------------------------------------------------------- */ inline void stats_update(int type) { if (stats_ispaused()) return; switch(type) { case STATS_IP: /* Avoid double counting tunneled packets */ if (stats_counted_ip) return; stats_counted_ip = 1; statistics.ip++; break; case STATS_UDP: /* Avoid double counting tunneled packets */ if (stats_counted_udp) return; stats_counted_udp = 1; statistics.udp++; break; case STATS_TCP: /* Avoid double counting tunneled packets */ if (stats_counted_tcp) return; stats_counted_tcp = 1; statistics.tcp++; break; case STATS_IPX: statistics.ipx++; break; case STATS_GRE: statistics.gre++; break; case STATS_ICMP: statistics.icmp++; stats_pause(); break; case STATS_IPV6: statistics.ipv6++; break; case STATS_ICMPV6: statistics.icmpv6++; stats_pause(); break; case STATS_OSPF: statistics.ospf++; break; case STATS_RSVP: statistics.rsvp++; break; case STATS_ARP: statistics.arp++; break; case STATS_AH: statistics.ah++; break; case STATS_ESP: statistics.esp++; break; case STATS_IGMP: statistics.igmp++; break; default: error_fatal("unknown packet type for statistics: %d\n", type); break; } } /*---------------------------------------------------------------------------- ** ** stats_dump() ** **---------------------------------------------------------------------------- */ inline void stats_dump(void) { fprintf(stderr, "ARP: %d\n", statistics.arp); fprintf(stderr, "IP: %d\n", statistics.ip); fprintf(stderr, "ICMP: %d\n", statistics.icmp); fprintf(stderr, "IGMP: %d\n", statistics.igmp); fprintf(stderr, "UDP: %d\n", statistics.udp); fprintf(stderr, "TCP: %d\n", statistics.tcp); fprintf(stderr, "IPX: %d\n", statistics.ipx); fprintf(stderr, "GRE: %d\n", statistics.gre); fprintf(stderr, "IPv6: %d\n", statistics.ipv6); fprintf(stderr, "ICMPv6: %d\n", statistics.icmpv6); fprintf(stderr, "OSPF: %d\n", statistics.ospf); fprintf(stderr, "RSVP: %d\n", statistics.rsvp); fprintf(stderr, "AH: %d\n", statistics.ah); fprintf(stderr, "ESP: %d\n", statistics.esp); }