arp_test.cpp

来自「发送ARP数据包的程序」· C++ 代码 · 共 328 行

CPP
328
字号
// ARP_test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

//全局变量
char *Ad_name = NULL;
libnet_t *G_l;
pcap_t *G_CPH;//抓包描述符句柄
HANDLE hThread_send;
HANDLE hThread_catch;

u_long G_tag_ip;
int G_flag = 0;
//全局函数
DWORD WINAPI CatchPacket(LPVOID lpParameter);
DWORD WINAPI SendPacket(LPVOID lpParameter);

char *iptos(u_long in)
{
	u_char *temp;
	char *num = (char *)malloc(16);
	int i = 0;
	temp = (u_char *)∈
	//for(i = 0; i < 4;i++)
	//	num[i] = *(temp + i);
	sprintf(num,"%d.%d.%d.%d",*temp,*(temp+1),*(temp+2),*(temp+3));
	return num;
}

int _tmain(int argc, _TCHAR* argv[])
{
	//wpcap
	int DeviceNumber;
	pcap_if_t *Devices;
	pcap_if_t *D;
	char errbuf[PCAP_ERRBUF_SIZE];


	//===============================================================
	//PROCESS_INFORMATION ProcessInfo; 
	//STARTUPINFO StartupInfo; //This is an [in] parameter
	//ZeroMemory(&StartupInfo, sizeof(StartupInfo));
	//StartupInfo.cb = sizeof StartupInfo ; //Only compulsory field
	//if(CreateProcess(_T("C:\\UI Library\\MAC_Filter\\MAC_Filter.exe"), NULL,NULL,NULL,FALSE,0,NULL,NULL,&StartupInfo,&ProcessInfo))
	//{ 
	//	WaitForSingleObject(ProcessInfo.hProcess,INFINITE);
	//	CloseHandle(ProcessInfo.hThread);
	//	CloseHandle(ProcessInfo.hProcess);
	//}  
	//else
	//{
	//	//MessageBox(_T("The process could not be started..."));
	//	cout<<"The process could not be started..."<<endl;
	//	//AfxMessageBox(_T("The process could not be started..."),0,0);
	//}
	////==================================================================
	//Sleep(45000);



	//读取设备信息列表的结构体
	if(pcap_findalldevs(&Devices,errbuf) == -1)
	{
		//AfxMessageBox(_T("pcap_findalldevs_ex出错了"),0,0);
		cout<<"pcap_findalldevs_ex出错了"<<endl;
		return -1;
	}
	//读取设备信息结构体成功后,list出来
	int count = 0;
	for(D = Devices;D != NULL; D = D->next)
	{
		//sz_Name = D->name;
		cout<<"[ "<<count+1<<" ]  "<<D->name<<endl;
		if(D->description != NULL)
			//sz_Describe = D->description;
			cout<<D->description<<endl;
		else 
			//sz_Describe = _T("该操作系统不支持描述信息");
			cout<<"该操作系统不支持描述信息"<<endl;

		count++;
	}
	if(count == 0)
	{
		//AfxMessageBox(_T("没有发现网络设备"),0,0);
		cout<<"没有发现网络设备"<<endl;
		return -1;
	}

	printf("请选择你要打开的设备接口,用于发送TCP Packet\n");
	
		//cin>>DeviceNumber;
		scanf("%d",&DeviceNumber);

		//	DeviceNumber = 2;

		if(DeviceNumber < 1 || DeviceNumber > count)
		{
			//cout<<"你所选择的设备接口已经超出了范围!请重新输入你所要发送的数据接口"<<endl;
			printf("你所选择的设备接口已经超出了范围!请重新输入你所要发送的数据接口\n");
			///* Free the device list */
			pcap_freealldevs(Devices);
			system("PAUSE");
			return -1;
		}

		//DeviceNumber = 2;
	
	//跳转到你所选择的数据接口处
    for(D = Devices, count = 0; count < DeviceNumber-1 ;D = D->next, count++);
	Ad_name = D->name;

	cout<<endl<<endl;
	cout<<::Ad_name<<endl;

	///-------------------------全局发包端口--------------------------
	::G_l = libnet_init(LIBNET_LINK,Ad_name,errbuf);
	if (G_l == NULL)
    {
        fprintf(stderr, "libnet_init() failed: %s", errbuf);
        system("PAUSE");
		return -1;
    }

	///-------------------------全局抓包端口--------------------
	if ((G_CPH = pcap_open(::Ad_name,65536,1,1000,NULL,errbuf)) == NULL)
	{
		cout<<"妈妈的那个接口打不开,晕!"<<Ad_name<<"不被WinPcap支持"<<endl;
		/* Free the device list */
		//AfxMessageBox(_T("NIC接口无法打开,")+error+_T("不被WinPcap支持"),0,0);
		return -1;
	}

	//hThread_catch = CreateThread(NULL,0,CatchPacket,NULL,0,NULL);
	//Sleep(50);
	CreateThread(NULL,0,SendPacket,NULL,0,NULL);

	system("PAUSE");
	return 0;
}

