MFC:使用SNMP编辑(添加/删除/修改)ARP表
2012-03-15 08:40
369 查看
MFC:使用SNMP编辑(添加/删除/修改)ARP表
本文章永久地址 http://www.limou.net/?p=306
介绍
这个工具像Windows命令行工具arp.exe一样显示和修改IP/物理地址转表(ARP表)。该工具将做两件事情。
显示ARP表
添加、删除、修改ARP表
这两项工作通过SNMP(简单网络管理协议)扩展库来完成。
通过SNMP处理IP和MAC地址
你可以通过SNMP读取或修改ARP表,通过SNMP得到或设置对象信息。SNMP命令的请求与响应是依靠MIB(管理信息库)来完成的。MIB为树装结构,MIB拥有所有为我们所用的可管理对象。
下面是MIB ipNetToMediaEntry条目
ipNetToMediaEntry OBJECT-TYPE
SYNTAX IpNetToMediaEntry
ACCESS not-accessible
STATUS mandatory
DESCRIPTION
"Each entry contains one IpAddress to 'physical'
address equivalence."
INDEX { ipNetToMediaIfIndex,
ipNetToMediaNetAddress }
::= { ipNetToMediaTable 1 }
MIB通过OID(对象标识)数字来存取对象,每个对象拥有一个数字,子对象拥有父对象的数字和自己的数字,数字之间用”.”来分割。例如:父对象数字为”1″,子对象数字为”3″,则子对象OID为”1.3″,子对象的子对象可以是”1.3.6″,…”1.3.6.1.2.1″等等…
下面是对象树的简单框图:
类的初始化
我们使用SnmpExtensionQuery函数来发送SNMP请求,使用之前我们必须调用SnmpExtensionInit来初始化SNMP扩展代理DLL。
这两个函数包含于Microsoft的inetmib1.dll中。
因此我们在类的构造函数中加载动态库并得到函数的地址,然后调用SnmpExtensionInit初始化SNMP扩展代理DLL。
下面是CARP类的构造函数
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CARP::CARP()
{
// Load dynamic library: inetmib1.dll
hMIBLibrary = LoadLibrary(TEXT("inetmib1.dll"));
// If library loaded, get addresses of (SnmpExtensionInit, pfnSnmpExtensionQuery) functions
if (hMIBLibrary)
{
pfnSnmpExtensionInit = (PFNSNMPEXTENSIONINIT) GetProcAddress(hMIBLibrary, "SnmpExtensionInit");
pfnSnmpExtensionQuery = (PFNSNMPEXTENSIONQUERY) GetProcAddress(hMIBLibrary, "SnmpExtensionQuery");
// If success get addresses and initialize SNMP, bInitialized = true
if (pfnSnmpExtensionInit && pfnSnmpExtensionQuery)
{
HANDLE hPollForTrapEvent;
AsnObjectIdentifier aoiSupportedView;
bInitialized = pfnSnmpExtensionInit(0, &hPollForTrapEvent, &aoiSupportedView);
}
}
else
{
// If fail to get addresses, bInitialized = false
bInitialized = FALSE;
AfxMessageBox(_T("Load library fail"));
}
}
得到ARP条目
函数GetEntries类似arp.exe -a,可以得到ARP条目,函数有三个参数:
PTable指针指向arpTable结构数组,用于填充IP和MAC地址。
TableLength是数组长度
AdapterIndex是NIC适配器的编号。
使用3个OID来得到ARP表条目:OID[0] = “1.3.6.1.2.1.4.22.1.1″ ,得到接口索引号。然后和OID[1] = “1.3.6.1.2.1.4.22.1.2″比较,得到IP和MAC地址OID[2] = “1.3.6.1.2.1.4.22.1.4″, 得到条目类型(静态或动态)
//-----------------------------------------------------------------------
// Function: GetEntries: Read ARP table for specific NIC interface.
//
// Parameters:
// pTable Pointer to array of arpTable struct
// TableLength Length of the array
// AdapterIndex NIC Adapter index number
//
// Returns:
// Number of read ARP entries
//-----------------------------------------------------------------------
int CARP::GetEntries(arpTable* pTable, int TableLength, int AdapterIndex)
{
// Be sure initialize SNMP true
if (!bInitialized)
return 0;
SnmpVarBindList SVBList[3];
SnmpVarBind SVBVars[3];
UINT OID[3][10];
AsnInteger32 aiErrorStatus[3], aiErrorIndex[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]};
unsigned long pIPAddress;
unsigned long pMACAddress;
int iEntries;
//-----------------------------------------------------------------------
// Fill array of 3 OIDs
//
// OID[0] : "1.3.6.1.2.1.4.22.1.1", ipNetToMediaIfIndex
// The interface on which this entry's equivalence is effective
//
// OID[1] : "1.3.6.1.2.1.4.22.1.2", ipNetToMediaPhysAddress
// The media-dependent 'physical' address
//
// OID[2] : "1.3.6.1.2.1.4.22.1.4", ipNetToMediaType
// Entry type: 1:Other, 2:Invalid(Remove), 3:Dynamic, 4:Static
//
for (int count=0; count<3; count++)
{
OID[count][0] = 1;
OID[count][1] = 3;
OID[count][2] = 6;
OID[count][3] = 1;
OID[count][4] = 2;
OID[count][5] = 1;
OID[count][6] = 4;
OID[count][7] = 22;
OID[count][8] = 1;
switch(count)
{
case 0:
// Adapter interface
OID[count][9] = 1;
break;
case 1:
// MAC address
OID[count][9] = 2;
break;
case 2:
// Entry Type
OID[count][9] = 4;
break;
}
}
ZeroMemory(pTable, sizeof(arpTable)*TableLength);
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);
iEntries = 0;
do
{
aiErrorStatus[0] = 0;
aiErrorIndex[0] = 0;
aiErrorStatus[1] = 0;
aiErrorIndex[1] = 0;
aiErrorStatus[2] = 0;
aiErrorIndex[2] = 0;
// Query information of 3 OIDs
if (pfnSnmpExtensionQuery(SNMP_PDU_GETNEXT, &SVBList[0], &aiErrorStatus[0], &aiErrorIndex[0]))
if (pfnSnmpExtensionQuery(SNMP_PDU_GETNEXT, &SVBList[1], &aiErrorStatus[1], &aiErrorIndex[1]))
if (pfnSnmpExtensionQuery(SNMP_PDU_GETNEXT, &SVBList[2], &aiErrorStatus[2], &aiErrorIndex[2]))
if (aiErrorStatus[0] == SNMP_ERRORSTATUS_NOERROR &&
aiErrorStatus[1] == SNMP_ERRORSTATUS_NOERROR &&
aiErrorStatus[2] == SNMP_ERRORSTATUS_NOERROR) // Check for error
{
//-----------------------------------------------------------------------
// From MSDN Help: http://msdn2.microsoft.com/en-us/library/aa378021.aspx
//
// If the extension agent cannot resolve the variable bindings on a Get Next request,
// it must change the name field of the SnmpVarBind structure to the value of the object
// identifier immediately following that of the currently supported MIB subtree view.
// For example, if the extension agent supports view ".1.3.6.1.4.1.77.1", a Get Next
// request on ".1.3.6.1.4.1.77.1.5.1" would result in a modified name field of ".1.3.6.1.4.1.77.2".
// This signals the SNMP service to continue the attempt to resolve the variable bindings
// with other extension agents
//-----------------------------------------------------------------------
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;
// Verify selected Adapter interface
if (AdapterIndex == SVBList[0].list->value.asnValue.number)
{
// pIPAddress get pointer ro IP Address
pIPAddress = (unsigned long)SVBList[1].list->name.ids;
pTable[iEntries].IPAddress[0] = *(unsigned char *)(pIPAddress + 44);
pTable[iEntries].IPAddress[1] = *(unsigned char *)(pIPAddress + 48);
pTable[iEntries].IPAddress[2] = *(unsigned char *)(pIPAddress + 52);
pTable[iEntries].IPAddress[3] = *(unsigned char *)(pIPAddress + 56);
// pIPAddress get pointer ro MAC Address
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);
}
// Entry Type
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
}
}
else
break; // If error exit do-while
}
while(iEntries < TableLength);
// 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
}
编辑ARP表条目
EditEntry函数可以添加、修改、删除ARP条目:
添加动态条目,就像:arp.exe 1.2.3.4 11-22-33-44-55-66
添加静态条目,就像:arp.exe –s 1.2.3.4 11-22-33-44-55-66
删除条目,就像:arp.exe –d 1.2.3.4
添加新条目,如果IP地址在ARP表中不存在则添加进去,如果已经存在则被更新。
删除条目,只需要提供NIC接口中的IP地址,MAC地址不需要提供。
函数有四个参数:4字节的IPAddress,6字节的MACAddress,条目类型(2:删除,3:动态,4:静态)
AdapterIndex:NIC适配器编号
使用4个OID设置ARP表条目:
OID[0] = “1.3.6.1.2.1.4.22.1.1″, 设置接口编号
OID[1] = “1.3.6.1.2.1.4.22.1.2″, 设置MAC地址
OID[3] = “1.3.6.1.2.1.4.22.1.3″, 设置IP地址
OID[2] = “1.3.6.1.2.1.4.22.1.4″, 设置条目类型 (静态或动态), 或删除
//-----------------------------------------------------------------------
// Function: EditEntry: Add/Modify/Remove ARP entry for specific NIC interface.
//
// Parameters:
// IPAddress Array of 4 BYTES, 4 octs of IP Address
// MACAddress Array of 4 BYTES, 6 octs of MAC Address
// Type Entry type (2:Remove, 3:Dynamic, 4:Static)
// AdapterIndex NIC Adapter index number
//
// Returns:
// TRUE if set successfully, FALSE otherwise.
//-----------------------------------------------------------------------
BOOL CARP::EditEntry(unsigned char IPAddress[4], unsigned char MACAddress[6], unsigned long Type, int AdapterIndex)
{
if (!bInitialized)
return 0;
SnmpVarBindList SVBList;
SnmpVarBind SVBVars[4];
UINT OID[4][10];
AsnInteger32 aiErrorStatus, aiErrorIndex;
BOOL bReturn = FALSE;
//-----------------------------------------------------------------------
// Fill array of 4 OIDs
//
// OID[0] : "1.3.6.1.2.1.4.22.1.1", ipNetToMediaIfIndex
// The interface on which this entry's equivalence is effective
//
// OID[1] : "1.3.6.1.2.1.4.22.1.2", ipNetToMediaPhysAddress
// The media-dependent 'physical' address
//
// OID[2] : "1.3.6.1.2.1.4.22.1.3", ipNetToMediaNetAddress
// The IpAddress corresponding to the media-dependent 'physical' address
//
// OID[3] : "1.3.6.1.2.1.4.22.1.4", ipNetToMediaType
// Entry type: 1:Other, 2:Invalid(Remove), 3:Dynamic, 4:Static
//-----------------------------------------------------------------------
for (int count=0; count<4; count++)
{
OID[count][0] = 1;
OID[count][1] = 3;
OID[count][2] = 6;
OID[count][3] = 1;
OID[count][4] = 2;
OID[count][5] = 1;
OID[count][6] = 4;
OID[count][7] = 22;
OID[count][8] = 1;
OID[count][9] = 1 + count;
switch(count)
{
case 0:
// OID[0] : "1.3.6.1.2.1.4.22.1.1", ipNetToMediaIfIndex
// The interface on which this entry's equivalence is effective
SVBVars[count].value.asnType = ASN_INTEGER;
SVBVars[count].value.asnValue.number = AdapterIndex;
break;
case 1:
// OID[1] : "1.3.6.1.2.1.4.22.1.2", ipNetToMediaPhysAddress
// The media-dependent 'physical' address
SVBVars[count].value.asnType = ASN_OCTETSTRING;
SVBVars[count].value.asnValue.string.stream = MACAddress;
SVBVars[count].value.asnValue.string.length = 6; // MAC Address length
SVBVars[count].value.asnValue.string.dynamic= FALSE;
break;
case 2:
// OID[2] : "1.3.6.1.2.1.4.22.1.3", ipNetToMediaNetAddress
// The IpAddress corresponding to the media-dependent 'physical' address
SVBVars[count].value.asnType = ASN_IPADDRESS;
SVBVars[count].value.asnValue.string.stream = IPAddress;
SVBVars[count].value.asnValue.string.length = 4; // IP Address length
SVBVars[count].value.asnValue.string.dynamic= FALSE;
break;
case 3:
// OID[3] : "1.3.6.1.2.1.4.22.1.4", ipNetToMediaType
// Entry type: 2:Remove, 3:Dynamic, 4:Static
SVBVars[count].value.asnType = ASN_INTEGER;
SVBVars[count].value.asnValue.number = Type;
break;
}
AsnObjectIdentifier AsnOID = {sizeof(OID[count])/sizeof(UINT), OID[count]};
SnmpUtilOidCpy(&SVBVars[count].name, &AsnOID);
}
SVBList.len = 4;
SVBList.list = SVBVars;
aiErrorStatus = 0;
aiErrorIndex = 0;
// Set information of entry (4 OIDs)
if (pfnSnmpExtensionQuery(SNMP_PDU_SET, &SVBList, &aiErrorStatus, &aiErrorIndex))
if (aiErrorStatus == SNMP_ERRORSTATUS_NOERROR)
bReturn = TRUE; // If success set bReturn = true
// Frees the memory allocated for the specified object identifiers
SnmpUtilOidFree(&SVBVars[3].name);
SnmpUtilOidFree(&SVBVars[2].name);
SnmpUtilOidFree(&SVBVars[1].name);
SnmpUtilOidFree(&SVBVars[0].name);
return bReturn; // TRUE if set successfully, FALSE otherwise.
}
请继续关注 李木空间 www.limou.net 更多精彩源代码。
本文章永久地址 http://www.limou.net/?p=306
介绍
这个工具像Windows命令行工具arp.exe一样显示和修改IP/物理地址转表(ARP表)。该工具将做两件事情。
显示ARP表
添加、删除、修改ARP表
这两项工作通过SNMP(简单网络管理协议)扩展库来完成。
通过SNMP处理IP和MAC地址
你可以通过SNMP读取或修改ARP表,通过SNMP得到或设置对象信息。SNMP命令的请求与响应是依靠MIB(管理信息库)来完成的。MIB为树装结构,MIB拥有所有为我们所用的可管理对象。
下面是MIB ipNetToMediaEntry条目
ipNetToMediaEntry OBJECT-TYPE
SYNTAX IpNetToMediaEntry
ACCESS not-accessible
STATUS mandatory
DESCRIPTION
"Each entry contains one IpAddress to 'physical'
address equivalence."
INDEX { ipNetToMediaIfIndex,
ipNetToMediaNetAddress }
::= { ipNetToMediaTable 1 }
MIB通过OID(对象标识)数字来存取对象,每个对象拥有一个数字,子对象拥有父对象的数字和自己的数字,数字之间用”.”来分割。例如:父对象数字为”1″,子对象数字为”3″,则子对象OID为”1.3″,子对象的子对象可以是”1.3.6″,…”1.3.6.1.2.1″等等…
下面是对象树的简单框图:
类的初始化
我们使用SnmpExtensionQuery函数来发送SNMP请求,使用之前我们必须调用SnmpExtensionInit来初始化SNMP扩展代理DLL。
这两个函数包含于Microsoft的inetmib1.dll中。
因此我们在类的构造函数中加载动态库并得到函数的地址,然后调用SnmpExtensionInit初始化SNMP扩展代理DLL。
下面是CARP类的构造函数
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CARP::CARP()
{
// Load dynamic library: inetmib1.dll
hMIBLibrary = LoadLibrary(TEXT("inetmib1.dll"));
// If library loaded, get addresses of (SnmpExtensionInit, pfnSnmpExtensionQuery) functions
if (hMIBLibrary)
{
pfnSnmpExtensionInit = (PFNSNMPEXTENSIONINIT) GetProcAddress(hMIBLibrary, "SnmpExtensionInit");
pfnSnmpExtensionQuery = (PFNSNMPEXTENSIONQUERY) GetProcAddress(hMIBLibrary, "SnmpExtensionQuery");
// If success get addresses and initialize SNMP, bInitialized = true
if (pfnSnmpExtensionInit && pfnSnmpExtensionQuery)
{
HANDLE hPollForTrapEvent;
AsnObjectIdentifier aoiSupportedView;
bInitialized = pfnSnmpExtensionInit(0, &hPollForTrapEvent, &aoiSupportedView);
}
}
else
{
// If fail to get addresses, bInitialized = false
bInitialized = FALSE;
AfxMessageBox(_T("Load library fail"));
}
}
得到ARP条目
函数GetEntries类似arp.exe -a,可以得到ARP条目,函数有三个参数:
PTable指针指向arpTable结构数组,用于填充IP和MAC地址。
TableLength是数组长度
AdapterIndex是NIC适配器的编号。
使用3个OID来得到ARP表条目:OID[0] = “1.3.6.1.2.1.4.22.1.1″ ,得到接口索引号。然后和OID[1] = “1.3.6.1.2.1.4.22.1.2″比较,得到IP和MAC地址OID[2] = “1.3.6.1.2.1.4.22.1.4″, 得到条目类型(静态或动态)
//-----------------------------------------------------------------------
// Function: GetEntries: Read ARP table for specific NIC interface.
//
// Parameters:
// pTable Pointer to array of arpTable struct
// TableLength Length of the array
// AdapterIndex NIC Adapter index number
//
// Returns:
// Number of read ARP entries
//-----------------------------------------------------------------------
int CARP::GetEntries(arpTable* pTable, int TableLength, int AdapterIndex)
{
// Be sure initialize SNMP true
if (!bInitialized)
return 0;
SnmpVarBindList SVBList[3];
SnmpVarBind SVBVars[3];
UINT OID[3][10];
AsnInteger32 aiErrorStatus[3], aiErrorIndex[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]};
unsigned long pIPAddress;
unsigned long pMACAddress;
int iEntries;
//-----------------------------------------------------------------------
// Fill array of 3 OIDs
//
// OID[0] : "1.3.6.1.2.1.4.22.1.1", ipNetToMediaIfIndex
// The interface on which this entry's equivalence is effective
//
// OID[1] : "1.3.6.1.2.1.4.22.1.2", ipNetToMediaPhysAddress
// The media-dependent 'physical' address
//
// OID[2] : "1.3.6.1.2.1.4.22.1.4", ipNetToMediaType
// Entry type: 1:Other, 2:Invalid(Remove), 3:Dynamic, 4:Static
//
for (int count=0; count<3; count++)
{
OID[count][0] = 1;
OID[count][1] = 3;
OID[count][2] = 6;
OID[count][3] = 1;
OID[count][4] = 2;
OID[count][5] = 1;
OID[count][6] = 4;
OID[count][7] = 22;
OID[count][8] = 1;
switch(count)
{
case 0:
// Adapter interface
OID[count][9] = 1;
break;
case 1:
// MAC address
OID[count][9] = 2;
break;
case 2:
// Entry Type
OID[count][9] = 4;
break;
}
}
ZeroMemory(pTable, sizeof(arpTable)*TableLength);
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);
iEntries = 0;
do
{
aiErrorStatus[0] = 0;
aiErrorIndex[0] = 0;
aiErrorStatus[1] = 0;
aiErrorIndex[1] = 0;
aiErrorStatus[2] = 0;
aiErrorIndex[2] = 0;
// Query information of 3 OIDs
if (pfnSnmpExtensionQuery(SNMP_PDU_GETNEXT, &SVBList[0], &aiErrorStatus[0], &aiErrorIndex[0]))
if (pfnSnmpExtensionQuery(SNMP_PDU_GETNEXT, &SVBList[1], &aiErrorStatus[1], &aiErrorIndex[1]))
if (pfnSnmpExtensionQuery(SNMP_PDU_GETNEXT, &SVBList[2], &aiErrorStatus[2], &aiErrorIndex[2]))
if (aiErrorStatus[0] == SNMP_ERRORSTATUS_NOERROR &&
aiErrorStatus[1] == SNMP_ERRORSTATUS_NOERROR &&
aiErrorStatus[2] == SNMP_ERRORSTATUS_NOERROR) // Check for error
{
//-----------------------------------------------------------------------
// From MSDN Help: http://msdn2.microsoft.com/en-us/library/aa378021.aspx
//
// If the extension agent cannot resolve the variable bindings on a Get Next request,
// it must change the name field of the SnmpVarBind structure to the value of the object
// identifier immediately following that of the currently supported MIB subtree view.
// For example, if the extension agent supports view ".1.3.6.1.4.1.77.1", a Get Next
// request on ".1.3.6.1.4.1.77.1.5.1" would result in a modified name field of ".1.3.6.1.4.1.77.2".
// This signals the SNMP service to continue the attempt to resolve the variable bindings
// with other extension agents
//-----------------------------------------------------------------------
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;
// Verify selected Adapter interface
if (AdapterIndex == SVBList[0].list->value.asnValue.number)
{
// pIPAddress get pointer ro IP Address
pIPAddress = (unsigned long)SVBList[1].list->name.ids;
pTable[iEntries].IPAddress[0] = *(unsigned char *)(pIPAddress + 44);
pTable[iEntries].IPAddress[1] = *(unsigned char *)(pIPAddress + 48);
pTable[iEntries].IPAddress[2] = *(unsigned char *)(pIPAddress + 52);
pTable[iEntries].IPAddress[3] = *(unsigned char *)(pIPAddress + 56);
// pIPAddress get pointer ro MAC Address
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);
}
// Entry Type
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
}
}
else
break; // If error exit do-while
}
while(iEntries < TableLength);
// 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
}
编辑ARP表条目
EditEntry函数可以添加、修改、删除ARP条目:
添加动态条目,就像:arp.exe 1.2.3.4 11-22-33-44-55-66
添加静态条目,就像:arp.exe –s 1.2.3.4 11-22-33-44-55-66
删除条目,就像:arp.exe –d 1.2.3.4
添加新条目,如果IP地址在ARP表中不存在则添加进去,如果已经存在则被更新。
删除条目,只需要提供NIC接口中的IP地址,MAC地址不需要提供。
函数有四个参数:4字节的IPAddress,6字节的MACAddress,条目类型(2:删除,3:动态,4:静态)
AdapterIndex:NIC适配器编号
使用4个OID设置ARP表条目:
OID[0] = “1.3.6.1.2.1.4.22.1.1″, 设置接口编号
OID[1] = “1.3.6.1.2.1.4.22.1.2″, 设置MAC地址
OID[3] = “1.3.6.1.2.1.4.22.1.3″, 设置IP地址
OID[2] = “1.3.6.1.2.1.4.22.1.4″, 设置条目类型 (静态或动态), 或删除
//-----------------------------------------------------------------------
// Function: EditEntry: Add/Modify/Remove ARP entry for specific NIC interface.
//
// Parameters:
// IPAddress Array of 4 BYTES, 4 octs of IP Address
// MACAddress Array of 4 BYTES, 6 octs of MAC Address
// Type Entry type (2:Remove, 3:Dynamic, 4:Static)
// AdapterIndex NIC Adapter index number
//
// Returns:
// TRUE if set successfully, FALSE otherwise.
//-----------------------------------------------------------------------
BOOL CARP::EditEntry(unsigned char IPAddress[4], unsigned char MACAddress[6], unsigned long Type, int AdapterIndex)
{
if (!bInitialized)
return 0;
SnmpVarBindList SVBList;
SnmpVarBind SVBVars[4];
UINT OID[4][10];
AsnInteger32 aiErrorStatus, aiErrorIndex;
BOOL bReturn = FALSE;
//-----------------------------------------------------------------------
// Fill array of 4 OIDs
//
// OID[0] : "1.3.6.1.2.1.4.22.1.1", ipNetToMediaIfIndex
// The interface on which this entry's equivalence is effective
//
// OID[1] : "1.3.6.1.2.1.4.22.1.2", ipNetToMediaPhysAddress
// The media-dependent 'physical' address
//
// OID[2] : "1.3.6.1.2.1.4.22.1.3", ipNetToMediaNetAddress
// The IpAddress corresponding to the media-dependent 'physical' address
//
// OID[3] : "1.3.6.1.2.1.4.22.1.4", ipNetToMediaType
// Entry type: 1:Other, 2:Invalid(Remove), 3:Dynamic, 4:Static
//-----------------------------------------------------------------------
for (int count=0; count<4; count++)
{
OID[count][0] = 1;
OID[count][1] = 3;
OID[count][2] = 6;
OID[count][3] = 1;
OID[count][4] = 2;
OID[count][5] = 1;
OID[count][6] = 4;
OID[count][7] = 22;
OID[count][8] = 1;
OID[count][9] = 1 + count;
switch(count)
{
case 0:
// OID[0] : "1.3.6.1.2.1.4.22.1.1", ipNetToMediaIfIndex
// The interface on which this entry's equivalence is effective
SVBVars[count].value.asnType = ASN_INTEGER;
SVBVars[count].value.asnValue.number = AdapterIndex;
break;
case 1:
// OID[1] : "1.3.6.1.2.1.4.22.1.2", ipNetToMediaPhysAddress
// The media-dependent 'physical' address
SVBVars[count].value.asnType = ASN_OCTETSTRING;
SVBVars[count].value.asnValue.string.stream = MACAddress;
SVBVars[count].value.asnValue.string.length = 6; // MAC Address length
SVBVars[count].value.asnValue.string.dynamic= FALSE;
break;
case 2:
// OID[2] : "1.3.6.1.2.1.4.22.1.3", ipNetToMediaNetAddress
// The IpAddress corresponding to the media-dependent 'physical' address
SVBVars[count].value.asnType = ASN_IPADDRESS;
SVBVars[count].value.asnValue.string.stream = IPAddress;
SVBVars[count].value.asnValue.string.length = 4; // IP Address length
SVBVars[count].value.asnValue.string.dynamic= FALSE;
break;
case 3:
// OID[3] : "1.3.6.1.2.1.4.22.1.4", ipNetToMediaType
// Entry type: 2:Remove, 3:Dynamic, 4:Static
SVBVars[count].value.asnType = ASN_INTEGER;
SVBVars[count].value.asnValue.number = Type;
break;
}
AsnObjectIdentifier AsnOID = {sizeof(OID[count])/sizeof(UINT), OID[count]};
SnmpUtilOidCpy(&SVBVars[count].name, &AsnOID);
}
SVBList.len = 4;
SVBList.list = SVBVars;
aiErrorStatus = 0;
aiErrorIndex = 0;
// Set information of entry (4 OIDs)
if (pfnSnmpExtensionQuery(SNMP_PDU_SET, &SVBList, &aiErrorStatus, &aiErrorIndex))
if (aiErrorStatus == SNMP_ERRORSTATUS_NOERROR)
bReturn = TRUE; // If success set bReturn = true
// Frees the memory allocated for the specified object identifiers
SnmpUtilOidFree(&SVBVars[3].name);
SnmpUtilOidFree(&SVBVars[2].name);
SnmpUtilOidFree(&SVBVars[1].name);
SnmpUtilOidFree(&SVBVars[0].name);
return bReturn; // TRUE if set successfully, FALSE otherwise.
}
请继续关注 李木空间 www.limou.net 更多精彩源代码。
相关文章推荐
- 使用SNMP编辑(添加/删除/修改)ARP表
- 使用SNMP编辑(添加/删除/修改)ARP表
- 使用GridView添加,删除,编辑记录
- NSDictionary的使用及常用方法(如实始化、添加元素、删除元素、修改元素值等)
- 使用注解做添加删除修改
- ADO.NET使用带参数方法实现添加、删除和修改数据
- 在数据库服务端,添加一个表格,然后在MFC中对数据库表格的数据做插入、删除和修改
- JS框架avalon简单例子 行编辑 添加 修改 删除 验证
- MFC VC++下ADO方式访问连接MySQL数据库 添加 删除 修改数据库
- 以用户登录、注册、添加删除修改为例,解析jdbcTemplate使用方式以及spring注解实现CRUD
- 学生成绩管理系统MFC可以添加,查找,删除,修改
- solrj的使用,环境准备,工程搭建,索引创建,添加\修改索引,删除索引,查询
- SQL Server 2008中SQL增强之三:Merge(在一条语句中使用Insert,Update,Delete) 一条语句实现两表同步(添加、删除、修改)
- 使用注册表文件(REG)添加、修改或删除Windows注册表项和值
- MFC中简单的数据库文件操作(添加,修改,查找,删除)
- java使用jdbc对sqlite 添加、删除、修改的操作
- MFC VC++下ADO方式访问连接MySQL数据库 添加 删除 修改数据库
- NSSet的使用及常用方法(如初始化、并集、交集、删除、添加、修改等)
- 如何通过使用注册项 (.reg) 文件添加、修改或删除注册表子项和值
- MFC中简单的数据库文件操作(添加,修改,查找,删除)