📄 discconc.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 "discconc.h"IMPORT BOOLEAN BeholderStrictRMON;static LONG DiscConnMaxNrConns = 20000;static LONG DiscConnTimeout = 10000;static BOOLEAN DiscConnCallback(MAC_COLL *collector, PROT_PKT *pkt);static BOOLEAN DiscConnUpdateTables(DISCCONN_CONTROL *discconncontrol, INT type, BYTE *src, INT srclen, BYTE *dst, INT dstlen, LWORD size, ULONG now);static VOID DiscConnRemoveEntry(DISCCONN_CONTROL *discconncontrol, DISCCONN *oldsrcdst);static BOOLEAN DiscConnAddConnList(INT type, DISCCONN **sdlexlist, DISCCONN **dslexlist, DISCCONN *host);static BOOLEAN DiscConnRemoveConnList(DISCCONN **sdlexlist, DISCCONN **dslexlist, DISCCONN *host);static DISCCONN* DiscConnAddLRUList(DISCCONN_CONTROL *discconncontrol, DISCCONN *srcdst);static BOOLEAN DiscConnUpdateLRUList(DISCCONN_CONTROL *discconncontrol, DISCCONN *srcdst);static BOOLEAN DiscConnRemoveLRUList(DISCCONN_CONTROL *discconncontrol, DISCCONN *srcdst);static VOID LRUTimerCallback(TIMER_DESCR *timer, ULONG now, VOID *param);static VOID DelConns(DISCCONN_CONTROL *discconncontrol, DISCCONN **sdlexlist, DISCCONN **dslexlist);static INT ConnLen(INT type);static int connrcmp(BYTE *srcdst1, BYTE *srcdst2, WORD addrlen, WORD len);BOOLEAN DiscConnConfigInit(VOID){ ConfigGetLong("beholder.discconn.maxnrconns", &DiscConnMaxNrConns); if (DiscConnMaxNrConns < 2) { DnpapMessage(DMC_WARNING, DISC_MAX, "discconncontrol: beholder.discconn.maxnrconns < 2, setting it to 2"); DiscConnMaxNrConns = 2; } ConfigGetLong("beholder.discconn.timeout", &DiscConnTimeout); if (DiscConnTimeout < 2) { DnpapMessage(DMC_WARNING, DISC_MAX, "discconncontrol: beholder.discconn.timeout < 2, setting it to 2"); DiscConnTimeout = 2; } return TRUE;}BOOLEAN DiscConnCInit(DISCCONN_CONTROL *discconncontrol){LONG source[] = {1,3,6,1,2,1,2,2,1,1,1}; memcpy(discconncontrol->Source, source, sizeof(source)); discconncontrol->SourceLen = sizeof(source)/sizeof(source[0]); discconncontrol->Channel = FALSE; discconncontrol->ChannelType = 0; discconncontrol->ChannelAccept = TRUE; discconncontrol->AddressLen = 0; discconncontrol->EthTableSize = 0; discconncontrol->IPTableSize = 0; discconncontrol->UDPTableSize = 0; discconncontrol->TCPTableSize = 0; discconncontrol->TableSize = 0; discconncontrol->TurnOnTime = 0; discconncontrol->LastDeleteTime = 0; discconncontrol->Owner[0] = '\0'; discconncontrol->OwnerLen = 0; discconncontrol->Status = SNMP_INVALID; if ((discconncontrol->Iface = MacIfaceGet((WORD) discconncontrol->Source[discconncontrol->SourceLen-1])) == NULL) { DnpapMessage(DMC_ERROR, DISC_NETINIT, "discconncontrol: network initialisation failed"); return (FALSE); } discconncontrol->Table = NULL; discconncontrol->EthSrcDstList = NULL; discconncontrol->IPSrcDstList = NULL; discconncontrol->UDPSrcDstList = NULL; discconncontrol->TCPSrcDstList = NULL; discconncontrol->EthDstSrcList = NULL; discconncontrol->IPDstSrcList = NULL; discconncontrol->UDPDstSrcList = NULL; discconncontrol->TCPDstSrcList = NULL; discconncontrol->LRUList = NULL; discconncontrol->LRULast = NULL; discconncontrol->LRUTimer = NULL; discconncontrol->LastLRUEntry = NULL; BooleanSetAllTrue(discconncontrol->ObjectSet); BooleanSetFalse(discconncontrol->ObjectSet, DISC_BOOLEAN_DATASOURCE); BooleanSetFalse(discconncontrol->ObjectSet, DISC_BOOLEAN_OWNER); return TRUE;}BOOLEAN DiscConnCStart(DISCCONN_CONTROL *discconncontrol){ if (BeholderStrictRMON && !BooleanCheckAllTrue(discconncontrol->ObjectSet)) return FALSE; if (discconncontrol->Channel == FALSE) { discconncontrol->Coll.Rcve = DiscConnCallback; discconncontrol->Coll.specific = discconncontrol; if (!MacCollRegister(&(discconncontrol->Coll))) { DnpapMessage(DMC_ERROR, DISC_NETERR, "discconncontrol: network initialisation failed"); return FALSE; } } if ((discconncontrol->Table = NewHash(DiscConnMaxNrConns/2+11, NULL)) == NULL) { DnpapMessage(DMC_ERROR, DISC_HASHERR, "discconncontrol: can not create hashtable"); return FALSE; } if ((discconncontrol->LRUTimer = TimerRegister(LRUTimerCallback, discconncontrol, DiscConnTimeout, TIMER_FOREVER, TIMER_TYPE_RECOVER)) == NULL) { DnpapMessage(DMC_ERROR, DISC_TIMER, "discconncontrol: can not set LRU timer"); return FALSE; } discconncontrol->TurnOnTime = TimeUsec(); return TRUE;}BOOLEAN DiscConnCStop(DISCCONN_CONTROL *discconncontrol){ TimerRemove(discconncontrol->LRUTimer); MacCollRemove(&(discconncontrol->Coll)); DelHash(discconncontrol->Table); DelConns(discconncontrol, &discconncontrol->EthSrcDstList, &discconncontrol->EthDstSrcList); DelConns(discconncontrol, &discconncontrol->IPSrcDstList, &discconncontrol->IPDstSrcList); DelConns(discconncontrol, &discconncontrol->UDPSrcDstList, &discconncontrol->UDPDstSrcList); DelConns(discconncontrol, &discconncontrol->TCPSrcDstList, &discconncontrol->TCPDstSrcList); return TRUE;}BOOLEAN DiscConnCallback(MAC_COLL *collector, PROT_PKT *pkt){DISCCONN_CONTROL *discconncontrol = collector->specific;PROT_OBJ Interface = {0, {1,2}}; if (ProtGetField(pkt,&Interface) == TRUE && Interface.Syntax.LngInt == discconncontrol->Source[discconncontrol->SourceLen-1]) DiscConnHandlePkt(discconncontrol, pkt); return TRUE;}VOID DiscConnHandlePkt(DISCCONN_CONTROL *discconncontrol, 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 (discconncontrol->Channel == FALSE) type = discconncontrol->Iface->type; else { type = discconncontrol->ChannelType; if (type == 0) { type = ChannelType(discconncontrol->Source[discconncontrol->SourceLen-1]); if (type == 0) return; discconncontrol->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 - discconncontrol->TurnOnTime; if (EthSrc.SyntaxLen != DISC_SIZE_ETHADDR || EthDst.SyntaxLen != DISC_SIZE_ETHADDR) { DnpapMessage(DMC_ERROR, DISC_INVPACKET, "discconncontrol: invalid packet"); return; } memcpy(src, EthSrc.Syntax.BufChr, DISC_SIZE_ETHADDR); memcpy(dst, EthDst.Syntax.BufChr, DISC_SIZE_ETHADDR); DiscConnUpdateTables(discconncontrol, 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); DiscConnUpdateTables(discconncontrol, 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); DiscConnUpdateTables(discconncontrol, 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); DiscConnUpdateTables(discconncontrol, DISC_TYPE_TCP, src, DISC_SIZE_TOTCPADDR, dst, DISC_SIZE_TOTCPADDR, size, now); } } } } return;}BOOLEAN DiscConnUpdateTables(DISCCONN_CONTROL *discconncontrol, INT type, BYTE *src, INT srclen, BYTE *dst, INT dstlen, LWORD size, ULONG now){BYTE srcdstaddr[DISC_SIZE_CONN];DISCCONN *srcdst, *oldsrcdst; memcpy(srcdstaddr, src, srclen); memcpy(srcdstaddr+srclen, dst, dstlen); if ((srcdst = HashSearch(discconncontrol->Table, srcdstaddr, srclen+dstlen)) == NULL) { /* first try to add the new srcdst */ if ((srcdst = DnpapMalloc(sizeof(DISCCONN))) != NULL) { memset(srcdst, 0, sizeof(DISCCONN)); memcpy(srcdst->SrcDst, srcdstaddr, (srcdst->SrcDstLen = srclen+dstlen)); srcdst->Type = (BYTE)type; if (HashAdd(discconncontrol->Table, srcdst->SrcDst, srclen+dstlen, srcdst) == NULL) { DnpapMessage(DMC_WARNING, DISC_NADD, "discconncontrol: connection could not be added to the hash table"); DnpapFree(srcdst); srcdst = NULL; } else { switch (type) { case DISC_TYPE_ETH: DiscConnAddConnList(type, &discconncontrol->EthSrcDstList, &discconncontrol->EthDstSrcList, srcdst); discconncontrol->EthTableSize++; break; case DISC_TYPE_IP: DiscConnAddConnList(type, &discconncontrol->IPSrcDstList, &discconncontrol->IPDstSrcList, srcdst); discconncontrol->IPTableSize++; break; case DISC_TYPE_UDP: DiscConnAddConnList(type, &discconncontrol->UDPSrcDstList, &discconncontrol->UDPDstSrcList, srcdst); discconncontrol->UDPTableSize++; break; case DISC_TYPE_TCP: DiscConnAddConnList(type, &discconncontrol->TCPSrcDstList, &discconncontrol->TCPDstSrcList, srcdst); discconncontrol->TCPTableSize++; break; } oldsrcdst = DiscConnAddLRUList(discconncontrol, srcdst); discconncontrol->TableSize++; if (discconncontrol->TableSize > (LONG)DiscConnMaxNrConns) DiscConnRemoveEntry(discconncontrol, oldsrcdst); } } } if (srcdst != NULL) { srcdst->Pkts++; srcdst->Octets += size; srcdst->LRUTime = now; DiscConnUpdateLRUList(discconncontrol, srcdst); } return TRUE;} VOID DiscConnRemoveEntry(DISCCONN_CONTROL *discconncontrol, DISCCONN *oldsrcdst){ DiscConnRemoveLRUList(discconncontrol, oldsrcdst); switch (oldsrcdst->Type) { case DISC_TYPE_ETH: DiscConnRemoveConnList(&discconncontrol->EthSrcDstList, &discconncontrol->EthDstSrcList, oldsrcdst); discconncontrol->EthTableSize--; break; case DISC_TYPE_IP: DiscConnRemoveConnList(&discconncontrol->IPSrcDstList, &discconncontrol->IPDstSrcList, oldsrcdst); discconncontrol->IPTableSize--; break; case DISC_TYPE_UDP: DiscConnRemoveConnList(&discconncontrol->UDPSrcDstList, &discconncontrol->UDPDstSrcList, oldsrcdst); discconncontrol->UDPTableSize--; break; case DISC_TYPE_TCP: DiscConnRemoveConnList(&discconncontrol->TCPSrcDstList, &discconncontrol->TCPDstSrcList, oldsrcdst); discconncontrol->TCPTableSize--; break; } HashRemove(discconncontrol->Table, oldsrcdst->SrcDst, oldsrcdst->SrcDstLen); DnpapFree(oldsrcdst); discconncontrol->LastDeleteTime = SysTime(); discconncontrol->TableSize--;}BOOLEAN DiscConnAddConnList(INT type, DISCCONN **sdlexlist, DISCCONN **dslexlist, DISCCONN *srcdst){DISCCONN *p, *q;WORD addrlen; addrlen = ConnLen(type); if (*sdlexlist == NULL && *dslexlist == NULL) { *sdlexlist = srcdst; srcdst->SrcDstPrev = NULL; srcdst->SrcDstNext = NULL; *dslexlist = srcdst; srcdst->DstSrcPrev = NULL; srcdst->DstSrcNext = NULL; return TRUE; } /* update SrcDstList */ for (p = *sdlexlist, q = NULL; p != NULL; q = p, p = p->SrcDstNext)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -