⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snmpsend.pas

📁 snmp设计增加相应SNMP的OID,是实时处理的.
💻 PAS
📖 第 1 页 / 共 3 页
字号:
 the basic SET method of the SNMP protocol. If the SNMP operation is successful,
 the result is @true. "Value" is value of MIB Oid for "SNMPHost" with "Community"
 access identifier. You must specify "ValueType" too.}
function SNMPSet(const OID, Community, SNMPHost, Value: AnsiString; ValueType: Integer): Boolean;

{:A very useful function and example of its use would be found in the TSNMPSend
 object. It implements basic GETNEXT method of the SNMP protocol. The MIB value
 is located in the "OID" variable, and is sent to the requested "SNMPHost" with
 the proper "Community" access identifier. Upon a successful retrieval, "Value"
 will contain the information requested. If the SNMP operation is successful,
 the result returns @true.}
function SNMPGetNext(var OID: AnsiString; const Community, SNMPHost: AnsiString; var Value: AnsiString): Boolean;

{:A very useful function and example of its use would be found in the TSNMPSend
 object. It implements basic read of SNMP MIB tables. As BaseOID you must
 specify basic MIB OID of requested table (base IOD is OID without row and
 column specificator!)
 Table is readed into stringlist, where each string is comma delimited string.

 Warning: this function is not have best performance. For better performance
 you must write your own function. best performace you can get by knowledge
 of structuture of table and by more then one MIB on one query. }
function SNMPGetTable(const BaseOID, Community, SNMPHost: AnsiString; const Value: TStrings): Boolean;

{:A very useful function and example of its use would be found in the TSNMPSend
 object. It implements basic read of SNMP MIB table element. As BaseOID you must
 specify basic MIB OID of requested table (base IOD is OID without row and
 column specificator!)
 As next you must specify identificator of row and column for specify of needed
 field of table.}
function SNMPGetTableElement(const BaseOID, RowID, ColID, Community, SNMPHost: AnsiString; var Value: AnsiString): Boolean;

{:A very useful function and example of its use would be found in the TSNMPSend
 object. It implements a TRAPv1 to send with all data in the parameters.}
function SendTrap(const Dest, Source, Enterprise, Community: AnsiString;
  Generic, Specific, Seconds: Integer; const MIBName, MIBValue: AnsiString;
  MIBtype: Integer): Integer;

{:A very useful function and example of its use would be found in the TSNMPSend
 object. It receives a TRAPv1 and returns all the data that comes with it.}
function RecvTrap(var Dest, Source, Enterprise, Community: AnsiString;
  var Generic, Specific, Seconds: Integer; const MIBName,
  MIBValue: TStringList): Integer;

implementation

{==============================================================================}

constructor TSNMPRec.Create;
begin
  inherited Create;
  FSNMPMibList := TList.Create;
  Clear;
  FID := 1;
  FMaxSize := 1472;
end;

destructor TSNMPRec.Destroy;
var
  i: Integer;
begin
  for i := 0 to FSNMPMibList.Count - 1 do
    TSNMPMib(FSNMPMibList[i]).Free;
  FSNMPMibList.Clear;
  FSNMPMibList.Free;
  inherited Destroy;
end;

function TSNMPRec.Pass2Key(const Value: AnsiString): AnsiString;
var
  key: AnsiString;
begin
  case FAuthMode of
    AuthMD5:
      begin
        key := MD5LongHash(Value, 1048576);
        Result := MD5(key + FAuthEngineID + key);
      end;
    AuthSHA1:
      begin
        key := SHA1LongHash(Value, 1048576);
        Result := SHA1(key + FAuthEngineID + key);
      end;
  else
    Result := '';
  end;
end;


function TSNMPRec.DecodeBuf(const Buffer: AnsiString): Boolean;
var
  Pos: Integer;
  EndPos: Integer;
  sm, sv: AnsiString;
  Svt: Integer;
  s: AnsiString;
  Spos: integer;
  x: Byte;
begin
  Clear;
  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);

  if FVersion = 3 then
  begin
    ASNItem(Pos, Buffer, Svt);  //header data seq
    ASNItem(Pos, Buffer, Svt);  //ID
    FMaxSize := StrToIntDef(ASNItem(Pos, Buffer, Svt), 0);
    s := ASNItem(Pos, Buffer, Svt);
    x := 0;
    if s <> '' then
      x := Ord(s[1]);
    FFlagReportable := (x and 4) > 0;
    x := x and 3;
    case x of
      1:
        FFlags := AuthNoPriv;
      3:
        FFlags := AuthPriv;
    else
      FFlags := NoAuthNoPriv;
    end;

    x := StrToIntDef(ASNItem(Pos, Buffer, Svt), 0);
    s := ASNItem(Pos, Buffer, Svt); //SecurityParameters
    //if SecurityModel is USM, then try to decode SecurityParameters
    if (x = 3) and (s <> '') then
    begin
      spos := 1;
      ASNItem(SPos, s, Svt);
      FAuthEngineID := ASNItem(SPos, s, Svt);
      FAuthEngineBoots := StrToIntDef(ASNItem(SPos, s, Svt), 0);
      FAuthEngineTime := StrToIntDef(ASNItem(SPos, s, Svt), 0);
      FAuthEngineTimeStamp := GetTick;
      FUserName := ASNItem(SPos, s, Svt);
      FAuthKey := ASNItem(SPos, s, Svt);
      FPrivKey := ASNItem(SPos, s, Svt);
    end;
    //scopedPDU
    s := ASNItem(Pos, Buffer, Svt);
    if Svt = ASN1_OCTSTR then
    begin
      //decrypt!
    end;
    FContextEngineID := ASNItem(Pos, Buffer, Svt);
    FContextName := ASNItem(Pos, Buffer, Svt);
  end
  else
  begin
    //old packet
    Self.FCommunity := ASNItem(Pos, Buffer, Svt);
  end;

  ASNItem(Pos, Buffer, Svt);
  Self.FPDUType := Svt;
  if Self.FPDUType = PDUTrap then
  begin
    FOldTrapEnterprise := ASNItem(Pos, Buffer, Svt);
    FOldTrapHost := ASNItem(Pos, Buffer, Svt);
    FOldTrapGen := StrToIntDef(ASNItem(Pos, Buffer, Svt), 0);
    FOldTrapSpec := StrToIntDef(ASNItem(Pos, Buffer, Svt), 0);
    FOldTrapTimeTicks := StrToIntDef(ASNItem(Pos, Buffer, Svt), 0);
  end
  else
  begin
    Self.FID := StrToIntDef(ASNItem(Pos, Buffer, Svt), 0);
    Self.FErrorStatus := StrToIntDef(ASNItem(Pos, Buffer, Svt), 0);
    Self.FErrorIndex := StrToIntDef(ASNItem(Pos, Buffer, Svt), 0);
  end;
  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: AnsiString;
var
  s: AnsiString;
  SNMPMib: TSNMPMib;
  n: Integer;
  pdu, head, auth, authbeg: AnsiString;
  x: Byte;
begin
  pdu := '';
  for n := 0 to FSNMPMibList.Count - 1 do
  begin
    SNMPMib := TSNMPMib(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;
    pdu := pdu + ASNObject(s, ASN1_SEQ);
  end;
  pdu := ASNObject(pdu, ASN1_SEQ);

  if Self.FPDUType = PDUTrap then
    pdu := ASNObject(MibToID(FOldTrapEnterprise), ASN1_OBJID) +
      ASNObject(IPToID(FOldTrapHost), ASN1_IPADDR) +
      ASNObject(ASNEncInt(FOldTrapGen), ASN1_INT) +
      ASNObject(ASNEncInt(FOldTrapSpec), ASN1_INT) +
      ASNObject(ASNEncUInt(FOldTrapTimeTicks), ASN1_TIMETICKS) +
      pdu
  else
    pdu := ASNObject(ASNEncInt(Self.FID), ASN1_INT) +
      ASNObject(ASNEncInt(Self.FErrorStatus), ASN1_INT) +
      ASNObject(ASNEncInt(Self.FErrorIndex), ASN1_INT) +
      pdu;
  pdu := ASNObject(pdu, Self.FPDUType);

  if FVersion = 3 then
  begin
    if FContextEngineID = '' then
      FContextEngineID := FAuthEngineID;
    //complete PDUv3...
    pdu := ASNObject(FContextEngineID, ASN1_OCTSTR)
      + ASNObject(FContextName, ASN1_OCTSTR)
      + pdu;
    //maybe encrypt pdu... in future
    pdu := ASNObject(pdu, ASN1_SEQ);

    //prepare flags
    case FFlags of
      AuthNoPriv:
        x := 1;
      AuthPriv:
        x := 3;
    else
      x := 0;
    end;
    if FFlagReportable then
      x := x or 4;
    head := ASNObject(ASNEncInt(Self.FVersion), ASN1_INT);
    s := ASNObject(ASNEncInt(FID), ASN1_INT)
      + ASNObject(ASNEncInt(FMaxSize), ASN1_INT)
      + ASNObject(AnsiChar(x), ASN1_OCTSTR)
    //encode security model USM
      + ASNObject(ASNEncInt(3), ASN1_INT);
    head := head + ASNObject(s, ASN1_SEQ);

    //compute engine time difference
    x := TickDelta(FAuthEngineTimeStamp, GetTick) div 1000;

    authbeg := ASNObject(FAuthEngineID, ASN1_OCTSTR)
      + ASNObject(ASNEncInt(FAuthEngineBoots), ASN1_INT)
      + ASNObject(ASNEncInt(FAuthEngineTime + x), ASN1_INT)
      + ASNObject(FUserName, ASN1_OCTSTR);


    case FFlags of
      AuthNoPriv,
      AuthPriv:
        begin
          s := authbeg + ASNObject(StringOfChar(#0, 12), ASN1_OCTSTR)
             + ASNObject(FPrivKey, ASN1_OCTSTR);
          s := ASNObject(s, ASN1_SEQ);
          s := head + ASNObject(s, ASN1_OCTSTR);
          s := ASNObject(s + pdu, ASN1_SEQ);
          //in s is entire packet without auth info...
          case FAuthMode of
            AuthMD5:
              begin
                s := HMAC_MD5(s, Pass2Key(FPassword) + StringOfChar(#0, 48));
                //strip to HMAC-MD5-96
                delete(s, 13, 4);
              end;
            AuthSHA1:
              begin
                s := HMAC_SHA1(s, Pass2Key(FPassword) + StringOfChar(#0, 44));
                //strip to HMAC-SHA-96
                delete(s, 13, 8);
              end;
          else
            s := '';
          end;
          FAuthKey := s;
        end;
    end;

    auth := authbeg + ASNObject(FAuthKey, ASN1_OCTSTR)
     + ASNObject(FPrivKey, ASN1_OCTSTR);
    auth := ASNObject(auth, ASN1_SEQ);

    head := head + ASNObject(auth, ASN1_OCTSTR);
    Result := ASNObject(head + pdu, ASN1_SEQ);
  end
  else
  begin
    head := ASNObject(ASNEncInt(Self.FVersion), ASN1_INT) +
      ASNObject(Self.FCommunity, ASN1_OCTSTR);
    Result := ASNObject(head + pdu, ASN1_SEQ);
  end;
end;

procedure TSNMPRec.Clear;
var
  i: Integer;
begin
  FVersion := SNMP_V1;
  FCommunity := 'public';
  FUserName := '';
  FPassword := '';
  FPDUType := 0;
  FErrorStatus := 0;
  FErrorIndex := 0;
  for i := 0 to FSNMPMibList.Count - 1 do
    TSNMPMib(FSNMPMibList[i]).Free;
  FSNMPMibList.Clear;
  FOldTrapEnterprise := '';
  FOldTrapHost := '';
  FOldTrapGen := 0;
  FOldTrapSpec := 0;
  FOldTrapTimeTicks := 0;
  FFlags := NoAuthNoPriv;
  FFlagReportable := false;
  FContextEngineID := '';
  FContextName := '';
  FAuthMode := AuthMD5;
  FAuthEngineID := '';
  FAuthEngineBoots := 0;
  FAuthEngineTime := 0;
  FAuthEngineTimeStamp := 0;
  FAuthKey := '';
  FPrivKey := '';
end;

procedure TSNMPRec.MIBAdd(const MIB, Value: AnsiString; ValueType: Integer);
var
  SNMPMib: TSNMPMib;
begin
  SNMPMib := TSNMPMib.Create;
  SNMPMib.OID := MIB;
  SNMPMib.Value := Value;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -