SNMP getbulk 的实现
Implementation of SNMP getbulk
是否可以在 Delphi 中使用 TIdSNMP
实现 GetBulk
请求?
IdSNMP1.Query.Version:=1;
IdSNMP1.Query.PDUType := PDUGetNextRequest;
IdSNMP1.Query.MIBAdd(OID,'',2);
while IdSNMP1.SendQuery do
begin
if Copy (IdSNMP1.Reply.MIBOID [0], 1, Length (OID)) <> OID then break;
Memo1.Lines.Append('Replies: ' + IdSNMP1.Reply.ValueOID [0] + ' ' + IdSNMP1.Reply.Value[0]);
IdSNMP1.Query.MIBDelete(0);
IdSNMP1.Query.MIBAdd(IdSNMP1.Reply.ValueOID [0], '');
IdSNMP1.Query.PDUType := PDUGetNextRequest;
end
结果,我得到了一个get-response
,我想实现完整的GetBulk
。
您没有考虑到响应可能包含多个 OID 值。您只查看每个回复的第一个 OID。 Reply
属性 有一个 ValueCount
属性,你应该遍历所有的值,然后使用最后提供的 OID 发送下一个请求,例如:
IdSNMP1.Query.Version := 1;
IdSNMP1.Query.PDUType := PDUGetNextRequest;
IdSNMP1.Query.MIBAdd(OID, '', ASN1_INT);
while IdSNMP1.SendQuery do
begin
if IdSNMP1.Reply.ValueCount = 0 then Break;
Stop := False;
for I := 0 to IdSNMP1.Reply.ValueCount then
begin
Stop := (IdSNMP1.Reply.ValueOID[I] <> OID) and (not TextStartsWith(IdSNMP1.Reply.ValueOID[I], OID+'.'));
if Stop then Break;
Memo1.Lines.Append('Replies: ' + IdSNMP1.Reply.ValueOID[I] + ' ' + IdSNMP1.Reply.Value[I]);
end;
if Stop then Break;
IdSNMP1.Query.MIBDelete(0);
IdSNMP1.Query.MIBAdd(IdSNMP1.Reply.ValueOID[IdSNMP1.Reply.ValueCount-1], '');
end
话虽这么说,TIdSNMP
主要仅实施 SNMP v1, however GETBULK was introduced in SNMP v2. There is a workitem 来更新 TIdSNMP
以支持更新的 SNMP 版本。同时,SNMP v2c 消息(与 v2p 或 v2u 相对)在某种程度上 与 SNMP v1 消息兼容,因此您可能能够做到类似于以下内容:
const
PDUGetBulkRequest = $a5;
IdSNMP1.Query.Version := 1;
IdSNMP1.Query.PDUType := PDUGetBulkRequest;
IdSNMP1.Query.ID := ...; // desired request-id value
IdSNMP1.Query.ErrorStatus := ...; // desired non-repeaters value
IdSNMP1.Query.ErrorIndex := ...; // desired max-repetitions value
IdSNMP1.Query.MIBAdd(OID, '', ASN1_INT);
while IdSNMP1.SendQuery do
begin
if IdSNMP1.Reply.ValueCount = 0 then Break;
Stop := False;
for I := 0 to IdSNMP1.Reply.ValueCount then
begin
Stop := (IdSNMP1.Reply.ValueOID[I] <> OID) and (not TextStartsWith(IdSNMP1.Reply.ValueOID[I], OID+'.'));
if Stop then Break;
Memo1.Lines.Append('Replies: ' + IdSNMP1.Reply.ValueOID[I] + ' ' + IdSNMP1.Reply.Value[I]);
end;
if Stop then Break;
IdSNMP1.Query.MIBDelete(0);
IdSNMP1.Query.MIBAdd(IdSNMP1.Reply.ValueOID[IdSNMP1.Reply.ValueCount-1], '');
end
是否可以在 Delphi 中使用 TIdSNMP
实现 GetBulk
请求?
IdSNMP1.Query.Version:=1;
IdSNMP1.Query.PDUType := PDUGetNextRequest;
IdSNMP1.Query.MIBAdd(OID,'',2);
while IdSNMP1.SendQuery do
begin
if Copy (IdSNMP1.Reply.MIBOID [0], 1, Length (OID)) <> OID then break;
Memo1.Lines.Append('Replies: ' + IdSNMP1.Reply.ValueOID [0] + ' ' + IdSNMP1.Reply.Value[0]);
IdSNMP1.Query.MIBDelete(0);
IdSNMP1.Query.MIBAdd(IdSNMP1.Reply.ValueOID [0], '');
IdSNMP1.Query.PDUType := PDUGetNextRequest;
end
结果,我得到了一个get-response
,我想实现完整的GetBulk
。
您没有考虑到响应可能包含多个 OID 值。您只查看每个回复的第一个 OID。 Reply
属性 有一个 ValueCount
属性,你应该遍历所有的值,然后使用最后提供的 OID 发送下一个请求,例如:
IdSNMP1.Query.Version := 1;
IdSNMP1.Query.PDUType := PDUGetNextRequest;
IdSNMP1.Query.MIBAdd(OID, '', ASN1_INT);
while IdSNMP1.SendQuery do
begin
if IdSNMP1.Reply.ValueCount = 0 then Break;
Stop := False;
for I := 0 to IdSNMP1.Reply.ValueCount then
begin
Stop := (IdSNMP1.Reply.ValueOID[I] <> OID) and (not TextStartsWith(IdSNMP1.Reply.ValueOID[I], OID+'.'));
if Stop then Break;
Memo1.Lines.Append('Replies: ' + IdSNMP1.Reply.ValueOID[I] + ' ' + IdSNMP1.Reply.Value[I]);
end;
if Stop then Break;
IdSNMP1.Query.MIBDelete(0);
IdSNMP1.Query.MIBAdd(IdSNMP1.Reply.ValueOID[IdSNMP1.Reply.ValueCount-1], '');
end
话虽这么说,TIdSNMP
主要仅实施 SNMP v1, however GETBULK was introduced in SNMP v2. There is a workitem 来更新 TIdSNMP
以支持更新的 SNMP 版本。同时,SNMP v2c 消息(与 v2p 或 v2u 相对)在某种程度上 与 SNMP v1 消息兼容,因此您可能能够做到类似于以下内容:
const
PDUGetBulkRequest = $a5;
IdSNMP1.Query.Version := 1;
IdSNMP1.Query.PDUType := PDUGetBulkRequest;
IdSNMP1.Query.ID := ...; // desired request-id value
IdSNMP1.Query.ErrorStatus := ...; // desired non-repeaters value
IdSNMP1.Query.ErrorIndex := ...; // desired max-repetitions value
IdSNMP1.Query.MIBAdd(OID, '', ASN1_INT);
while IdSNMP1.SendQuery do
begin
if IdSNMP1.Reply.ValueCount = 0 then Break;
Stop := False;
for I := 0 to IdSNMP1.Reply.ValueCount then
begin
Stop := (IdSNMP1.Reply.ValueOID[I] <> OID) and (not TextStartsWith(IdSNMP1.Reply.ValueOID[I], OID+'.'));
if Stop then Break;
Memo1.Lines.Append('Replies: ' + IdSNMP1.Reply.ValueOID[I] + ' ' + IdSNMP1.Reply.Value[I]);
end;
if Stop then Break;
IdSNMP1.Query.MIBDelete(0);
IdSNMP1.Query.MIBAdd(IdSNMP1.Reply.ValueOID[IdSNMP1.Reply.ValueCount-1], '');
end