【ARP】win32操作arp缓存示例代码

下面是设置以太网卡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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值