#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;
}
######请问这是怎么回事?