📄 matrix_c.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 "matrix_d.h"#include "matrix_e.h"#include "matrix_c.h"IMPORT BOOLEAN BeholderStrictRMON;static LONG MatrixMaxNrSrcDsts = 8000;static BOOLEAN MatrixCallback(MAC_COLL *collector, PROT_PKT *pkt);static BOOLEAN MatrixAddSrcDstList(MATRIX_CONTROL *matrixcontrol, SRCDST *host);static BOOLEAN MatrixRemoveSrcDstList(MATRIX_CONTROL *matrixcontrol, SRCDST *host);static SRCDST* MatrixAddLRUList(MATRIX_CONTROL *matrixcontrol, SRCDST *srcdst);static BOOLEAN MatrixUpdateLRUList(MATRIX_CONTROL *matrixcontrol, SRCDST *srcdst);static BOOLEAN MatrixRemoveLRUList(MATRIX_CONTROL *matrixcontrol, SRCDST *srcdst);static VOID DelSrcDsts(MATRIX_CONTROL *matrixcontrol);#define conncmp(srcdst1, srcdst2, addrlen, len) \ connbbcmp((srcdst1)->SrcDst, (srcdst2)->SrcDst, addrlen, len)#define connrcmp(srcdst1, srcdst2, addrlen, len) \ connbbrcmp((srcdst1)->SrcDst, (srcdst2)->SrcDst, addrlen, len)#define connbcmp(srcdst1, srcdst2, addrlen, len) \ connbbcmp((srcdst1)->SrcDst, srcdst2, addrlen, len)#define connbrcmp(srcdst1, srcdst2, addrlen, len) \ connbbrcmp((srcdst1)->SrcDst, srcdst2, addrlen, len)static int connbbcmp(BYTE *srcdst1, BYTE *srcdst2, WORD addrlen, WORD len);static int connbbrcmp(BYTE *srcdst1, BYTE *srcdst2, WORD addrlen, WORD len);BOOLEAN MatrixConfigInit(VOID){ ConfigGetLong("beholder.matrix.maxnrsrcdsts", &MatrixMaxNrSrcDsts); if (MatrixMaxNrSrcDsts < 2) { DnpapMessage(DMC_WARNING, MATRIX_MAX, "matrixcontrol: beholder.matrix.maxnrsrcdsts < 2, setting it to 2"); MatrixMaxNrSrcDsts = 2; } return TRUE;}BOOLEAN MatrixCInit(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, MATRIX_NETINIT, "matrixcontrol: network initialisation failed"); return (FALSE); } matrixcontrol->Table = NULL; matrixcontrol->SrcDstList = NULL; matrixcontrol->DstSrcList = NULL; matrixcontrol->LRUList = NULL; matrixcontrol->LRULast = NULL; BooleanSetAllTrue(matrixcontrol->ObjectSet); BooleanSetFalse(matrixcontrol->ObjectSet, MATRIX_BOOLEAN_DATASOURCE); BooleanSetFalse(matrixcontrol->ObjectSet, MATRIX_BOOLEAN_OWNER); return TRUE;}BOOLEAN MatrixCStart(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, MATRIX_NETERR, "matrixcontrol: network initialisation failed"); return FALSE; } } if ((matrixcontrol->Table = NewHash(MatrixMaxNrSrcDsts/2+11, NULL)) == NULL) { DnpapMessage(DMC_ERROR, MATRIX_HASHERR, "matrixcontrol: can not create hashtable"); return FALSE; } return TRUE;}BOOLEAN MatrixCStop(MATRIX_CONTROL *matrixcontrol){ MacCollRemove(&(matrixcontrol->Coll)); DelHash(matrixcontrol->Table); DelSrcDsts(matrixcontrol); return TRUE;}BOOLEAN MatrixCallback(MAC_COLL *collector, PROT_PKT *pkt){MATRIX_CONTROL *matrixcontrol = collector->specific;PROT_OBJ Interface = {0, {1,2}}; if (ProtGetField(pkt,&Interface) == TRUE && Interface.Syntax.LngInt == matrixcontrol->Source[matrixcontrol->SourceLen-1]) MatrixHandlePkt(matrixcontrol, pkt); return TRUE;}VOID MatrixHandlePkt(MATRIX_CONTROL *matrixcontrol, PROT_PKT *pkt){SRCDST *srcdst = NULL, *oldsrcdst = NULL;BYTE srcdstaddr[2*HOST_SIZE_ADDR];PROT_OBJ EthSize = {0, {1,4}};PROT_OBJ EthDst = {1, {2,1}};PROT_OBJ EthSrc = {1, {2,2}};BYTE *src, *dst;LWORD size; WORD addrlen;INT type; src = NULL; dst = NULL; if (matrixcontrol->Channel == FALSE) type = matrixcontrol->Iface->type; else { type = matrixcontrol->ChannelType; if (type == 0) { type = ChannelType(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) 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 (matrixcontrol->AddressLen == 0) matrixcontrol->AddressLen = addrlen; else if (matrixcontrol->AddressLen != addrlen) { DnpapMessage(DMC_FATAL, MATRIX_INCONSISTENT, "matrix: inconsistent address length encountered"); DnpapExit(1); } break; default: return; } memcpy(srcdstaddr, src, addrlen); memcpy(srcdstaddr+addrlen, dst, addrlen); if ((srcdst = HashSearch(matrixcontrol->Table, srcdstaddr, 2*addrlen)) == NULL) { /* first try to add the new srcdst */ if ((srcdst = DnpapMalloc(sizeof(SRCDST))) != NULL) { memset(srcdst, 0, sizeof(SRCDST)); memcpy(srcdst->SrcDst, srcdstaddr, 2*addrlen); if (HashAdd(matrixcontrol->Table, srcdst->SrcDst, 2*addrlen, srcdst) == NULL) { DnpapMessage(DMC_WARNING, MATRIX_NADD, "matrixcontrol: srcdst could not be added to the hash table"); DnpapFree(srcdst); srcdst = NULL; } else { MatrixAddSrcDstList(matrixcontrol, srcdst); oldsrcdst = MatrixAddLRUList(matrixcontrol, srcdst); matrixcontrol->TableSize++; if (matrixcontrol->TableSize > (LONG)MatrixMaxNrSrcDsts) { MatrixRemoveLRUList(matrixcontrol, oldsrcdst); MatrixRemoveSrcDstList(matrixcontrol, oldsrcdst); HashRemove(matrixcontrol->Table, oldsrcdst->SrcDst, 2*addrlen); DnpapFree(oldsrcdst); matrixcontrol->LastDeleteTime = SysTime(); matrixcontrol->TableSize--; } } } } if (srcdst != NULL) { srcdst->Pkts++; srcdst->Octets += size; MatrixUpdateLRUList(matrixcontrol, srcdst); } return;}BOOLEAN MatrixAddSrcDstList(MATRIX_CONTROL *matrixcontrol, SRCDST *srcdst){SRCDST *p, *q;WORD addrlen = matrixcontrol->AddressLen; if (matrixcontrol->SrcDstList == NULL && matrixcontrol->DstSrcList == NULL) { matrixcontrol->SrcDstList = srcdst; srcdst->SrcDstPrev = NULL; srcdst->SrcDstNext = NULL; matrixcontrol->DstSrcList = srcdst; srcdst->DstSrcPrev = NULL; srcdst->DstSrcNext = NULL; return TRUE; } /* update SrcDstList */ for (p = matrixcontrol->SrcDstList, q = NULL; p != NULL; q = p, p = p->SrcDstNext) { if (conncmp(p, srcdst, addrlen, 2*addrlen) >= 0) break; } if (q != NULL) q->SrcDstNext = srcdst; else matrixcontrol->SrcDstList = srcdst; if (p != NULL) p->SrcDstPrev = srcdst; srcdst->SrcDstPrev = q; srcdst->SrcDstNext = p; /* update DstSrcList */ for (p = matrixcontrol->DstSrcList, q = NULL; p != NULL; q = p, p = p->DstSrcNext) { if (connrcmp(p, srcdst, addrlen, 2*addrlen) >= 0) break; } if (q != NULL) q->DstSrcNext = srcdst; else matrixcontrol->DstSrcList = srcdst; if (p != NULL) p->DstSrcPrev = srcdst; srcdst->DstSrcPrev = q; srcdst->DstSrcNext = p; return TRUE;}SRCDST* MatrixAddLRUList(MATRIX_CONTROL *matrixcontrol, SRCDST *srcdst){ if (matrixcontrol->LRUList == NULL) { matrixcontrol->LRUList = srcdst; matrixcontrol->LRULast = srcdst; srcdst->LRUPrev = NULL; srcdst->LRUNext = NULL; return NULL; } srcdst->LRUNext = matrixcontrol->LRUList; srcdst->LRUPrev = NULL; matrixcontrol->LRUList->LRUPrev = srcdst; matrixcontrol->LRUList = srcdst; return matrixcontrol->LRULast;}BOOLEAN MatrixUpdateLRUList(MATRIX_CONTROL *matrixcontrol, SRCDST *srcdst){ if (matrixcontrol->TableSize > 1) { MatrixRemoveLRUList(matrixcontrol, srcdst); MatrixAddLRUList(matrixcontrol, srcdst); } return TRUE;}BOOLEAN MatrixRemoveSrcDstList(MATRIX_CONTROL *matrixcontrol, SRCDST *srcdst){ if (srcdst->SrcDstPrev != NULL) srcdst->SrcDstPrev->SrcDstNext = srcdst->SrcDstNext; else matrixcontrol->SrcDstList = srcdst->SrcDstNext; if (srcdst->SrcDstNext != NULL) srcdst->SrcDstNext->SrcDstPrev = srcdst->SrcDstPrev; if (srcdst->DstSrcPrev != NULL) srcdst->DstSrcPrev->DstSrcNext = srcdst->DstSrcNext; else matrixcontrol->DstSrcList = srcdst->DstSrcNext; if (srcdst->DstSrcNext != NULL) srcdst->DstSrcNext->DstSrcPrev = srcdst->DstSrcPrev; return TRUE;}BOOLEAN MatrixRemoveLRUList(MATRIX_CONTROL *matrixcontrol, SRCDST *srcdst){ if (srcdst->LRUPrev != NULL) srcdst->LRUPrev->LRUNext = srcdst->LRUNext; else matrixcontrol->LRUList = srcdst->LRUNext; if (srcdst->LRUNext != NULL) srcdst->LRUNext->LRUPrev = srcdst->LRUPrev; else matrixcontrol->LRULast = srcdst->LRUPrev; return TRUE;}VOID DelSrcDsts(MATRIX_CONTROL *matrixcontrol){SRCDST *srcdst1, *srcdst2; for (srcdst2 = matrixcontrol->SrcDstList; srcdst2 != NULL; srcdst2 = srcdst1) { srcdst1 = srcdst2->SrcDstNext; DnpapFree(srcdst2); matrixcontrol->TableSize--; } matrixcontrol->SrcDstList = NULL; matrixcontrol->DstSrcList = NULL;}SRCDST* MatrixSearchNext(MATRIX_CONTROL *matrixcontrol, BYTE *srcdst, WORD len, BOOLEAN SDorder){SRCDST* p;BYTE srcdst2[2*HOST_SIZE_ADDR];WORD addrlen = matrixcontrol->AddressLen; if (SDorder == TRUE) { if (len == 2*addrlen && (p = HashSearch(matrixcontrol->Table, srcdst, 2*addrlen)) != NULL) return p->SrcDstNext; for (p = matrixcontrol->SrcDstList; p != NULL; p = p->SrcDstNext) { if (connbcmp(p, srcdst, addrlen, len) >= 0) return p; } return NULL; } else { /* srcdst contains destination and source in that order, so switch them */ memcpy(srcdst2, srcdst+addrlen, addrlen); memcpy(srcdst2+addrlen, srcdst, addrlen); if (len == 2*addrlen) { if ((p = HashSearch(matrixcontrol->Table, srcdst2, 2*addrlen)) != NULL) return p->DstSrcNext; } for (p = matrixcontrol->DstSrcList; p != NULL; p = p->DstSrcNext) { /* compare destination and source ordered connections */ if (connbrcmp(p, srcdst2, addrlen, len) >= 0) return p; } return NULL; }}SRCDST* MatrixSearchHash(MATRIX_CONTROL *matrixcontrol, SNMP_OBJECT *obj, WORD idlen, BOOLEAN SDorder){WORD i;BYTE srcdst[2*HOST_SIZE_ADDR];WORD addrlen = matrixcontrol->AddressLen; if (obj->Id[idlen+1] != addrlen || obj->Id[idlen+1+addrlen+1] != addrlen) return NULL; if (SDorder == TRUE) { for (i = 0; i < addrlen; i++) { srcdst[i] = (BYTE)obj->Id[idlen+2+i]; srcdst[addrlen+i] = (BYTE)obj->Id[idlen+3+addrlen+i]; } return HashSearch(matrixcontrol->Table, srcdst, 2*addrlen); } else { for (i = 0; i < addrlen; i++) { srcdst[i] = (BYTE)obj->Id[idlen+3+addrlen+i]; srcdst[addrlen+i] = (BYTE)obj->Id[idlen+2+i]; } return HashSearch(matrixcontrol->Table, srcdst, 2*addrlen); }}int connbbcmp(BYTE *srcdst1, BYTE *srcdst2, WORD addrlen, WORD len){INT i1, i2; if (len > 2*addrlen) len = 2*addrlen; for (i1 = 0, i2 = 0; len > 0; i1++, i2++, len--) { if (srcdst1[i1] < srcdst2[i2]) return -1; else if (srcdst1[i1] > srcdst2[i2]) return 1; } return 0;}int connbbrcmp(BYTE *srcdst1, BYTE *srcdst2, WORD addrlen, WORD len){INT i1, i2; if (len > 2*addrlen) len = 2*addrlen; for (i1 = addrlen, i2 = addrlen; len > 0; i1++, i2++, len--) { if (i1 >= 2*addrlen) i1 = i2 = 0; if (srcdst1[i1] < srcdst2[i2]) return -1; else if (srcdst1[i1] > srcdst2[i2]) return 1; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -