⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 matrix_c.c

📁 嵌入式RMON,RMON为Remote monitor的缩写,基于SNMP为网络提供主动监控及错误告警,智能交换路由必备协议
💻 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 + -