www.pudn.com > NetScan.rar > NetScanView.cpp
// NetScanView.cpp : implementation of the CNetScanView class // #include "stdafx.h" #include "NetScan.h" #include "NetScanDoc.h" #include "NetScanView.h" #include "Ping.h" #include#include "Afxsock.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif extern volatile BOOL g_threadContral;//线程停止的标准,true为运行,false为停止; //-------端口扫描线程 声明-------- //CCriticalSection global_criticalsection; UINT PortScanThread(LPVOID pParam); struct _PORTSCANTHREADPARAM { unsigned int m_BBeginSegAddress; //该线程扫描的起始IP地址 unsigned int m_BEndSegAddress; //该线程扫描的终止IP地址 unsigned int timeout; //超时时间 CNetScanView *const dlg; //对话框指针 _PORTSCANTHREADPARAM(CNetScanView *d):dlg(d)//构造函数 { //dlg->SetWindowText("扫描端口!"); } }; _PORTSCANTHREADPARAM *param2=NULL;//全局的线程参数对象 volatile BOOL g_bStop;//线程停止的标准,true为运行,false为停止; ///////////////////////////////////////////////////////////////////////////// // CNetScanView IMPLEMENT_DYNCREATE(CNetScanView, CFormView) BEGIN_MESSAGE_MAP(CNetScanView, CFormView) //{{AFX_MSG_MAP(CNetScanView) ON_WM_CLOSE() ON_BN_CLICKED(IDC_BTN_START, OnBtnStart) //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CFormView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CFormView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CFormView::OnFilePrintPreview) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CNetScanView construction/destruction CNetScanView::CNetScanView() : CFormView(CNetScanView::IDD) { //{{AFX_DATA_INIT(CNetScanView) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // TODO: add construction code here m_run=0; m_timeout=100; for(int i=0;i<6;i++) m_Port[i]=0; m_uThreadNum=1; } CNetScanView::~CNetScanView() { } void CNetScanView::DoDataExchange(CDataExchange* pDX) { CFormView::DoDataExchange(pDX); //{{AFX_DATA_MAP(CNetScanView) DDX_Control(pDX, IDC_LIST1, m_ctrlList); //}}AFX_DATA_MAP } BOOL CNetScanView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs return CFormView::PreCreateWindow(cs); } void CNetScanView::OnInitialUpdate() { CFormView::OnInitialUpdate(); GetParentFrame()->RecalcLayout(); ResizeParentToFit(); if(AfxSocketInit(NULL)==FALSE)//初始化Socket { AfxMessageBox("Sorry,socket 失败!"); } g_bStop=true; g_threadContral=false; param2 = new _PORTSCANTHREADPARAM(this); SetUI(); } ///////////////////////////////////////////////////////////////////////////// // CNetScanView printing BOOL CNetScanView::OnPreparePrinting(CPrintInfo* pInfo) { // default preparation return DoPreparePrinting(pInfo); } void CNetScanView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add extra initialization before printing } void CNetScanView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add cleanup after printing } void CNetScanView::OnPrint(CDC* pDC, CPrintInfo* /*pInfo*/) { // TODO: add customized printing code here } ///////////////////////////////////////////////////////////////////////////// // CNetScanView diagnostics #ifdef _DEBUG void CNetScanView::AssertValid() const { CFormView::AssertValid(); } void CNetScanView::Dump(CDumpContext& dc) const { CFormView::Dump(dc); } CNetScanDoc* CNetScanView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CNetScanDoc))); return (CNetScanDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CNetScanView message handlers //DEL void CNetScanView::OnButton1() //DEL { //DEL //DEL } void CNetScanView::StartPing() {//运行ping程序 if(g_threadContral) { ((CButton *)GetDlgItem(IDC_BTN_START))->SetWindowText("开始ping"); g_threadContral=false; return; }else { ((CButton *)GetDlgItem(IDC_BTN_START))->SetWindowText("停止ping"); g_threadContral=true; //开始循环ping地址 CPing * pinger=new CPing(this); //设置Ping参数 pinger->SetConfigure(m_BBeginAddress,m_BEndAddress,m_pingNumber,m_timeout); //开始Ping pinger->ping(); return; } } void CNetScanView::StartPortScan() {//运行端口扫描程序 //开启一个新的扫描线程 if(g_bStop) { ((CButton *)GetDlgItem(IDC_BTN_START))->SetWindowText("停止扫描"); g_bStop=false; param2->m_BBeginSegAddress=m_BBeginAddress; param2->m_BEndSegAddress=m_BEndAddress; param2->timeout=m_timeout; AfxBeginThread(PortScanThread,(LPVOID)param2); }else { ((CButton *)GetDlgItem(IDC_BTN_START))->SetWindowText("开始扫描"); g_bStop=true; } } void CNetScanView::OnClose() { // TODO: Add your message handler code here and/or call default CFormView::OnClose(); } void CNetScanView::OnBtnStart() { switch(m_run) { case 0: break; case PING: StartPing(); break; case PORTSCAN: StartPortScan(); break; default: break; } } void CNetScanView::SetUI() {//设置用户界面 int i=0;//子项索引 LV_COLUMN lvcol; lvcol.mask=LVCF_FMT|LVCF_SUBITEM|LVCF_TEXT|LVCF_WIDTH; lvcol.fmt=LVCFMT_CENTER;//居中 m_ctrlList.DeleteAllItems(); if(m_run==0) { ((CButton *)GetDlgItem(IDC_BTN_START))->EnableWindow(false); return; } if(m_run==PING) { while(m_ctrlList.DeleteColumn(0))//删除所有列 { } //设置list控件的表头 i=0; lvcol.pszText="能ping通的IP地址";//ListCtrl第1项 lvcol.iSubItem=i; lvcol.cx=120; m_ctrlList.InsertColumn(i++,&lvcol); lvcol.pszText="返回时间";//ListCtrl第2项 lvcol.iSubItem=i; lvcol.cx=70; m_ctrlList.InsertColumn(i++,&lvcol); /* lvcol.pszText="seq";//ListCtrl第3项 lvcol.iSubItem=i; lvcol.cx=70; m_ctrlList.InsertColumn(i++,&lvcol); */ return; } if(m_run==PORTSCAN) { while(m_ctrlList.DeleteColumn(0))//删除所有列 { } //设置list控件的表头 i=0; lvcol.pszText="IP地址"; lvcol.iSubItem=i; lvcol.cx=120; m_ctrlList.InsertColumn(i++,&lvcol); lvcol.cx=80; if(m_Port[0]==80)//http { lvcol.pszText="HTTP(80)"; lvcol.iSubItem=i; m_ctrlList.InsertColumn(i++,&lvcol); } if(m_Port[1]==21)//ftp { lvcol.pszText="FTP(21)"; lvcol.iSubItem=i; m_ctrlList.InsertColumn(i++,&lvcol); } if(m_Port[2]==53)//dns { lvcol.pszText="DNS(53)"; lvcol.iSubItem=i; m_ctrlList.InsertColumn(i++,&lvcol); } if(m_Port[3]==25)//smtp { lvcol.pszText="SMTP(25)"; lvcol.iSubItem=i; m_ctrlList.InsertColumn(i++,&lvcol); } if(m_Port[4]==110)//pop3 { lvcol.pszText="POP3(110)"; lvcol.iSubItem=i; m_ctrlList.InsertColumn(i++,&lvcol); }if(m_Port[5]==161)//snmp { lvcol.pszText="SNMP(161)"; lvcol.iSubItem=i; m_ctrlList.InsertColumn(i++,&lvcol); } return; } } /*------------端口扫描技术------------------ * TCP connect() 扫描 *这是最基本的TCP扫描。操作系统提供的connect()系统调用,用来与每一个感兴趣的目标计算机的端口进行连接。 *如果端口处于侦听状态,那么connect()就能成功。否则,这个端口是不能用的,即没有提供服务。 *这个技术最大的优点是,不需要任何权限。系统中的任何用户都有权利使用这个调用。 *另一个好处就是速度。如果对每个目标端口以线性的方式,使用单独的connect()调用, *那么将会花费相当长的时间,你可以通过同时打开多个套接字,从而加速扫描。 *使用非阻塞I/O允许你设置一个低的时间用尽周期,同时观察多个套接字。 *但这种方法的缺点是很容易被发觉,并且被过滤掉。 *目标计算机的logs文件会显示一连串的连接和连接是出错的服务消息,并且能很快的使它关闭。 *-------------------------------------*/ //----------端口扫描函数------------ UINT PortScanThread(LPVOID pParam) { _PORTSCANTHREADPARAM* param=(_PORTSCANTHREADPARAM*)pParam; ASSERT(pParam); CNetScanView *dlg=param->dlg; int currentip[4]; unsigned int timeout=param->timeout; //UINT port; CString ip; CString result; unsigned int b,e,c; //将4个BYTE的地址转换成一个unsigned int型的地址,方便之后的操作 b=param->m_BBeginSegAddress; e=param->m_BEndSegAddress; //扫描每个IP地址 for(c=b;c<=e;c++) { if(g_bStop)//判断是否需要退出扫描 { break; } currentip[0]=(c&(255<<24))>>24; currentip[1]=(c&(255<<16))>>16; currentip[2]=(c&(255<<8))>>8; currentip[3]=c&255; //在将地址转换成一个字符串 ip.Format("%d.%d.%d.%d",currentip[0],currentip[1],currentip[2],currentip[3]); result=""; dlg->SetDlgItemText(IDC_S,"开始扫描 "+ip); //扫描每个端口 BOOL tempPort[6];//存储扫描后端口的状态,端口开放为true,关闭为false for(int i=0;i<6;i++) { if(g_bStop)//判断是否需要退出扫描 { break; } tempPort[i]=false; if(dlg->m_Port[i]!=0) { //开启socket正是扫描 CSocket socket; //创建socket if(socket.Create(0,SOCK_STREAM)==FALSE) { int error1=socket.GetLastError(); dlg->SetDlgItemText(IDC_S,"创建socket错误!"); //AfxMessageBox("socket create error!"); return 0; } /* //设置发送超时 if(setsockopt(socket,SOL_SOCKET,SO_SNDTIMEO, (char *)&timeout, sizeof(timeout))) { int error2=socket.GetLastError(); result.Format("%d",error2); dlg->SetDlgItemText(IDC_S,"设置发送Timeout错误!错误号="+result); return 0; } //设置接收超时 if(setsockopt(socket,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout, sizeof(timeout))) { int error3=socket.GetLastError(); result.Format("%d",error3); dlg->SetDlgItemText(IDC_S,"设置接收Timeout错误!错误号="+result); return 0; } */ result.Format("%d",dlg->m_Port[i]); result="正在扫描:"+ip+" 端口:"+result; if(socket.Connect(ip,dlg->m_Port[i])==FALSE) //连接对方 { int error2=socket.GetLastError(); TRACE("\n连接错误号:%d",error2); switch(error2) { case 10060: dlg->SetDlgItemText(IDC_S,result+" 连接超时!"); break; case 10061: dlg->SetDlgItemText(IDC_S,result+" 强行拒绝连接!"); break; default: dlg->SetDlgItemText(IDC_S,result+" 连接失败!"); break; } socket.Close(); continue; } else{ dlg->SetDlgItemText(IDC_S,result+" 连接成功!"); socket.Close(); tempPort[i]=true; } /* //发送数据 if(socket.SendTo("hello",6,dlg->m_Port[i],ip)==SOCKET_ERROR) { TRACE("%d\n",socket.GetLastError( )); dlg->SetDlgItemText(IDC_S,result+" 连接失败!"); socket.Close(); continue; }else { dlg->SetDlgItemText(IDC_S,result+" 连接成功!"); socket.Close(); tempPort[i]=true; } //接收对方该端口的反馈信息 char buffer[256]; memset(buffer,'\0',256); if(socket.Receive(buffer,256,0)==SOCKET_ERROR) { dlg->SetDlgItemText(IDC_S,result+" 关闭!"); socket.Close(); continue; }else { dlg->SetDlgItemText(IDC_S,result+" 开放!"); socket.Close(); tempPort[i]=true; continue; } */ } } //在列表控件里显示结果数据 if(true) { if(tempPort[0]||tempPort[1]||tempPort[2]|| tempPort[3]||tempPort[4]||tempPort[5]) { int isub=0; int iPos=0; LV_ITEM lvitem1; lvitem1.mask=LVIF_TEXT; lvitem1.iItem=1; lvitem1.iSubItem=isub++; lvitem1.pszText=ip.GetBuffer(16); iPos=dlg->m_ctrlList.InsertItem(&lvitem1);//返回表项插入后的索引号 for(int j=0;j<6;j++) if(dlg->m_Port[j]!=0) if(tempPort[j]) { lvitem1.iItem=iPos; lvitem1.iSubItem=isub++; lvitem1.pszText=_T("开启"); dlg->m_ctrlList.SetItem(&lvitem1);//返回表项插入后的索引号 } else { lvitem1.iItem=iPos; lvitem1.iSubItem=isub++; lvitem1.pszText=_T("关闭"); dlg->m_ctrlList.SetItem(&lvitem1);//返回表项插入后的索引号 } } } } dlg->SetDlgItemText(IDC_S,"结束扫描 "); ((CButton *)dlg->GetDlgItem(IDC_BTN_START))->SetWindowText("开始扫描"); g_bStop=true; return 0; }