下面是设置以太网卡arp缓存的代码,要看效果的话需要以太网连接
#include <winsock2.h>
#include <ws2ipdef.h>
#include <iphlpapi.h>
#include <winerror.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")
void show_table(PMIB_IPNET_TABLE2 table)
{
for (ULONG i = 0; i < table->NumEntries; i++)
{
PIN_ADDR pIpv4addr = &table->Table[i].Address.Ipv4.sin_addr;
// 只看192.168.1开头的
if (pIpv4addr->S_un.S_un_b.s_b1 == 192 &&
pIpv4addr->S_un.S_un_b.s_b2 == 168 &&
pIpv4addr->S_un.S_un_b.s_b3 == 1)
{
PMIB_IPNET_ROW2 pRow = &table->Table[i];
if (pRow->InterfaceIndex != 2)
continue;
printf("NetLuidIndex: %u, Type: %u, NetIfIndex: %u\n", (ULONG)pRow->InterfaceLuid.Info.NetLuidIndex, (ULONG)pRow->InterfaceLuid.Info.IfType, pRow->InterfaceIndex);
printf("ip: %d.%d.%d.%d\t", pIpv4addr->S_un.S_un_b.s_b1, pIpv4addr->S_un.S_un_b.s_b2, pIpv4addr->S_un.S_un_b.s_b3, pIpv4addr->S_un.S_un_b.s_b4);
printf("mac: ");
ULONG j = 0;
for (; j < pRow->PhysicalAddressLength; j++) {
if (j == (pRow->PhysicalAddressLength - 1))
printf("%.2X\n", (int)pRow->PhysicalAddress[j]);
else
printf("%.2X-", (int)pRow->PhysicalAddress[j]);
}
if (j == 0)
printf("\n");
}
}
}
void get_ethernet(char ip[16], int* index);
void add_or_modify_1row(IN_ADDR ipv4Addr, char mac[6])
{
NETIO_STATUS rs;
char ip[16];
int ifIndex = -1;
get_ethernet(ip, &ifIndex);
if (ifIndex > -1)
{
MIB_IPNET_ROW2 row;
row.InterfaceLuid.Value = 0;
row.InterfaceIndex = ifIndex;
memset(&row.Address, 0, sizeof(row.Address));
row.Address.Ipv4.sin_family = AF_INET;
inet_pton(AF_INET, "192.168.1.30", (void*)& row.Address.Ipv4.sin_addr.s_addr);
row.Address.Ipv4.sin_port = 0;
rs = GetIpNetEntry2(&row);
switch (rs)
{
case NO_ERROR:
printf("NO_ERROR\n");
row.PhysicalAddressLength = 6;
row.PhysicalAddress[0] = 0x00;
row.PhysicalAddress[1] = 0x80;
row.PhysicalAddress[2] = 0xE1;
row.PhysicalAddress[3] = 0x22;
row.PhysicalAddress[4] = 0x00;
row.PhysicalAddress[5] = 0x24;
rs = SetIpNetEntry2(&row);
if (rs == ERROR_NOT_FOUND)
goto err_not_found;
break;
case ERROR_INVALID_PARAMETER:
return ERROR_INVALID_PARAMETER;
case ERROR_NOT_FOUND:
{
err_not_found:
printf("NOT_FOUND\n");
// 用以设置
row.PhysicalAddressLength = 6;
row.PhysicalAddress[0] = 0x00;
row.PhysicalAddress[1] = 0x80;
row.PhysicalAddress[2] = 0xE1;
row.PhysicalAddress[3] = 0x22;
row.PhysicalAddress[4] = 0x00;
row.PhysicalAddress[5] = 0x24;
rs = CreateIpNetEntry2(&row);
if (rs == ERROR_ACCESS_DENIED || rs == ERROR_INVALID_PARAMETER)
return rs;
}
}
}
return E_FAIL;
}
void get_ethernet(char ip[16], int *index)
{
memset(ip, 0, 16);
PIP_ADAPTER_INFO pAdapterInfo;
PIP_ADAPTER_INFO pAdapterInfoTmp = NULL;
pAdapterInfo = (IP_ADAPTER_INFO*)GlobalAlloc(GMEM_ZEROINIT, sizeof(IP_ADAPTER_INFO));
ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) != ERROR_SUCCESS)
{
GlobalFree(pAdapterInfo);
pAdapterInfo = (IP_ADAPTER_INFO*)GlobalAlloc(GMEM_ZEROINIT, ulOutBufLen);
}
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == NO_ERROR)
{
pAdapterInfoTmp = pAdapterInfo;
while (pAdapterInfoTmp)
{
if (pAdapterInfoTmp->Type == MIB_IF_TYPE_ETHERNET)
{
if (pAdapterInfoTmp->CurrentIpAddress)
memcpy(ip, pAdapterInfoTmp->CurrentIpAddress->IpAddress.String, 16);
else
memcpy(ip, pAdapterInfoTmp->IpAddressList.IpAddress.String, 16);
if (strcmp(ip, "") == 0)
printf("empty ip\n");
else if (strcmp(ip, "0.0.0.0") == 0)
printf("ip is 0.0.0.0\n");
else
{
*index = pAdapterInfoTmp->Index;
printf("found ip: %s\n", ip);
break;
}
}
pAdapterInfoTmp = pAdapterInfoTmp->Next;
}
}
GlobalFree(pAdapterInfo);
}
int __cdecl main()
{
PMIB_IPNET_TABLE2 table;
volatile DWORD rs = GetIpNetTable2(AF_INET, &table);
printf("-----before operation-----\n");
show_table(table); //操作前
printf("-----before operation-----\n");
//add_or_modify_1row(table, )
IN_ADDR ipv4Addr;
ipv4Addr.s_addr = 0xC0A8011C; //192.168.1.28
add_or_modify_1row(ipv4Addr, NULL);
Sleep(1000);
printf("-----after operation-----\n");
show_table(table); //操作后
printf("-----after operation-----\n");
return 0;
}
运行上述代码后,打开控制台输入
arp -a
在以太网卡arp表格中,即可看到刚刚添加的arp一栏
192.168.1.30 以及C0A8011C