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

📄 discconc.c

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