📄 result.cpp
字号:
// Result.cpp : implementation file
//
#include "stdafx.h"
#include "LANDetect.h"
#include "Result.h"
#include <win32/libnet.h>
#include "ARP.h"
#include "MainFrm.h"
#include "Log.h"
#include <lm.h>
#include <lmmsg.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CResult dialog
HWND result_hnd;
BOOL pflag; //判断一条报文是否已处理完
//int num; //统计共收到几条报文
CResult::CResult(CWnd* pParent /*=NULL*/)
: CDialog(CResult::IDD, pParent)
{
//{{AFX_DATA_INIT(CResult)
m_send = _T("");
//}}AFX_DATA_INIT
}
void CResult::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CResult)
DDX_Control(pDX, IDC_LIST_RESULT, m_result);
DDX_Text(pDX, IDC_EDIT_SEND, m_send);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CResult, CDialog)
//{{AFX_MSG_MAP(CResult)
ON_BN_CLICKED(IDC_START, OnStart)
ON_BN_CLICKED(IDC_BUTTON_STOP, OnButtonStop)
ON_BN_CLICKED(IDC_BUTTON_LOG, OnButtonLog)
ON_BN_CLICKED(IDC_BUTTON_SEND, OnButtonSend)
ON_BN_CLICKED(IDC_BUTTON_SENDALL, OnButtonSendall)
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CResult message handlers
BOOL CResult::OnInitDialog()
{
CDialog::OnInitDialog();
GetDlgItem(IDC_BUTTON_STOP)->EnableWindow(false);
GetDlgItem(IDC_START)->EnableWindow(true);
GetDlgItem(IDCANCEL)->EnableWindow(true);
GetDlgItem(IDC_BUTTON_LOG)->EnableWindow(true);
GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(false);
GetDlgItem(IDC_BUTTON_SENDALL)->EnableWindow(false);
DWORD dwStyle=GetWindowLong(m_result.GetSafeHwnd(),GWL_STYLE);
dwStyle&=~LVS_TYPEMASK;
dwStyle|=LVS_REPORT;
SetWindowLong(m_result.GetSafeHwnd(),GWL_STYLE,dwStyle);
m_result.InsertColumn(0,"IP地址",LVCFMT_LEFT,120);
m_result.InsertColumn(1,"主机MAC地址",LVCFMT_LEFT,180);
m_result.InsertColumn(2,"时间",LVCFMT_LEFT,180);
m_result.SetExtendedStyle(LVS_EX_GRIDLINES);
::SendMessage(m_result.m_hWnd, LVM_SETEXTENDEDLISTVIEWSTYLE,
LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
result_hnd=GetDlgItem(IDC_LIST_RESULT)->m_hWnd; //获得控件的句柄
m_send="请停止监测,并尽快与管理员取得联系,否则将停止你的网络访问权限!";
UpdateData(false);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CResult::Insert(CString ip,CString mac_str,CString time)
{
m_result.m_hWnd=result_hnd;
m_result.InsertItem(0,ip,0);
m_result.SetItemText(0,1,mac_str);
m_result.SetItemText(0,2,time);
if(m_db.IsOpen())
m_db.Close();
CString sql;
sql="select * from Record";
m_db.Open(CRecordset::dynaset,_T(sql));
m_db.AddNew();
//m_db.m_Sno=1;
m_db.m_DIP=ip;
m_db.m_DMAC=mac_str;
m_db.m_DTimes=time;
m_db.Update();
m_db.Requery();
}
/*
=======================================================================================================================
下面是实现ARP协议分析的函数,函数类型与回调函数相同
=======================================================================================================================
*/
void arp_protocol_packet_callback(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content)
{
struct arp_header *arp_protocol;
u_short operation_code;
struct in_addr source_ip_address;
u_char *mac_string;
arp_protocol = (struct arp_header*)(packet_content + 14);
operation_code = ntohs(arp_protocol->arp_operation_code);
CString filter_ip;
filter_ip.Format("%d.%d.%d.%d",m1[0],m1[1],m1[2],1);
memcpy((void*) &source_ip_address, (void*) &arp_protocol->arp_source_ip_address, sizeof(struct in_addr));
CString ip,mac,time;
ip=inet_ntoa(source_ip_address);
mac_string = arp_protocol->arp_source_ethernet_address;
CString mac_str;
mac_str.Format("%02x-%02x-%02x-%02x-%02x-%02x", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));
if(operation_code == 2&&filter_ip!=ip)
{
SYSTEMTIME st = {0};
GetLocalTime(&st);//获得当前本地时间
time.Format("%d-%d-%d %d:%d:%d",st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond);
CResult p;
p.Insert(ip,mac_str,time);
Sleep(500);
}
}
UINT ReceivePacket(LPVOID param)
{
pcap_t *pcap_handle;
/* Winpcap句柄 */
char error_content[PCAP_ERRBUF_SIZE];
/* 存储错误信息 */
struct bpf_program bpf_filter;
/* BPF过滤规则 */
char *bpf_filter_string;
CString filt = "dst host "+myIP+" and arp";
bpf_filter_string=(char *)(LPCSTR)filt;
/* 过滤规则字符串 */
bpf_u_int32 net_ip;
/* 网路地址 */
if((pcap_handle=pcap_open_live(dev->name,65536,1,1000,error_content))==NULL){//若网卡无法绑定
AfxMessageBox("网卡打开失败!");
return -1;
}
/* 打开网路接口,设成混杂模式 */
pcap_compile(pcap_handle, &bpf_filter, bpf_filter_string, 0, net_ip);
/* 编译BPF过滤规则 */
pcap_setfilter(pcap_handle, &bpf_filter);
/* 设置过滤规则 */
if (pcap_datalink(pcap_handle) != DLT_EN10MB)
return 0;
do{
pcap_loop(pcap_handle, 1, arp_protocol_packet_callback, NULL);
}
while(!pflag);
/* 注册回调函数,循环捕获网络数据包,利用回调函数来处理每个数据包 */
pcap_close(pcap_handle);
/* 关闭Winpcap操作 */
return 0;
}
UINT SendPacket(LPVOID param) //发送报文
{
libnet_t *l;
libnet_ptag_t protocol_tag;
char *device=NULL;
char error_information[LIBNET_ERRBUF_SIZE];
char *destination_ip_str; //目的IP地址
char *source_ip_str=(char *)(LPCSTR)myIP;
u_char hardware_source[6]={0x00,0x1A,0x6B,0x5D,0x43,0x70};
u_char hardware_destination[6];
u_long destination_ip;
u_long source_ip;
CString ip_src,ip_dst; //IP地址范围
ip_src.Format("%d.%d.%d.%d",int(m1[0]),int(m1[1]),int(m1[2]),int(m1[3]));
ip_dst.Format("%d.%d.%d.%d",int(m2[0]),int(m2[1]),int(m2[2]),int(m2[3]));
for(int i=1;i<=6;i++) //获取MAC地址
{
hardware_destination[i-1]=GetMAC(i,bmac);
}
//判断需要发的包
if(check==0)
{
destination_ip_str=(char *)(LPCSTR)ip_src;
destination_ip=libnet_name2addr4(l,destination_ip_str,LIBNET_RESOLVE);
source_ip=libnet_name2addr4(l,source_ip_str,LIBNET_RESOLVE);
l=libnet_init(
LIBNET_LINK_ADV,
device,
error_information);
protocol_tag=libnet_build_arp(
ARPHRD_ETHER,
ETHERTYPE_IP,
6,
4,
ARPOP_REQUEST,
hardware_source,
(u_int8_t *)&source_ip,
hardware_destination,
(u_int8_t *)&destination_ip,
NULL,
0,
l,
0
);
protocol_tag=libnet_autobuild_ethernet(
hardware_destination,
ETHERTYPE_ARP,
l
);
libnet_write(l);
libnet_destroy(l);
}
else
{
BYTE TEMP1[4],TEMP2[4];
for(int i=0;i<4;i++)
{
TEMP1[i]=m1[i];
TEMP2[i]=m2[i];
}
do
{
destination_ip_str=(char *)(LPCSTR)ip_src;
destination_ip=libnet_name2addr4(l,destination_ip_str,LIBNET_RESOLVE);
source_ip=libnet_name2addr4(l,source_ip_str,LIBNET_RESOLVE);
l=libnet_init(
LIBNET_LINK_ADV,
device,
error_information);
protocol_tag=libnet_build_arp(
ARPHRD_ETHER,
ETHERTYPE_IP,
6,
4,
ARPOP_REQUEST,
hardware_source,
(u_int8_t *)&source_ip,
hardware_destination,
(u_int8_t *)&destination_ip,
NULL,
0,
l,
0
);
protocol_tag=libnet_autobuild_ethernet(
hardware_destination,
ETHERTYPE_ARP,
l
);
libnet_write(l);
libnet_destroy(l);
if(TEMP1[2]<=TEMP2[2])
{
if(TEMP1[3]<TEMP2[3])
TEMP1[3]++;
else if(TEMP1[2]<TEMP2[2]&&TEMP1[3]<255)
TEMP1[3]++;
else if(TEMP1[2]<TEMP2[2]&&TEMP1[3]==255)
{
TEMP1[3]=0;
TEMP1[2]++;
}
ip_src.Format("%d.%d.%d.%d",int(TEMP1[0]),int(TEMP1[1]),int(TEMP1[2]),int(TEMP1[3]));
}
else
break;
if(TEMP1[3]>=TEMP2[3]&&TEMP1[2]>=TEMP2[2])
break;
}
while(TEMP1[2]<=255&&TEMP1[3]<=255);
}
Sleep(1000);
//SetEnd();
return 0;
}
CWinThread *r,*s;
void CResult::OnStart()
{
pflag=false;
m_result.DeleteAllItems();
GetDlgItem(IDC_BUTTON_STOP)->EnableWindow(true);
GetDlgItem(IDC_START)->EnableWindow(false);
GetDlgItem(IDCANCEL)->EnableWindow(false);
GetDlgItem(IDC_BUTTON_LOG)->EnableWindow(false);
GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(false);
GetDlgItem(IDC_BUTTON_SENDALL)->EnableWindow(false);
r=AfxBeginThread(AFX_THREADPROC(ReceivePacket),(LPVOID)this);//启动收包线程
if(frequency==0)
s=AfxBeginThread(AFX_THREADPROC(SendPacket),(LPVOID)this);
else
{
s=AfxBeginThread(AFX_THREADPROC(SendPacket),(LPVOID)this);
if(!pflag)
SetTimer(1,sec*1000,NULL);
else
return;
}
}
void CResult::OnCancel()
{
// TODO: Add extra cleanup here
if(r!=NULL)
{
TerminateThread(r->m_hThread,0);
CloseHandle(r->m_hThread);
}
if(s!=NULL)
{
TerminateThread(s->m_hThread,0);
CloseHandle(s->m_hThread);
}
CDialog::OnCancel();
}
void CResult::OnButtonStop()
{
pflag=true; //设置标志结束
GetDlgItem(IDC_BUTTON_STOP)->EnableWindow(false);
GetDlgItem(IDC_START)->EnableWindow(true);
GetDlgItem(IDCANCEL)->EnableWindow(true);
GetDlgItem(IDC_BUTTON_LOG)->EnableWindow(true);
GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(true);
GetDlgItem(IDC_BUTTON_SENDALL)->EnableWindow(true);
if(r!=NULL)
{
TerminateThread(r->m_hThread,0);
CloseHandle(r->m_hThread);
}
if(s!=NULL)
{
TerminateThread(s->m_hThread,0);
CloseHandle(s->m_hThread);
}
}
void CResult::OnButtonLog()
{
CLog dlg;
dlg.DoModal();
}
void CResult::OnButtonSend()
{
POSITION pos=m_result.GetFirstSelectedItemPosition();
if(pos==NULL)
{
AfxMessageBox("请从监测结果列表中选择一项!");
return;
}
int SelIndex = m_result.GetNextSelectedItem(pos);
CString str; //记录要发送的主机IP
str=m_result.GetItemText(SelIndex,0);
UpdateData(true);
wchar_t wszbuf[500];
wchar_t wsztarget[20];
int len=MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,str,-1,NULL,0);
MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,str,-1,wsztarget,len);
len=MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,m_send,-1,NULL,0);
MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,m_send,-1,wszbuf,len);
NetMessageBufferSend(NULL,wsztarget,NULL,(LPBYTE)wszbuf,m_send.GetLength());
AfxMessageBox("发送成功!");
}
void CResult::OnButtonSendall()
{
UpdateData(true);
if(m_result.GetItemCount()==0)
{
AfxMessageBox("列表中无待发送主机!");
return;
}
wchar_t wszbuf[500];
wchar_t wsztarget[20];
int len=MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,m_send,-1,NULL,0);
MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,m_send,-1,wszbuf,len);
for(int i=0;i<m_result.GetItemCount();i++)
{
CString str; //获取IP
str=m_result.GetItemText(i,0);
len=MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,str,-1,NULL,0);
MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,str,-1,wsztarget,len);
NetMessageBufferSend(NULL,wsztarget,NULL,(LPBYTE)wszbuf,m_send.GetLength());
}
AfxMessageBox("发送成功!");
}
void CResult::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
s=AfxBeginThread(AFX_THREADPROC(SendPacket),(LPVOID)this);
CDialog::OnTimer(nIDEvent);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -