二哈它爸 2022-01-14 13:08 采纳率: 62.5%
浏览 24
已结题

本人结合winpcap进行开发编程,构造并发送了arp包,但是在ensp上的主机收到的arp包却多了一个,请问是怎么回事?

本人结合winpcap进行开发编程,构造并发送了arp包,但是在ensp上的主机收到的arp包却多了一个,请问是怎么回事?
#pragma execution_character_set("utf-8")

#include <atlstr.h>
#include <WinSock2.h>
#include <Iphlpapi.h>
#include <iostream>
#include <pcap.h>
#pragma comment(lib,"Iphlpapi.lib") //需要添加Iphlpapi.lib库
#pragma comment(lib,"Packet.lib")
#pragma comment(lib, "wpcap.lib")
#pragma comment(lib,"ws2_32.lib")

using namespace std;

// DLC Header
#pragma pack (1)//使结构体按1字节方式对齐
typedef struct tagDLCHeader
{
    unsigned char DesMAC[6];//以太网目的mac地址
    unsigned char SrcMAC[6];//以太网源目的mac地址
    unsigned short Ethertype;//帧类型
} 
DLCHEADER, * PDLCHEADER;

typedef struct tagARPFrame
{
    unsigned short HW_Type;//硬件类型,2字节,填充0x0001
    unsigned short Prot_Type;//协议的类型,2字节,填充0x0800
    unsigned char HW_Addr_Len;//MAC地址长度,1字节
    unsigned char Prot_Addr_Len;//IP地址长度,1字节
    unsigned short Opcode;//操作码,2字节,0x0001为请求包,0x0002为应答包
    unsigned char Send_HW_Addr[6];//发送方的MAC地址
    unsigned long Send_Prot_Addr;//发送方的IP地址
    unsigned char Targ_HW_Addr[6];//接受方的MAC地址
    unsigned long Targ_Prot_Addr;//接收方的IP地址
} 
ARPFRAME, * PARPFRAME;

// ARP Packet = DLC header + ARP Frame
typedef struct tagARPPacket
{
    DLCHEADER dlcHeader; //以太网头部
    ARPFRAME arpFrame;//arp头部
} 

ARPPACKET, * PARPPACKET;

// DLC Header
#pragma pack (1)//使结构体按1字节方式对齐

PIP_ADAPTER_INFO get_IpAdapterInfoes(PIP_ADAPTER_INFO a)
{

    PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO();//PIP_ADAPTER_INFO结构体指针存储本机网卡信息
    unsigned long stSize = sizeof(IP_ADAPTER_INFO);//得到结构体大小,用于GetAdaptersInfo参数
    int nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);//调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量;其中stSize参数既是一个输入量也是一个输出量   
    int netCardNum = 0;//记录网卡数量
    int IPnumPerNetCard = 0;//记录每张网卡上的IP地址数量
    if (ERROR_BUFFER_OVERFLOW == nRel)
    {
        //如果函数返回的是ERROR_BUFFER_OVERFLOW
        //则说明GetAdaptersInfo参数传递的内存空间不够,同时其传出stSize,表示需要的空间大小
        //这也是说明为什么stSize既是一个输入量也是一个输出量
        pIpAdapterInfo = (PIP_ADAPTER_INFO)new BYTE[stSize];//重新申请内存空间用来存储所有网卡信息
        nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);//再次调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量
    }
    if (ERROR_SUCCESS == nRel)
    {
        while (pIpAdapterInfo)//输出网卡信息,可能有多网卡,因此通过循环去判断
        {
            return pIpAdapterInfo;
        }

    }
    return pIpAdapterInfo;
}

const char* get_IpAdapter_name(char* choose_wangka, char* filled_ip, char* filled_mask)
{
    char* ret = (char*)malloc(128);
    memset(ret, 0, sizeof(&ret));

    char const* str1= "\\Device\\NPF_";
    int len1 = strlen(str1) + 1;
    strcat_s(ret, len1, str1);

    const char* default_wangka_p = "请选择网卡";
    char* default_wangka = new char[strlen(default_wangka_p) + 1];
    strcpy_s(default_wangka, int(strlen(default_wangka_p) + 1), default_wangka_p);
    if (strcmp(choose_wangka, default_wangka))
    {
        PIP_ADAPTER_INFO c = new IP_ADAPTER_INFO();
        c = get_IpAdapterInfoes(c);
        while (c)
        {
            IP_ADDR_STRING* pIpAddrString = &(c->IpAddressList);
            if ((strcmp(pIpAddrString->IpAddress.String, filled_ip) == NULL) && (strcmp(pIpAddrString->IpMask.String, filled_mask) == NULL))
            {
                //cout << c->AdapterName << endl;//{8296B904-C70D-490D-A744-7F5F1A4A47B5}
                char* str2 = c->AdapterName;
                int len2 = strlen(ret) + strlen(str2) + 1;
                strcat_s(ret, len2, str2);
                break;
            }
            c = c->Next;
        }
    }
    else
    {
        cout << "请先选择网卡!" << endl;
        //return FALSE;
    }
    cout << ret << endl;
    return ret;
}

char* get_self_mac(char* choose_wangka, char* filled_ip, char* filled_mask)
{
    char* ret = (char*)malloc(20);
    memset(ret, 0, sizeof(&ret));

    const char default_wangka_p[] = "请选择网卡";
    char* default_wangka = new char[strlen(default_wangka_p) + 1];
    strcpy_s(default_wangka, int(strlen(default_wangka_p) + 1), default_wangka_p);
    if (strcmp(choose_wangka, default_wangka))
    {
        PIP_ADAPTER_INFO c = new IP_ADAPTER_INFO();
        c = get_IpAdapterInfoes(c);
        while (c)
        {
            IP_ADDR_STRING* pIpAddrString = &(c->IpAddressList);
            if (strcmp(pIpAddrString->IpAddress.String, filled_ip)==NULL && strcmp(pIpAddrString->IpMask.String, filled_mask) == NULL)
            {
                for (DWORD j = 0; j < c->AddressLength; j++)
                {
                    int v = (c->Address[j]) / 16; //取除数(前面一位)
                    int m = (c->Address[j]) % 16; //取模(后面一位)
                    if (v >= 0 && v <= 9) { v += 48; } //数字转ASCII
                    else if (v >= 97 && v <= 122) { v = v + 87; } //小写字母转ASCII
                    else { v = v + 55; } //大写字母转ASCII
                    char vChar = (char)v; //ASCII码转为char类型
                    //后面一位转char
                    if (m >= 0 && m <= 9) { m += 48; }
                    else if (m >= 97 && m <= 122) { m = m + 87; }
                    else { m = m + 55; }
                    char mChar = (char)m;
                    //两位char合并为一个字符串
                    char strKVCTmp[3] = { vChar,mChar }; //char字符合并成string
                    if (j < c->AddressLength - 1)
                    {
                        int len1 = strlen(ret)+strlen(strKVCTmp)+1;
                        strcat_s(ret, len1, strKVCTmp);

                        int len2 = strlen(ret)+strlen(":")+1;
                        strcat_s(ret, len2, ":");
                    }
                    else
                    {
                        int len3 = strlen(ret)+strlen(strKVCTmp)+1;
                        strcat_s(ret, len3, strKVCTmp);
                        break;
                    }
                }
            }
            c = c->Next;
        }
    }
    else
    {
        cout << "请先选择网卡!" << endl;
        //return FALSE;
    }
    cout << ret << endl;
    return ret;
}

int mac_str_to_bin(char* str, char* mac)
{
    int i;
    char* s, * e = new(char);
    if ((mac == NULL) || (str == NULL))
    {
        return -1;
    }
    s = (char*)str;
    for (i = 0; i < 6; ++i)
    {
        mac[i] = s ? strtoul(s, &e, 16) : 0;
        if (s)
            s = (*e) ? e + 1 : e;
    }
    return 0;
}

pcap_t* adhandle;
char errbuf[PCAP_ERRBUF_SIZE];

pcap_t* get_adhandle(const char* wangka_name)
{
    if ((adhandle = pcap_open_live(wangka_name,   //适配器的名称
        65535,                                //捕获的数据包的部分
        //65535是捕获所有流经的数据包,所有的数据包通过都产生端口
        0,
        1000,                                 //读取超时时间
        errbuf                                //错误缓存
    ))
        == NULL)
    {
        system("chcp 65001");
        cout << "该网卡不可用" << endl;
        return 0;
    }
    
    else
    {
        system("chcp 65001");
        cout << "网卡可用" << endl;
        return adhandle;
    }
}

ARPPACKET  make_request_Arp(int arpType, char* srcMac, char* srcIP)
{
    ARPPACKET ARPPacket;// 定义ARPPACKET结构体变量
    char* desMac;
    char mac[19]="ff:ff:ff:ff:ff:ff";
    desMac = mac;

    mac_str_to_bin(srcMac, (char*)ARPPacket.dlcHeader.SrcMAC);
    mac_str_to_bin(desMac, (char*)ARPPacket.dlcHeader.DesMAC);

    ARPPacket.dlcHeader.Ethertype = htons((unsigned short)0x0806); // DLC Header的以太网类型ARP包
    ARPPacket.arpFrame.HW_Type = htons((unsigned short)0x0001);
    ARPPacket.arpFrame.Prot_Type = htons((unsigned short)0x0800);
    ARPPacket.arpFrame.HW_Addr_Len = (unsigned char)6;//MAC地址长度
    ARPPacket.arpFrame.Prot_Addr_Len = (unsigned char)4;// IP地址长度
    ARPPacket.arpFrame.Opcode = htons((unsigned short)arpType);//arp包类型
    mac_str_to_bin(srcMac, (char*)ARPPacket.arpFrame.Send_HW_Addr);
    ARPPacket.arpFrame.Send_Prot_Addr = inet_pton(AF_INET, srcIP, (void*)&srcIP);// 源IP 
    //  printf("%6.6x \n", ARPPacket.arpFrame.Send_Prot_Addr);
    mac_str_to_bin(desMac, (char*)ARPPacket.arpFrame.Targ_HW_Addr);
    //ARPPacket.arpFrame.Targ_Prot_Addr = inet_pton(AF_INET, desIP, (void*)&desIP);//目的IP
    //  printf("%6.6x \n", ARPPacket.arpFrame.Targ_Prot_Addr);
    return ARPPacket;
}

void sendArpPacket(pcap_t* adhandle, ARPPACKET& ARPPacket)
{
    /* Send down the packet */
    if (pcap_sendpacket(adhandle,             // Adapter
        (const u_char*)&ARPPacket,     // buffer with the packet
        sizeof(ARPPacket)               // size
    ) != 0)
    {
        fprintf(stderr, "\nError sending the packet: %s\n", pcap_geterr(adhandle));
        printf("send NULL ! \n");
        return;
    }
    else
    {
        //      printf("%d", sizeof(ARPPacket));
        printf("send OK ! \n");
    }
}

void  analysis_reveived_arp()
{

}

int main()
{
    const char* choose_wangka_p="VirtualBox Host-Only Ethernet Adapter";
    char* choose_wangka= new char[strlen(choose_wangka_p) + 1];
    strcpy_s(choose_wangka, int(strlen(choose_wangka_p) + 1), "VirtualBox Host-Only Ethernet Adapter");
    const char* filled_ip_p = "192.168.56.1";
    char* filled_ip= new char[strlen(filled_ip_p) + 1];
    strcpy_s(filled_ip,int(strlen(filled_ip_p) + 1), filled_ip_p);
    const char* filled_mask_p = "255.255.255.0";
    char* filled_mask = new char[strlen(filled_mask_p) + 1];
    strcpy_s(filled_mask,int(strlen(filled_mask_p) + 1), filled_mask_p);
    const char* wangka_name;
    wangka_name=get_IpAdapter_name(choose_wangka, filled_ip, filled_mask);
    char* self_mac;
    self_mac=get_self_mac(choose_wangka, filled_ip, filled_mask);

    pcap_t* adhandle = get_adhandle(wangka_name);
    ARPPACKET ARPPacket_A = make_request_Arp(1, self_mac, filled_ip);

    while (true)
    {
        sendArpPacket(adhandle, ARPPacket_A);
        //      sendarppacket(adhandle, arppacket_b);
        Sleep(500);
        //      sleep(1000);
    }
    pcap_close(adhandle);
    return 0;
}


我只构造了192.168.56.1ip地址的arp包,并没有构造1.0.0.0的arp包,请问1.0.0.0的arp包是怎么产生的?

img

######请问这是怎么回事?

  • 写回答

0条回答 默认 最新

    报告相同问题?

    问题事件

    • 系统已结题 1月22日
    • 创建了问题 1月14日

    悬赏问题

    • ¥20 软件测试决策法疑问求解答
    • ¥15 win11 23H2删除推荐的项目,支持注册表等
    • ¥15 matlab 用yalmip搭建模型,cplex求解,线性化处理的方法
    • ¥15 qt6.6.3 基于百度云的语音识别 不会改
    • ¥15 关于#目标检测#的问题:大概就是类似后台自动检测某下架商品的库存,在他监测到该商品上架并且可以购买的瞬间点击立即购买下单
    • ¥15 神经网络怎么把隐含层变量融合到损失函数中?
    • ¥15 lingo18勾选global solver求解使用的算法
    • ¥15 全部备份安卓app数据包括密码,可以复制到另一手机上运行
    • ¥20 测距传感器数据手册i2c
    • ¥15 RPA正常跑,cmd输入cookies跑不出来