📄 dmatrixc.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 <maxmem.h>#include <dchan.h>#include "dmatrixd.h"#include "dmatrixe.h"#include "dmatrixc.h"IMPORT BOOLEAN BeholderStrictRMON;static LONG MatrixMaxNrSrcDsts = 8000;static BOOLEAN MatrixCallback(MAC_COLL * collector, PROT_PKT * pkt);static LRUEntry *MatrixAddLRUList(DNPAP_MATRIX_CONTROL * matrixcontrol, LRUEntry * entry);static BOOLEAN MatrixRemoveLRUList(DNPAP_MATRIX_CONTROL * matrixcontrol, LRUEntry * entry);static BOOLEAN MatrixUpdateLRUList(DNPAP_MATRIX_CONTROL * matrixcontrol, LRUEntry * connaddr);static BOOLEAN MatrixDelConns(DNPAP_MATRIX_CONTROL * matrixcontrol);static BOOLEAN MatrixDelConn(DNPAP_MATRIX_CONTROL * matrixcontrol, LRUEntry * entry);static VOID MatrixDelHost(DNPAP_MATRIX_CONTROL * matrixcontrol, Host * host, BOOLEAN source);static VOID ListDelConn(Host * host, ConnInfo * conn);static BOOLEAN MatrixAddHost(DNPAP_MATRIX_CONTROL * matrixcontrol, Host * host, BOOLEAN source);static BOOLEAN ListAddTop(Host * host, ConnInfo * conn);static BOOLEAN ListUpdateTop(Host * host, ConnInfo * conn);static BOOLEAN ListAddLex(Host * host, ConnInfo * conn, WORD addrlen);static ConnInfo *ListConnSearch(Host * host, BYTE * addr, WORD addrlen);#ifdef DEBUGstatic VOID ListCheckConns(Host * host);#endifBOOLEAN DnpapMatrixConfigInit(VOID){ ConfigGetLong("beholder.dmatrix.maxnrsrcdsts", &MatrixMaxNrSrcDsts); if (MatrixMaxNrSrcDsts < 2) { DnpapMessage(DMC_WARNING, DMATRIX_MAX, "dmatrix: beholder.dmatrix.maxnrsrcdsts < 2, setting it to 2"); MatrixMaxNrSrcDsts = 2; } return TRUE;}BOOLEAN DnpapMatrixCInit(DNPAP_MATRIX_CONTROL * matrixcontrol){ LONG source[] = {1, 3, 6, 1, 2, 1, 2, 2, 1, 1, 1}; memcpy(matrixcontrol->Source, source, sizeof(source)); matrixcontrol->SourceLen = sizeof(source) / sizeof(source[0]); matrixcontrol->Channel = FALSE; matrixcontrol->ChannelType = 0; matrixcontrol->ChannelAccept = TRUE; matrixcontrol->AddressLen = 0; matrixcontrol->TableSize = 0; matrixcontrol->LastDeleteTime = 0; matrixcontrol->Owner[0] = '\0'; matrixcontrol->OwnerLen = 0; matrixcontrol->Status = SNMP_INVALID; if ((matrixcontrol->Iface = MacIfaceGet((WORD) matrixcontrol->Source[matrixcontrol->SourceLen - 1])) == NULL) { DnpapMessage(DMC_ERROR, DMATRIX_NETINIT, "dmatrix: network initialisation failed"); return (FALSE); } matrixcontrol->SrcTable = NULL; matrixcontrol->DstTable = NULL; matrixcontrol->LRUList = NULL; matrixcontrol->LRULast = NULL; matrixcontrol->SrcList = NULL; matrixcontrol->DstList = NULL; BooleanSetAllTrue(matrixcontrol->ObjectSet); BooleanSetFalse(matrixcontrol->ObjectSet, MATRIX_BOOLEAN_DATASOURCE); BooleanSetFalse(matrixcontrol->ObjectSet, MATRIX_BOOLEAN_OWNER); return TRUE;}BOOLEAN DnpapMatrixCStart(DNPAP_MATRIX_CONTROL * matrixcontrol){ if (BeholderStrictRMON && !BooleanCheckAllTrue(matrixcontrol->ObjectSet)) return FALSE; if (matrixcontrol->Channel == FALSE) { matrixcontrol->Coll.Rcve = MatrixCallback; matrixcontrol->Coll.specific = matrixcontrol; if (!MacCollRegister(&(matrixcontrol->Coll))) { DnpapMessage(DMC_ERROR, DMATRIX_NETERR, "dmatrix: network initialisation failed"); return FALSE; } } if ((matrixcontrol->SrcTable = NewHash(MatrixMaxNrSrcDsts/2+11, NULL)) == NULL) { DnpapMessage(DMC_ERROR, DMATRIX_HASHERR, "dmatrix: can not create source hashtable"); return FALSE; } if ((matrixcontrol->DstTable = NewHash(MatrixMaxNrSrcDsts/2+11, NULL)) == NULL) { DnpapMessage(DMC_ERROR, DMATRIX_HASHERR, "dmatrix: can not create destination hashtable"); return FALSE; } return TRUE;}BOOLEAN DnpapMatrixCStop(DNPAP_MATRIX_CONTROL * matrixcontrol){ MacCollRemove(&(matrixcontrol->Coll)); MatrixDelConns(matrixcontrol); DelHash(matrixcontrol->SrcTable); DelHash(matrixcontrol->DstTable); return TRUE;}BOOLEAN MatrixCallback(MAC_COLL * collector, PROT_PKT * pkt){ DNPAP_MATRIX_CONTROL *matrixcontrol = collector->specific; PROT_OBJ Interface = {0, {1, 2}}; if (ProtGetField(pkt, &Interface) == TRUE && Interface.Syntax.LngInt == matrixcontrol->Source[matrixcontrol->SourceLen - 1]) DnpapMatrixHandlePkt(matrixcontrol, pkt); return TRUE;}VOID DnpapMatrixHandlePkt(DNPAP_MATRIX_CONTROL * matrixcontrol, PROT_PKT * pkt){ PROT_OBJ EthSize = {0, {1, 4}}; PROT_OBJ EthDst = {1, {2, 1}}; PROT_OBJ EthSrc = {1, {2, 2}}; BYTE *s, *d; LWORD size; WORD addrlen; Host *src; Host *dst; ConnInfo *conndst; ConnInfo *connsrc; ConnStats *stats; LRUEntry *entry, *oldentry; BOOLEAN newconn; INT type; s = NULL; d = NULL; if (matrixcontrol->Channel == FALSE) type = matrixcontrol->Iface->type; else { type = matrixcontrol->ChannelType; if (type == 0) { type = DnpapChannelType(matrixcontrol->Source[matrixcontrol->SourceLen-1]); if (type == 0) return; matrixcontrol->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) s = EthSrc.Syntax.BufChr; if (ProtGetField(pkt,&EthDst) == TRUE) d = EthDst.Syntax.BufChr; if (EthSrc.SyntaxLen != ETH_SIZE_ADDR) s = NULL; if (EthDst.SyntaxLen != ETH_SIZE_ADDR) d = NULL; addrlen = ETH_SIZE_ADDR; if (matrixcontrol->AddressLen == 0) matrixcontrol->AddressLen = addrlen; else if (matrixcontrol->AddressLen != addrlen) { DnpapMessage(DMC_FATAL, DMATRIX_INCONSISTENT, "dmatrix: inconsistent address length encountered"); DnpapExit(1); } break; default: return; } newconn = FALSE; if ((src = HashSearch(matrixcontrol->SrcTable, s, addrlen)) == NULL) { if ((src = DnpapMalloc(sizeof(Host))) != NULL) { memcpy(src->Addr, s, addrlen); src->LexList = NULL; src->TopList = NULL; src->TopLast = NULL; src->NumberConnect = 0; src->Next = NULL; src->Prev = NULL; if (HashAdd(matrixcontrol->SrcTable, src->Addr, addrlen, src) == NULL) { DnpapMessage(DMC_WARNING, DMATRIX_MAX, "dmatrix: source could not be added to the table"); DnpapFree(src); src = NULL; return; } else { MatrixAddHost(matrixcontrol, src, TRUE); } newconn = TRUE; } } if ((dst = HashSearch(matrixcontrol->DstTable, d, addrlen)) == NULL) { if ((dst = DnpapMalloc(sizeof(Host))) != NULL) { memcpy(dst->Addr, d, addrlen); dst->LexList = NULL; dst->TopList = NULL; dst->TopLast = NULL; dst->NumberConnect = 0; dst->Next = NULL; dst->Prev = NULL; if (HashAdd(matrixcontrol->DstTable, dst->Addr, addrlen, dst) == NULL) { DnpapMessage(DMC_WARNING, DMATRIX_MAX, "dmatrix: destination could not be added to the table"); DnpapFree(dst); dst = NULL; return; } else { MatrixAddHost(matrixcontrol, dst, FALSE); } newconn = TRUE; } } conndst = ListConnSearch(src, dst->Addr, matrixcontrol->AddressLen); if (conndst == NULL) { if ((conndst = DnpapMalloc(sizeof(ConnInfo))) != NULL) { conndst->ConnHost = dst; conndst->Stats = NULL; conndst->LexNext = NULL; conndst->LexPrev = NULL; conndst->TopNext = NULL; conndst->TopPrev = NULL; conndst->Entry = NULL; ListAddLex(src, conndst, matrixcontrol->AddressLen); ListAddTop(src, conndst); src->NumberConnect++; newconn = TRUE; } else { DnpapMessage(DMC_WARNING, DMATRIX_MAX, "dmatrix: not enough memory"); DnpapFree(conndst); return; } } connsrc = ListConnSearch(dst, src->Addr, matrixcontrol->AddressLen); if (connsrc == NULL) { if ((connsrc = DnpapMalloc(sizeof(ConnInfo))) != NULL) { connsrc->ConnHost = src; connsrc->Stats = NULL; connsrc->LexNext = NULL; connsrc->LexPrev = NULL; connsrc->TopNext = NULL; connsrc->TopPrev = NULL; connsrc->Entry = NULL; ListAddLex(dst, connsrc, matrixcontrol->AddressLen); ListAddTop(dst, connsrc); dst->NumberConnect++; newconn = TRUE; } else { DnpapMessage(DMC_WARNING, DMATRIX_MAX, "dmatrix: not enough memory"); ListDelConn(src, conndst); DnpapFree(connsrc); return; } } if (newconn == TRUE) { matrixcontrol->TableSize++; if ((entry = DnpapMalloc(sizeof(LRUEntry))) == NULL) { DnpapMessage(DMC_WARNING, DMATRIX_MAX, "dmatrix: LRU entry could not be added to the table"); } else { entry->ConnSrc = connsrc; entry->ConnDst = conndst; connsrc->Entry = entry; conndst->Entry = entry; oldentry = MatrixAddLRUList(matrixcontrol, entry); if (matrixcontrol->TableSize > MatrixMaxNrSrcDsts) { MatrixRemoveLRUList(matrixcontrol, oldentry); MatrixDelConn(matrixcontrol, oldentry); DnpapFree(oldentry); matrixcontrol->LastDeleteTime = SysTime(); matrixcontrol->TableSize--; } } if ((stats = DnpapMalloc(sizeof(ConnStats))) == NULL) { DnpapMessage(DMC_ERROR, DMATRIX_STATSERR, "dmatrix: could not allocate statistics entry"); MatrixRemoveLRUList(matrixcontrol, entry); MatrixDelConn(matrixcontrol, entry); DnpapFree(entry); matrixcontrol->TableSize--; return; } else { stats->Pkts = 0; stats->Octets = 0; stats->Errors = 0; if (connsrc->Stats != NULL || conndst->Stats != NULL) { DnpapMessage(DMC_FATAL, DMATRIX_STATSERR, "dmatrix: error in internal tables"); DnpapExit(DMATRIX_STATSERR); } connsrc->Stats = stats; conndst->Stats = stats; } } else { entry = connsrc->Entry; if (entry != conndst->Entry) { DnpapMessage(DMC_FATAL, DMATRIX_LRUERR, "dmatrix: error in internal tables"); DnpapExit(DMATRIX_LRUERR); } stats = connsrc->Stats; if (stats != conndst->Stats) { DnpapMessage(DMC_FATAL, DMATRIX_STATSERR, "dmatrix: error in internal tables"); DnpapExit(DMATRIX_STATSERR); } } if (stats != NULL) { stats->Pkts++; stats->Octets += size; ListUpdateTop(dst, connsrc); ListUpdateTop(src, conndst); MatrixUpdateLRUList(matrixcontrol, entry); }#ifdef DEBUG ListCheckConns(src); ListCheckConns(dst);#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -