1010 lines
38 KiB
Plaintext
1010 lines
38 KiB
Plaintext
|
{
|
||
|
$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<TIdMIBValue>;
|
||
|
{$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.
|