home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 November / Chip_2002-11_cd1.bin / zkuste / delphi / kompon / d3456 / SYNAPSE.ZIP / source / lib / SNMPSend.pas < prev    next >
Pascal/Delphi Source File  |  2002-07-07  |  14KB  |  437 lines

  1. {==============================================================================|
  2. | Project : Delphree - Synapse                                   | 002.005.000 |
  3. |==============================================================================|
  4. | Content: SNMP client                                                         |
  5. |==============================================================================|
  6. | Copyright (c)1999-2002, Lukas Gebauer                                        |
  7. | All rights reserved.                                                         |
  8. |                                                                              |
  9. | Redistribution and use in source and binary forms, with or without           |
  10. | modification, are permitted provided that the following conditions are met:  |
  11. |                                                                              |
  12. | Redistributions of source code must retain the above copyright notice, this  |
  13. | list of conditions and the following disclaimer.                             |
  14. |                                                                              |
  15. | Redistributions in binary form must reproduce the above copyright notice,    |
  16. | this list of conditions and the following disclaimer in the documentation    |
  17. | and/or other materials provided with the distribution.                       |
  18. |                                                                              |
  19. | Neither the name of Lukas Gebauer nor the names of its contributors may      |
  20. | be used to endorse or promote products derived from this software without    |
  21. | specific prior written permission.                                           |
  22. |                                                                              |
  23. | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"  |
  24. | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE    |
  25. | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE   |
  26. | ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR  |
  27. | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL       |
  28. | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR   |
  29. | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER   |
  30. | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT           |
  31. | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY    |
  32. | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH  |
  33. | DAMAGE.                                                                      |
  34. |==============================================================================|
  35. | The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
  36. | Portions created by Lukas Gebauer are Copyright (c)2000,2001.                |
  37. | All Rights Reserved.                                                         |
  38. |==============================================================================|
  39. | Contributor(s):                                                              |
  40. |   Jean-Fabien Connault (cycocrew@worldnet.fr)                                |
  41. |==============================================================================|
  42. | History: see HISTORY.HTM from distribution package                           |
  43. |          (Found at URL: http://www.ararat.cz/synapse/)                       |
  44. |==============================================================================}
  45.  
  46. {$Q-}
  47. {$WEAKPACKAGEUNIT ON}
  48.  
  49. unit SNMPSend;
  50.  
  51. interface
  52.  
  53. uses
  54.   Classes, SysUtils,
  55.   blckSock, SynaUtil, ASN1Util;
  56.  
  57. const
  58.   cSnmpProtocol = '161';
  59.  
  60.   //PDU type
  61.   PDUGetRequest = $A0;
  62.   PDUGetNextRequest = $A1;
  63.   PDUGetResponse = $A2;
  64.   PDUSetRequest = $A3;
  65.   PDUTrap = $A4;
  66.  
  67.   //errors
  68.   ENoError = 0;
  69.   ETooBig = 1;
  70.   ENoSuchName = 2;
  71.   EBadValue = 3;
  72.   EReadOnly = 4;
  73.   EGenErr = 5;
  74.  
  75. type
  76.   TSNMPMib = class(TObject)
  77.   private
  78.     FOID: string;
  79.     FValue: string;
  80.     FValueType: Integer;
  81.   published
  82.     property OID: string read FOID write FOID;
  83.     property Value: string read FValue write FValue;
  84.     property ValueType: Integer read FValueType write FValueType;
  85.   end;
  86.  
  87.   TSNMPRec = class(TObject)
  88.   private
  89.     FVersion: Integer;
  90.     FCommunity: string;
  91.     FPDUType: Integer;
  92.     FID: Integer;
  93.     FErrorStatus: Integer;
  94.     FErrorIndex: Integer;
  95.     FSNMPMibList: TList;
  96.   public
  97.     constructor Create;
  98.     destructor Destroy; override;
  99.     function DecodeBuf(const Buffer: string): Boolean;
  100.     function EncodeBuf: string;
  101.     procedure Clear;
  102.     procedure MIBAdd(const MIB, Value: string; ValueType: Integer);
  103.     procedure MIBDelete(Index: Integer);
  104.     function MIBGet(const MIB: string): string;
  105.   published
  106.     property Version: Integer read FVersion write FVersion;
  107.     property Community: string read FCommunity write FCommunity;
  108.     property PDUType: Integer read FPDUType write FPDUType;
  109.     property ID: Integer read FID write FID;
  110.     property ErrorStatus: Integer read FErrorStatus write FErrorStatus;
  111.     property ErrorIndex: Integer read FErrorIndex write FErrorIndex;
  112.     property SNMPMibList: TList read FSNMPMibList;
  113.   end;
  114.  
  115.   TSNMPSend = class(TSynaClient)
  116.   private
  117.     FSock: TUDPBlockSocket;
  118.     FBuffer: string;
  119.     FHostIP: string;
  120.     FQuery: TSNMPRec;
  121.     FReply: TSNMPRec;
  122.   public
  123.     constructor Create;
  124.     destructor Destroy; override;
  125.     function DoIt: Boolean;
  126.   published
  127.     property HostIP: string read FHostIP;
  128.     property Query: TSNMPRec read FQuery;
  129.     property Reply: TSNMPRec read FReply;
  130.     property Sock: TUDPBlockSocket read FSock;
  131.   end;
  132.  
  133. function SNMPGet(const OID, Community, SNMPHost: string; var Value: string): Boolean;
  134. function SNMPSet(const OID, Community, SNMPHost, Value: string; ValueType: Integer): Boolean;
  135. function SNMPGetNext(var OID: string; const Community, SNMPHost: string; var Value: string): Boolean;
  136. function SNMPGetTable(const BaseOID, Community, SNMPHost: string; const Value: TStrings): Boolean;
  137. function SNMPGetTableElement(const BaseOID, RowID, ColID, Community, SNMPHost: string; var Value: String): Boolean;
  138.  
  139. implementation
  140.  
  141. {==============================================================================}
  142.  
  143. constructor TSNMPRec.Create;
  144. begin
  145.   inherited Create;
  146.   FSNMPMibList := TList.Create;
  147.   FID := 1;
  148. end;
  149.  
  150. destructor TSNMPRec.Destroy;
  151. var
  152.   i: Integer;
  153. begin
  154.   for i := 0 to FSNMPMibList.Count - 1 do
  155.     TSNMPMib(FSNMPMibList[i]).Free;
  156.   FSNMPMibList.Clear;
  157.   FSNMPMibList.Free;
  158.   inherited Destroy;
  159. end;
  160.  
  161. function TSNMPRec.DecodeBuf(const Buffer: string): Boolean;
  162. var
  163.   Pos: Integer;
  164.   EndPos: Integer;
  165.   sm, sv: string;
  166.   Svt: Integer;
  167. begin
  168.   Result := False;
  169.   if Length(Buffer) < 2 then
  170.     Exit;
  171.   if (Ord(Buffer[1]) and $20) = 0 then
  172.     Exit;
  173.   Pos := 2;
  174.   EndPos := ASNDecLen(Pos, Buffer);
  175.   if Length(Buffer) < (EndPos + 2) then
  176.     Exit;
  177.   Self.FVersion := StrToIntDef(ASNItem(Pos, Buffer, Svt), 0);
  178.   Self.FCommunity := ASNItem(Pos, Buffer, Svt);
  179.   Self.FPDUType := StrToIntDef(ASNItem(Pos, Buffer, Svt), 0);
  180.   Self.FID := StrToIntDef(ASNItem(Pos, Buffer, Svt), 0);
  181.   Self.FErrorStatus := StrToIntDef(ASNItem(Pos, Buffer, Svt), 0);
  182.   Self.FErrorIndex := StrToIntDef(ASNItem(Pos, Buffer, Svt), 0);
  183.   ASNItem(Pos, Buffer, Svt);
  184.   while Pos < EndPos do
  185.   begin
  186.     ASNItem(Pos, Buffer, Svt);
  187.     Sm := ASNItem(Pos, Buffer, Svt);
  188.     Sv := ASNItem(Pos, Buffer, Svt);
  189.     Self.MIBAdd(sm, sv, Svt);
  190.   end;
  191.   Result := True;
  192. end;
  193.  
  194. function TSNMPRec.EncodeBuf: string;
  195. var
  196.   data, s: string;
  197.   SNMPMib: TSNMPMib;
  198.   n: Integer;
  199. begin
  200.   data := '';
  201.   for n := 0 to FSNMPMibList.Count - 1 do
  202.   begin
  203.     SNMPMib := FSNMPMibList[n];
  204.     case SNMPMib.ValueType of
  205.       ASN1_INT:
  206.         s := ASNObject(MibToID(SNMPMib.OID), ASN1_OBJID) +
  207.           ASNObject(ASNEncInt(StrToIntDef(SNMPMib.Value, 0)), SNMPMib.ValueType);
  208.       ASN1_COUNTER, ASN1_GAUGE, ASN1_TIMETICKS:
  209.         s := ASNObject(MibToID(SNMPMib.OID), ASN1_OBJID) +
  210.           ASNObject(ASNEncUInt(StrToIntDef(SNMPMib.Value, 0)), SNMPMib.ValueType);
  211.       ASN1_OBJID:
  212.         s := ASNObject(MibToID(SNMPMib.OID), ASN1_OBJID) +
  213.           ASNObject(MibToID(SNMPMib.Value), SNMPMib.ValueType);
  214.       ASN1_IPADDR:
  215.         s := ASNObject(MibToID(SNMPMib.OID), ASN1_OBJID) +
  216.           ASNObject(IPToID(SNMPMib.Value), SNMPMib.ValueType);
  217.       ASN1_NULL:
  218.         s := ASNObject(MibToID(SNMPMib.OID), ASN1_OBJID) +
  219.           ASNObject('', ASN1_NULL);
  220.     else
  221.       s := ASNObject(MibToID(SNMPMib.OID), ASN1_OBJID) +
  222.         ASNObject(SNMPMib.Value, SNMPMib.ValueType);
  223.     end;
  224.     data := data + ASNObject(s, ASN1_SEQ);
  225.   end;
  226.   data := ASNObject(data, ASN1_SEQ);
  227.   data := ASNObject(ASNEncInt(Self.FID), ASN1_INT) +
  228.     ASNObject(ASNEncInt(Self.FErrorStatus), ASN1_INT) +
  229.     ASNObject(ASNEncInt(Self.FErrorIndex), ASN1_INT) +
  230.     data;
  231.   data := ASNObject(ASNEncInt(Self.FVersion), ASN1_INT) +
  232.     ASNObject(Self.FCommunity, ASN1_OCTSTR) +
  233.     ASNObject(data, Self.FPDUType);
  234.   data := ASNObject(data, ASN1_SEQ);
  235.   Result := data;
  236. end;
  237.  
  238. procedure TSNMPRec.Clear;
  239. var
  240.   i: Integer;
  241. begin
  242.   FVersion := 0;
  243.   FCommunity := '';
  244.   FPDUType := 0;
  245.   FErrorStatus := 0;
  246.   FErrorIndex := 0;
  247.   for i := 0 to FSNMPMibList.Count - 1 do
  248.     TSNMPMib(FSNMPMibList[i]).Free;
  249.   FSNMPMibList.Clear;
  250. end;
  251.  
  252. procedure TSNMPRec.MIBAdd(const MIB, Value: string; ValueType: Integer);
  253. var
  254.   SNMPMib: TSNMPMib;
  255. begin
  256.   SNMPMib := TSNMPMib.Create;
  257.   SNMPMib.OID := MIB;
  258.   SNMPMib.Value := Value;
  259.   SNMPMib.ValueType := ValueType;
  260.   FSNMPMibList.Add(SNMPMib);
  261. end;
  262.  
  263. procedure TSNMPRec.MIBDelete(Index: Integer);
  264. begin
  265.   if (Index >= 0) and (Index < FSNMPMibList.Count) then
  266.   begin
  267.     TSNMPMib(FSNMPMibList[Index]).Free;
  268.     FSNMPMibList.Delete(Index);
  269.   end;
  270. end;
  271.  
  272. function TSNMPRec.MIBGet(const MIB: string): string;
  273. var
  274.   i: Integer;
  275. begin
  276.   Result := '';
  277.   for i := 0 to FSNMPMibList.Count - 1 do
  278.   begin
  279.     if ((TSNMPMib(FSNMPMibList[i])).OID = MIB) then
  280.     begin
  281.       Result := (TSNMPMib(FSNMPMibList[i])).Value;
  282.       Break;
  283.     end;
  284.   end;
  285. end;
  286.  
  287. {==============================================================================}
  288.  
  289. constructor TSNMPSend.Create;
  290. begin
  291.   inherited Create;
  292.   FQuery := TSNMPRec.Create;
  293.   FReply := TSNMPRec.Create;
  294.   FQuery.Clear;
  295.   FReply.Clear;
  296.   FSock := TUDPBlockSocket.Create;
  297.   FSock.CreateSocket;
  298.   FTimeout := 5000;
  299.   FTargetPort := cSnmpProtocol;
  300.   FHostIP := '';
  301. end;
  302.  
  303. destructor TSNMPSend.Destroy;
  304. begin
  305.   FSock.Free;
  306.   FReply.Free;
  307.   FQuery.Free;
  308.   inherited Destroy;
  309. end;
  310.  
  311. function TSNMPSend.DoIt: Boolean;
  312. begin
  313.   FReply.Clear;
  314.   FBuffer := FQuery.EncodeBuf;
  315.   FSock.Bind(FIPInterface, cAnyPort);
  316.   FSock.Connect(FTargetHost, FTargetPort);
  317.   FHostIP := cAnyHost;
  318.   FSock.SendString(FBuffer);
  319.   FBuffer := FSock.RecvPacket(FTimeout);
  320.   if FSock.LastError = 0 then
  321.   begin
  322.     FHostIP := FSock.GetRemoteSinIP;
  323.     Result := FReply.DecodeBuf(FBuffer);
  324.   end
  325.   else
  326.     Result := False;
  327. end;
  328.  
  329. {==============================================================================}
  330.  
  331. function SNMPGet(const OID, Community, SNMPHost: string; var Value: string): Boolean;
  332. var
  333.   SNMPSend: TSNMPSend;
  334. begin
  335.   SNMPSend := TSNMPSend.Create;
  336.   try
  337.     SNMPSend.Query.Clear;
  338.     SNMPSend.Query.Community := Community;
  339.     SNMPSend.Query.PDUType := PDUGetRequest;
  340.     SNMPSend.Query.MIBAdd(OID, '', ASN1_NULL);
  341.     SNMPSend.TargetHost := SNMPHost;
  342.     Result := SNMPSend.DoIt;
  343.     Value := '';
  344.     if Result then
  345.       Value := SNMPSend.Reply.MIBGet(OID);
  346.   finally
  347.     SNMPSend.Free;
  348.   end;
  349. end;
  350.  
  351. function SNMPSet(const OID, Community, SNMPHost, Value: string; ValueType: Integer): Boolean;
  352. var
  353.   SNMPSend: TSNMPSend;
  354. begin
  355.   SNMPSend := TSNMPSend.Create;
  356.   try
  357.     SNMPSend.Query.Clear;
  358.     SNMPSend.Query.Community := Community;
  359.     SNMPSend.Query.PDUType := PDUSetRequest;
  360.     SNMPSend.Query.MIBAdd(OID, Value, ValueType);
  361.     SNMPSend.TargetHost := SNMPHost;
  362.     Result := SNMPSend.DoIt = True;
  363.   finally
  364.     SNMPSend.Free;
  365.   end;
  366. end;
  367.  
  368. function SNMPGetNext(var OID: string; const Community, SNMPHost: string; var Value: string): Boolean;
  369. var
  370.   SNMPSend: TSNMPSend;
  371. begin
  372.   SNMPSend := TSNMPSend.Create;
  373.   try
  374.     SNMPSend.Query.Clear;
  375.     SNMPSend.Query.Community := Community;
  376.     SNMPSend.Query.PDUType := PDUGetNextRequest;
  377.     SNMPSend.Query.MIBAdd(OID, '', ASN1_NULL);
  378.     SNMPSend.TargetHost := SNMPHost;
  379.     Result := SNMPSend.DoIt;
  380.     Value := '';
  381.     if Result then
  382.       if SNMPSend.Reply.SNMPMibList.Count > 0 then
  383.       begin
  384.         OID := TSNMPMib(SNMPSend.Reply.SNMPMibList[0]).OID;
  385.         Value := TSNMPMib(SNMPSend.Reply.SNMPMibList[0]).Value;
  386.       end;
  387.   finally
  388.     SNMPSend.Free;
  389.   end;
  390. end;
  391.  
  392. function SNMPGetTable(const BaseOID, Community, SNMPHost: string; const Value: TStrings): Boolean;
  393. var
  394.   OID: string;
  395.   s: string;
  396.   col,row: string;
  397.   lastcol: string;
  398.   x, n: integer;
  399. begin
  400.   Value.Clear;
  401.   OID := BaseOID;
  402.   lastcol := '';
  403.   x := 0;
  404.   repeat
  405.     Result := SNMPGetNext(OID, Community, SNMPHost, s);
  406.     if Pos(BaseOID, OID) <> 1 then
  407.         break;
  408.     row := separateright(oid, baseoid + '.');
  409.     col := fetch(row, '.');
  410.     if col = lastcol then
  411.       inc(x)
  412.     else
  413.       x:=0;
  414.     lastcol := col;
  415.     if value.count <= x then
  416.       for n := value.Count - 1 to x do
  417.         value.add('');
  418.     if value[x] <> '' then
  419.       value[x] := value[x] + ',';
  420.     if IsBinaryString(s) then
  421.       s := StrToHex(s);
  422.     value[x] := value[x] + AnsiQuotedStr(s, '"');
  423.   until not result;
  424. end;
  425.  
  426. function SNMPGetTableElement(const BaseOID, RowID, ColID, Community, SNMPHost: string; var Value: String): Boolean;
  427. var
  428.   s: string;
  429. begin
  430.   s := BaseOID + '.' + ColID + '.' + RowID;
  431.   Result := SnmpGet(s, Community, SNMPHost, Value);
  432. end;
  433.  
  434. end.
  435.  
  436.  
  437.