📄 dstatc.c
字号:
/* Beholder RMON ethernet network monitor,Copyright (C) 1993 DNPAP group *//* See file COPYING 'GNU General Public Licence' for copyright details */#include <memory.h>#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <dnpap.h>#include <message.h>#include <mac.h>#include <timer.h>#include <protocol.h>#include "dstate.h"#include "dstatc.h"IMPORT BOOLEAN BeholderStrictRMON;static VOID StatTimerCallback(TIMER_DESCR * timer, ULONG now, VOID * param);static BOOLEAN StatMacCallback(MAC_COLL * collector, PROT_PKT * pkt);static BOOLEAN AddTypeEntry(DNPAP_ETHER_STATS * etherStats, TypeEntry * entry);static BOOLEAN DelTypeEntry(DNPAP_ETHER_STATS * etherStats, TypeEntry * entry);BOOLEAN DnpapStatCInit(DNPAP_ETHER_STATS * etherStats){ LONG source[] = {1, 3, 6, 1, 2, 1, 2, 2, 1, 1, 1}; etherStats->SourceLen = sizeof(source) / sizeof(long); memcpy(etherStats->Source, source, sizeof(source)); etherStats->Octets = 0; etherStats->Pkts = 0; etherStats->Pkts64Octets = 0; etherStats->Pkts65to127Octets = 0; etherStats->Pkts128to255Octets = 0; etherStats->Pkts256to511Octets = 0; etherStats->Pkts512to1023Octets = 0; etherStats->Pkts1024to1518Octets = 0; etherStats->Time = 0; etherStats->Timer = NULL; etherStats->UtilInterval = 100; etherStats->UtilTime = 0; etherStats->UtilOctets = 0; etherStats->UtilPkts = 0; etherStats->Utilization = 0; etherStats->IFTBuckets = 10; etherStats->IFTSize = 1000; etherStats->LengthBuckets = 16; etherStats->LengthSize = 100; etherStats->TypeBuckets = 0; if ((etherStats->IFTArrayPkts = NewBuckets(etherStats->IFTBuckets)) == NULL) return FALSE; if ((etherStats->IFTArrayOctets = NewBuckets(etherStats->IFTBuckets)) == NULL) return FALSE; if ((etherStats->LengthArrayPkts = NewBuckets(etherStats->LengthBuckets)) == NULL) return FALSE; if ((etherStats->LengthArrayOctets = NewBuckets(etherStats->LengthBuckets)) == NULL) return FALSE; if ((etherStats->TypeTable = NewHash(111, NULL)) == NULL) return FALSE; etherStats->TypeList = NULL; etherStats->TypeLast = NULL; if ((etherStats->Iface = MacIfaceGet((WORD) etherStats->Source[etherStats->SourceLen - 1])) == NULL) { DnpapMessage(DMC_ERROR, DSTAT_NETINIT, "detherstat: network initialization failed"); return (FALSE); } BooleanSetAllTrue(etherStats->ObjectSet); BooleanSetFalse(etherStats->ObjectSet, STAT_BOOLEAN_DATASOURCE); BooleanSetFalse(etherStats->ObjectSet, STAT_BOOLEAN_OWNER); return TRUE;}BOOLEAN DnpapStatCStart(DNPAP_ETHER_STATS * etherStats){ if (BeholderStrictRMON && !BooleanCheckAllTrue(etherStats->ObjectSet)) return FALSE; etherStats->Coll.Rcve = StatMacCallback; etherStats->Coll.specific = etherStats; if (!MacCollRegister(&(etherStats->Coll))) { DnpapMessage(DMC_ERROR, DSTAT_NETINIT, "detherstat: network initialization failed"); return (FALSE); } if ((etherStats->Timer = TimerRegister(StatTimerCallback, etherStats, etherStats->UtilInterval * 10, TIMER_FOREVER, TIMER_TYPE_SKIP)) == NULL) { DnpapMessage(DMC_ERROR, DSTAT_TIMER, "history: can not register a timer"); return FALSE; } MacStatistics(etherStats->Iface, ðerStats->BaseStat); etherStats->UtilTime = TimerNow(); etherStats->UtilOctets = etherStats->BaseStat.Octets; etherStats->UtilPkts = etherStats->BaseStat.Pkts; return TRUE;}BOOLEAN DnpapStatCStop(DNPAP_ETHER_STATS * etherStats){TypeEntry *entry; TimerRemove(etherStats->Timer); MacCollRemove(&(etherStats->Coll)); DelBuckets(etherStats->IFTArrayPkts); DelBuckets(etherStats->IFTArrayOctets); DelBuckets(etherStats->LengthArrayPkts); DelBuckets(etherStats->LengthArrayOctets); while (etherStats->TypeBuckets > 0) { entry = etherStats->TypeList; DelTypeEntry(etherStats, etherStats->TypeList); DnpapFree(entry); } DelHash(etherStats->TypeTable); return TRUE;}VOID StatTimerCallback(TIMER_DESCR * timer, ULONG now, VOID * param){ ULONG dtime; MAC_STAT netstat; ULONG octets, pkts; DNPAP_ETHER_STATS *etherStats = param; dtime = now - etherStats->UtilTime; etherStats->UtilTime = now; MacStatistics(etherStats->Iface, &netstat); octets = netstat.Octets - etherStats->UtilOctets; pkts = netstat.Pkts - etherStats->UtilPkts; etherStats->Utilization = (octets + pkts * 24) * 8 / dtime; etherStats->UtilOctets = netstat.Octets; etherStats->UtilPkts = netstat.Pkts; return;}BOOLEAN StatMacCallback(MAC_COLL * collector, PROT_PKT * pkt){ PROT_OBJ Interface = {0, {1, 2}}; PROT_OBJ Size = {0, {1, 4}}; PROT_OBJ Time = {0, {1, 6}}; PROT_OBJ Type = {1, {2, 3}}; ULONG size; ULONG time; WORD type; TypeEntry *entry; LONG iat, iatindex, lenindex; DNPAP_ETHER_STATS *etherStats = collector->specific; if (ProtGetField(pkt, &Interface) == TRUE && Interface.Syntax.LngInt == etherStats->Source[etherStats->SourceLen - 1]) { if (ProtGetField(pkt, &Size) == TRUE && ProtGetField(pkt, &Time) == TRUE && ProtGetField(pkt, &Type) == TRUE) { etherStats->Pkts++; size = Size.Syntax.LngUns + 4L; etherStats->Octets += size; if (size == 64) etherStats->Pkts64Octets++; if (size >= 65) { if (size <= 127) etherStats->Pkts65to127Octets++; else if (size <= 255) etherStats->Pkts128to255Octets++; else if (size <= 511) etherStats->Pkts256to511Octets++; else if (size <= 1023) etherStats->Pkts512to1023Octets++; else if (size <= 1518) etherStats->Pkts1024to1518Octets++; } lenindex = size / etherStats->LengthSize; if (lenindex >= etherStats->LengthBuckets) lenindex = etherStats->LengthBuckets - 1; etherStats->LengthArrayPkts[lenindex]++; etherStats->LengthArrayOctets[lenindex] += size; time = Time.Syntax.LngUns; if (etherStats->Time == 0) etherStats->Time = time; else { iat = time - etherStats->Time; etherStats->Time = time; iatindex = iat / etherStats->IFTSize; if (iatindex >= etherStats->IFTBuckets) iatindex = etherStats->IFTBuckets - 1; etherStats->IFTArrayPkts[iatindex]++; etherStats->IFTArrayOctets[iatindex] += size; } type = Type.Syntax.LngUns; /* see Ethernet-codes: @ According to the October 1988 issue of COURIER (page 8), "if it is less than 600H, the packet is assumed to be an 802.3 packet; if it is greater than 600H, the packet is flagged as an Ethernet packet." */ if (type < 0x600) type = 1; if ((entry = HashSearch(etherStats->TypeTable, (BYTE *) & type, sizeof(type))) == NULL) { if ((entry = DnpapMalloc(sizeof(TypeEntry))) != NULL) { entry->Type = type; entry->Pkts = 0; entry->Octets = 0; if ((entry = HashAdd(etherStats->TypeTable, (BYTE *) & entry->Type, sizeof(type), entry)) != NULL) AddTypeEntry(etherStats, entry); } } if (entry != NULL) { entry->Pkts++; entry->Octets += size; } } } return TRUE;}TypeEntry *DnpapNextTypeEntry(DNPAP_ETHER_STATS * etherStats, WORD type){TypeEntry *e; for (e = etherStats->TypeList; e != NULL; e = e->Next) if (e->Type > type) return e; return NULL;}TypeEntry *DnpapTypeEntrySearch(DNPAP_ETHER_STATS * etherStats, SNMP_OBJECT * obj, WORD idlen){ WORD type = obj->Id[idlen + 1]; return HashSearch(etherStats->TypeTable, (BYTE *) & type, sizeof(type));}BOOLEAN AddTypeEntry(DNPAP_ETHER_STATS * etherStats, TypeEntry * entry){ TypeEntry *e, *p; if (etherStats->TypeList == NULL) { entry->Next = NULL; entry->Prev = NULL; etherStats->TypeList = entry; etherStats->TypeLast = entry; } else { for (e = etherStats->TypeList, p = NULL; e != NULL; p = e, e = e->Next) if (e->Type > entry->Type) break; if (p != NULL) p->Next = entry; else etherStats->TypeList = entry; if (e != NULL) e->Prev = entry; else etherStats->TypeLast = entry; entry->Next = e; entry->Prev = p; } etherStats->TypeBuckets++; return TRUE;}BOOLEAN DelTypeEntry(DNPAP_ETHER_STATS * etherStats, TypeEntry * entry){ if (entry->Prev != NULL) entry->Prev->Next = entry->Next; else etherStats->TypeList = entry->Next; if (entry->Next != NULL) entry->Next->Prev = entry->Prev; else etherStats->TypeLast = entry->Prev; etherStats->TypeBuckets--; return TRUE;}ULONG *NewBuckets(LONG nrbuckets){ ULONG *p; if ((p = DnpapMalloc(nrbuckets * sizeof(ULONG))) == NULL) return NULL; memset(p, 0, (size_t) nrbuckets * sizeof(ULONG)); return p;}ULONG *ReNewBuckets(ULONG * buckets, LONG nrbuckets){ ULONG *p; if ((p = DnpapRealloc(buckets, nrbuckets * sizeof(ULONG))) == NULL) return NULL; memset(p, 0, (size_t) nrbuckets * sizeof(ULONG)); return p;}VOID DelBuckets(ULONG * buckets){ DnpapFree(buckets);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -