📄 hostc.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 <memory.h>#include <dnpap.h>#include <config.h>#include <message.h>#include <mac.h>#include <hash.h>#include <sysmib.h>#include <protocol.h>#include <channel.h>#include <topn.h>#include "hoste.h"#include "hostc.h"IMPORT BOOLEAN BeholderStrictRMON;static LONG HostMaxNrHosts = 2000;static BOOLEAN HostCallback(MAC_COLL * collector, PROT_PKT * pkt);static BOOLEAN HostAddLexList(HOST_CONTROL * hostcontrol, HOST * host);static BOOLEAN HostRemoveLexList(HOST_CONTROL * hostcontrol, HOST * host);static BOOLEAN HostAddTimeList(HOST_CONTROL * hostcontrol, HOST * host);static BOOLEAN HostRemoveTimeList(HOST_CONTROL * hostcontrol, HOST * host);static HOST *HostAddLRUList(HOST_CONTROL * hostcontrol, HOST * host);static BOOLEAN HostUpdateLRUList(HOST_CONTROL * hostcontrol, HOST * host);static BOOLEAN HostRemoveLRUList(HOST_CONTROL * hostcontrol, HOST * host);static BOOLEAN HostUpdateTimeTable(HOST_CONTROL * hostcontrol);static VOID DelHosts(HOST_CONTROL * hostcontrol);static int addrcmp(HOST * host1, HOST * host2, WORD addrlen, WORD len);#ifdef DEBUGstatic VOID HostCheckListsConsistency(HOST_CONTROL * host);static VOID HostCheckListsRemove(HOST_CONTROL * hostcontrol, HOST * host);static VOID HostCheckListsRemove2(HOST_CONTROL * hostcontrol, HOST * host);static VOID HostCheckListsAdd(HOST_CONTROL * hostcontrol, HOST * host);static VOID HostCheckListsAdd2(HOST_CONTROL * hostcontrol, HOST * host);#endifBOOLEAN HostConfigInit(VOID){ ConfigGetLong("beholder.host.maxnrhosts", &HostMaxNrHosts); if (HostMaxNrHosts < 2) { DnpapMessage(DMC_WARNING, HOST_MAX, "hostcontrol: beholder.host.maxnrhosts < 2, setting it to 2"); HostMaxNrHosts = 2; } return TRUE;}BOOLEAN HostCInit(HOST_CONTROL * hostcontrol){ LONG source[] = {1, 3, 6, 1, 2, 1, 2, 2, 1, 1, 1}; hostcontrol->Index = 0; memcpy(hostcontrol->Source, source, sizeof(source)); hostcontrol->SourceLen = sizeof(source) / sizeof(source[0]); hostcontrol->Channel = FALSE; hostcontrol->ChannelType = 0; hostcontrol->ChannelAccept = TRUE; hostcontrol->AddressLen = 0; hostcontrol->TableSize = 0; hostcontrol->LastDeleteTime = 0; hostcontrol->Owner[0] = '\0'; hostcontrol->OwnerLen = 0; hostcontrol->Status = SNMP_INVALID; if ((hostcontrol->Iface = MacIfaceGet((WORD) hostcontrol->Source[hostcontrol->SourceLen - 1])) == NULL) { DnpapMessage(DMC_ERROR, HOST_NETINIT, "hostcontrol: network initialisation failed"); return (FALSE); } hostcontrol->Table = NULL; hostcontrol->LexList = NULL; hostcontrol->TimeList = NULL; hostcontrol->TimeLast = NULL; hostcontrol->TimeTable = NULL; hostcontrol->TimeListUpdated = FALSE; hostcontrol->LRUList = NULL; hostcontrol->LRULast = NULL; BooleanSetAllTrue(hostcontrol->ObjectSet); BooleanSetFalse(hostcontrol->ObjectSet, HOST_BOOLEAN_DATASOURCE); BooleanSetFalse(hostcontrol->ObjectSet, HOST_BOOLEAN_OWNER); return TRUE;}BOOLEAN HostCStart(HOST_CONTROL * hostcontrol){ if (BeholderStrictRMON && !BooleanCheckAllTrue(hostcontrol->ObjectSet)) return FALSE; if (hostcontrol->Channel == FALSE) { hostcontrol->Coll.Rcve = HostCallback; hostcontrol->Coll.specific = hostcontrol; if (!MacCollRegister(&(hostcontrol->Coll))) { DnpapMessage(DMC_ERROR, HOST_NETERR, "hostcontrol: network initialisation failed"); return FALSE; } } if ((hostcontrol->Table = NewHash(HostMaxNrHosts / 2 + 11, NULL)) == NULL) { DnpapMessage(DMC_ERROR, HOST_HASHERR, "hostcontrol: can not create hashtable"); return FALSE; } if ((hostcontrol->TimeTable = (HOST **) DnpapMalloc(HostMaxNrHosts * sizeof(HOST *))) == NULL) { DnpapMessage(DMC_ERROR, HOST_TIMER, "hostcontrol: can not create time ordered table"); return FALSE; } return TRUE;}BOOLEAN HostCStop(HOST_CONTROL * hostcontrol){ TopNHostStop(hostcontrol->Index); MacCollRemove(&(hostcontrol->Coll)); DelHash(hostcontrol->Table); DelHosts(hostcontrol); DnpapFree(hostcontrol->TimeTable); return TRUE;}BOOLEAN HostCallback(MAC_COLL * collector, PROT_PKT * pkt){ HOST_CONTROL *hostcontrol = collector->specific; PROT_OBJ Interface = {0, {1, 2}}; if (ProtGetField(pkt, &Interface) == TRUE && Interface.Syntax.LngInt == hostcontrol->Source[hostcontrol->SourceLen - 1]) HostHandlePkt(hostcontrol, pkt); return TRUE;}VOID HostHandlePkt(HOST_CONTROL * hostcontrol, PROT_PKT * pkt){ HOST *host = NULL, *oldhost = NULL; BYTE EthBroadcast[ETH_SIZE_ADDR] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; PROT_OBJ EthSize = {0, {1, 4}}; PROT_OBJ EthDst = {1, {2, 1}}; PROT_OBJ EthSrc = {1, {2, 2}}; BYTE *src, *dst; WORD addrlen; LWORD size; INT type; src = NULL; dst = NULL; if (hostcontrol->Channel == FALSE) type = hostcontrol->Iface->type; else { type = hostcontrol->ChannelType; if (type == 0) { type = ChannelType(hostcontrol->Source[hostcontrol->SourceLen - 1]); if (type == 0) return; hostcontrol->ChannelType = type; } } switch (type) { case MAC_TYPE_ETHERNET_CSMACD: case MAC_TYPE_88023_CSMACD: if (ProtGetField(pkt, &EthSize) == TRUE) size = EthSize.Syntax.LngUns + 4L; else return; if (ProtGetField(pkt, &EthSrc) == TRUE) src = EthSrc.Syntax.BufChr; if (ProtGetField(pkt, &EthDst) == TRUE) dst = EthDst.Syntax.BufChr; if (EthSrc.SyntaxLen != ETH_SIZE_ADDR) src = NULL; if (EthDst.SyntaxLen != ETH_SIZE_ADDR) dst = NULL; addrlen = ETH_SIZE_ADDR; if (hostcontrol->AddressLen == 0) hostcontrol->AddressLen = addrlen; else if (hostcontrol->AddressLen != addrlen) { DnpapMessage(DMC_FATAL, HOST_INCONSISTENT, "host: inconsistent address length encountered"); DnpapExit(1); } break; default: return; } if ((host = HashSearch(hostcontrol->Table, src, addrlen)) == NULL) { /* first try to add the new host */ if ((host = DnpapMalloc(sizeof(HOST))) != NULL) { memset(host, 0, sizeof(HOST)); memcpy(host->Address, src, addrlen);#ifdef DEBUG HostCheckListsAdd(hostcontrol, host);#endif if (HashAdd(hostcontrol->Table, host->Address, addrlen, host) == NULL) { DnpapMessage(DMC_WARNING, HOST_NADD, "hostcontrol: host could not be added to the hash table"); DnpapFree(host); host = NULL; } else {#ifdef DEBUG if (HashSearch(hostcontrol->Table, src, addrlen) == NULL) DnpapMessage(DMC_FATAL, HOST_ERROR, "host that was just added can not be retrieved");#endif HostAddLexList(hostcontrol, host); HostAddTimeList(hostcontrol, host); oldhost = HostAddLRUList(hostcontrol, host);#ifdef DEBUG HostCheckListsAdd2(hostcontrol, host);#endif hostcontrol->TableSize++; if (hostcontrol->TableSize > (LONG) HostMaxNrHosts) {#ifdef DEBUG HostCheckListsRemove2(hostcontrol, oldhost);#endif HostRemoveLRUList(hostcontrol, oldhost); HostRemoveTimeList(hostcontrol, oldhost); HostRemoveLexList(hostcontrol, oldhost); HashRemove(hostcontrol->Table, oldhost->Address, addrlen);#ifdef DEBUG HostCheckListsRemove(hostcontrol, oldhost); memset(oldhost->Address, 0, HOST_SIZE_ADDR);#endif TopNEntryReset(hostcontrol->Index, oldhost, hostcontrol->AddressLen); DnpapFree(oldhost); hostcontrol->LastDeleteTime = SysTime(); hostcontrol->TableSize--;#ifdef DEBUG if (HashSearch(hostcontrol->Table, src, addrlen) == NULL) DnpapMessage(DMC_FATAL, HOST_ERROR, "host that was just added can not be retrieved");#endif } } } } if (host != NULL) { host->OutPkts++; host->OutOctets += size; switch (type) { case MAC_TYPE_ETHERNET_CSMACD: case MAC_TYPE_88023_CSMACD: if (!memcmp(dst, &EthBroadcast, addrlen)) host->OutBroadcastPkts++; else if (dst[0] & 0x01) host->OutMulticastPkts++; break; default: break; } HostUpdateLRUList(hostcontrol, host); TopNEntryUpdate(hostcontrol->Index, host, hostcontrol->AddressLen); }#ifdef DEBUG HostCheckListsConsistency(hostcontrol);#endif if ((host = HashSearch(hostcontrol->Table, dst, addrlen)) == NULL) { if ((host = DnpapMalloc(sizeof(HOST))) != NULL) { memset(host, 0, sizeof(HOST)); memcpy(host->Address, dst, addrlen);#ifdef DEBUG HostCheckListsAdd(hostcontrol, host);#endif if (HashAdd(hostcontrol->Table, host->Address, addrlen, host) == NULL) { DnpapMessage(DMC_WARNING, HOST_NADD, "hostcontrol: host could not be added to the hash table"); DnpapFree(host); host = NULL; } else {#ifdef DEBUG if (HashSearch(hostcontrol->Table, dst, addrlen) == NULL) DnpapMessage(DMC_FATAL, HOST_ERROR, "host that was just added can not be retrieved");#endif HostAddLexList(hostcontrol, host); HostAddTimeList(hostcontrol, host); oldhost = HostAddLRUList(hostcontrol, host);#ifdef DEBUG HostCheckListsAdd2(hostcontrol, host);#endif hostcontrol->TableSize++; if (hostcontrol->TableSize > (LONG) HostMaxNrHosts) {#ifdef DEBUG HostCheckListsRemove2(hostcontrol, oldhost);#endif HostRemoveLRUList(hostcontrol, oldhost); HostRemoveTimeList(hostcontrol, oldhost); HostRemoveLexList(hostcontrol, oldhost); HashRemove(hostcontrol->Table, oldhost->Address, addrlen);#ifdef DEBUG HostCheckListsRemove(hostcontrol, oldhost); memset(oldhost->Address, 0, HOST_SIZE_ADDR);#endif TopNEntryReset(hostcontrol->Index, oldhost, hostcontrol->AddressLen); DnpapFree(oldhost); hostcontrol->LastDeleteTime = SysTime(); hostcontrol->TableSize--;#ifdef DEBUG if (HashSearch(hostcontrol->Table, dst, addrlen) == NULL) DnpapMessage(DMC_FATAL, HOST_ERROR, "host that was just added can not be retrieved");#endif } } } } if (host != NULL) { host->InPkts++; host->InOctets += size; HostUpdateLRUList(hostcontrol, host); TopNEntryUpdate(hostcontrol->Index, host, hostcontrol->AddressLen); }#ifdef DEBUG HostCheckListsConsistency(hostcontrol);#endif return;}BOOLEAN HostAddLexList(HOST_CONTROL * hostcontrol, HOST * host){ HOST *p, *q; WORD addrlen = hostcontrol->AddressLen; if (hostcontrol->LexList == NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -