{ $Project$ $Workfile$ $Revision$ $DateUTC$ $Id$ This file is part of the Indy (Internet Direct) project, and is offered under the dual-licensing agreement described on the Indy website. (http://www.indyproject.org/) Copyright: (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. } { $Log$ } { Rev 1.3 10/26/2004 11:08:04 PM JPMugaas Updated refs. Rev 1.2 2004.02.03 5:44:22 PM czhower Name changes Rev 1.1 1/21/2004 4:03:36 PM JPMugaas InitComponent Rev 1.0 11/13/2002 08:01:02 AM JPMugaas } unit IdSNMP; { -2001.02.13 - Kudzu - Misc "Indy" Changes. -Contributions also by: Hernan Sanchez (hernan.sanchez@iname.com) -Original Author: Lukas Gebauer The Synapse SNMP component was converted for use in INDY. | The Original Code is Synapse Delphi Library. | |==============================================================================| | The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).| | Portions created by Lukas Gebauer are Copyright (c)2000. | | All Rights Reserved. | |==============================================================================| | Contributor(s): | | Hernan Sanchez (hernan.sanchez@iname.com) Original author | | Colin Wilson (colin@wilsonc.demon.co.uk) Fixed some bugs & added support | | for Value types | | Remy Lebeau (remy@lebeausoftware.org) Added support for Unicode and | | Generics | |==============================================================================| | History: see HISTORY.HTM from distribution package | | (Found at URL: http://www.ararat.cz/synapse/) | |==============================================================================| } interface {$i IdCompilerDefines.inc} uses Classes, {$IFDEF HAS_UNIT_Generics_Collections} System.Generics.Collections, {$ENDIF} IdASN1Util, IdException, IdGlobal, IdUDPBase, IdUDPClient, IdSocketHandle; const //PDU type PDUGetRequest = $a0; PDUGetNextRequest = $a1; PDUGetResponse = $a2; PDUSetRequest = $a3; PDUTrap = $a4; //errors ENoError = 0; ETooBig = 1; ENoSuchName = 2; EBadValue = 3; EReadOnly = 4; EGenErr = 5; type TIdSNMP = class; // TODO: create TIdMIBValueList for non-Generics compilers... {$IFDEF HAS_GENERICS_TList} TIdMIBValue = record OID: String; Value: String; ValueType: Integer; constructor Create(const AOID, AValue: String; const AValueType: Integer); end; TIdMIBValueList = TList; {$ENDIF} TSNMPInfo = class(TObject) private fOwner : TIdSNMP; fCommunity: string; function GetValue (idx : Integer) : string; function GetValueCount: Integer; function GetValueType (idx : Integer) : Integer; function GetValueOID(idx: Integer): string; procedure SetCommunity(const Value: string); protected Buffer: string; {$IFNDEF HAS_GENERICS_TList} procedure SyncMIB; {$ENDIF} public Host : string; Port : TIdPort; Enterprise: string; GenTrap: integer; SpecTrap: integer; Version : integer; PDUType : integer; TimeTicks : integer; ID : integer; ErrorStatus : integer; ErrorIndex : integer; {$IFDEF HAS_GENERICS_TList} MIBValues : TIdMIBValueList; {$ELSE} MIBOID : TStrings; MIBValue : TStrings; {$ENDIF} constructor Create (AOwner : TIdSNMP); destructor Destroy; override; function EncodeTrap: Boolean; function DecodeTrap: Boolean; procedure DecodeBuf(Buffer: string); function EncodeBuf: string; procedure Clear; procedure MIBAdd(MIB, Value: string; ValueType: Integer = ASN1_OCTSTR); procedure MIBDelete(Index: integer); function MIBGet(MIB: string): string; property Owner : TIdSNMP read fOwner; property Community : string read fCommunity write SetCommunity; property ValueCount : Integer read GetValueCount; property Value [idx : Integer] : string read GetValue; property ValueOID [idx : Integer] : string read GetValueOID; property ValueType [idx : Integer] : Integer read GetValueType; end; TIdSNMP = class(TIdUDPClient) protected fCommunity: string; fTrapPort: TIdPort; fTrapRecvBinding: TIdSocketHandle; procedure SetCommunity(const Value: string); procedure SetTrapPort(const AValue: TIdPort); procedure InitComponent; override; function GetBinding: TIdSocketHandle; override; procedure CloseBinding; override; public Query : TSNMPInfo; Reply : TSNMPInfo; Trap : TSNMPInfo; {$IFDEF WORKAROUND_INLINE_CONSTRUCTORS} constructor Create(AOwner: TComponent); reintroduce; overload; {$ENDIF} destructor Destroy; override; function SendQuery : Boolean; function QuickSend(const Mib, DestCommunity, DestHost: string; var Value: string):Boolean; function QuickSendTrap(const DestHost, Enterprise, DestCommunity: string; DestPort: TIdPort; Generic, Specific: integer; {$IFDEF HAS_GENERICS_TList} MIBValues: TIdMIBValueList {$ELSE} MIBName, MIBValue: TStrings {$ENDIF} ): Boolean; function QuickReceiveTrap(var SrcHost, Enterprise, SrcCommunity: string; var SrcPort: TIdPort; var Generic, Specific, Seconds: integer; {$IFDEF HAS_GENERICS_TList} MIBValues: TIdMIBValueList {$ELSE} MIBName, MIBValue: TStrings {$ENDIF} ): Boolean; function SendTrap: Boolean; function ReceiveTrap: Boolean; published property Port default 161; property TrapPort : TIdPort read fTrapPort write SetTrapPort default 162; property Community : string read fCommunity write SetCommunity; end; implementation uses IdStack, IdStackConsts, SysUtils; //Hernan Sanchez function IPToID(Host: string): string; var s, t: string; i, x: integer; begin Result := ''; {Do not Localize} for x := 1 to 3 do begin t := ''; {Do not Localize} s := Copy(Host, IndyPos('.', Host), Length(Host)); {Do not Localize} t := Copy(Host, 1, (Length(Host) - Length(s))); Delete(Host, 1, (Length(Host) - Length(s) + 1)); i := IndyStrToInt(t, 0); Result := Result + Chr(i); end; i := IndyStrToInt(Host, 0); Result := Result + Chr(i); end; function MibIntToASNObject(const OID: String; const Value: Integer; const ObjType: Integer = ASN1_INT): String; {$IFDEF USE_INLINE}inline;{$ENDIF} begin Result := ASNObject(MibToID(OID), ASN1_OBJID) + ASNObject(ASNEncInt(Value), ObjType); end; function MibUIntToASNObject(const OID: String; const Value, ObjType: Integer): String; {$IFDEF USE_INLINE}inline;{$ENDIF} begin Result := ASNObject(MibToID(OID), ASN1_OBJID) + ASNObject(ASNEncUInt(Value), ObjType); end; function MibObjIDToASNObject(const ObjID, Value: String): String; {$IFDEF USE_INLINE}inline;{$ENDIF} begin Result := ASNObject(MibToID(ObjID), ASN1_OBJID) + ASNObject(MibToID(Value), ASN1_OBJID); end; function MibIPAddrToASNObject(const OID, Value: String): String; {$IFDEF USE_INLINE}inline;{$ENDIF} begin Result := ASNObject(MibToID(OID), ASN1_OBJID) + ASNObject(IPToID(Value), ASN1_IPADDR); end; function MibNullToASNObject(const OID: String): String; {$IFDEF USE_INLINE}inline;{$ENDIF} begin Result := ASNObject(MibToID(OID), ASN1_OBJID) + ASNObject('', ASN1_NULL); {Do not Localize} end; function MibStrToASNObject(const OID, Value: String; const ObjType: Integer = ASN1_OCTSTR): String; {$IFDEF USE_INLINE}inline;{$ENDIF} begin Result := ASNObject(MibToID(OID), ASN1_OBJID) + ASNObject(Value, ObjType); end; {========================== SNMP INFO OBJECT ==================================} {$IFDEF HAS_GENERICS_TList} constructor TIdMIBValue.Create(const AOID, AValue: String; const AValueType: Integer); begin OID := AOID; Value := AValue; ValueType := AValueType; end; {$ENDIF} { TSNMPInfo } (*----------------------------------------------------------------------------* | constructor TSNMPInfo.Create () | | | | Constructor for TSNMPInfo | | | | Parameters: | | AOwner : TIdSNMP The owning IdSNMP Component | | | *----------------------------------------------------------------------------*) constructor TSNMPInfo.Create(AOwner : TIdSNMP); begin inherited Create; fOwner := AOwner; {$IFDEF HAS_GENERICS_TList} MIBValues := TIdMIBValueList.Create; {$ELSE} MIBOID := TStringList.Create; MIBValue := TStringList.Create; {$ENDIF} fCommunity := AOwner.Community; Port := AOwner.Port; end; (*----------------------------------------------------------------------------* | destructor TSNMPInfo.Destroy | | | | Destructor for TSNMPInfo | *----------------------------------------------------------------------------*) destructor TSNMPInfo.Destroy; begin {$IFDEF HAS_GENERICS_TList} FreeAndNil(MIBValues); {$ELSE} FreeAndNil(MIBValue); FreeAndNil(MIBOID); {$ENDIF} inherited Destroy; end; {$IFNDEF HAS_GENERICS_TList} (*----------------------------------------------------------------------------* | procedure TSNMPInfo.SyncMIB | | | | Ensure that there are as many 'values' as 'oids' | *----------------------------------------------------------------------------*) procedure TSNMPInfo.SyncMIB; var n,x: integer; begin x := MIBValue.Count; for n := x to MIBOID.Count-1 do begin MIBValue.Add(''); end; end; {$ENDIF} (*----------------------------------------------------------------------------* | procedure TSNMPInfo.DecodeBuf | | | | Decode an ASN buffer into version, community, MIB OID/Value pairs, etc. | | | | Parameters: | | Buffer:string The ASN buffer to decode | *----------------------------------------------------------------------------*) procedure TSNMPInfo.DecodeBuf(Buffer: string); var Pos: integer; endpos,vt: integer; sm,sv: string; begin Pos := 2; Endpos := ASNDecLen(Pos, Buffer); Version := IndyStrToInt(ASNItem(Pos,Buffer,vt),0); Community := ASNItem(Pos,buffer,vt); PDUType := IndyStrToInt(ASNItem(Pos,Buffer,vt),0); ID := IndyStrToInt(ASNItem(Pos,Buffer,vt),0); ErrorStatus := IndyStrToInt(ASNItem(Pos,Buffer,vt),0); ErrorIndex := IndyStrToInt(ASNItem(Pos,Buffer,vt),0); ASNItem(Pos, Buffer, vt); while Pos < Endpos do // Decode MIB/Value pairs begin ASNItem(Pos, Buffer, vt); Sm := ASNItem(Pos, Buffer, vt); Sv := ASNItem(Pos, Buffer, vt); MIBAdd(sm, sv, vt); end; end; (*----------------------------------------------------------------------------* | function TSNMPInfo.EncodeBuf | | | | Encode the details into an ASN string | | | | The function returns the encoded ASN string | *----------------------------------------------------------------------------*) function TSNMPInfo.EncodeBuf: string; var data,s: string; n: integer; objType: Integer; begin data := ''; {Do not Localize} {$IFNDEF HAS_GENERICS_TList} SyncMIB; {$ENDIF} for n := 0 to {$IFDEF HAS_GENERICS_TList}MIBValues{$ELSE}MIBOID{$ENDIF}.Count-1 do begin objType := GetValueType(n); case objType of ASN1_INT: s := MibIntToASNObject(GetValueOID(n), IndyStrToInt(GetValue(n), 0)); ASN1_COUNTER, ASN1_GAUGE, ASN1_TIMETICKS: s := MibUIntToASNObject(GetValueOID(n), IndyStrToInt(GetValue(n), 0), objType); ASN1_OBJID: s := MibObjIDToASNObject(GetValueOID(n), GetValue(n)); ASN1_IPADDR: s := MibIPAddrToASNObject(GetValueOID(n), GetValue(n)); ASN1_NULL: s := MibNullToASNObject(GetValueOID(n)); else s := MibStrToASNObject(GetValueOID(n), GetValue(n), objType); end; data := data + ASNObject(s, ASN1_SEQ); end; data := ASNObject(char(ID), ASN1_INT) + ASNObject(char(ErrorStatus), ASN1_INT) + ASNObject(char(ErrorIndex), ASN1_INT) + ASNObject(data, ASN1_SEQ); data := ASNObject(char(Version), ASN1_INT) + ASNObject(Community, ASN1_OCTSTR) + ASNObject(data, PDUType); data := ASNObject(data, ASN1_SEQ); Result := data; end; (*----------------------------------------------------------------------------* | procedure TSNMPInfo.Clear | | | | Clear the header info and MIBOID/Value lists. | *----------------------------------------------------------------------------*) procedure TSNMPInfo.Clear; begin Version:=0; fCommunity := Owner.Community; if Self = fOwner.Trap then begin Port := Owner.TrapPort end else begin Port := Owner.Port; end; Host := Owner.Host; PDUType := 0; ID := 0; ErrorStatus := 0; ErrorIndex := 0; {$IFDEF HAS_GENERICS_TList} MIBValues.Clear; {$ELSE} MIBOID.Clear; MIBValue.Clear; {$ENDIF} end; (*----------------------------------------------------------------------------* | procedure TSNMPInfo.MIBAdd | | | | Add a MIBOID/Value pair | | | | Parameters: | | MIB : string The MIBOID to add | | Value : string The Value | | valueType : Integer The Value's type. Optional - defaults to | {Do not Localize} | ASN1_OCTSTR | *----------------------------------------------------------------------------*) procedure TSNMPInfo.MIBAdd(MIB, Value: string; ValueType: Integer); {$IFNDEF HAS_GENERICS_TList} var x: integer; {$ENDIF} begin {$IFDEF HAS_GENERICS_TList} MIBValues.Add(TIdMIBValue.Create(MIB, Value, ValueType)); {$ELSE} SyncMIB; MIBOID.Add(MIB); x := MIBOID.Count; if MIBValue.Count > x then begin MIBValue[x-1] := Value; MIBValue.Objects[x-1] := TObject(ValueType); end else begin MIBValue.AddObject(Value, TObject(ValueType)); end; {$ENDIF} end; (*----------------------------------------------------------------------------* | procedure TSNMPInfo.MIBDelete | | | | Delete a MIBOID/Value pair | | | | Parameters: | | Index:integer The index of the pair to delete | *----------------------------------------------------------------------------*) procedure TSNMPInfo.MIBDelete(Index: integer); begin {$IFDEF HAS_GENERICS_TList} MIBValues.Delete(Index); {$ELSE} SyncMIB; MIBOID.Delete(Index); if (MIBValue.Count-1) >= Index then begin MIBValue.Delete(Index); end; {$ENDIF} end; (*----------------------------------------------------------------------------* | function TSNMPInfo.MIBGet | | | | Get a string representation of the value of the specified MIBOID | | | | Parameters: | | MIB:string The MIBOID to query | | | | The function returns the string representation of the value. | *----------------------------------------------------------------------------*) function TSNMPInfo.MIBGet(MIB: string): string; var x: integer; begin {$IFDEF HAS_GENERICS_TList} Result := ''; {Do not Localize} for x := 0 to MIBValues.Count-1 do begin if TextIsSame(MIBValues[x].OID, MIB) then begin Result := MIBValues[x].Value; Exit; end; end; {$ELSE} SyncMIB; x := MIBOID.IndexOf(MIB); if x < 0 then begin Result := ''; {Do not Localize} end else begin Result := MIBValue[x]; end; {$ENDIF} end; {======================= TRAPS =====================================} (*----------------------------------------------------------------------------* | procedure TSNMPInfo.EncodeTrap | | | | Encode the trap details into an ASN string - the 'Buffer' member | | | | The function returns 1 for historical reasons! | *----------------------------------------------------------------------------*) function TSNMPInfo.EncodeTrap: Boolean; var s: string; n: integer; objType: Integer; begin Buffer := ''; {Do not Localize} for n := 0 to {$IFDEF HAS_GENERICS_TList}MIBValues{$ELSE}MIBOID{$ENDIF}.Count-1 do begin objType := GetValueType(n); case objType of ASN1_INT: s := MibIntToASNObject(GetValueOID(n), IndyStrToInt(GetValue(n), 0)); ASN1_COUNTER, ASN1_GAUGE, ASN1_TIMETICKS: s := MibUIntToASNObject(GetValueOID(n), IndyStrToInt(GetValue(n), 0), objType); ASN1_OBJID: s := MibObjIDToASNObject(GetValueOID(n), GetValue(n)); ASN1_IPADDR: s := MibIPAddrToASNObject(GetValueOID(n), GetValue(n)); ASN1_NULL: s := MibNullToASNObject(GetValueOID(n)); else s := MibStrToASNObject(GetValueOID(n), GetValue(n), objType); end; Buffer := Buffer + ASNObject(s, ASN1_SEQ); end; Buffer := ASNObject(MibToID(Enterprise), ASN1_OBJID) + ASNObject(IPToID(Host), ASN1_IPADDR) + ASNObject(ASNEncInt(GenTrap), ASN1_INT) + ASNObject(ASNEncInt(SpecTrap), ASN1_INT) + ASNObject(ASNEncInt(TimeTicks), ASN1_TIMETICKS) + ASNObject(Buffer, ASN1_SEQ); Buffer := ASNObject(Char(Version), ASN1_INT) + ASNObject(Community, ASN1_OCTSTR) + ASNObject(Buffer, PDUType); Buffer := ASNObject(Buffer, ASN1_SEQ); Result := True; end; (*----------------------------------------------------------------------------* | procedure TSNMPInfo.DecodeTrap | | | | Decode the 'Buffer' trap string to fil in our member variables. | {Do not Localize} | | | The function returns 1. | *----------------------------------------------------------------------------*) function TSNMPInfo.DecodeTrap: Boolean; var Pos, EndPos, vt: integer; Sm, Sv: string; begin Pos := 2; EndPos := ASNDecLen(Pos, Buffer); Version := IndyStrToInt(ASNItem(Pos, Buffer, vt), 0); Community := ASNItem(Pos, Buffer, vt); PDUType := IndyStrToInt(ASNItem(Pos, Buffer, vt), PDUTRAP); Enterprise := ASNItem(Pos, Buffer, vt); Host := ASNItem(Pos, Buffer, vt); GenTrap := IndyStrToInt(ASNItem(Pos, Buffer, vt), 0); Spectrap := IndyStrToInt(ASNItem(Pos, Buffer, vt), 0); TimeTicks := IndyStrToInt(ASNItem(Pos, Buffer, vt), 0); ASNItem(Pos, Buffer, vt); while Pos < EndPos do begin ASNItem(Pos, Buffer, vt); Sm := ASNItem(Pos, Buffer, vt); Sv := ASNItem(Pos, Buffer, vt); MIBAdd(Sm, Sv, vt); end; Result := True; end; (*----------------------------------------------------------------------------* | TSNMPInfo.SetCommunity | | | | Set the community. | | | | Parameters: | | const Value: string The new community value | *----------------------------------------------------------------------------*) procedure TSNMPInfo.SetCommunity(const Value: string); begin if fCommunity <> Value then begin Clear; fCommunity := Value; end; end; { TIdSNMP } {============================== IdSNMP OBJECT ================================} (*----------------------------------------------------------------------------* | constructor TIdSNMP.Create | | | | Contructor for TIdSNMP component | | | | Parameters: | | aOwner : TComponent | *----------------------------------------------------------------------------*) {$IFDEF WORKAROUND_INLINE_CONSTRUCTORS} constructor TIdSNMP.Create(AOwner: TComponent); begin inherited Create(AOwner); end; {$ENDIF} procedure TIdSNMP.InitComponent; begin inherited InitComponent; Port := 161; fTrapPort := 162; fCommunity := 'public'; {Do not Localize} Query := TSNMPInfo.Create(Self); Reply := TSNMPInfo.Create(Self); Trap := TSNMPInfo.Create(Self); Query.Clear; Reply.Clear; Trap.Clear; FReceiveTimeout := 5000; end; (*----------------------------------------------------------------------------* | destructor TIdSNMP.Destroy | | | | Destructor for TIdSNMP component | *----------------------------------------------------------------------------*) destructor TIdSNMP.Destroy; begin FreeAndNil(Reply); FreeAndNil(Query); FreeAndNil(Trap); inherited Destroy; end; (*----------------------------------------------------------------------------* | function TIdSNMP.GetBinding | | | | Prepare socket handles for use. | *----------------------------------------------------------------------------*) function TIdSNMP.GetBinding: TIdSocketHandle; begin Result := inherited GetBinding; if fTrapRecvBinding = nil then begin fTrapRecvBinding := TIdSocketHandle.Create(nil); end; if (not fTrapRecvBinding.HandleAllocated) and (fTrapPort <> 0) then begin fTrapRecvBinding.IPVersion := Result.IPVersion; fTrapRecvBinding.AllocateSocket(Id_SOCK_DGRAM); fTrapRecvBinding.IP := Result.IP; fTrapRecvBinding.Port := fTrapPort; fTrapRecvBinding.Bind; end; end; (*----------------------------------------------------------------------------* | procedure TIdSNMP.CloseBinding | | | | Clean up socket handles. | *----------------------------------------------------------------------------*) procedure TIdSNMP.CloseBinding; begin FreeAndNil(fTrapRecvBinding); inherited CloseBinding; end; (*----------------------------------------------------------------------------* | function TIdSNMP.SendQuery | | | | Send an SNMP query and receive a reply. | | | | nb. Before calling this, ensure that the following members are set: | | | | Community The SNMP community being queried - eg. 'public' | {Do not Localize} | Host The IP address being queried. 127.0.0.1 for the | | local machine. | | | | The call Query.Clear, then set: | | | | Query.PDUType PDUGetRequest to get a single set of MIBOID | | value(s) or PDUGetNextRequest to start walking | | the MIB | | | | Next call Query.Clear, call MIBAdd to add the MIBOID(s) you require. | | | | The function returns True if a response was received. IF a response was | | received, it will be decoded into Reply.Value | *----------------------------------------------------------------------------*) function TIdSNMP.SendQuery: Boolean; var LEncoding: IIdTextEncoding; begin Reply.Clear; Query.Buffer := Query.EncodeBuf; LEncoding := IndyTextEncoding_8Bit; Send(Query.Host, Query.Port, Query.Buffer, LEncoding{$IFDEF STRING_IS_ANSI}, LEncoding{$ENDIF}); try Reply.Buffer := ReceiveString(Query.Host, Query.Port, FReceiveTimeout, LEncoding{$IFDEF STRING_IS_ANSI}, LEncoding{$ENDIF}); except on e : EIdSocketError do begin if e.LastError = 10054 then begin Reply.Buffer := ''; {Do not Localize} end else begin raise; end; end; end; if Reply.Buffer <> '' then begin Reply.DecodeBuf(Reply.Buffer); {Do not Localize} end; Result := (Reply.Buffer <> '') and (Reply.ErrorStatus = 0); {Do not Localize} end; (*----------------------------------------------------------------------------* | TIdSNMP.QuickSend | | | | Query a single MIBOID value. | | | | Parameters: | | Mib : string The MIBOID to query | | Community : string The SNMP comunity | | Host : string The SNMP host | | var value : string String representation of the returned value. | | | | The function returns true if a value was returned for the MIB OID | *----------------------------------------------------------------------------*) function TIdSNMP.QuickSend (const Mib, DestCommunity, DestHost: string; var Value: string): Boolean; begin Community := DestCommunity; Host := DestHost; Query.Clear; Query.PDUType := PDUGetRequest; Query.MIBAdd(MIB, ''); {Do not Localize} Result := SendQuery; if Result then begin Value := Reply.MIBGet(MIB); end; end; (*----------------------------------------------------------------------------* | TIdSNMP.SendTrap | | | | Send an SNMP trap. | | | | The function returns 1 | *----------------------------------------------------------------------------*) function TIdSNMP.SendTrap: Boolean; var LEncoding: IIdTextEncoding; begin Trap.PDUType := PDUTrap; Trap.EncodeTrap; LEncoding := IndyTextEncoding_8Bit; Send(Trap.Host, Trap.Port, Trap.Buffer, LEncoding{$IFDEF STRING_IS_ANSI}, LEncoding{$ENDIF}); Result := True; end; function TIdSNMP.ReceiveTrap: Boolean; var i, LMSec: Integer; LBuffer : TIdBytes; LIPVersion: TIdIPVersion; begin Result := False; Trap.Clear; Trap.PDUType := PDUTrap; LMSec := ReceiveTimeOut; if (LMSec = IdTimeoutDefault) or (LMSec = 0) then begin LMSec := IdTimeoutInfinite; end; GetBinding; // make sure fTrapBinding is allocated SetLength(LBuffer, BufferSize); if not fTrapRecvBinding.Readable(LMSec) then begin Trap.Host := ''; {Do not Localize} Trap.Port := 0; Exit; end; i := fTrapRecvBinding.RecvFrom(LBuffer, Trap.Host, Trap.Port, LIPVersion); Trap.Buffer := BytesToString(LBuffer, 0, i, IndyTextEncoding_8Bit); if Trap.Buffer <> '' then begin {Do not Localize} Trap.DecodeTrap; Result := True; end; end; function TIdSNMP.QuickSendTrap(const DestHost, Enterprise, DestCommunity: string; DestPort: TIdPort; Generic, Specific: integer; {$IFDEF HAS_GENERICS_TList} MIBValues: TIdMIBValueList {$ELSE} MIBName, MIBValue: TStrings {$ENDIF} ): Boolean; var i: integer; begin Trap.Clear; Trap.Host := DestHost; Trap.Port := DestPort; Trap.Community := DestCommunity; Trap.Enterprise := Enterprise; Trap.GenTrap := Generic; Trap.SpecTrap := Specific; for i := 0 to {$IFDEF HAS_GENERICS_TList}MIBValues{$ELSE}MIBName{$ENDIF}.Count-1 do begin Trap.MIBAdd( {$IFDEF HAS_GENERICS_TList} MIBValues[i].OID, MIBValues[i].Value, MIBValues[i].ValueType {$ELSE} MIBName[i], MIBValue[i], PtrInt(MIBValue.Objects[i]) {$ENDIF} ); end; Result := SendTrap; end; function TIdSNMP.QuickReceiveTrap(var SrcHost, Enterprise, SrcCommunity: string; var SrcPort: TIdPort; var Generic, Specific, Seconds: integer; {$IFDEF HAS_GENERICS_TList} MIBValues: TIdMIBValueList {$ELSE} MIBName, MIBValue: TStrings {$ENDIF} ): Boolean; var i: integer; begin Result := ReceiveTrap; if Result then begin SrcHost := Trap.Host; SrcPort := Trap.Port; Enterprise := Trap.Enterprise; SrcCommunity := Trap.Community; Generic := Trap.GenTrap; Specific := Trap.SpecTrap; Seconds := Trap.TimeTicks; {$IFDEF HAS_GENERICS_TList} MIBValues.Clear; {$ELSE} MIBName.Clear; MIBValue.Clear; {$ENDIF} for i := 0 to Trap.{$IFDEF HAS_GENERICS_TList}MIBValues{$ELSE}MIBOID{$ENDIF}.Count-1 do begin {$IFDEF HAS_GENERICS_TList} MIBValues.Add(TIdMIBValue.Create(Trap.ValueOID[i], Trap.Value[i], Trap.ValueType[i])); {$ELSE} MIBName.Add(Trap.ValueOID[i]); MIBValue.AddObject(Trap.Value[i], TObject(Trap.ValueType[i])); {$ENDIF} end; end; end; (*----------------------------------------------------------------------------* | TSNMPInfo.GetValue | | | | Return string representation of value 'idx' | | | | Parameters: | | idx : Integer The value to get | | | | The function returns the string representation of the value. | *----------------------------------------------------------------------------*) function TSNMPInfo.GetValue (idx : Integer) : string; begin {$IFDEF HAS_GENERICS_TList} Result := MIBValues[idx].Value; {$ELSE} Result := MIBValue[idx]; {$ENDIF} end; (*----------------------------------------------------------------------------* | TSNMPInfo.GetValueCount | | | | Get the number of values. | | | | The function returns the number of values. | *----------------------------------------------------------------------------*) function TSNMPInfo.GetValueCount: Integer; begin {$IFDEF HAS_GENERICS_TList} Result := MIBValues.Count; {$ELSE} Result := MIBValue.Count; {$ENDIF} end; (*----------------------------------------------------------------------------* | TSNMPInfo.GetValueType | | | | Return the 'type' of value 'idx' | | | | Parameters: | | idx : Integer The value type to get | | | | The function returns the value type. | *----------------------------------------------------------------------------*) function TSNMPInfo.GetValueType (idx : Integer): Integer; begin {$IFDEF HAS_GENERICS_TList} Result := MIBValues[idx].ValueType; {$ELSE} Result := Integer(MIBValue.Objects[idx]); {$ENDIF} if Result = 0 then begin Result := ASN1_OCTSTR; end; end; (*----------------------------------------------------------------------------* | TSNMPInfo.GetValueOID | | | | Get the MIB OID for value 'idx' | | | | Parameters: | | idx: Integer The MIB OID to gey | | | | The function returns the specified MIB OID | *----------------------------------------------------------------------------*) function TSNMPInfo.GetValueOID(idx: Integer): string; begin {$IFDEF HAS_GENERICS_TList} Result := MIBValues[idx].OID; {$ELSE} Result := MIBOID[idx]; {$ENDIF} end; (*----------------------------------------------------------------------------* | TIdSNMP.SetCommunity | | | | Setter for the Community property. | | | | Parameters: | | const Value: string The new community value | *----------------------------------------------------------------------------*) procedure TIdSNMP.SetCommunity(const Value: string); begin if fCommunity <> Value then begin fCommunity := Value; Query.Community := Value; Reply.Community := Value; Trap.Community := Value end end; (*----------------------------------------------------------------------------* | TIdSNMP.SetTrapPort | | | | Setter for the TrapPort property. | | | | Parameters: | | const Value: TIdPort The new port value | *----------------------------------------------------------------------------*) procedure TIdSNMP.SetTrapPort(const AValue: TIdPort); begin if fTrapPort <> AValue then begin if Assigned(fTrapRecvBinding) then begin fTrapRecvBinding.CloseSocket; end; fTrapPort := AValue; end; end; end.