📄 discnodc.c
字号:
/* Beholder RMON ethernet network monitor,Copyright (C) 1993 DNPAP group *//* See file COPYING 'GNU General Public Licence' for copyright details */#include <stdlib.h>#include <limits.h>#include <memory.h>#include <dnpap.h>#include <timer.h>#include <config.h>#include <message.h>#include <mac.h>#include <hash.h>#include <dmath.h>#include <dtime.h>#include <sysmib.h>#include <protocol.h>#include <channel.h>#include "discd.h"#include "disce.h"#include "discnodc.h"IMPORT BOOLEAN BeholderStrictRMON;static LONG DiscNodeMaxNrNodes = 8000;static LONG DiscNodeTimeout = 10000;static BOOLEAN DiscNodeCallback(MAC_COLL *collector, PROT_PKT *pkt);static BOOLEAN DiscNodeUpdateTables(DISCNODE_CONTROL *discnodecontrol, INT type, BYTE *src, INT srclen, BYTE *dst, INT dstlen, LWORD size, ULONG now);static BOOLEAN DiscNodeUpdateTablesPerNode(DISCNODE_CONTROL *discnodecontrol, INT type, BYTE *node, INT nodelen, INT direction, LWORD size, ULONG now);static VOID DiscNodeRemoveEntry(DISCNODE_CONTROL *discnodecontrol, DISCNODE *olddisc);static BOOLEAN DiscNodeAddLexList(INT type, DISCNODE **lexlist, DISCNODE *disc);static BOOLEAN DiscNodeRemoveLexList(DISCNODE **lexlist, DISCNODE *disc);static DISCNODE *DiscNodeAddLRUList(DISCNODE_CONTROL *discnodecontrol, DISCNODE *disc);static BOOLEAN DiscNodeUpdateLRUList(DISCNODE_CONTROL *discnodecontrol, DISCNODE *disc);static BOOLEAN DiscNodeRemoveLRUList(DISCNODE_CONTROL *discnodecontrol, DISCNODE *disc);static BOOLEAN DiscNodeAddTimeList(DISCNODE_CONTROL *discnodecontrol, INT type, DISCNODE **timelist, DISCNODE **timelast, DISCNODE *disc);static BOOLEAN DiscNodeRemoveTimeList(DISCNODE_CONTROL *discnodecontrol, INT type, DISCNODE **timelist, DISCNODE **timelast, DISCNODE *disc);static BOOLEAN DiscNodeUpdateTimeTables(DISCNODE_CONTROL *discnodecontrol);static BOOLEAN DiscNodeUpdateSpecificTimeTable(DISCNODE *timelist, DISCNODE **timetable, LONG size);static VOID LRUTimerCallback(TIMER_DESCR *timer, ULONG now, VOID *param);static VOID DelDiscNodes(DISCNODE_CONTROL *discnodecontrol, DISCNODE **lexlist);static INT NodeLen(INT type);BOOLEAN DiscNodeConfigInit(VOID){ ConfigGetLong("beholder.discnode.maxnrnodes", &DiscNodeMaxNrNodes); if (DiscNodeMaxNrNodes < 2) { DnpapMessage(DMC_WARNING, DISC_MAX, "discnodecontrol: beholder.disc.maxnrnodes < 2, setting it to 2"); DiscNodeMaxNrNodes = 2; } ConfigGetLong("beholder.discnode.timeout", &DiscNodeTimeout); if (DiscNodeTimeout < 2) { DnpapMessage(DMC_WARNING, DISC_MAX, "discnodecontrol: beholder.discnode.timeout < 2, setting it to 2"); DiscNodeTimeout = 2; } return TRUE;}BOOLEAN DiscNodeCInit(DISCNODE_CONTROL *discnodecontrol){LONG source[] = {1,3,6,1,2,1,2,2,1,1,1}; memcpy(discnodecontrol->Source, source, sizeof(source)); discnodecontrol->SourceLen = sizeof(source)/sizeof(source[0]); discnodecontrol->Channel = FALSE; discnodecontrol->ChannelType = 0; discnodecontrol->ChannelAccept = TRUE; discnodecontrol->AddressLen = 0; discnodecontrol->EthTableSize = 0; discnodecontrol->IPTableSize = 0; discnodecontrol->UDPTableSize = 0; discnodecontrol->TCPTableSize = 0; discnodecontrol->TableSize = 0; discnodecontrol->TurnOnTime = 0; discnodecontrol->LastDeleteTime = 0; discnodecontrol->Owner[0] = '\0'; discnodecontrol->OwnerLen = 0; discnodecontrol->Status = SNMP_INVALID; if ((discnodecontrol->Iface = MacIfaceGet((WORD) discnodecontrol->Source[discnodecontrol->SourceLen-1])) == NULL) { DnpapMessage(DMC_ERROR, DISC_NETINIT, "discnodecontrol: network initialisation failed"); return (FALSE); } discnodecontrol->Table = NULL; discnodecontrol->EthLexList = NULL; discnodecontrol->IPLexList = NULL; discnodecontrol->UDPLexList = NULL; discnodecontrol->TCPLexList = NULL; discnodecontrol->LRUList = NULL; discnodecontrol->LRULast = NULL; discnodecontrol->EthTimeList = NULL; discnodecontrol->EthTimeLast = NULL; discnodecontrol->EthTimeTable = NULL; discnodecontrol->EthTimeListUpdated = FALSE; discnodecontrol->IPTimeList = NULL; discnodecontrol->IPTimeLast = NULL; discnodecontrol->IPTimeTable = NULL; discnodecontrol->IPTimeListUpdated = FALSE; discnodecontrol->UDPTimeList = NULL; discnodecontrol->UDPTimeLast = NULL; discnodecontrol->UDPTimeTable = NULL; discnodecontrol->UDPTimeListUpdated = FALSE; discnodecontrol->TCPTimeList = NULL; discnodecontrol->TCPTimeLast = NULL; discnodecontrol->TCPTimeTable = NULL; discnodecontrol->TCPTimeListUpdated = FALSE; discnodecontrol->LRUTimer = NULL; discnodecontrol->LastLRUEntry = NULL; BooleanSetAllTrue(discnodecontrol->ObjectSet); BooleanSetFalse(discnodecontrol->ObjectSet, DISC_BOOLEAN_DATASOURCE); BooleanSetFalse(discnodecontrol->ObjectSet, DISC_BOOLEAN_OWNER); return TRUE;}BOOLEAN DiscNodeCStart(DISCNODE_CONTROL *discnodecontrol){ if (BeholderStrictRMON && !BooleanCheckAllTrue(discnodecontrol->ObjectSet)) return FALSE; if (discnodecontrol->Channel == FALSE) { discnodecontrol->Coll.Rcve = DiscNodeCallback; discnodecontrol->Coll.specific = discnodecontrol; if (!MacCollRegister(&(discnodecontrol->Coll))) { DnpapMessage(DMC_ERROR, DISC_NETERR, "discnodecontrol: network initialisation failed"); return FALSE; } } if ((discnodecontrol->Table = NewHash(DiscNodeMaxNrNodes/2+11, NULL)) == NULL) { DnpapMessage(DMC_ERROR, DISC_HASHERR, "discnodecontrol: can not create hashtable"); return FALSE; } if ((discnodecontrol->EthTimeTable = (DISCNODE**)DnpapMalloc(DiscNodeMaxNrNodes*sizeof(DISCNODE*))) == NULL) { DnpapMessage(DMC_ERROR, DISC_TIMETABLE, "discnodecontrol: can not create time ordered Ethernet table"); return FALSE; } if ((discnodecontrol->IPTimeTable = (DISCNODE**)DnpapMalloc(DiscNodeMaxNrNodes*sizeof(DISCNODE*))) == NULL) { DnpapMessage(DMC_ERROR, DISC_TIMETABLE, "discnodecontrol: can not create time ordered IP table"); return FALSE; } if ((discnodecontrol->UDPTimeTable = (DISCNODE**)DnpapMalloc(DiscNodeMaxNrNodes*sizeof(DISCNODE*))) == NULL) { DnpapMessage(DMC_ERROR, DISC_TIMETABLE, "discnodecontrol: can not create time ordered UDP table"); return FALSE; } if ((discnodecontrol->TCPTimeTable = (DISCNODE**)DnpapMalloc(DiscNodeMaxNrNodes*sizeof(DISCNODE*))) == NULL) { DnpapMessage(DMC_ERROR, DISC_TIMETABLE, "discnodecontrol: can not create time ordered TCP table"); return FALSE; } if ((discnodecontrol->LRUTimer = TimerRegister(LRUTimerCallback, discnodecontrol, DiscNodeTimeout, TIMER_FOREVER, TIMER_TYPE_RECOVER)) == NULL) { DnpapMessage(DMC_ERROR, DISC_TIMER, "discnodecontrol: can not set LRU timer"); return FALSE; } discnodecontrol->TurnOnTime = TimeUsec(); return TRUE;}BOOLEAN DiscNodeCStop(DISCNODE_CONTROL *discnodecontrol){ TimerRemove(discnodecontrol->LRUTimer); MacCollRemove(&(discnodecontrol->Coll)); DelHash(discnodecontrol->Table); DelDiscNodes(discnodecontrol, &discnodecontrol->EthLexList); DelDiscNodes(discnodecontrol, &discnodecontrol->IPLexList); DelDiscNodes(discnodecontrol, &discnodecontrol->UDPLexList); DelDiscNodes(discnodecontrol, &discnodecontrol->TCPLexList); DnpapFree(discnodecontrol->EthTimeTable); DnpapFree(discnodecontrol->IPTimeTable); DnpapFree(discnodecontrol->UDPTimeTable); DnpapFree(discnodecontrol->TCPTimeTable); return TRUE;}BOOLEAN DiscNodeCallback(MAC_COLL *collector, PROT_PKT *pkt){DISCNODE_CONTROL *discnodecontrol = collector->specific;PROT_OBJ Interface = {0, {1,2}}; if (ProtGetField(pkt,&Interface) == TRUE && Interface.Syntax.LngInt == discnodecontrol->Source[discnodecontrol->SourceLen-1]) DiscNodeHandlePkt(discnodecontrol, pkt); return TRUE;}VOID DiscNodeHandlePkt(DISCNODE_CONTROL *discnodecontrol, PROT_PKT *pkt){PROT_OBJ EthDst = {1, {2,1}};PROT_OBJ EthSrc = {1, {2,2}};PROT_OBJ EthSize = {0, {1,4}};PROT_OBJ EthTime = {0, {1,6}};PROT_OBJ IPSize = {2, {3,4}};PROT_OBJ IPOffset = {2, {3,7}};PROT_OBJ IPSrc = {2, {3,11}};PROT_OBJ IPDst = {2, {3,12}};PROT_OBJ UDPSrc = {3, {5,1}};PROT_OBJ UDPDst = {3, {5,2}};PROT_OBJ UDPSize = {3, {5,3}};PROT_OBJ TCPSrc = {3, {4,1}};PROT_OBJ TCPDst = {3, {4,2}};PROT_OBJ TCPSize = {3, {4,5}};ULONG now;BYTE src[DISC_SIZE_NODE], dst[DISC_SIZE_NODE];LWORD size;INT type; if (discnodecontrol->Channel == FALSE) type = discnodecontrol->Iface->type; else { type = discnodecontrol->ChannelType; if (type == 0) { type = ChannelType(discnodecontrol->Source[discnodecontrol->SourceLen-1]); if (type == 0) return; discnodecontrol->ChannelType = type; } } if (type != MAC_TYPE_ETHERNET_CSMACD && type != MAC_TYPE_88023_CSMACD) return; if (ProtGetField(pkt,&EthSize) == TRUE && ProtGetField(pkt,&EthTime) == TRUE && ProtGetField(pkt,&EthSrc) == TRUE && ProtGetField(pkt,&EthDst) == TRUE) { size = EthSize.Syntax.LngUns + 4L; now = EthTime.Syntax.LngUns - discnodecontrol->TurnOnTime; if (EthSrc.SyntaxLen != DISC_SIZE_ETHADDR || EthDst.SyntaxLen != DISC_SIZE_ETHADDR) { DnpapMessage(DMC_ERROR, DISC_INVPACKET, "discnodecontrol: invalid packet"); return; } memcpy(src, EthSrc.Syntax.BufChr, DISC_SIZE_ETHADDR); memcpy(dst, EthDst.Syntax.BufChr, DISC_SIZE_ETHADDR); DiscNodeUpdateTables(discnodecontrol, DISC_TYPE_ETH, src, DISC_SIZE_ETHADDR, dst, DISC_SIZE_ETHADDR, size, now); if (ProtGetField(pkt,&IPSize) == TRUE && ProtGetField(pkt,&IPSrc) == TRUE && ProtGetField(pkt,&IPDst) == TRUE) { size = IPSize.Syntax.LngUns; NETLVALUEPTR2BYTES(src+DISC_SIZE_ETHADDR, IPSrc.Syntax.BufChr); NETLVALUEPTR2BYTES(dst+DISC_SIZE_ETHADDR, IPDst.Syntax.BufChr); DiscNodeUpdateTables(discnodecontrol, DISC_TYPE_IP, src, DISC_SIZE_TOIPADDR, dst, DISC_SIZE_TOIPADDR, size, now); if (ProtGetField(pkt,&IPOffset) == TRUE && IPOffset.Syntax.LngUns == 0) { if (ProtGetField(pkt,&UDPSize) == TRUE && ProtGetField(pkt,&UDPSrc) == TRUE && ProtGetField(pkt,&UDPDst) == TRUE) { size = UDPSize.Syntax.LngUns; VALUE2BYTES(src+DISC_SIZE_TOIPADDR, UDPSrc.Syntax.LngInt); VALUE2BYTES(dst+DISC_SIZE_TOIPADDR, UDPDst.Syntax.LngInt); DiscNodeUpdateTables(discnodecontrol, DISC_TYPE_UDP, src, DISC_SIZE_TOUDPADDR, dst, DISC_SIZE_TOUDPADDR, size, now); } else if (ProtGetField(pkt,&TCPSize) == TRUE && ProtGetField(pkt,&TCPSrc) == TRUE && ProtGetField(pkt,&TCPDst) == TRUE) { size = TCPSize.Syntax.LngUns; VALUE2BYTES(src+DISC_SIZE_TOIPADDR, TCPSrc.Syntax.LngInt); VALUE2BYTES(dst+DISC_SIZE_TOIPADDR, TCPDst.Syntax.LngInt); DiscNodeUpdateTables(discnodecontrol, DISC_TYPE_TCP, src, DISC_SIZE_TOTCPADDR, dst, DISC_SIZE_TOTCPADDR, size, now); } } } } return;}BOOLEAN DiscNodeUpdateTables(DISCNODE_CONTROL *discnodecontrol, INT type, BYTE *src, INT srclen, BYTE *dst, INT dstlen, LWORD size, ULONG now){ BOOLEAN rc = TRUE; if (DiscNodeUpdateTablesPerNode(discnodecontrol, type, src, srclen, DISC_TYPE_SOURCE, size, now) == FALSE) rc = FALSE; if (DiscNodeUpdateTablesPerNode(discnodecontrol, type, dst, dstlen, DISC_TYPE_DEST, size, now) == FALSE) rc = FALSE; return rc;} BOOLEAN DiscNodeUpdateTablesPerNode(DISCNODE_CONTROL *discnodecontrol, INT type, BYTE *node, INT nodelen, INT direction, LWORD size, ULONG now){ DISCNODE *disc, *olddisc; if ((disc = HashSearch(discnodecontrol->Table, node, nodelen)) == NULL) { /* first try to add the new disc */ if ((disc = DnpapMalloc(sizeof(DISCNODE))) != NULL) { memset(disc, 0, sizeof(DISCNODE)); memcpy(disc->Address, node, (disc->AddressLen = nodelen)); disc->Type = (BYTE)type; if (HashAdd(discnodecontrol->Table, disc->Address, nodelen, disc) == NULL) { DnpapMessage(DMC_WARNING, DISC_NADD, "discnodecontrol: node could not be added to the hash table"); DnpapFree(disc); disc = NULL; } else { switch (type) { case DISC_TYPE_ETH: DiscNodeAddLexList(type, &discnodecontrol->EthLexList, disc); DiscNodeAddTimeList(discnodecontrol, type, &discnodecontrol->EthTimeList, &discnodecontrol->EthTimeLast, disc); discnodecontrol->EthTableSize++; break; case DISC_TYPE_IP: DiscNodeAddLexList(type, &discnodecontrol->IPLexList, disc); DiscNodeAddTimeList(discnodecontrol, type, &discnodecontrol->IPTimeList, &discnodecontrol->IPTimeLast, disc); discnodecontrol->IPTableSize++; break; case DISC_TYPE_UDP: DiscNodeAddLexList(type, &discnodecontrol->UDPLexList, disc); DiscNodeAddTimeList(discnodecontrol, type, &discnodecontrol->UDPTimeList, &discnodecontrol->UDPTimeLast, disc); discnodecontrol->UDPTableSize++; break; case DISC_TYPE_TCP: DiscNodeAddLexList(type, &discnodecontrol->TCPLexList, disc); DiscNodeAddTimeList(discnodecontrol, type, &discnodecontrol->TCPTimeList, &discnodecontrol->TCPTimeLast, disc); discnodecontrol->TCPTableSize++; break; default: DnpapMessage(DMC_FATAL, DISC_TYPE, "discnodecontrol: unknown type"); DnpapExit(DISC_TYPE); } olddisc = DiscNodeAddLRUList(discnodecontrol, disc); discnodecontrol->TableSize++; if (discnodecontrol->TableSize > (LONG)DiscNodeMaxNrNodes) DiscNodeRemoveEntry(discnodecontrol, olddisc); } } } if (disc != NULL) { switch (direction) { case DISC_TYPE_SOURCE: disc->OutPkts++; disc->OutOctets += size; break; case DISC_TYPE_DEST: disc->InPkts++; disc->InOctets += size; break; } disc->LRUTime = now; DiscNodeUpdateLRUList(discnodecontrol, disc); } return TRUE;}VOID DiscNodeRemoveEntry(DISCNODE_CONTROL *discnodecontrol, DISCNODE *olddisc) { INT type; DiscNodeRemoveLRUList(discnodecontrol, olddisc); switch (type = olddisc->Type) { case DISC_TYPE_ETH: DiscNodeRemoveTimeList(discnodecontrol, type, &discnodecontrol->EthTimeList, &discnodecontrol->EthTimeLast, olddisc); DiscNodeRemoveLexList(&discnodecontrol->EthLexList, olddisc); discnodecontrol->EthTableSize--; break; case DISC_TYPE_IP: DiscNodeRemoveTimeList(discnodecontrol, type, &discnodecontrol->IPTimeList, &discnodecontrol->IPTimeLast, olddisc); DiscNodeRemoveLexList(&discnodecontrol->IPLexList, olddisc); discnodecontrol->IPTableSize--; break; case DISC_TYPE_UDP: DiscNodeRemoveTimeList(discnodecontrol, type, &discnodecontrol->UDPTimeList, &discnodecontrol->UDPTimeLast, olddisc); DiscNodeRemoveLexList(&discnodecontrol->UDPLexList, olddisc); discnodecontrol->UDPTableSize--; break; case DISC_TYPE_TCP: DiscNodeRemoveTimeList(discnodecontrol, type, &discnodecontrol->TCPTimeList, &discnodecontrol->TCPTimeLast, olddisc); DiscNodeRemoveLexList(&discnodecontrol->TCPLexList, olddisc); discnodecontrol->TCPTableSize--; break; } HashRemove(discnodecontrol->Table, olddisc->Address, olddisc->AddressLen); DnpapFree(olddisc); discnodecontrol->LastDeleteTime = SysTime(); discnodecontrol->TableSize--; }BOOLEAN DiscNodeAddLexList(INT type, DISCNODE **lexlist, DISCNODE *disc){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -