www.pudn.com > checkUnusedIP.rar > CheckIPDlg.cpp


// CheckIPDlg.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "CheckIP.h" 
#include "CheckIPDlg.h" 
 
#include "pcap.h" 
#include "Iphlpapi.h" 
#include ".\checkipdlg.h" 
#pragma comment (lib,"Iphlpapi") 
#pragma comment (lib,"wpcap") 
 
#include "SetIPDialog.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
 
HANDLE ghCapture; 
 
///////////////////////////////////////////////////////////////////////////// 
 
//ARP包结构定义 
typedef struct arphdr 
{ 
 
   unsigned char      DesMAC[6];             /* destination HW addrress */ 
   unsigned char      SrcMAC[6];             /* source HW addresss */ 
   unsigned short     Ethertype;                /* ethernet type */ 
 
	unsigned short         HW_Type;           /* hardware address */ 
	unsigned short         Prot_Type;             /* protocol address */ 
	unsigned char      HW_Addr_Len;       /* length of hardware address */ 
	unsigned char      Prot_Addr_Len;         /* length of protocol address */ 
	unsigned short         Opcode;                /* ARP/RARP */ 
  
	unsigned char      Send_HW_Addr[6];     /* sender hardware address */ 
	unsigned char      Send_Prot_Addr[4];      /* sender protocol address */ 
 
	//这里有数据对齐的问题, 
	//不知道是怎么一回事 
	unsigned char      Targ_HW_Addr[6];     /* target hardware address */ 
	unsigned char      Targ_Prot_Addr[4];      /* target protocol address */ 
	unsigned char      padding[18]; 
 
 
}ARPHDR,*PARPHDR; 
 
 
////////////////////////////////////////////////////////////////////////// 
//填充MAC地址 
void SetSrcMac(char *chSrcMac,LPVOID lParam) 
 