//------------抓取---------------------------
DWORD WINAPI CatchPacket(LPVOID lpParameter)
{
	//-----------------抓包变量	
	struct pcap_pkthdr *header;
	const u_char *pkt_data;
	ether_header *ether_h;
	arp_header *arp_h;

	u_long temp_src_ip;
	u_short temp_op_code;

	char errbuf[PCAP_ERRBUF_SIZE];
	int res;
	//过滤规则使用的变量
	u_int netmask;
	char *packet_filter = "arp";//之抓Router发来的端口
	struct bpf_program filter_code;		//编译处理过的过滤规则,函数调用时自动填入

	/* Check the link layer. We support only Ethernet for simplicity. */
	if(pcap_datalink(G_CPH) != DLT_EN10MB)
	{
		fprintf(stderr,"\nThis program works only on Ethernet networks.\n");
		//AfxMessageBox(_T("非以太网类型,该程序只能工作在以太网上!"),0,0);
		/* Free the device list */
		return -1;
	}
	
	//if(D->addresses != NULL)
	//	/* Retrieve the mask of the first address of the interface */
	//	netmask = ((struct sockaddr_in *)D->addresses->netmask)->sin_addr.s_addr;
	//else
		/* If the interface is without addresses we suppose to be in a C class network */
	netmask=0xffffff; 

	//compile the filter
	if (pcap_compile(G_CPH, &filter_code, packet_filter, 1, netmask) < 0 )
	{
		fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n");
		/* Free the device list */
		//AfxMessageBox(_T("过滤器编译失败!"),0,0);
		return -1;
	}
	
	//set the filter
	if (pcap_setfilter(G_CPH, &filter_code) < 0)
	{
		fprintf(stderr,"\nError setting the filter.\n");
		/* Free the device list */
		//AfxMessageBox(_T("过滤器设置失败!"),0,0);
		return -1;
	}

	//-===============================================
	while((res = pcap_next_ex(G_CPH,&header,&pkt_data)) >= 0)
	{
			if(res == 0)
            /* Timeout elapsed */
            continue;
		//========================================================================================================================
			{
					//解析packets的结构体
					//取得EtherNet头部
					//ether_h = (ether_header *)pkt_data;

					//u_short ethernet_type = 0;	
					//ethernet_type = ntohs(ether_h->Ethertype);

					//取得IP头部数据信息
					arp_h = (arp_header *)(pkt_data+14);

					u_char *src_ip_ch = (u_char *)((u_char *)arp_h + 14);
					temp_op_code = ntohs(arp_h->arp_operation_code);
					u_long temp_src_ip = *(u_long *)src_ip_ch;

					//char *temp_str_ip = ::iptos(temp_src_ip);
					//cout<<temp_str_ip<<endl;
					
					
					if(temp_op_code == 2&&temp_src_ip == ::G_tag_ip)//cout<<"test case pass!"<<endl;
					{
							cout<<"pass"<<endl;
							G_flag = 1;
					}
//========================================================================================================================
				if(res == -1)
				{
					printf("Error reading the packets: %s\n", pcap_geterr(::G_CPH));
					//AfxMessageBox(_T("数据表读取失败!"),0,0);
					return -1;
				}

			}
	}

	printf("catch OK!");
	system("PAUSE");
	ExitThread(0);
}

//-------------发送---------------------------
DWORD WINAPI SendPacket(LPVOID lpParameter)
{
	int c,jj;
    libnet_ptag_t t;
    char errbuf[LIBNET_ERRBUF_SIZE];

	struct libnet_ether_addr *ethaddr;
	u_long src_ip = 0;
	u_long dst_ip = 0;
	u_char enet_src[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
	u_char enet_dst[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
	//u_char arp_src[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
	//u_char arp_dst[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

	src_ip = inet_addr("192.168.1.1");//libnet_get_ipaddr4(l);
	G_tag_ip = dst_ip = inet_addr("192.168.1.2");

	ethaddr = libnet_get_hwaddr(G_l);
	for(jj = 0; jj < 6; jj++)
	{
		enet_src[jj] = ethaddr->ether_addr_octet[jj];
		//arp_src[jj] = ethaddr->ether_addr_octet[jj];
	}
	
  
    t = libnet_build_arp(
            ARPHRD_ETHER,                           /* hardware addr */
            ETHERTYPE_IP,                           /* protocol addr */
            6,                                      /* hardware addr size */
            4,                                      /* protocol addr size */
            1,//ARPOP_REPLY,ARPOP_REQUEST                            /* operation type */
            enet_src,                              /* sender hardware addr */
            (u_int8_t *)&src_ip,                         /* sender protocol addr */
            enet_dst,                               /* target hardware addr */
            (u_int8_t *)&dst_ip,                         /* target protocol addr */
            NULL,                                   /* payload */
            0,                                      /* payload size */
            G_l,                                      /* libnet context */
            0);                                     /* libnet id */
	if (t == -1)
	{
		fprintf(stderr, "Can't build ARP header: %s\n", libnet_geterror(G_l));
		system("PAUSE");
		return -1;
	}

	t = libnet_build_ethernet(
    enet_dst,                                   /* ethernet destination */
    enet_src,                                   /* ethernet source */
    ETHERTYPE_ARP,                               /* protocol type */
    NULL,                                       /* payload */
    0,                                          /* payload size */
    G_l,                                          /* libnet handle */
    0);                                         /* libnet id */
	if (t == -1)
	{
		fprintf(stderr, "Can't build ethernet header: %s\n", libnet_geterror(G_l));
		system("PAUSE");
		return -1;
	}


    c = libnet_write(G_l);
    if (c == -1)
    {
        fprintf(stderr, "Write error: %s\n", libnet_geterror(G_l));
       	system("PAUSE");
		return -1;
    }
    
	libnet_clear_packet(G_l);
	printf("send OK!");


	//Sleep(5000);
	//TerminateThread(hThread_catch,0);

	//if(G_flag == 1)
	//	cout<<"test case pass!"<<endl;
	//else
	//	cout<<"timeout over test case fial"<<endl<<endl;

	//cout<<"test end....!"<<endl;
    return (EXIT_SUCCESS);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?