synapse/snmpsend.pas

356 lines
10 KiB
ObjectPascal
Raw Normal View History

{==============================================================================|
| Project : Delphree - Synapse | 002.003.002 |
|==============================================================================|
| Content: SNMP client |
|==============================================================================|
| The contents of this file are subject to the Mozilla Public License Ver. 1.1 |
| (the "License"); you may not use this file except in compliance with the |
| License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ |
| |
| Software distributed under the License is distributed on an "AS IS" basis, |
| WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for |
| the specific language governing rights and limitations under the License. |
|==============================================================================|
| 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,2001. |
| All Rights Reserved. |
|==============================================================================|
| Contributor(s): |
| Jean-Fabien Connault (jfconnault@mail.dotcom.fr) |
|==============================================================================|
| History: see HISTORY.HTM from distribution package |
| (Found at URL: http://www.ararat.cz/synapse/) |
|==============================================================================}
{$Q-}
{$WEAKPACKAGEUNIT ON}
unit SNMPSend;
interface
uses
Classes, SysUtils,
blckSock, SynaUtil, ASN1Util;
const
cSnmpProtocol = '161';
//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
TSNMPMib = class(TObject)
private
FOID: string;
FValue: string;
FValueType: Integer;
published
property OID: string read FOID Write FOID;
property Value: string read FValue Write FValue;
property ValueType: Integer read FValueType Write FValueType;
end;
TSNMPRec = class(TObject)
private
FVersion: Integer;
FCommunity: string;
FPDUType: Integer;
FID: Integer;
FErrorStatus: Integer;
FErrorIndex: Integer;
FSNMPMibList: TList;
public
constructor Create;
destructor Destroy; override;
function DecodeBuf(const Buffer: string): Boolean;
function EncodeBuf: string;
procedure Clear;
procedure MIBAdd(const MIB, Value: string; ValueType: Integer);
procedure MIBDelete(Index: Integer);
function MIBGet(const MIB: string): string;
published
property Version: Integer read FVersion Write FVersion;
property Community: string read FCommunity Write FCommunity;
property PDUType: Integer read FPDUType Write FPDUType;
property ID: Integer read FID Write FID;
property ErrorStatus: Integer read FErrorStatus Write FErrorStatus;
property ErrorIndex: Integer read FErrorIndex Write FErrorIndex;
property SNMPMibList: TList read FSNMPMibList;
end;
TSNMPSend = class(TObject)
private
FSock: TUDPBlockSocket;
FBuffer: string;
FTimeout: Integer;
FHost: string;
FHostIP: string;
FQuery: TSNMPRec;
FReply: TSNMPRec;
public
constructor Create;
destructor Destroy; override;
function DoIt: Boolean;
published
property Timeout: Integer read FTimeout Write FTimeout;
property Host: string read FHost Write FHost;
property HostIP: string read FHostIP;
property Query: TSNMPRec read FQuery;
property Reply: TSNMPRec read FReply;
end;
function SNMPGet(const Oid, Community, SNMPHost: string;
var Value: string): Boolean;
function SNMPSet(const Oid, Community, SNMPHost, Value: string;
ValueType: Integer): Boolean;
implementation
{==============================================================================}
constructor TSNMPRec.Create;
begin
inherited Create;
FSNMPMibList := TList.Create;
id := 1;
end;
destructor TSNMPRec.Destroy;
var
i: Integer;
begin
for i := 0 to FSNMPMibList.Count - 1 do
TSNMPMib(FSNMPMibList[i]).Free;
FSNMPMibList.Free;
inherited Destroy;
end;
function TSNMPRec.DecodeBuf(const Buffer: string): Boolean;
var
Pos: Integer;
EndPos: Integer;
sm, sv: string;
Svt: Integer;
begin
Result := False;
if Length(Buffer) < 2 then
Exit;
if (Ord(Buffer[1]) and $20) = 0 then
Exit;
Pos := 2;
EndPos := ASNDecLen(Pos, Buffer);
if Length(Buffer) < (EndPos + 2) then
Exit;
Self.FVersion := StrToIntDef(ASNItem(Pos, Buffer, Svt), 0);
Self.FCommunity := ASNItem(Pos, Buffer, Svt);
Self.FPDUType := StrToIntDef(ASNItem(Pos, Buffer, Svt), 0);
Self.FID := StrToIntDef(ASNItem(Pos, Buffer, Svt), 0);
Self.FErrorStatus := StrToIntDef(ASNItem(Pos, Buffer, Svt), 0);
Self.FErrorIndex := StrToIntDef(ASNItem(Pos, Buffer, Svt), 0);
ASNItem(Pos, Buffer, Svt);
while Pos < EndPos do
begin
ASNItem(Pos, Buffer, Svt);
Sm := ASNItem(Pos, Buffer, Svt);
Sv := ASNItem(Pos, Buffer, Svt);
Self.MIBAdd(sm, sv, Svt);
end;
Result := True;
end;
function TSNMPRec.EncodeBuf: string;
var
data, s: string;
SNMPMib: TSNMPMib;
n: Integer;
begin
data := '';
for n := 0 to FSNMPMibList.Count - 1 do
begin
SNMPMib := FSNMPMibList[n];
case SNMPMib.ValueType of
ASN1_INT:
s := ASNObject(MibToID(SNMPMib.OID), ASN1_OBJID) +
ASNObject(ASNEncInt(StrToIntDef(SNMPMib.Value, 0)), SNMPMib.ValueType);
ASN1_COUNTER, ASN1_GAUGE, ASN1_TIMETICKS:
s := ASNObject(MibToID(SNMPMib.OID), ASN1_OBJID) +
ASNObject(ASNEncUInt(StrToIntDef(SNMPMib.Value, 0)), SNMPMib.ValueType);
ASN1_OBJID:
s := ASNObject(MibToID(SNMPMib.OID), ASN1_OBJID) +
ASNObject(MibToID(SNMPMib.Value), SNMPMib.ValueType);
ASN1_IPADDR:
s := ASNObject(MibToID(SNMPMib.OID), ASN1_OBJID) +
ASNObject(IPToID(SNMPMib.Value), SNMPMib.ValueType);
ASN1_NULL:
s := ASNObject(MibToID(SNMPMib.OID), ASN1_OBJID) +
ASNObject('', ASN1_NULL);
else
s := ASNObject(MibToID(SNMPMib.OID), ASN1_OBJID) +
ASNObject(SNMPMib.Value, SNMPMib.ValueType);
end;
data := data + ASNObject(s, ASN1_SEQ);
end;
data := ASNObject(data, ASN1_SEQ);
data := ASNObject(ASNEncInt(Self.FID), ASN1_INT) +
ASNObject(ASNEncInt(Self.FErrorStatus), ASN1_INT) +
ASNObject(ASNEncInt(Self.FErrorIndex), ASN1_INT) +
data;
data := ASNObject(ASNEncInt(Self.FVersion), ASN1_INT) +
ASNObject(Self.FCommunity, ASN1_OCTSTR) +
ASNObject(data, Self.FPDUType);
data := ASNObject(data, ASN1_SEQ);
Result := data;
end;
procedure TSNMPRec.Clear;
var
i: Integer;
begin
FVersion := 0;
FCommunity := '';
FPDUType := 0;
FErrorStatus := 0;
FErrorIndex := 0;
for i := 0 to FSNMPMibList.Count - 1 do
TSNMPMib(FSNMPMibList[i]).Free;
FSNMPMibList.Clear;
end;
procedure TSNMPRec.MIBAdd(const MIB, Value: string; ValueType: Integer);
var
SNMPMib: TSNMPMib;
begin
SNMPMib := TSNMPMib.Create;
SNMPMib.OID := MIB;
SNMPMib.Value := Value;
SNMPMib.ValueType := ValueType;
FSNMPMibList.Add(SNMPMib);
end;
procedure TSNMPRec.MIBDelete(Index: Integer);
begin
if (Index >= 0) and (Index < FSNMPMibList.Count) then
begin
TSNMPMib(FSNMPMibList[Index]).Free;
FSNMPMibList.Delete(Index);
end;
end;
function TSNMPRec.MIBGet(const MIB: string): string;
var
i: Integer;
begin
Result := '';
for i := 0 to FSNMPMibList.Count - 1 do
begin
if ((TSNMPMib(FSNMPMibList[i])).OID = MIB) then
begin
Result := (TSNMPMib(FSNMPMibList[i])).Value;
Break;
end;
end;
end;
{==============================================================================}
constructor TSNMPSend.Create;
begin
inherited Create;
FQuery := TSNMPRec.Create;
FReply := TSNMPRec.Create;
FQuery.Clear;
FReply.Clear;
FSock := TUDPBlockSocket.Create;
FSock.CreateSocket;
FTimeout := 5000;
FHost := cLocalhost;
FHostIP := '';
end;
destructor TSNMPSend.Destroy;
begin
FSock.Free;
FReply.Free;
FQuery.Free;
inherited Destroy;
end;
function TSNMPSend.DoIt: Boolean;
var
x: Integer;
begin
Result := False;
FReply.Clear;
FBuffer := Query.EncodeBuf;
FSock.Connect(FHost, cSnmpProtocol);
FHostIP := FSock.GetRemoteSinIP;
FSock.SendBuffer(PChar(FBuffer), Length(FBuffer));
if FSock.CanRead(FTimeout) then
begin
x := FSock.WaitingData;
if x > 0 then
begin
SetLength(FBuffer, x);
FSock.RecvBuffer(PChar(FBuffer), x);
Result := True;
end;
end;
if Result then
Result := FReply.DecodeBuf(FBuffer);
end;
{==============================================================================}
function SNMPGet(const Oid, Community, SNMPHost: string;
var Value: string): Boolean;
var
SNMP: TSNMPSend;
begin
SNMP := TSNMPSend.Create;
try
SNMP.Query.Community := Community;
SNMP.Query.PDUType := PDUGetRequest;
SNMP.Query.MIBAdd(Oid, '', ASN1_NULL);
SNMP.Host := SNMPHost;
Result := SNMP.DoIt;
if Result then
Value := SNMP.Reply.MIBGet(Oid);
finally
SNMP.Free;
end;
end;
function SNMPSet(const Oid, Community, SNMPHost, Value: string;
ValueType: Integer): Boolean;
var
SNMPSend: TSNMPSend;
begin
SNMPSend := TSNMPSend.Create;
try
SNMPSend.Query.Community := Community;
SNMPSend.Query.PDUType := PDUSetRequest;
SNMPSend.Query.MIBAdd(Oid, Value, ValueType);
SNMPSend.Host := SNMPHost;
Result := SNMPSend.DoIt = True;
finally
SNMPSend.Free;
end;
end;
end.