📄 dcaptm.c
字号:
/* Beholder RMON ethernet network monitor,Copyright (C) 1993 DNPAP group *//* See file COPYING 'GNU General Public Licence' for copyright details */#include <dnpap.h>#include <dtime.h>#include <memory.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <snmp.h>#include <mibsup.h>#include <protocol.h>#include <message.h>#include <maxmem.h>#include <ring.h>#include "dcapte.h"#include "dcaptc.h"#include "dcapt.h"IMPORT BOOLEAN BeholderStrictRMON;#define BUFFERSIZE 1#define CAPTURESIZE 2#define CAPTURE_FIRST 1#define CAPTURE_GET 2#define CAPTURE_NXT 3 #define MAXPACKET 1514static MIB_LOCAL *BufferList = NULL;EXPORT WORD dnpapMemoryPerc = 75;static BOOLEAN RmonNext (SNMP_OBJECT *Obj, MIB_LOCAL **Local, WORD IdLen, WORD IdSze, LONG *Elm);static LONG CaptureSearch (WORD Request, SNMP_OBJECT *Obj, MIB_LOCAL *Local, WORD IdLen);BOOLEAN DnpapCaptureMInit(VOID){ MessageConfig(DNPAP_CAPTURE_ERROR, "DnpapCapture"); return DnpapCaptureConfigInit();}/******************************************************************* NAME: RmonNext** SYNOPSIS: BOOLEAN RmonNext (SNMP_OBJECT *Obj,** MIB_LOCAL **Local, WORD IdLen,** WORD IdSze, LONG *Elm)** PARAMETERS: Obj: requested object** Local: local datastructure: a collector** IdLen: identifier length known to the SNMP** IdSze: size part application of identifier** including the collector index !!** Elm: pointer to object if tables are used** DESCRIPTION: application specific RMON NEXT function.** only called after MibRmon() for next requests ** searches the next object in the collector** REMARKS: ONLY FOR INTERNAL USE** RETURNS: TRUE: object found** OPTIONAL: Elm -> index to object in ringbuffer*******************************************************************/static BOOLEAN RmonNext (SNMP_OBJECT *Obj, MIB_LOCAL **Local, WORD IdLen, WORD IdSze, LONG *Elm){ MIB_LOCAL *local = *Local; if (local == NULL) return FALSE; if (Obj->IdLen == IdLen || local->Index > Obj->Id[IdLen]) { if (IdSze == BUFFERSIZE || (IdSze == CAPTURESIZE && (*Elm = CaptureSearch (CAPTURE_FIRST, Obj, local, IdLen)) != -1)) { Obj->Id[IdLen] = local->Index; Obj->IdLen = IdLen + IdSze; return TRUE; } } else if (IdSze == CAPTURESIZE && (*Elm = CaptureSearch (CAPTURE_NXT, Obj, local, IdLen)) != -1) { Obj->Id[IdLen] = local->Index; Obj->IdLen = IdLen + IdSze; return TRUE; } *Local = local->Next; return RmonNext (Obj, Local, IdLen, IdSze, Elm);}/******************************************************************* NAME: CaptureSearch** SYNOPSIS: LONG CaptureSearch (WORD Request, SNMP_OBJECT *Obj, MIB_LOCAL *local, WORD IdLen)** PARAMETERS: Request: CAPTURE_GET = get index request** CAPTURE_FIRST = get first index request** CAPTURE_NXT = get next index request** *Obj: requested object** *local: local datastructure: a collector** IdLen: identifier length known to the SNMP** DESCRIPTION: capture get/first/next function.** searches dependent on Request the requested, the** first, or next object in the capture buffer.** REMARKS: ONLY FOR INTERNAL USE** RETURNS: ringbuffer index to the data of the found object** NULL: object was not found*******************************************************************/LONG CaptureSearch (WORD Request, SNMP_OBJECT *Obj, MIB_LOCAL *local, WORD IdLen){ BYTE *p;LONG index;DNPAP_BUFFER *buffer = (DNPAP_BUFFER *)local->Data; if (buffer->CapturedPkts == 0) return -1; if (Obj->IdLen < IdLen + CAPTURESIZE) Request = CAPTURE_FIRST; index = 2*(Obj->Id[IdLen+1]-1); switch (Request) { case CAPTURE_GET: if (RingPeekMem(buffer->RingBuf, index, 0, &p, NULL, NULL) == TRUE) return index; break; case CAPTURE_FIRST: if (buffer->CapturedPkts > 0) { Obj->Id[IdLen+1] = 1; return 0; } break; case CAPTURE_NXT: if (Obj->Id[IdLen+1] < buffer->CapturedPkts) { Obj->Id[IdLen+1]++; return index+2; } break; } return -1;}WORD DBufferControlIndex (SNMP_OBJECT *Obj, WORD IdLen){ MIB_LOCAL *local = NULL; if ((local = MibRmon (Obj, BufferList, IdLen, BUFFERSIZE)) == NULL) return SNMP_NOSUCHNAME; switch (Obj->Request) { case SNMP_PDU_NEXT: if (RmonNext (Obj, &local, IdLen, BUFFERSIZE, NULL) == FALSE) return SNMP_NOSUCHNAME; case SNMP_PDU_GET: Obj->Syntax.LngInt = local->Index; return SNMP_NOERROR; } return SNMP_GENERROR;}WORD DBufferControlChannelIndex (SNMP_OBJECT *Obj, WORD IdLen){ MIB_LOCAL *local = NULL; DNPAP_BUFFER *data; if ((local = MibRmon (Obj, BufferList, IdLen, BUFFERSIZE)) == NULL) return SNMP_NOSUCHNAME; switch (Obj->Request) { case SNMP_PDU_NEXT: if (RmonNext (Obj, &local, IdLen, BUFFERSIZE, NULL) == FALSE) return SNMP_NOSUCHNAME; case SNMP_PDU_GET: data = (DNPAP_BUFFER *) local->Data; if (BeholderStrictRMON && !BooleanCheck(data->ObjectSet, CAPTURE_BOOLEAN_INDEX)) return SNMP_NOSUCHNAME; Obj->Syntax.LngInt = data->ChannelIndex; return SNMP_NOERROR; case SNMP_PDU_SET: data = (DNPAP_BUFFER *) local->Data; if (data->Status != SNMP_UNDERCREATION) return SNMP_READONLY; data->ChannelIndex = Obj->Syntax.LngInt; BooleanSetTrue(data->ObjectSet, CAPTURE_BOOLEAN_INDEX); return SNMP_NOERROR; } return SNMP_GENERROR;}WORD DBufferControlFullStatus (SNMP_OBJECT *Obj, WORD IdLen){ MIB_LOCAL *local = NULL; DNPAP_BUFFER *data; if ((local = MibRmon (Obj, BufferList, IdLen, BUFFERSIZE)) == NULL) return SNMP_NOSUCHNAME; switch (Obj->Request) { case SNMP_PDU_NEXT: if (RmonNext (Obj, &local, IdLen, BUFFERSIZE, NULL) == FALSE) return SNMP_NOSUCHNAME; case SNMP_PDU_GET: data = (DNPAP_BUFFER *) local->Data; Obj->Syntax.LngInt = data->FullStatus; return SNMP_NOERROR; } return SNMP_GENERROR;}WORD DBufferControlFullAction (SNMP_OBJECT *Obj, WORD IdLen){ MIB_LOCAL *local = NULL; DNPAP_BUFFER *data; if ((local = MibRmon (Obj, BufferList, IdLen, BUFFERSIZE)) == NULL) return SNMP_NOSUCHNAME; switch (Obj->Request) { case SNMP_PDU_NEXT: if (RmonNext (Obj, &local, IdLen, BUFFERSIZE, NULL) == FALSE) return SNMP_NOSUCHNAME; case SNMP_PDU_GET: data = (DNPAP_BUFFER *) local->Data; Obj->Syntax.LngInt = data->FullAction; return SNMP_NOERROR; case SNMP_PDU_SET: data = (DNPAP_BUFFER *) local->Data; if (Obj->Syntax.LngInt != 1 && Obj->Syntax.LngInt != 2) return SNMP_BADVALUE; data->FullAction = Obj->Syntax.LngInt; return SNMP_NOERROR; } return SNMP_GENERROR;}WORD DBufferControlCaptureSliceSize (SNMP_OBJECT *Obj, WORD IdLen){ MIB_LOCAL *local = NULL; DNPAP_BUFFER *data; if ((local = MibRmon (Obj, BufferList, IdLen, BUFFERSIZE)) == NULL) return SNMP_NOSUCHNAME; switch (Obj->Request) { case SNMP_PDU_NEXT: if (RmonNext (Obj, &local, IdLen, BUFFERSIZE, NULL) == FALSE) return SNMP_NOSUCHNAME; case SNMP_PDU_GET: data = (DNPAP_BUFFER *) local->Data; Obj->Syntax.LngInt = data->CaptureSliceSize; return SNMP_NOERROR; case SNMP_PDU_SET: data = (DNPAP_BUFFER *) local->Data; if (data->Status != SNMP_UNDERCREATION) return SNMP_READONLY; if (Obj->Syntax.LngInt < 0 || Obj->Syntax.LngInt > data->MaxOctetsAvailable - sizeof(DNPAP_CAPTURE)) return SNMP_BADVALUE; data->CaptureSliceSize = Obj->Syntax.LngInt; return SNMP_NOERROR; } return SNMP_GENERROR;}WORD DBufferControlDownloadSliceSize (SNMP_OBJECT *Obj, WORD IdLen){ MIB_LOCAL *local = NULL; DNPAP_BUFFER *data; if ((local = MibRmon (Obj, BufferList, IdLen, BUFFERSIZE)) == NULL) return SNMP_NOSUCHNAME; switch (Obj->Request) { case SNMP_PDU_NEXT: if (RmonNext (Obj, &local, IdLen, BUFFERSIZE, NULL) == FALSE) return SNMP_NOSUCHNAME; case SNMP_PDU_GET: data = (DNPAP_BUFFER *) local->Data; Obj->Syntax.LngInt = data->DownloadSliceSize; return SNMP_NOERROR; case SNMP_PDU_SET: data = (DNPAP_BUFFER *) local->Data; if (Obj->Syntax.LngInt < 1 || Obj->Syntax.LngInt > SNMP_SIZE_BUFCHR || Obj->Syntax.LngInt > data->CaptureSliceSize) return SNMP_BADVALUE; data->DownloadSliceSize = Obj->Syntax.LngInt; return SNMP_NOERROR; } return SNMP_GENERROR;}WORD DBufferControlDownloadOffset (SNMP_OBJECT *Obj, WORD IdLen){ MIB_LOCAL *local = NULL; DNPAP_BUFFER *data; if ((local = MibRmon (Obj, BufferList, IdLen, BUFFERSIZE)) == NULL) return SNMP_NOSUCHNAME; switch (Obj->Request) { case SNMP_PDU_NEXT: if (RmonNext (Obj, &local, IdLen, BUFFERSIZE, NULL) == FALSE) return SNMP_NOSUCHNAME; case SNMP_PDU_GET: data = (DNPAP_BUFFER *) local->Data; Obj->Syntax.LngInt = data->DownloadOffset; return SNMP_NOERROR; case SNMP_PDU_SET: data = (DNPAP_BUFFER *) local->Data; if (Obj->Syntax.LngInt < 0 || Obj->Syntax.LngInt >= data->CaptureSliceSize) return SNMP_BADVALUE; data->DownloadOffset = Obj->Syntax.LngInt; return SNMP_NOERROR; } return SNMP_GENERROR;}WORD DBufferControlMaxOctetsRqstd (SNMP_OBJECT *Obj, WORD IdLen){ MIB_LOCAL *local = NULL; DNPAP_BUFFER *data; Ring *newring; LONG octetsCopied; LONG maxmemchunk; BYTE *p; LONG i, n, len; BYTE packet[MAXPACKET]; if ((local = MibRmon (Obj, BufferList, IdLen, BUFFERSIZE)) == NULL) return SNMP_NOSUCHNAME; switch (Obj->Request) { case SNMP_PDU_NEXT: if (RmonNext (Obj, &local, IdLen, BUFFERSIZE, NULL) == FALSE) return SNMP_NOSUCHNAME; case SNMP_PDU_GET: data = (DNPAP_BUFFER *) local->Data; Obj->Syntax.LngInt = data->MaxOctetsRequested; return SNMP_NOERROR; case SNMP_PDU_SET: data = (DNPAP_BUFFER *) local->Data; maxmemchunk = (MemoryGetAvail()/100)*dnpapMemoryPerc; if (maxmemchunk > MemoryGetMaxChunk()) maxmemchunk = MemoryGetMaxChunk(); if (Obj->Syntax.LngInt == -1) { octetsCopied = maxmemchunk; if (octetsCopied <= data->MaxOctetsAvailable) { data->MaxOctetsRequested = -1; data->MaxOctetsGranted = -1; data->FullStatus = 1; return SNMP_NOERROR; } if (octetsCopied < data->CaptureSliceSize+sizeof(DNPAP_CAPTURE)) return SNMP_BADVALUE; if ((newring = RingAlloc(octetsCopied, DnpapCaptureElems(octetsCopied, data->CaptureSliceSize))) == NULL) return SNMP_GENERROR; data->MaxOctetsRequested = -1; data->MaxOctetsGranted = -1; } else { if (Obj->Syntax.LngInt < 1) return SNMP_BADVALUE; if ((octetsCopied = Obj->Syntax.LngInt) > maxmemchunk) octetsCopied = maxmemchunk; if (octetsCopied < data->CaptureSliceSize+sizeof(DNPAP_CAPTURE)) return SNMP_BADVALUE; if ((newring = RingAlloc(octetsCopied, DnpapCaptureElems(octetsCopied, data->CaptureSliceSize))) == NULL) return SNMP_GENERROR; data->MaxOctetsRequested = Obj->Syntax.LngInt; data->MaxOctetsGranted = octetsCopied; } if (octetsCopied > data->MaxOctetsAvailable) data->FullStatus = 1; data->MaxOctetsAvailable = octetsCopied; if (data->CapturedPkts > 0) { for (i = 2*data->CapturedPkts-1, n = 0; i > 0; ) { if (RingPeekMem(data->RingBuf, i, 0, &p, NULL, &len) == FALSE) { DnpapMessage(DMC_FATAL, DCAPTURE_SYNC, "dcapture: ring buffer out of sync"); DnpapExit(1); } i--; n += len; if (RingPeekMem(data->RingBuf, i, 0, &p, NULL, &len) == FALSE) { DnpapMessage(DMC_FATAL, DCAPTURE_SYNC, "dcapture: ring buffer out of sync"); DnpapExit(1); } i--; n += len; if (n > octetsCopied) break; } i++; /* backup one step to compensate i-- */ if (n > octetsCopied) i += 2; /* backup 2 steps forward */ for ( ; i < 2*data->CapturedPkts; i++) { len = 0; RingPeekMem(data->RingBuf, i, 0, &p, packet, &len); RingPutMem(newring, packet, len); } } RingFree(data->RingBuf); data->RingBuf = newring; data->CapturedPkts = RingGetElems(data->RingBuf)/2; return SNMP_NOERROR; } return SNMP_GENERROR;}WORD DBufferControlMaxOctetsGranted (SNMP_OBJECT *Obj, WORD IdLen){ MIB_LOCAL *local = NULL; DNPAP_BUFFER *data; if ((local = MibRmon (Obj, BufferList, IdLen, BUFFERSIZE)) == NULL) return SNMP_NOSUCHNAME; switch (Obj->Request) { case SNMP_PDU_NEXT: if (RmonNext (Obj, &local, IdLen, BUFFERSIZE, NULL) == FALSE) return SNMP_NOSUCHNAME; case SNMP_PDU_GET: data = (DNPAP_BUFFER *) local->Data; Obj->Syntax.LngInt = data->MaxOctetsGranted; return SNMP_NOERROR; } return SNMP_GENERROR;}WORD DBufferControlCapturedPackets (SNMP_OBJECT *Obj, WORD IdLen){ MIB_LOCAL *local = NULL; DNPAP_BUFFER *data;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -