📄 fvenumnet.cpp
字号:
// FVEnumNet.cpp : implementation file
//
#include "stdafx.h"
#include "FVEnumNet.h"
#include "arp.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern HINSTANCE g_hInsGJEnumNetDLL;
/////////////////////////////////////////////////////////////////////////////
// CFVEnumNet
IMPLEMENT_DYNCREATE(CFVEnumNet, CFormView)
CFVEnumNet::CFVEnumNet(CString strDllFile)
: CFormView(CFVEnumNet::IDD),m_strDllFile(strDllFile)
{
//{{AFX_DATA_INIT(CFVEnumNet)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
CFVEnumNet::~CFVEnumNet()
{
}
void CFVEnumNet::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CFVEnumNet)
DDX_Control(pDX, IDC_STATIC_FUNCTION, m_oHsTitle);
DDX_Control(pDX, IDC_STATIC_XBK, m_oHGif);
DDX_Control(pDX, IDC_TREE, m_oTree);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CFVEnumNet, CFormView)
//{{AFX_MSG_MAP(CFVEnumNet)
ON_WM_SIZE()
//}}AFX_MSG_MAP
ON_MESSAGE(UM_ENUM_NET, OnEnumNet)
ON_MESSAGE(UM_CLK_TREE_ITEM, OnTreeItemChanged)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFVEnumNet diagnostics
#ifdef _DEBUG
void CFVEnumNet::AssertValid() const
{
CFormView::AssertValid();
}
void CFVEnumNet::Dump(CDumpContext& dc) const
{
CFormView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CFVEnumNet message handlers
void CFVEnumNet::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
if(m_oHGif.Load(MAKEINTRESOURCE(IDR_EARTH),"GIF",g_hInsGJEnumNetDLL)){
m_oHGif.SetBkColor(RGB(255,255,255));
m_oHGif.Draw();
}
CString strText,str;
m_oHsTitle.GetWindowText(str);
BOOL bFromNet=(m_strDllFile.Find(STR_XBKR_PROTOCAL_HEAD,0)>=0);
strText.Format(" %s(%s版)",str,(bFromNet?"网络":"单机"));
strText+=" ";
strText+=" ";
m_oHsTitle.SetWindowText(strText);
m_oHsTitle.SetFontColor(RGB(255,255,255));
m_oHsTitle.SetFontHeight(25);
m_oHsTitle.SetFontWeight(400);
m_oHsTitle.SetBkColor(GetSysColor(COLOR_3DDKSHADOW));
m_oHsTitle.SetWindowPos(NULL,40,8,1800,26,SWP_SHOWWINDOW);
EnumNetCard();
}
int CFVEnumNet::EnumNetCard()
{
HTREEITEM hRoot=m_oTree.InsertItem("网络适配器");
m_oTree.SetItemData(hRoot,ITEM_DATA_ROOT);
pcap_if_t *alldevs=NULL;
pcap_if_t *pDvc=NULL;
pcap_addr_t *pAdr=NULL;
char szErr[PCAP_ERRBUF_SIZE+1];
if(-1==pcap_findalldevs(&alldevs,szErr)){// 取设备列表
AfxPromptBox(szErr);
return -1;
}
int nCount=0;
CString str;
pDvc=alldevs;
while(NULL!=pDvc){
if(NULL==pDvc->description){
pDvc=pDvc->next;
continue;
}
nCount++;
str=pDvc->description;
str.TrimRight();
HTREEITEM hItem=m_oTree.InsertItem(str,hRoot);
m_oTree.SetItemData(hItem,ITEM_DATA_CARD);
while(1){
pAdr=pDvc->addresses;
if(NULL==pAdr){
str="没有地址";
break;
}
if(AF_INET!=pAdr->addr->sa_family){
str="不是IP地址类型";
break;
}
DWORD dwLocalIP=((struct sockaddr_in *)pAdr->addr)->sin_addr.s_addr;
if('0'==ipTostr(dwLocalIP)[0]){
str="该适配器连接不正常";
break;
}
if(!g_gotMac){
g_chLocalMac=getSelfMac(pDvc->name,dwLocalIP);
}
if(!g_gotMac){
str="该适配器工作不正常";
break;
}
str.Format("%s[NetMask:%s](单击查找此局网内的活动主机)",ipTostr(dwLocalIP),
ipTostr(((struct sockaddr_in *)pAdr->netmask)->sin_addr.s_addr));
break;
}
HTREEITEM h=m_oTree.InsertItem(str,hItem);
m_oTree.SetItemData(h,ITEM_DATA_DOMAIN);
pDvc=pDvc->next;
}
pcap_freealldevs(alldevs);
return nCount;
}
void CFVEnumNet::SetControlPos()
{
CRect rc,rcTree,rcBnEnum;
GetClientRect(&rc);
int nH=rc.Height();
int nW=rc.Width();
rcTree=rc;
rcTree.top+=45;
rcTree.bottom-=3;
if(m_oTree.GetSafeHwnd()!=NULL)
m_oTree.MoveWindow(rcTree);
}
void CFVEnumNet::OnSize(UINT nType, int cx, int cy)
{
CFormView::OnSize(nType, cx, cy);
SetControlPos();
}
LRESULT CFVEnumNet::OnTreeItemChanged(WPARAM wParam, LPARAM lParam)
{
if(ITEM_DATA_DOMAIN!=wParam)return 0;
CTreeItemSelChangedParm p=*(CTreeItemSelChangedParm*)lParam;
CString str=p.m_strPath;
CString strDvc=AnalysisAddress(str);
str.Replace(strDvc,"");
str.TrimLeft('\\');
strDvc=AnalysisAddress(str);
pcap_if_t* alldevs = 0;
pcap_if_t* pDvc = 0;
pcap_addr_t* pAdr = 0;
char szErr[PCAP_ERRBUF_SIZE + 1];
if(-1==pcap_findalldevs(&alldevs,szErr)){// 取设备列表
AfxPromptBox(szErr);
return -1;
}
pDvc=alldevs;
while(NULL!=pDvc){
if(NULL==pDvc->description){
pDvc=pDvc->next;
continue;
}
str=pDvc->description;
str.TrimRight();
if(str==strDvc)break;
pDvc=pDvc->next;
}
if(NULL==pDvc)return 0;
SQueryParam qp;
qp.pDvc=pDvc;
qp.hItem=p.m_hItem;
qp.pWnd=this;
g_bThreadWaitingStop=0;
AfxBeginThread(ThreadWaiting,&qp);
MessageLoop();//交出CPU,线程完成初始化
AfxBeginThread(ThreadQuery,pDvc);
return 1;
}
UINT CFVEnumNet::ThreadQuery(LPVOID lParam)
{
//对选中设备的所有绑定的IP网段进行ARP请求
sendArpReq((pcap_if_t*)lParam,g_chLocalMac);
return 0;
}
UINT CFVEnumNet::ThreadWaiting(LPVOID lParam)
{
SQueryParam qp;
qp.pWnd=((SQueryParam*)lParam)->pWnd;
qp.hItem=((SQueryParam*)lParam)->hItem;
qp.pDvc=((SQueryParam*)lParam)->pDvc;
char szErr[PCAP_ERRBUF_SIZE+1];
//arp包最大长度是60,节省内存资源,不设为65536!并且只接收发往本机的ARP包,
//由过滤器与非混杂模式两个条件决定
pcap_t *pAdaptHandle=pcap_open_live(qp.pDvc->name,60,0,100,szErr);
if (NULL==pAdaptHandle){
CHGeneric::AfxPromptBox("无法打开适配器,可能与之不兼容!\n%s",szErr);
return -1;
}
string ipWithMac[BUFFERSIZE];
bpf_program fcode;
usint arp_op = 0;
uchar* arp_sha = (uchar*)malloc(sizeof(uchar) * 6);
ulint arp_spa = 0;
struct pcap_pkthdr *header;
const u_char *pkt_data;
//这里可以加大过滤范围,因为本程序工作在共享介质的网内,不会太大
char* szFilter = "arp";//"ether proto\\arp";
if (pcap_compile(pAdaptHandle, &fcode, szFilter, 1, (ulint)(0xFFFFFF)) < 0){
AfxPromptBox("过滤条件语法错误!");
free(arp_sha);
return -1;
}
//设置过滤条件
if (pcap_setfilter(pAdaptHandle, &fcode) < 0){
AfxPromptBox("适配器与过滤条件不兼容!");
free(arp_sha);
return -1;
}
int nIdx = 0;
while(1){
if (g_bThreadWaitingStop) break;
if (0==pcap_next_ex(pAdaptHandle,&header,&pkt_data))continue;//空包,继续收一下包
ipWithMac[nIdx] = "";
memcpy(&arp_op, pkt_data + 20, 2);
memcpy(arp_sha, pkt_data + 22, 6);
memcpy(&arp_spa, pkt_data + 28, 4);
ipWithMac[nIdx] += ipTostr(arp_spa);
ipWithMac[nIdx] += "[MAC:";
ipWithMac[nIdx] += macTostr(arp_sha);
ipWithMac[nIdx] += "]";
//前三位是厂商ID,通常一个网络小环境买的网卡大多出自一厂,
for (int i = 5; i >= 0; i--){
if (arp_sha[i] != g_chLocalMac[i])break;
}
if(arp_op == htons(ARP_REPLY) && i + 1){
if (BUFFERSIZE==nIdx)nIdx=0;
if(NULL==qp.pWnd)break;
qp.pWnd->PostMessage(UM_ENUM_NET,0,
LPARAM(new CTreeItemSelChangedParm(qp.hItem,ITEM_DATA_DOMAIN,
((string)ipWithMac[nIdx]).c_str())));
}
}
free(arp_sha);
return 0;
}
LRESULT CFVEnumNet::OnEnumNet(WPARAM wParam, LPARAM lParam)
{
if(NULL==lParam)return 0;
CTreeItemSelChangedParm p=*(CTreeItemSelChangedParm*)lParam;
if(NULL!=m_oTree.GetChildItemByText(p.m_hItem,p.m_strPath))return 0;
m_oTree.InsertItem(p.m_strPath,p.m_hItem);
m_oTree.Invalidate();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -