分享一段SNMP的代码,顺带列出几个不解之处

ynwlgh 2011-02-18 05:07:36
codeproject上来的代码,用于获取ARP列表



// Function: GetEntries: Read ARP table for specific NIC interface.
//第一,二个参数用于获取数据
int GetEntries(arpTable* pTable, int tableLen, int adapterIndex)
{
UINT OID[3][10];

//三个OID。
for(int i=0;i<3;i++)
{
OID[i][0] = 1;
OID[i][1] = 3;
OID[i][2] = 6;
OID[i][3] = 1;
OID[i][4] = 2;
OID[i][5] = 1;
OID[i][6] = 4;
OID[i][7] = 22;
OID[i][8] = 1;

switch(i)
{
case 0:
// Adapter interface
OID[i][9] = 1;
break;

case 1:
// MAC address
OID[i][9] = 2;
break;

case 2:
// Entry Type
OID[i][9] = 4;
break;
}
}

ZeroMemory(pTable,sizeof(arpTable)*tableLen);


SnmpVarBindList SVBList[3];
SnmpVarBind SVBVars[3];

AsnObjectIdentifier AsnOID0={sizeof(OID[0])/sizeof(UINT),OID[0]};
AsnObjectIdentifier AsnOID1={sizeof(OID[1])/sizeof(UINT),OID[1]};
AsnObjectIdentifier AsnOID2={sizeof(OID[2])/sizeof(UINT),OID[2]};

SVBList[0].len=1;
SVBList[0].list=&SVBVars[0];
SnmpUtilOidCpy(&SVBVars[0].name,&AsnOID0);

SVBList[1].len=1;
SVBList[1].list=&SVBVars[1];
SnmpUtilOidCpy(&SVBVars[1].name,&AsnOID1);

SVBList[2].len=1;
SVBList[2].list=&SVBVars[2];
SnmpUtilOidCpy(&SVBVars[2].name,&AsnOID2);

int iEntries=0;
AsnInteger32 aiErrorStatus[3], aiErrorIndex[3];

do
{
aiErrorStatus[0]=0;
aiErrorIndex[0]=0;
aiErrorStatus[1]=0;
aiErrorIndex[1]=0;
aiErrorStatus[2]=0;
aiErrorIndex[2]=0;

//SnmpExtensionQuery的函数指针
if(!pfunSnmpExtensionQuery(SNMP_PDU_GETNEXT,&SVBList[0],&aiErrorStatus[0],&aiErrorIndex[0]))
continue; //@@@@@@@ 1
if(!pfunSnmpExtensionQuery(SNMP_PDU_GETNEXT,&SVBList[1],&aiErrorStatus[1],&aiErrorIndex[1]))
continue;
if(!pfunSnmpExtensionQuery(SNMP_PDU_GETNEXT,&SVBList[2],&aiErrorStatus[2],&aiErrorIndex[2]))
continue;

if(aiErrorStatus[0]!=SNMP_ERRORSTATUS_NOERROR
||aiErrorStatus[1]!=SNMP_ERRORSTATUS_NOERROR
||aiErrorStatus[2]!=SNMP_ERRORSTATUS_NOERROR)
break;

if(SnmpUtilOidNCmp(&SVBVars[0].name,&AsnOID0,AsnOID0.idLength))
break;
if(SnmpUtilOidNCmp(&SVBVars[1].name,&AsnOID1,AsnOID1.idLength))
break;
if(SnmpUtilOidNCmp(&SVBVars[2].name,&AsnOID2,AsnOID2.idLength))
break;


if(SVBList[0].list->value.asnValue.number==adapterIndex)
{
unsigned long pIPAddress;
unsigned long pMACAddress;

//获得ARP IP
pIPAddress=(unsigned long)SVBList[1].list->name.ids;

pTable[iEntries].IPAddress[0]=*(unsigned char*)(pIPAddress+44); //@@@@@@@@@@@@@ 2
pTable[iEntries].IPAddress[1]=*(unsigned char*)(pIPAddress+48);
pTable[iEntries].IPAddress[2]=*(unsigned char*)(pIPAddress+52);
pTable[iEntries].IPAddress[3]=*(unsigned char*)(pIPAddress+56);

//获得MAC
pMACAddress= (unsigned long)SVBList[1].list->value.asnValue.string.stream;
if (pMACAddress)
{
pTable[iEntries].MACAddress[0] = *(unsigned char *)(pMACAddress + 0);
pTable[iEntries].MACAddress[1] = *(unsigned char *)(pMACAddress + 1);
pTable[iEntries].MACAddress[2] = *(unsigned char *)(pMACAddress + 2);
pTable[iEntries].MACAddress[3] = *(unsigned char *)(pMACAddress + 3);
pTable[iEntries].MACAddress[4] = *(unsigned char *)(pMACAddress + 4);
pTable[iEntries].MACAddress[5] = *(unsigned char *)(pMACAddress + 5);
}


// 获得ARP类型,动态/静态。。
pTable[iEntries].Type = (unsigned long)SVBList[2].list->value.asnValue.number;

// Type must be one of (1, 2, 3, 4),确认类型是否有效
if (pTable[iEntries].Type>=1 && pTable[iEntries].Type<=4)
iEntries++; // Move to next array position

}

} while (iEntries<tableLen);

//清理工作
// Frees the memory allocated for the specified object identifiers
SnmpUtilOidFree(&SVBVars[2].name);
SnmpUtilOidFree(&SVBVars[1].name);
SnmpUtilOidFree(&SVBVars[0].name);

return iEntries; // Return number of Entries
}
...全文
184 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
ynwlgh 2011-02-23
  • 打赏
  • 举报
回复
算了,改用snmp++了。简单方便些
oyljerry 2011-02-18
  • 打赏
  • 举报
回复
SNMP_PDU_GETNEXT 应该是获取下一个数据,遍历

MIB是SNMP协议中的数据结构,标示OID是数据标示符,参考SNMP协议RFC
ynwlgh 2011-02-18
  • 打赏
  • 举报
回复
哦。SNMP_PDU_GETNEXT用于在do while循环中获取吧。
CSDN API文档:
注解:
当SNMP服务接收一个SNMP PDU请求时,它调用SnmpExtensionQuery函数来处理此请求。扩展代理必须遵循RFC1157中的规则来解析变量绑定或者产生一个错误。
如果扩展代理不能解析取下一个(Get Next)请求时的变量绑定,它就必须改变SnmpVarBind结构的name域的值为沿当前支持的MIB子树图的紧下面一个对象标识符的值。例如,如果扩展代理支持图”.1.3.6.1.4.77.1”, 对于”.1.3.6.1.4.1.77.1.5.1”的取下一个(Get Next)请求将导致改变的name域".1.3.6.1.4.1.77.2"。此向SNMP会话发信号以继续试图解析与其它扩展代理的变量绑定。
特别注意在调用SnmpExtensionQuery函数的过程中SNMP服务和扩展代理或许需要交换动态分配的内存。服务在每一传递到扩展代理的SnmpVarBind结构中动态分配对象标识符。然而,当扩展代理处理取下一个(Get Next)请求时为了替换此对象标识符它必须释放这个内存。扩展代理为变长对象类型分配动态内存。SNMP服务把此对象置于应答PDU中后释放这个内存。
ynwlgh 2011-02-18
  • 打赏
  • 举报
回复
1.SnmpExtensionQuery这个函数用来干嘛,没太看清楚。
他用SNMP_PDU_GETNEXT这个参数是干嘛?
获取值的话,为什么不用 SNMP_PDU_GET。

2.pTable[iEntries].IPAddress[0]=*(unsigned char*)(pIPAddress+44); //@@@@@@@@@@@@@ 2
这里为什么加上44?

3.MIB的结构到底是怎么个样。
好像没有相关的文档说明,OID对应的值该怎么有效获得。
用这个函数SnmpExtensionQuery的话,数据是保存在AsnObjectName(即AsnAny),或AsnObjectSyntax里边。
这结构太太复杂。

暂时只有这么多。

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