分享
 
 
 

VC中ARP 的开发

王朝vc·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

下面我举个填充包头的例子,我首先定义个了一个转换字符的函数,如下

/****************************************************************************

* Name & Params::

* formatStrToMAC

* (

* const LPSTR lpHWAddrStr : 用户输入的MAC地址字符串

* unsigned char *HWAddr : 返回的MAC地址字符串(赋给数据包结构体)

* )

* Purpose:

* 将用户输入的MAC地址字符转成数据包结构体需要的格式

****************************************************************************/

void formatStrToMAC(const LPSTR lpHWAddrStr, unsigned char *HWAddr)

{

unsigned int i, index = 0, value, temp;

unsigned char c;

_strlwr(lpHWAddrStr); // 转换成小写

for (i = 0; i < strlen(lpHWAddrStr); i++)

{

c = *(lpHWAddrStr + i);

if (( c>='0' && c<='9' ) || ( c>='a' && c<='f' ))

{

if (c>='0' && c<='9') temp = c - '0'; // 数字

if (c>='a' && c<='f') temp = c - 'a' + 0xa; // 字母

if ( (index % 2) == 1 )

{

value = value*0x10 + temp;

HWAddr[index/2] = value;

}

else value = temp;

index++;

}

if (index == 12) break;

}

}

// 开始填充各个字段

ARPPACKET ARPPacket; // 定义ARPPACKET结构体变量

memset(&ARPPacket, 0, sizeof(ARPPACKET)); // 数据包初始化

formatStrToMAC(“DLC源MAC字符串”,ARPPacket.dlcHeader.SrcMAC); // DLC帧头

formatStrToMAC(“DLC目的MAC字符串”,ARPPacket.dlcHeader.DesMAC);

formatStrToMAC(“ARP源MAC字符串”,ARPPacket.arpFrame.Send_HW_Addr); // 源MAC

ARPPacket.arpFrame.Send_Prot_Addr = inet_addr(srcIP); // 源IP

formatStrToMAC(“ARP目的MAC字符串”,ARPPacket.arpFrame.Targ_HW_Addr); // 目的MAC

ARPPacket.arpFrame.Targ_Prot_Addr = inet_addr(desIP); // 目的IP

ARPPacket.arpFrame.Opcode = htons((unsigned short)arpType); // arp包类型

// 自动填充的常量

ARPPacket.dlcHeader.Ethertype = htons((unsigned short)0x0806); // DLC Header的以太网类型

ARPPacket.arpFrame.HW_Type = htons((unsigned short)1); // 硬件类型

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地址长度

That’s all ! ^_^

填充完毕之后,我们需要做的就是把我们的ARPPACKET结构体发送出去

2.发送ARP数据包:

我们发送ARP包就要用到winpcap的api了,具体步骤及函数是这样的,为了简单易懂,我把错误处理的地方都去掉了,详见代码

/**********************************************************************

* Name & Params::

* SendARPPacket()

* Purpose:

* 发送ARP数据包

* Remarks:

* 用的是winpcap的api函数

***********************************************************************/

void SendARPPacket()

{

char *AdapterDeviceName =GetCurAdapterName(); // 首先获得获得网卡名字

lpAdapter = PacketOpenAdapter(AdapterDeviceName); // 根据网卡名字打开网卡

lpPacket = PacketAllocatePacket(); // 给PACKET结构指针分配内存

PacketInitPacket(lpPacket, &ARPPacket, sizeof(ARPPacket)); //初始化PACKET结构指针

// 其中的ARPPacket就是我们先前填充的ARP包

PacketSetNumWrites(lpAdapter, 1); // 每次只发送一个包

PacketSendPacket(lpAdapter, lpPacket, true) // Send !!!!! ^_^

PacketFreePacket(lpPacket); // 释放资源

PacketCloseAdapter(lpAdapter);

}

呵呵,至此,关于ARP包最关键的部分就讲完了,你现在就可以来随心所欲的发送自己的ARP包了

既然作为一篇“科普文章”,接下来我再讲一讲与整个项目有关的附加步骤以及说明

三.附加步骤以及说明

1. 如何在VC中使用winpcap驱动

虽然winpcap开发包使用起来非常简便,但是前期准备工作还是要费一番功夫的,缺一不可。^_^

首先就是要安装它的驱动程序了,可以到它的主页下载,更新很快的

http://winpcap.polito.it/install/default.htm

下载WinPcap auto-installer (driver +DLLs),直接安装就好了,或者我提供的代码包里面也有。

希望以后用winpcap作开发的朋友,还需要下载 Developer's pack,解压即可。

然后,需要设置我们工程的附加包含目录为我们下载Developer's pack开发包的Inclulde目录,连接器的附加依赖库设置为Developer's pack的lib目录。

当然,因为我们的工作比较简单,就是借用winpcap发送数据包而已,所以只用从

winpcap开发包的include文件夹中,拷贝Packet32.h,到我们的工程来,并且包含它就可

以,但是要注意,Packet32.h本身还要包含一个Devioctl.h,也要一并拷贝进来,当然还有运

行库Packet.lib,一共就是需要拷贝3个文件了,如果加入库不用我多说了吧,在工程里面设

置,或者是在需要它的地方加入 #pragma comment(lib, "Packet.lib")了。

整个项目其实可以分为四个部分,填充数据包、发送数据包、枚举系统网卡列表和

相关信息以及枚举系统ARP缓存列表,下面我再讲一下如何获得系统的网卡以及ARP列

表,这两个部分都要用到IP Helper的api,所以要包含<Iphlpapi.h>以及库文件Iphlpapi.lib,

其实都是很简单的,只用寥寥几行就OK了

2. 枚举系统网卡以及信息

最好是先定义关于网卡信息的一个结构体,这样显得结构比较清晰

// 网卡信息

typedef struct tagAdapterInfo

{

char szDeviceName[128]; // 名字

char szIPAddrStr[16]; // IP

char szHWAddrStr[18]; // MAC

DWORD dwIndex; // 编号

}INFO_ADAPTER, *PINFO_ADAPTER;

/*********************************************************************

* Name & Params::

* AddAdapInfoToList

* (

* CListCtrl& list : CARPPlayerDlg传入的list句柄

* )

* Purpose:

* 获得系统的网卡信息,并将其添加到list控件中

* Remarks:

* 获得网卡IP及MAC用到了IpHelper api GetAdaptersInfo

******************************************************************/

void AddAdapInfoToList(CListCtrl& list)

{

char tempChar;

ULONG uListSize=1;

PIP_ADAPTER_INFO pAdapter; // 定义PIP_ADAPTER_INFO结构存储网卡信息

int nAdapterIndex = 0;

DWORD dwRet = GetAdaptersInfo((PIP_ADAPTER_INFO)&tempChar, &uListSize);//关键函数

if (dwRet == ERROR_BUFFER_OVERFLOW)

{

PIP_ADAPTER_INFO pAdapterListBuffer = (PIP_ADAPTER_INFO)new(char[uListSize]);

dwRet = GetAdaptersInfo(pAdapterListBuffer, &uListSize);

if (dwRet == ERROR_SUCCESS)

{

pAdapter = pAdapterListBuffer;

while (pAdapter) // 枚举网卡然后将相关条目添加到List中

{

// 网卡名字

CString strTemp = pAdapter->AdapterName;

strTemp = "\\Device\\NPF_" + strTemp; // 加上前缀

list.InsertItem(nAdapterIndex,strTemp);

strcpy(AdapterList[nAdapterIndex].szDeviceName,strTemp);

// IP

strcpy(AdapterList[nAdapterIndex].szIPAddrStr,

pAdapter->IpAddressList.IpAddress.String );

list.SetItemText(nAdapterIndex,1,AdapterList[nAdapterIndex].szIPAddrStr);

// MAC

formatMACToStr( AdapterList[nAdapterIndex].szHWAddrStr, pAdapter->Address );

list.SetItemText(nAdapterIndex,2,AdapterLis[nAdapterIndex].szHWAddrStr);

// 网卡编号

AdapterList[nAdapterIndex].dwIndex = pAdapter->Index;

pAdapter = pAdapter->Next;

nAdapterIndex ++;

}

delete pAdapterListBuffer;

}

}

}

2)获取ARP条目列表

// ARP条目信息

typedef struct tagARPInfo

{

char szIPAddrStr[16]; // IP

char szHWAddrStr[18]; // MAC

DWORD dwType; // 类型

}INFO_ARP, *PINFO_ARP;

/**********************************************************************

* Name & Params::

* AddARPInfoToList

* (

* CListCtrl& list : CARPPlayerDlg传入的list句柄

* const short nAdapterIndex : 用户选中的网卡编号

* )

* Purpose:

* 读入系统的ARP缓存列表,.并添加到对话框中

* Remarks:

* 用到了IpHelper api GetIpNetTable

* 而且用到了WinSock的api,所以要包含<WinSock2.h>

*****************************************************************/

void AddARPInfoToList(CListCtrl& list,const short nAdapterIndex)

{

char tempChar;

DWORD dwListSize = 1;

DWORD dwRet;

in_addr inaddr;

list.DeleteAllItems();

dwRet = GetIpNetTable((PMIB_IPNETTABLE)&tempChar, &dwListSize, TRUE); // 关键函数

if (dwRet == ERROR_INSUFFICIENT_BUFFER)

{

PMIB_IPNETTABLE pIpNetTable = (PMIB_IPNETTABLE)new(char[dwListSize]);

dwRet = GetIpNetTable(pIpNetTable, &dwListSize, TRUE);

if (dwRet == ERROR_SUCCESS)

{

for (int i=0; i<(int)pIpNetTable->dwNumEntries; i++)

{

// IP

inaddr.S_un.S_addr = pIpNetTable->table[i].dwAddr;

strcpy( ARPList[i].szIPAddrStr, inet_ntoa(inaddr) );

// MAC

formatMACToStr( ARPList[i].szHWAddrStr, pIpNetTable->table[i].bPhysAddr );

// Type

ARPList[i].dwType = pIpNetTable->table[i].dwType;

if (AdapterList[nAdapterIndex].dwIndex != pIpNetTable->table[i].dwIndex) continue;

list.InsertItem(i,ARPList[i].szIPAddrStr);

list.SetItemText(i,1,ARPList[i].szHWAddrStr);

switch(ARPList[i].dwType) { // 根据type的值来转换成字符显示

case 3:

list.SetItemText(i,2,"Dynamic");

break;

case 4:

list.SetItemText(i,2,"Static");

break;

case 1:

list.SetItemText(i,2,"Invalid");

default:

list.SetItemText(i,2,"Other");

}

}

}

delete pIpNetTable;

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有