{ 
	 
	CCheckIPDlg *l_DlgObj = (CCheckIPDlg *) lParam; 
	int iNumNID = l_DlgObj->m_ComBox.GetCurSel();	//获得ComboBox的选择 
	ULONG uListSize=1;	 
	int iNumTemp=0;								//和iNum比较的数 
 
	IP_ADAPTER_INFO temp; 
	CString strTest; 
	DWORD dwRet; 
 
 
	PIP_ADAPTER_INFO pAdapter; // 定义PIP_ADAPTER_INFO结构存储网卡信息 
 
	dwRet = GetAdaptersInfo((PIP_ADAPTER_INFO)&temp,&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) { 
				if (iNumTemp==iNumNID) { 
					memcpy(chSrcMac,pAdapter->Address,6);//对mac地址设定 
					delete pAdapterListBuffer; 
					return; 
				} 
				 
				pAdapter = pAdapter->Next; 
				iNumTemp++; 
			} 
			 
			delete pAdapterListBuffer; 
 
		} 
		else 
		{ 
			AfxMessageBox(_T("读取网卡MAC地址错误")); 
			delete pAdapterListBuffer; 
			return; 
		} 
 
	} 
	else 
	{ 
		strTest.Format("%d.%d",dwRet,uListSize); 
		AfxMessageBox(strTest); 
	} 
	return; 
 
} 
 
 
 
 
//ARP发送线程 
//功能:利用用户填写的IP地址作为目的地址发送ARP包 
// 
void StartARPSend (LPVOID lParam) 
{ 
	CCheckIPDlg *l_DlgObj = (CCheckIPDlg *) lParam; 
	DWORD dwIPStart; 
	DWORD dwIPEnd; 
 
	//得到用户填写的IP地址 
	l_DlgObj->m_IPAddrStart.GetAddress(dwIPStart);   
	l_DlgObj->m_IPAddrEnd.GetAddress(dwIPEnd);   
 
 
	//开始使用winpcap发送arp包 
	pcap_t * adhandle = NULL; 
	char errbuf[PCAP_ERRBUF_SIZE]; 
 
	pcap_if_t * alldevs; 
	pcap_if_t * l_dev; 
	int i=0; 
	int NICid = l_DlgObj->m_ComBox.GetCurSel()+1; //得到用户选择的网卡 
 
 
 
	//取得网络设备列表 
	if(pcap_findalldevs(&alldevs, errbuf) == -1) 
	{ 
		AfxMessageBox("Error in pcap_findalldevs"); 
		return; 
	} 
 
	l_dev=alldevs; 
	//得到选定的网络设备接口 
	for(int i=0;inext; 
	} 
 
 
	//打开指定的网卡设备,以供发送ARP包 
	if ((adhandle = pcap_open_live(l_dev->name, 
							65535, 
							1, 
							1000, 
							errbuf 
							)) == NULL) 
 
	{	 
		pcap_freealldevs(alldevs); 
		return ; 
	} 
 
	 
	//看起来太不爽了 
	//一定要改进 
 
	/* 
	//一个ARP request包的格式 
	ffffffffffff 
	00-0B-74-17-5C-D7  //我得mac地址 
	0806 
	0001 
	0800 
	06 
	04 
	0001 
	ffffffffffff		//源mac 
	c0a80001             //源IP地址 
	000000000000		//目的mac 
	c0a8039b			//目的IP地址 
	c027dae85010ff9b57710000202020202020  //随机 
	*/ 
 
	ARPHDR packet; 
	char NoChange[]=	 
	"\x08\x06" 
	"\x00\x01" 
	"\x08\x00" 
	"\x06" 
	"\x04" 
	"\x00\x01" 
	"\xff\xff\xff\xff\xff\xff"		//源mac 
	"\x40\x40\x40\x40"             //源IP地址 
	"\x00\x00\x00\x00\x00\x00"		//目的mac 
	//"\xc0\xa8\x03\x0a"			//目的IP地址 
	; 
 
	memset(packet.DesMAC,0xff,6);   //目的地址 
 
	//填写源MAC地址.用作路由的.必须填写真实MAC 
	 
	SetSrcMac((char *)packet.SrcMAC,lParam); 
	//memcpy(packet.SrcMAC,g_chSrcMac,6); 
	memcpy(&packet.Ethertype,NoChange,26); //协议之类得都不会改变 
	memset(packet.padding,20,18);       //随便什么值 
  
	//检测是否检测的IP开始地址比IP结束地址小 
 
	DWORD dwIPTemp; 
	if (dwIPStart > dwIPEnd) 
	{ 
		dwIPTemp  = dwIPEnd; 
		dwIPEnd = dwIPStart; 
		dwIPStart = dwIPTemp; 
	} 
 
	//等待捕获线程开始,再开始发包,不然前几个包有可能捕获不到 
	WaitForSingleObject(ghCapture,INFINITE); 
	//发送ARP包 
	DWORD dwIP; 
	for (dwIP=dwIPStart;dwIP<=dwIPEnd;dwIP++) 
	{ 
 
		//填充ARP包 
		//packet.Targ_Prot_Addr = dwIP;  //当初用unsigned long的时候有数据对齐的问题 
 
		DWORD dwIPSend; 
		dwIPSend = htonl(dwIP);	//进行转换 
		memcpy(packet.Targ_Prot_Addr,&dwIPSend,4); 
		if (pcap_sendpacket(adhandle, (unsigned char *)&packet, 60 /* size */) != 0) 
		{ 
			AfxMessageBox("Error sending the packet"); 
			return ; 
		} 
		Sleep(20); 
	} 
	//释放设备 
	pcap_freealldevs(alldevs); 
 
 
 
	//AfxMessageBox("Send Thread Sucess"); 
	return; 
 
 
} 
 
///////////////////////////////////////////////////////////////////////////// 
//线程函数 
 
//ARP包接收线程 
//功能:当发送ARP请求包之后启动,接收ARP reply,在规定时间内接收到返回的 
//就不是空闲IP 
void StartARPCapture(LPVOID lParam) 
{ 
	CCheckIPDlg *l_DlgObj = (CCheckIPDlg *) lParam; //得到对话框句柄 
	DWORD dwIPStart; 
	DWORD dwIPEnd; 
	DWORD *dwIP;          //用来定位list Control的 
	//得到用户填写的IP地址 
	l_DlgObj->m_IPAddrStart.GetAddress(dwIPStart);  //IP开始地址 
	l_DlgObj->m_IPAddrEnd.GetAddress(dwIPEnd);		//IP结束地址 
	////////////////////////////////////////////////////////////////////////// 
	//交换大小次序 
	DWORD dwIPTemp; 
	if (dwIPStart > dwIPEnd) 
	{ 
		dwIPTemp  = dwIPEnd; 
		dwIPEnd = dwIPStart; 
		dwIPStart = dwIPTemp; 
	} 
 
	//由查询IP的多少来判断要多少时间来捕获数据包 
	//最少是3000,很简单的算法,如果有时间测试一下,可以改进一下 
	DWORD dwTimeOut = (dwIPEnd-dwIPStart)*40; 
	if (dwTimeOut<3000) { 
		dwTimeOut = 3000; 
	} 
 
	////////////////////////////////////////////////////////////////////////// 
 
	ARPHDR *pARPPacket; 
	int NICid = l_DlgObj->m_ComBox.GetCurSel()+1; //得到用户选择的网卡 
	pcap_if_t *alldevs,*l_dev; 
	char errbuf[PCAP_ERRBUF_SIZE]; 
	pcap_t *fp=NULL; 
 
	int res; 
	struct pcap_pkthdr *header; 
	const u_char *pkt_data; 
 
	//取得网络设备列表 
	if(pcap_findalldevs(&alldevs, errbuf) == -1) 
	{ 
		AfxMessageBox("Error in pcap_findalldevs"); 
		return; 
	} 
 
	l_dev=alldevs; 
	//得到选定的网络设备接口 
	for(int i=0;inext; 
	} 
 
	if ( (fp= pcap_open_live(l_dev->name, 40, 0, 500, errbuf) ) == NULL) 
	{ 
		AfxMessageBox("PCAP error: Error opening the adapter"); 
		pcap_freealldevs(alldevs); 
		return; 
	} 
 
	u_int netmask; 
 
	char packet_filter[] = "arp" ;  //过滤规则,只接收ARP包 
 
	struct bpf_program fcode; 
 
	if(l_dev->addresses != NULL) 
		netmask = ((struct sockaddr_in *)(l_dev->addresses->netmask))->sin_addr.S_un.S_addr; 
	else 
		netmask = 0xffffff; 
 
 
	//编译过滤规则 
	if(pcap_compile(fp, &fcode, packet_filter, 1, netmask) < 0) 
	{ 
		//fprintf(stderr, "\nUnable to compile the packet filter. Check the syntax.\n"); 
		AfxMessageBox( "\nUnable to compile the packet filter. Check the syntax.\n"); 
		pcap_freealldevs(alldevs); 
		return; 
	} 
	//设定过滤规则 
	if(pcap_setfilter(fp, &fcode) < 0) 
	{ 
		fprintf(stderr, "\nError setting the filter.\n"); 
		pcap_freealldevs(alldevs); 
		return; 
	} 
 
	pcap_freealldevs(alldevs); 
 
	//得到当前时间,用来规定捕获包的时间 
	DWORD dwStartTime = GetTickCount(); 
 
 
	//设置ghCapture,让发包线程开始 
	SetEvent(ghCapture); 
	//开始捕获数据包 
	while((res = pcap_next_ex( fp, &header, &pkt_data)) >= 0){ 
 
		//判断超时的时间 
		if ((GetTickCount()-dwStartTime)>dwTimeOut) { 
			break; 
		}		 
 
 
		if(res == 0) 
			//超时,跳过继续接收 
			continue; 
 
		pARPPacket = (ARPHDR *)pkt_data; 
		//判断是否是ARP reply 
		if (pARPPacket->Opcode!=0x0200) { 
			continue; 
		} 
		//判断是否是ARP,其实不用的哈 
		if (pARPPacket->Ethertype!=0x0608) { 
			AfxMessageBox("not arp"); 
		} 
 
		//把得到的IP地址转换之后,由list control的index来判断是哪个IP返回了 
		//这里和列表控件结合非常紧密,注意 
		//还有就是这里应该尽量的少操作,提高包的捕获率 
		dwIP = (DWORD *)pARPPacket->Send_Prot_Addr; 
		l_DlgObj->m_MessageList.SetItemText(htonl(*dwIP)-dwIPStart,1,_T("已使用")); 
 
	} 
 
	if(res == -1){ 
		//接收的时候出现错误就直接返回 
		return; 
	} 
 
	CString strStata; 
	CString strIP; 
	int iNum=0;  //计数器 
	for (DWORD dwIPTemp=dwIPStart;dwIPTemp<=dwIPEnd;dwIPTemp++) 
	{ 
		strStata = l_DlgObj->m_MessageList.GetItemText((dwIPTemp-dwIPStart),1); 
 
		if (strStata.Compare("已使用"))  
		{ 
			//AfxMessageBox(strIP); 
			strIP = l_DlgObj->m_MessageList.GetItemText((dwIPTemp-dwIPStart),0); 
			l_DlgObj->m_MessageList.SetItemText((dwIPTemp-dwIPStart),1,_T("***")); 
			l_DlgObj->m_FreeIPList.InsertItem(iNum,strIP); 
			iNum++; 
		} 
 
	} 
 
	l_DlgObj->GetDlgItem(IDC_CHECK)->SetWindowText(_T("开始检查")); 
	l_DlgObj->GetDlgItem(IDC_CHECK)->EnableWindow(TRUE); 
	l_DlgObj->GetDlgItem(IDC_STOP)->EnableWindow(FALSE); 
	l_DlgObj->m_IPAddrStart.EnableWindow(TRUE); 
	l_DlgObj->m_IPAddrEnd.EnableWindow(TRUE); 
	pcap_close(fp); 
	return; 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CAboutDlg dialog used for App About 
 
class CAboutDlg : public CDialog 
{ 
public: 
	CAboutDlg(); 
 
// Dialog Data 
	//{{AFX_DATA(CAboutDlg) 
	enum { IDD = IDD_ABOUTBOX }; 
	//}}AFX_DATA 
 
	// ClassWizard generated virtual function overrides 
	//{{AFX_VIRTUAL(CAboutDlg) 
	protected: 
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support 
	//}}AFX_VIRTUAL 
 
// Implementation 
protected: 
	//{{AFX_MSG(CAboutDlg) 
	//}}AFX_MSG 
	DECLARE_MESSAGE_MAP() 
}; 
 
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) 
{ 
	//{{AFX_DATA_INIT(CAboutDlg) 
	//}}AFX_DATA_INIT 
} 
 
void CAboutDlg::DoDataExchange(CDataExchange* pDX) 
{ 
	CDialog::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(CAboutDlg) 
	//}}AFX_DATA_MAP 
} 
 
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) 
	//{{AFX_MSG_MAP(CAboutDlg) 
		// No message handlers 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CCheckIPDlg dialog 
 
CCheckIPDlg::CCheckIPDlg(CWnd* pParent /*=NULL*/) 
	: CDialog(CCheckIPDlg::IDD, pParent) 
	, m_strFreeIPAddr(_T("")) 
{ 
	//{{AFX_DATA_INIT(CCheckIPDlg) 
		// NOTE: the ClassWizard will add member initialization here 
	//}}AFX_DATA_INIT 
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32 
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); 
} 
 
void CCheckIPDlg::DoDataExchange(CDataExchange* pDX) 
{ 
	CDialog::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(CCheckIPDlg) 
	DDX_Control(pDX, IDC_IPADDRESS2, m_IPAddrEnd); 
	DDX_Control(pDX, IDC_IPADDRESS1, m_IPAddrStart); 
	//}}AFX_DATA_MAP 
	DDX_Control(pDX, IDC_LIST, m_MessageList); 
	DDX_Control(pDX, IDC_LIST1, m_FreeIPList); 
	DDX_Control(pDX, IDC_COMBO1, m_ComBox); 
	 
} 
 
BEGIN_MESSAGE_MAP(CCheckIPDlg, CDialog) 
	//{{AFX_MSG_MAP(CCheckIPDlg) 
	ON_WM_SYSCOMMAND() 
	ON_WM_PAINT() 
	ON_WM_QUERYDRAGICON() 
	ON_BN_CLICKED(IDC_CHECK, OnCheck) 
	//}}AFX_MSG_MAP 
//	ON_BN_CLICKED(IDCANCEL, OnBnClickedCancel) 
ON_BN_CLICKED(IDC_STOP, OnBnClickedStop) 
//ON_NOTIFY(NM_RDBLCLK, IDC_LIST1, OnNMRdblclkList1) 
//ON_NOTIFY(NM_DBLCLK, IDC_LIST1, OnNMDblclkList1) 
ON_NOTIFY(NM_DBLCLK, IDC_LIST1, OnNMDblclkList1) 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CCheckIPDlg message handlers 
 
BOOL CCheckIPDlg::OnInitDialog() 
{ 
	CDialog::OnInitDialog(); 
 
	// Add "About..." menu item to system menu. 
 
	// IDM_ABOUTBOX must be in the system command range. 
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); 
	ASSERT(IDM_ABOUTBOX < 0xF000); 
 
	CMenu* pSysMenu = GetSystemMenu(FALSE); 
	if (pSysMenu != NULL) 
	{ 
		CString strAboutMenu; 
		strAboutMenu.LoadString(IDS_ABOUTBOX); 
		if (!strAboutMenu.IsEmpty()) 
		{ 
			pSysMenu->AppendMenu(MF_SEPARATOR); 
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); 
		} 
	} 
 
	// Set the icon for this dialog.  The framework does this automatically 
	//  when the application's main window is not a dialog 
	SetIcon(m_hIcon, TRUE);			// Set big icon 
	SetIcon(m_hIcon, FALSE);		// Set small icon 
	 
 
	//设置一个event来协调发包线程和捕获包线程 
	ghCapture = CreateEvent(NULL, TRUE, FALSE, NULL);//人工重置,开始为false 
 
	//设置IP状态列表 属性 
	m_MessageList.SetTextColor(RGB(0,0,0));                  //显示字体的颜色 
	DWORD dwStyle = m_MessageList.GetStyle(); 
	dwStyle |= LVS_EX_GRIDLINES |LVS_EX_FULLROWSELECT|LVS_SHOWSELALWAYS ; 
	m_MessageList.SetExtendedStyle(dwStyle); 
	m_MessageList.SetBkColor(RGB(240,247,233));             //选中此列是的颜色 
	 
	//插入列名称 
	m_MessageList.InsertColumn(0,"IP地址",LVCFMT_CENTER,100,0); 
	m_MessageList.InsertColumn(1,"状态",LVCFMT_CENTER,120,1); 
	 
	//设置空闲IP列表 属性 
	m_FreeIPList.SetTextColor(RGB(255,0,0));                  //显示字体的颜色 
	dwStyle = m_FreeIPList.GetStyle(); 
	dwStyle |= LVS_EX_GRIDLINES |LVS_EX_FULLROWSELECT|LVS_SHOWSELALWAYS ; 
	m_FreeIPList.SetExtendedStyle(dwStyle); 
	m_FreeIPList.SetBkColor(RGB(240,247,233));             //选中此列是的颜色 
 
	//插入列名称 
	m_FreeIPList.InsertColumn(0,"IP地址",LVCFMT_CENTER,90,0); 
	m_FreeIPList.InsertColumn(1,"双击可以直接指定IP",LVCFMT_CENTER,120,1);	 
   
	//初始化IP控件 
	CString  strIP="211.83.150.1";   
	DWORD  dwIP;   
	dwIP  =  inet_addr(strIP);   
	unsigned  char  *pIP  =  (unsigned  char*)&dwIP;   
	m_IPAddrStart.SetAddress(*pIP,  *(pIP+1),  *(pIP+2),  *(pIP+3)); 
 
	strIP="211.83.150.254";   
	dwIP  =  inet_addr(strIP);   
	unsigned  char  *pIP1  =  (unsigned  char*)&dwIP;   
	m_IPAddrEnd.SetAddress(*pIP1,  *(pIP1+1),  *(pIP1+2),  *(pIP1+3)); 
 
	//初始化comboBox控件 
	SetComBox(); 
 
	 
	return TRUE;  // return TRUE  unless you set the focus to a control 
} 
 
void CCheckIPDlg::OnSysCommand(UINT nID, LPARAM lParam) 
{ 
	if ((nID & 0xFFF0) == IDM_ABOUTBOX) 
	{ 
		CAboutDlg dlgAbout; 
		dlgAbout.DoModal(); 
	} 
	else 
	{ 
		CDialog::OnSysCommand(nID, lParam); 
	} 
} 
 
// If you add a minimize button to your dialog, you will need the code below 
//  to draw the icon.  For MFC applications using the document/view model, 
//  this is automatically done for you by the framework. 
 
void CCheckIPDlg::OnPaint()  
{ 
	if (IsIconic()) 
	{ 
		CPaintDC dc(this); // device context for painting 
 
		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); 
 
		// Center icon in client rectangle 
		int cxIcon = GetSystemMetrics(SM_CXICON); 
		int cyIcon = GetSystemMetrics(SM_CYICON); 
		CRect rect; 
		GetClientRect(&rect); 
		int x = (rect.Width() - cxIcon + 1) / 2; 
		int y = (rect.Height() - cyIcon + 1) / 2; 
 
		// Draw the icon 
		dc.DrawIcon(x, y, m_hIcon); 
	} 
	else 
	{ 
		CDialog::OnPaint(); 
	} 
} 
 
// The system calls this to obtain the cursor to display while the user drags 
//  the minimized window. 
HCURSOR CCheckIPDlg::OnQueryDragIcon() 
{ 
	return (HCURSOR) m_hIcon; 
} 
 
void CCheckIPDlg::OnCheck()  
{ 
 
	//清空列表 
	m_MessageList.DeleteAllItems(); 
	m_FreeIPList.DeleteAllItems(); 
	//设置按钮状态 
	GetDlgItem(IDC_CHECK)->SetWindowText(_T("正在检查")); 
	GetDlgItem(IDC_CHECK)->EnableWindow(FALSE); 
	GetDlgItem(IDC_STOP)->EnableWindow(TRUE); 
	m_IPAddrStart.EnableWindow(FALSE); 
	m_IPAddrEnd.EnableWindow(FALSE); 
	 
	//交换数据 
	UpdateData(TRUE); 
 
 
	DWORD dwIPStart; 
	DWORD dwIPEnd; 
 
	//得到用户填写的IP地址 
	m_IPAddrStart.GetAddress(dwIPStart);   
	m_IPAddrEnd.GetAddress(dwIPEnd);   
	 
	////////////////////////////////////////////////////////////////////////// 
	//交换大小次序 
	DWORD dwIPTemp; 
	if (dwIPStart > dwIPEnd) 
	{ 
		dwIPTemp  = dwIPEnd; 
		dwIPEnd = dwIPStart; 
		dwIPStart = dwIPTemp; 
	} 
	//最多两个C,也就是512个IP 
	if ((dwIPEnd-dwIPStart)>512) { 
		AfxMessageBox(_T("最多探测512台主机")); 
		//恢复个按钮状态!! 
		GetDlgItem(IDC_CHECK)->SetWindowText(_T("开始检查")); 
		GetDlgItem(IDC_CHECK)->EnableWindow(TRUE); 
		GetDlgItem(IDC_STOP)->EnableWindow(FALSE); 
		m_IPAddrStart.EnableWindow(TRUE); 
		m_IPAddrEnd.EnableWindow(TRUE); 
		return; 
	} 
 
	DWORD dwIP; 
	CString  strIP; 
	int nItem=0;//插入,和捕获线程共同发挥作用 
	//在IP状态列表中显示检测IP列表 
	for (dwIP=dwIPStart;dwIP<=dwIPEnd;dwIP++) 
	{ 
		unsigned  char  *pIP;   
		pIP  =  (unsigned  char*)&dwIP;   
		strIP.Format("%u.%u.%u.%u",*(pIP+3),  *(pIP+2),  *(pIP+1),  *pIP); 
		m_MessageList.InsertItem(nItem,strIP); 
		m_MessageList.SetItemText(nItem,1,_T("正在检测中...")); 
		nItem++; 
		strIP.Empty(); 
	} 
 
 
	//创建捕获ARP包线程 
	m_hCapture = CreateThread( 0,0,(LPTHREAD_START_ROUTINE)StartARPCapture,this,0,0 ); 
	if(m_hCapture==NULL) 
	{ 
		AfxMessageBox("Proccess Probe thread start failed !"); 
		return; 
	} 
	//创建ARP包发送线程 
	m_hSend = CreateThread( 0,0,(LPTHREAD_START_ROUTINE)StartARPSend,this,0,0 ); 
	if(m_hSend==NULL) 
	{ 
		AfxMessageBox("Proccess Probe thread start failed !"); 
		return; 
	} 
	 
 
	return ; 
	 
} 
 
//void CCheckIPDlg::OnBnClickedCancel() 
//{ 
// 
//} 
 
 
void CCheckIPDlg::OnBnClickedStop() 
{ 
	GetDlgItem(IDC_CHECK)->SetWindowText(_T("开始检查")); 
	GetDlgItem(IDC_CHECK)->EnableWindow(TRUE); 
	GetDlgItem(IDC_STOP)->EnableWindow(FALSE); 
	m_IPAddrStart.EnableWindow(TRUE); 
	m_IPAddrEnd.EnableWindow(TRUE); 
 
	if (m_hSend!=NULL) { 
		TerminateThread(m_hSend,0); 
 
	} 
	if (m_hSend!=NULL) { 
		TerminateThread(m_hCapture,0); 
	}	 
 
} 
 
// 设定ComboBox 
BOOL CCheckIPDlg::SetComBox() 
{ 
	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) { 
				m_ComBox.AddString(pAdapter->Description); 
				pAdapter = pAdapter->Next; 
			} 
			m_ComBox.SetCurSel(0); 
			delete pAdapterListBuffer; 
 
		} 
 
	} 
	 
	return 0; 
} 
 
 
 
void CCheckIPDlg::OnNMDblclkList1(NMHDR *pNMHDR, LRESULT *pResult) 
{ 
	//得到当前焦点的item号 
	UINT uCol = m_FreeIPList.GetHotItem(); 
	CString string = m_FreeIPList.GetItemText (uCol,0); 
	if (!string.IsEmpty()) { 
		//将得到的IP地址放入到public m_strFreeIPAddr中,以便打开的对话筐访问!! 
		m_strFreeIPAddr = string; 
		//激活修改IP对话框 
		CSetIPDialog dlg; 
		int nResponse = dlg.DoModal(); 
		if (nResponse == IDOK) 
		{ 
			//从注册表中读出"本地连接" 
			CString strNIDName = GetNIDName(); 
			if (strNIDName.IsEmpty()) 
			{ 
				AfxMessageBox(_T("读取网卡出现错误")); 
				return; 
			} 
			HKEY RootKey = HKEY_LOCAL_MACHINE; 
			CString strSubKey("SYSTEM\\ControlSet001\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\"); 
			strSubKey = strSubKey + strNIDName + "\\Connection"; 
			HKEY hKey; 
			CString strValueName("Name");  //键名 
			DWORD dwType=REG_SZ;  //类型 
			DWORD dwLength=256;   //长度 
			unsigned char chName [256]; 
 
			 
			if(RegOpenKeyEx(RootKey,strSubKey,0,KEY_READ,&hKey)==ERROR_SUCCESS) 
			{ 
				if(RegQueryValueEx(hKey,strValueName,NULL,&dwType,(unsigned char *)chName,&dwLength)!=ERROR_SUCCESS) 
				{ 
					AfxMessageBox("错误:无法查询有关的注册表信息"); 
					 
				} 
				RegCloseKey(hKey); 
			} 
			else 
			{ 
				AfxMessageBox("错误:无法打开有关的hKEY"); 
				 
			} 
			 
			//读取用户设定的IP,子网掩码,网关 
			CString strIPAddr,strIPMask,strIPGateWay; 
			unsigned  char  *pIP;   
			pIP  =  (unsigned  char*)&dlg.m_dwIPAddr;   
			strIPAddr.Format("%u.%u.%u.%u",*(pIP+3),  *(pIP+2),  *(pIP+1),  *pIP); //IP 
			pIP  =  (unsigned  char*)&dlg.m_dwIPMask;   
			strIPMask.Format("%u.%u.%u.%u",*(pIP+3),  *(pIP+2),  *(pIP+1),  *pIP); //掩码 
			pIP  =  (unsigned  char*)&dlg.m_dwIPGateWay;   
			strIPGateWay.Format("%u.%u.%u.%u",*(pIP+3),  *(pIP+2),  *(pIP+1),  *pIP);//网关 
 
			CString strCMD("pushd interface ip \r\nset address \""); 
			strCMD = strCMD + chName +"\" static"; 
			strCMD = strCMD + " " +strIPAddr; 
			strCMD = strCMD + " " +strIPMask; 
			strCMD = strCMD + " " +strIPGateWay +" 1"; 
			strCMD = strCMD + "\r\n"; 
			 
						 
			//读取用户设定的DNS 
			//首先判断check按钮是否被点住了 
			if (dlg.m_bIsButtonChecked) { 
				CString strIPPriDNS,strIPSecDNS,strIPThDNS; 
				   
				pIP  =  (unsigned  char*)&dlg.m_dwIPPriDNS;   
				strIPPriDNS.Format("%u.%u.%u.%u",*(pIP+3),  *(pIP+2),  *(pIP+1),  *pIP); //IP 
				pIP  =  (unsigned  char*)&dlg.m_dwIPSecDNS;   
				strIPSecDNS.Format("%u.%u.%u.%u",*(pIP+3),  *(pIP+2),  *(pIP+1),  *pIP); //掩码 
				pIP  =  (unsigned  char*)&dlg.m_dwIPThDNS;   
				strIPThDNS.Format("%u.%u.%u.%u",*(pIP+3),  *(pIP+2),  *(pIP+1),  *pIP);//网关	 
 
				//第一个DNS 
				strCMD +="set dns \""; 
				strCMD = strCMD + chName +"\" static"; 
				strCMD = strCMD + " " +strIPPriDNS; 
				strCMD +="\r\n"; 
 
				//第二个DNS 
				strCMD +="add dns \""; 
				strCMD = strCMD + chName +"\" "; 
				strCMD +=strIPSecDNS; 
				strCMD +="\r\n"; 
 
				//第三个DNS 
				strCMD +="add dns \""; 
				strCMD = strCMD + chName +"\" "; 
				strCMD +=strIPThDNS; 
			 
			} 
			strCMD +="\r\npopd";//结束标志 
			if (WriteToFile(strCMD)==FALSE) { 
				return; 
			} 
			WinExec("netsh -f C:\\interface_by_galihoo.txt",SW_HIDE); 
 
			 
		} 
		else if (nResponse == IDCANCEL) 
		{ 
			return; 
		} 
	} 
	*pResult = 0; 
	return; 
} 
 
 
//得到网卡的特定名称 
CString  CCheckIPDlg::GetNIDName() 
{ 
	char tempChar; 
	int iNum = m_ComBox.GetCurSel();	//获得ComboBox的选择 
	int iNumTemp=0;								//和iNum比较的数 
	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) { 
				if (iNumTemp==iNum) { 
					//AfxMessageBox(pAdapter->AdapterName);//对mac地址设定 
					return pAdapter->AdapterName; 
				} 
				pAdapter = pAdapter->Next; 
				iNumTemp++; 
			} 
			delete pAdapterListBuffer; 
 
		} 
		return CString(); 
 
	}	 
	return CString(); 
} 
 
 
 
BOOL CCheckIPDlg::WriteToFile(CString strCMD) 
{ 
	HANDLE hFile = CreateFile("C:\\interface_by_galihoo.txt", GENERIC_WRITE,FILE_SHARE_WRITE, NULL, 
			CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
 
		if (INVALID_HANDLE_VALUE != hFile) 
		{ 
			 
			DWORD dwBytesWriteded = 0; 
			 
			if (!WriteFile(hFile, strCMD, strCMD.GetLength(), &dwBytesWriteded, NULL)) 
			{ 
				AfxMessageBox(_T("文件写入错误")); 
				return FALSE; 
			} 
			CloseHandle(hFile); 
 
		} 
		else 
		{ 
			CloseHandle(hFile); 
			return FALSE; 
		} 
	return TRUE; 
}