ARP报文发送的可视化实现

一、安装VS2013,下载wpdpack,为VS2010配置WinpCap环境:

  ⑴首先在View中选择Property Manager,然后展开工程,再展开Debug|Win32 ,接着右击 Mircrosoft.Cpp.Win32.user选择Properties(此处设置全局有效)

  ⑵之后分三步:

  ①设置环境目录

    在VC++ Directiories中 Include Directories和Library Directories中添加路径。

    假如将wpdpack放到c盘。则:

    Include Directories:c:/wpdpack/Include;

    Library Directories:c:/wpdpack/Lib;

    注意分号!

  ②设置编译条件

    C/C++下Preprocessor(预处理器)的Preprocessor Definitions(预处理定义)

    添加WPCAP;HAVE_REMOTE;

    注意分号,每个预定义符用“;”分开。

  ③设置链接器

    Linker(链接器)下的Input(输入)中的Additional Dependencies(附加依赖项)中添加:

    wpcap.lib;ws2_32.lib;(注意分号)

二、使用mfc实现可视化界面:

    目的视图:

  

    1、新建项目:

      选择Visual C++ -> MFC -> MFC应用程序 –>修改项目名称test1 -> 下一步 –> 选择基于对话框 -> 完成

  2、相关视图介绍:

  ①解决方案资源管理器:可以看见所有的头文件和源(.cpp)文件,此程序只需用到test1Dlg.cpp和test1Dlg.h。另外MFC中main函数被封装起来了,并且我们也并不需要知道main函数在哪,因为我们希望实现的功能通常是触发某个控件,这个控件的触发函数为我们实现,并不需要将代码写到main函数内。

  ②类视图:在类视图中,我们可以看到三个类,此处只需要用到Ctest1Dlg,点击类名,可以在下方很方便的找到类中的函数和变量。

  ③属性管理器:在为VS配置全局环境时会用到。

  ④资源视图:在test1 -> test1.rc -> Dialog -> IDD_TEST1_DIALOG可以看见自己设计的可视化界面。

  ⑤属性:处理控件时,在此处修改控件的属性。

3、相关控件的使用:

   ①静态文本框Static Text:caption修改文字内容

  ②编辑框Edit Control:Read Only设置是否只读

    ③IP地址编辑框IP Address Control:用法与普通编辑框一样,只不过读取内容时可以使用GetAddress()函数。

    ④组合框Combo Box:Type分为三种:简易(Simple)组合框、下拉式(Dropdown)组合框和下拉列表式(Drop List)组合框,这里选择Drop List。

三、详细设计:

  1.ARP发送中重要方法:

  填充ARP包方法的流程图:

    

四、添加函数:

  1、 更改各控件ID,并给部分空间增加变量。Combo Box的默认ID更改为IDC_NIC_COMBO,增加控件变量m_comboNic;目的MAC地址的编辑框ID设为IDC_DESTI_MACADDRESS_EDIT,添加控件变量为m_editDesti;目的IP地址的编辑框ID设为IDC_DESTI_IPADDRESS,添加控件变量为m_ipaddressSesti;源MAC地址的编辑框ID设为IDC_SOURCE_MACADDRESS_EDIT,添加控件变量为m_editSource;源IP地址的编辑框ID设为IDC_SOURCE_IPADDRESS,添加控件变量为m_ipaddressSource;结果显示编辑框ID设为IDC_RESULT_EDIT,添加控件变量为m_editResult。

  2、 依据ARP包的结构定义结构体,并将需要引入的头文件、结构体和相关常量的定义写入test1Dlg.h文件中。

#include "stdafx.h"

#include <pcap.h>

#define ETH_ARP         0x0806  //以太网帧类型表示后面数据的类型,对于ARP请求或应答来说,该字段的值为x0806
#define ARP_HARDWARE    1  //硬件类型字段值为表示以太网地址
#define ETH_IP          0x0800  //协议类型字段表示要映射的协议地址类型值为x0800表示IP地址
#define ARP_REQUEST     1   //ARP请求
#define ARP_RESPONSE       2      //ARP应答

//14字节以太网首部
struct EthernetHeader
{
    u_char DestMAC[6];    //目的MAC地址 6字节
    u_char SourMAC[6];   //源MAC地址 6字节
    u_short EthType;         //上一层协议类型,如0x0800代表上一层是IP协议,0x0806为arp  2字节
};

//28字节ARP帧结构
struct ArpHeader
{
    unsigned short hdType;   //硬件类型
    unsigned short proType;   //协议类型
    unsigned char hdSize;   //硬件地址长度
    unsigned char proSize;   //协议地址长度
    unsigned short op;   //操作类型,ARP请求(1),ARP应答(2),RARP请求(3),RARP应答(4)。
    u_char smac[6];   //源MAC地址
    u_char sip[4];   //源IP地址
    u_char dmac[6];   //目的MAC地址
    u_char dip[4];   //目的IP地址
};

//定义整个arp报文包,总长度42字节
struct ArpPacket {
    EthernetHeader ed;
    ArpHeader ah;
};

  3、 在Ctest1Dlg::OnInitDialog()中写入初始化的界面的代码。

/* 获取本机设备列表 */
    if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
    {
        m_comboNic.AddString(_T("Error in pcap_findalldevs!"));
        exit(1);
    }

    /* 打印列表 */
    for (d = alldevs; d; d = d->next)
    {
        ++i;
        if (d->description)
            m_comboNic.AddString(LPCTSTR(CString(d->name)));
        else
            m_comboNic.AddString(_T("(No description available)"));
    }

    if (i == 0)
    {
        m_comboNic.AddString(_T("No interfaces found! Make sure WinPcap is installed."));
        return -1;
    }
    // 默认选择第一项
    m_comboNic.SetCurSel(0);
    //目的MAC地址编辑框中默认显示"00-00-00-00-00-00"
    SetDlgItemText(IDC_EDIT1, _T("00-00-00-00-00-00"));

  4、 在确认按钮的响应函数内添加以下代码:

// 获取组合框控件的列表框中选中项的索引
    inum = m_comboNic.GetCurSel();
    /* 跳转到选中的适配器 */
    for (d = alldevs, i = 0; i<= inum - 1; d = d->next, i++);
    /* 打开设备 */
    if ((adhandle = pcap_open(d->name,          // 设备名
        65536,            // 65535保证能捕获到不同数据链路层上的每个数据包的全部内容
        PCAP_OPENFLAG_PROMISCUOUS,    // 混杂模式
        1000,             // 读取超时时间
        NULL,             // 远程机器验证
        errbuf            // 错误缓冲池
        )) == NULL)
    {
        m_editResult.SetWindowText(_T("Unable to open the adapter. \rIt is not supported by WinPcap"));
        /* 释放设备列表 */
        pcap_freealldevs(alldevs);
        exit(-1);
    }

    unsigned char sendbuf[42]; //arp包结构大小,42个字节
    BYTE IPByte[4];
    m_ipaddressSesti.GetAddress(IPByte[0], IPByte[1], IPByte[2], IPByte[3]);
    BYTE IPByte2[4];
    m_ipaddressSource.GetAddress(IPByte2[0], IPByte2[1], IPByte2[2], IPByte2[3]);

    CString str;
    char *c;
    BYTE mac[7] = { 0 };//源MAC地址
    m_editSource.GetWindowText(str);//获取字符串
    c = cs2ca(str);    //CString转为char*
    sscanf_s(c, "%h2x-%h2x-%h2x-%h2x-%h2x-%h2x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);

    EthernetHeader eh;
    ArpHeader ah;
    if (IsDlgButtonChecked(IDC_RADIO1) == 1) {
        //请求报文
      .....//相应代码    }
    else if (IsDlgButtonChecked(IDC_RADIO2) == 1) {
        //应答报文
         .....//相应代码    }
    //构造一个ARP请求
    memset(sendbuf, 0, sizeof(sendbuf));   //ARP清零
    memcpy(sendbuf, &eh, sizeof(eh));
    memcpy(sendbuf + sizeof(eh), &ah, sizeof(ah));
    //如果发送成功
    if (pcap_sendpacket(adhandle, sendbuf, 42) == 0) {
        m_editResult.SetWindowText(_T("\nPacketSend succeed\n"));
    }
    else {
        m_editResult.SetWindowText(_T("\nPacketSendPacket in getmine Error\n"));
    }

    /* 释放设备列表 */
    pcap_freealldevs(alldevs);
    

  其中主要遇到的困难是,如何获取三个编辑框中用户输入的地址,将这种Cstring格式的地址转为u_char格式的字符数组。IP ADDRESS CONTROL可以使用其函数GetAddress(IPByte[0], IPByte[1], IPByte[2], IPByte[3]);获得。而MAC地址的编辑框获得的字符串就不太好转换了。碰过好多好多坑,试过好多好多方法之后,最终找到一种可行的方法:先把Cstring字符串利用函数转换为char*型,再使用sscanf将每两位代表十六进制的字符存在BYTE mac[7]数组中,但是貌似在vs2015中无法使用这个方法。

四、运行效果:

    

    

    

    

传送门:

  1.鸡啄米VS2010/MFC教程

  2.WinPcap实战(一)——发送ARP

  3.用sscanf转换MAC字符串为BYTE数组时遇到的问题

时间: 2024-10-25 21:16:57

ARP报文发送的可视化实现的相关文章

实现Arp报文发送和接收

继上次实现了 Ping 之后,尝试进入更底层的网络接口层实现局域网的 ARP 报文收发 ARP 协议概述 ARP(Address Resolution Protocol) 地址解析协议是用来通过网络层地址(IP地址)去寻找数据链路层地址(MAC地址)的网络传输协议. 在以太网(Ethernet)协议中规定,同一局域网中的一台主机要和另一台主机进行直接通信,必须要知道目标主机的 MAC 地址.而在 TCP/IP 协议中,网络层和传输层只关心目标主机的IP地址.这就导致在以太网中使用 IP 协议时,

ARP报文与arp_ignore arp_announce

背景: (1)根据缺省的TCP/IP协议栈处理,响应报文的源地址等于请求报文的目的IP. (2)关于ARP表: IP.MAC.网络接口的映射表:列表中的IP都属于本设备所在的网段,发送/转发非本地网段时候是通过网关,所以只需要使用网关对应的MAC即可. (3)ARP条目更新的条件(满足任意一个即可): 1.收到ARP request:目的MAC是广播,且Target IP是本机上的IP:(这里说Target IP是为了与目的IP区分) 2.收到ARP reply:目的MAC是广播或本机MAC,且

ARP报文格式

ARP/RARP报文格式 地址解析协议ARP(Address Resolution Protocol)是用来将IP地址解析为MAC地址的协议. 报文格式 字段 长度(bit) 含义 Ethernet Address of destination 48比特 目的以太网地址.发送ARP请求时,为广播的MAC地址,0xFF.FF.FF.FF.FF.FF. Ethernet Address of sender 48比特 源以太网地址. Frame Type 16比特 表示后面数据的类型.对于ARP请求或

linux内核-网络报文发送流程

报文的发送是由网络协议栈的上层发起的.网络协议栈上层构造一个需要发送的skb结构后(该skb已经包含了数据链路层的报头),调用dev_queue_xmit函数进行发送:dev_queue_xmit(skb);该函数先会处理一些缓冲区重组.计算校验和之类的杂事,然后开始处理报文的发送.发送报文有两种策略,有队列或无队列.这是由网络设备驱动程序在定义其对应的dev结构时指定的,一般的设备都会使用队列.dev->qdisc指向一个队列的实例,里面包含了队列本身以及操作队列的方法(enqueue.deq

IP 层收发报文简要剖析4--ip 报文发送

无论是从本地输出的数据还是转发的数据报文,经过路由后都要输出到网络设备,而输出到网络设备的接口就是dst_output(output)函数 路由的时候,dst_output函数设置为ip_output ip_mc_output等 1.TCP输出接口 L4 层在发送数据时会根据协议的不同调用上面提到的几个辅助函数之一,tcp协议打包成ip数据包文的方法根据tcp段的不同而选择不同的接口, 其中ip_queue_xmit为常用接口,ip_build_and_send_pkt.ip_send_repl

报文发送解析xml

1 FtpBasicRequestForMany ftpBasicRequestForMany = new FtpBasicRequestForMany(); 2 FtpPackRequestForMany ftpPackRequestForMany = new FtpPackRequestForMany(); 3 FtpParamsForMany ftpParamsForMany = new FtpParamsForMany(); 4 ftpParamsForMany.setFileName(

Keepalived基础

Keepalived基础 keepalived 简介 keepalived是vrrp协议的软件实现,原生设计目的是为了高可用ipvs服务.vrrp:静态网关虚拟协议,在两个路由器之间虚拟出一个IP地址,当一个路由器损坏时,自动将虚拟出的IP地址移动到另外一台路由器上 Keepalived 组件 用户空间核心组件vrrp stack 消息通告组件,用来广播虚拟的ip地址在自己这里checkers 监测组件,监测后端服务器的存活状态system call 标记realserver权重SMTP 邮件组

2.1【基本路由原理】数据转发原理3

数据转发原理 //抓包看ARP的报文结构: 注意Opcode:  1=request  (ARP)        2=reply(ARP) 3=request(RARP)        4=reply(RARP) ***************************************************************************** 普通ARP   ##普通ARP的request报文:   广播(获取目的IP地址的MAC): 目的收到request报文,先检查二

ARP地址解析协议&lt;四&gt;——ARP地址规格参数和通用地址及报文格式

1.ARP的基本操作: 就是本地网络中的一对请求和响应的传输. 理解:源(要发送IP数据报的设备)发送一个包含目的地(接收数据报的一方)信息的广播,目的地则使用单播向该源发回一个响应,告诉源那个目的地的MAC地址. 2.ARP报文类型: 首先,在ARP中发送了2种不同的报文,分别是,从源到目的地和从目的地到源.发送方是发送报文,目标方是接收报文.发送方和目标方的身份对每个报文都不一样,根据具体的情况而定. 3.发送方和目标方的身份是如何用于请求和回答的呢? 首先,再先介绍4个关键词: 请求.回答