zoukankan      html  css  js  c++  java
  • 网络抓包,协议分析,流量统计程序

    
    // YQPackageCaptureDlg.cpp : 实现文件
    //
    
    #include "stdafx.h"
    #include "YQPackageCapture.h"
    #include "YQPackageCaptureDlg.h"
    #include "afxdialogex.h"
    #include <pcap.h>
    #include <vector>
    #include <afxwin.h>
    using namespace std;
    #pragma warning(disable:4996)
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    
    /*_____________________________________________结构体_________________________________________*/
    /* 4字节的IP地址 */
    typedef struct ip_address
    {
    	u_char byte1;
    	u_char byte2;
    	u_char byte3;
    	u_char byte4;
    } ip_address;
    
    /* IPv4 首部 */   //Internet Protocol version 4
    typedef struct ip_header
    {
    	u_char  ver_ihl;        // 版本 (4 bits) + 首部长度 (4 bits)
    	u_char  tos;            // 服务类型(Type of service)
    	u_short tlen;           // 总长(Total length)
    	u_short identification; // 标识(Identification)
    	u_short flags_fo;       // 标志位(Flags) (3 bits) + 段偏移量(Fragment offset) (13 bits)
    	u_char  ttl;            // 存活时间(Time to live)
    	u_char  proto;          // 协议(Protocol)
    	u_short crc;            // 首部校验和(Header checksum)
    	ip_address  saddr;      // 源地址(Source address)
    	ip_address  daddr;      // 目的地址(Destination address)
    	u_int   op_pad;         // 选项与填充(Option + Padding)
    } ip_header;
    
    /* UDP 首部*/
    /*UDP 是User Datagram Protocol的简称,
    中文名是用户数据报协议,
    是OSI(Open System Interconnection,开放式系统互联)参考模型中一种无连接的传输层协议*/
    typedef struct udp_header
    {
    	u_short sport;          // 源端口(Source port)
    	u_short dport;          // 目的端口(Destination port)
    	u_short len;            // UDP数据包长度(Datagram length)
    	u_short crc;            // 校验和(Checksum)
    } udp_header;
    
    /*TCP头部*/
    typedef struct tcp_header
    {
    	short m_sSourPort;                // 源端口号16bit
    	short m_sDestPort;      // 目的端口号16bit
    	unsigned int m_uiSequNum;      // 序列号32bit
    	unsigned int m_uiAcknowledgeNum;  // 确认号32bit
    	short m_sHeaderLenAndFlag;     // 前4位:TCP头长度;中6位:保留;后6位:标志位
    	short m_sWindowSize;    // 窗口大小16bit
    	short m_sCheckSum;       // 检验和16bit
    	short m_surgentPointer;     // 紧急数据偏移量16bit
    }tcp_header;
    
    typedef struct ip_flow
    {
    	ip_address  ipaddr;      // 源地址(Source address)
    	float flow;             //该源地址的流量
    }ip_flow;
    
    typedef struct package_info
    {
    	u_char *package;      // 源地址(Source address)
    	short len;             //该源地址的流量
    }package_info;
    
    /*_____________________________________________全局变量_________________________________________*/
    
    int no = 0;
    LARGE_INTEGER m_nFreq;         //内部计时器的时钟周期,用于计时
    LARGE_INTEGER m_nBeginTime;    //开始捕获时,计时器的值,用于计时
    vector<package_info> package_vec;
    vector<ip_flow>ip_flow_vec;
    CListCtrl CYQPackageCaptureDlg::list_package;
    CListCtrl CYQPackageCaptureDlg::list_flow;
    pcap_t *adhandle; //网卡句柄
    pcap_if_t *alldevs;
    pcap_if_t *d;
    int stopNow=0;  //是否现在要停止捕获
    
    /*______________________________ 回调函数原型 ______________________________________________*/
    void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
    
    
    // 用于应用程序“关于”菜单项的 CAboutDlg 对话框
    
    class CAboutDlg : public CDialogEx
    {
    public:
    	CAboutDlg();
    
    // 对话框数据
    #ifdef AFX_DESIGN_TIME
    	enum { IDD = IDD_ABOUTBOX };
    #endif
    
    	protected:
    	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
    
    // 实现
    protected:
    	DECLARE_MESSAGE_MAP()
    };
    
    CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
    {
    }
    
    void CAboutDlg::DoDataExchange(CDataExchange* pDX)
    {
    	CDialogEx::DoDataExchange(pDX);
    }
    
    BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
    END_MESSAGE_MAP()
    
    
    // CYQPackageCaptureDlg 对话框
    
    
    
    CYQPackageCaptureDlg::CYQPackageCaptureDlg(CWnd* pParent /*=NULL*/)
    	: CDialogEx(IDD_YQPACKAGECAPTURE_DIALOG, pParent)
    {
    	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    }
    
    void CYQPackageCaptureDlg::DoDataExchange(CDataExchange* pDX)
    {
    	CDialogEx::DoDataExchange(pDX);
    	DDX_Control(pDX, IDC_COMBO_ADAPTER, com_adapter);
    	DDX_Control(pDX, IDC_LIST_PACKAGES, list_package);
    	DDX_Control(pDX, IDC_LIST_FLOW, list_flow);
    }
    
    BEGIN_MESSAGE_MAP(CYQPackageCaptureDlg, CDialogEx)
    	ON_WM_SYSCOMMAND()
    	ON_WM_PAINT()
    	ON_WM_QUERYDRAGICON()
    	ON_BN_CLICKED(IDC_BUTTON_START_CAP, &CYQPackageCaptureDlg::OnBnClickedButtonStartCap)
    	ON_CBN_SELCHANGE(IDC_COMBO_ADAPTER, &CYQPackageCaptureDlg::OnCbnSelchangeComboAdapter)
    	ON_EN_CHANGE(IDC_EDIT_DESCRIPTION, &CYQPackageCaptureDlg::OnEnChangeEditDescription)
    	ON_BN_CLICKED(IDC_BUTTON_STOP_CAP, &CYQPackageCaptureDlg::OnBnClickedButtonStopCap)
    	ON_EN_CHANGE(IDC_EDIT_ASCII, &CYQPackageCaptureDlg::OnEnChangeEditAscii)
    	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_PACKAGES, &CYQPackageCaptureDlg::OnLvnItemchangedListPackages)
    END_MESSAGE_MAP()
    
    
    // CYQPackageCaptureDlg 消息处理程序
    
    BOOL CYQPackageCaptureDlg::OnInitDialog()
    {
    	CDialogEx::OnInitDialog();
    
    	// 将“关于...”菜单项添加到系统菜单中。
    
    	// IDM_ABOUTBOX 必须在系统命令范围内。
    	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    	ASSERT(IDM_ABOUTBOX < 0xF000);
    
    	CMenu* pSysMenu = GetSystemMenu(FALSE);
    	if (pSysMenu != NULL)
    	{
    		BOOL bNameValid;
    		CString strAboutMenu;
    		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
    		ASSERT(bNameValid);
    		if (!strAboutMenu.IsEmpty())
    		{
    			pSysMenu->AppendMenu(MF_SEPARATOR);
    			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
    		}
    	}
    
    	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
    	//  执行此操作
    	SetIcon(m_hIcon, TRUE);			// 设置大图标
    	SetIcon(m_hIcon, FALSE);		// 设置小图标
    
    	// TODO: 在此添加额外的初始化代码
    	/***________________________显示可选的网卡__________________________***/
    	//pcap_if_t *alldevs;
    	//pcap_if_t *d;
    	int inum;
    	int adapter_counter = 0;           //网卡数目
    	//pcap_t *adhandle; //网卡句柄
    	char errbuf[PCAP_ERRBUF_SIZE];
    	u_int netmask;
    	char packet_filter[] = "ip and tcp or udp";   //程序最终可以得到IPV4,udp和tcp的数据包,并把它们复制给应用程序
    	struct bpf_program fcode;   //伯克利封包过滤器(Berkeley Packet Filter,缩写 BPF)
    								//printf("%d
    ", sizeof(u_char));
    								/* 获得设备列表 */
    	if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
    	{
    		fprintf(stderr, "Error in pcap_findalldevs: %s
    ", errbuf);
    		exit(1);
    	}
    
    	/* 显示网卡 */
    	 //为组合框控件的列表框添加列表项
    	for (d = alldevs; d; d = d->next)
    	{
    		CString name(d->name);
    		com_adapter.InsertString(adapter_counter++, name);
    		//adapter_counter++;
    	}
    	
    
    	if (adapter_counter == 0)
    	{
    		AfxMessageBox(L"
    No interfaces found! Make sure WinPcap is installed.
    ");
    		return -1;
    	}
    	// 默认选择第一项   
    	com_adapter.SetCurSel(0);
    	
    	/* 跳转到已选设备 */
    	inum = com_adapter.GetCurSel();
    	int i;
    	for (d = alldevs, i = 0; i< inum - 1; d = d->next, i++);
    	//显示网卡描述
    	CString description_str(d->description);
    	SetDlgItemText(IDC_EDIT_DESCRIPTION, description_str);
    	///* 释放设备列表 */
    	//pcap_freealldevs(alldevs);
    
    
    	/*____________显示control list package 的基本信息_______________________*/
    	CRect rect;
    	list_package.GetClientRect(&rect);   //获得客户区
    	list_package.SetExtendedStyle(list_package.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);         //设置风格,LVS_EX_FULLROWSELECT是有线条,后面那个是充满
    																										  //插入列:
    	list_package.InsertColumn(0, _T("NO."), LVCFMT_CENTER, rect.Width() /14, 0);
    	list_package.InsertColumn(1, _T("Time"), LVCFMT_CENTER, rect.Width() / 7, 1);
    	list_package.InsertColumn(2, _T("Source"), LVCFMT_CENTER, rect.Width() / 7, 2);
    	list_package.InsertColumn(3, _T("Destination"), LVCFMT_CENTER, rect.Width() / 7, 3);
    	list_package.InsertColumn(4, _T("Protocol"), LVCFMT_CENTER, rect.Width() /14, 4);
    	list_package.InsertColumn(5, _T("Length"), LVCFMT_CENTER, rect.Width() / 14, 5);
    	list_package.InsertColumn(6, _T("Info"), LVCFMT_CENTER, 5*rect.Width() /14, 6);
    
    
    	list_flow.GetClientRect(&rect);   //获得客户区
    	list_flow.SetExtendedStyle(list_package.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);         //设置风格,LVS_EX_FULLROWSELECT是有线条,后面那个是充满
    																													  //插入列:
    	list_flow.InsertColumn(0, _T("源IP地址"), LVCFMT_CENTER, rect.Width() / 2, 0);
    	list_flow.InsertColumn(1, _T("流量"), LVCFMT_CENTER, rect.Width() / 2, 1);
    	
    	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
    }
    
    void CYQPackageCaptureDlg::OnSysCommand(UINT nID, LPARAM lParam)
    {
    	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    	{
    		CAboutDlg dlgAbout;
    		dlgAbout.DoModal();
    	}
    	else
    	{
    		CDialogEx::OnSysCommand(nID, lParam);
    	}
    }
    
    // 如果向对话框添加最小化按钮,则需要下面的代码
    //  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
    //  这将由框架自动完成。
    
    void CYQPackageCaptureDlg::OnPaint()
    {
    	if (IsIconic())
    	{
    		CPaintDC dc(this); // 用于绘制的设备上下文
    
    		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
    
    		// 使图标在工作区矩形中居中
    		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;
    
    		// 绘制图标
    		dc.DrawIcon(x, y, m_hIcon);
    	}
    	else
    	{
    		CDialogEx::OnPaint();
    	}
    }
    
    //当用户拖动最小化窗口时系统调用此函数取得光标
    //显示。
    HCURSOR CYQPackageCaptureDlg::OnQueryDragIcon()
    {
    	return static_cast<HCURSOR>(m_hIcon);
    }
    
    
    /*开始捕获按钮*/
    void CYQPackageCaptureDlg::OnBnClickedButtonStartCap()
    {
    	// TODO: 在此添加控件通知处理程序代码
    	//pcap_if_t *alldevs;
    	//pcap_if_t *d;
    	int inum;
    	int adapter_counter = 0;
    	
    	char errbuf[PCAP_ERRBUF_SIZE];
    	u_int netmask;
    	char packet_filter[] = "ip and tcp or udp";   //程序最终可以得到IPV4,udp和tcp的数据包,并把它们复制给应用程序
    	struct bpf_program fcode;   //伯克利封包过滤器(Berkeley Packet Filter,缩写 BPF)
    								//printf("%d
    ", sizeof(u_char));
    	
    	/* 跳转到已选设备 */
    	inum= com_adapter.GetCurSel();
    	int i;
    	for (d = alldevs, i = 0; i< inum - 1; d = d->next, i++);
    
    	/* 打开适配器 */
    	if ((adhandle = pcap_open(d->name,  // 设备名
    		65536,     // 要捕捉的数据包的部分
    				   // 65535保证能捕获到不同数据链路层上的每个数据包的全部内容
    		PCAP_OPENFLAG_PROMISCUOUS,         // 混杂模式
    		1000,      // 读取超时时间
    		NULL,      // 远程机器验证
    		errbuf     // 错误缓冲池
    		)) == NULL)
    	{
    		AfxMessageBox(L"
    Unable to open the adapter. %s is not supported by WinPcap
    ");
    		fprintf(stderr, "
    Unable to open the adapter. %s is not supported by WinPcap
    ", d->name);
    		/* 释放设备列表 */
    		pcap_freealldevs(alldevs);
    		return ;
    	}
    
    	/* 检查数据链路层,为了简单,我们只考虑以太网 */
    	/*返回链路层的类型,链路层的类型包括:
    	DLT_NULL: BSD回路封装;链路层协议头是一个4字节的域,……
    	DLT_EN10MB: 以太网(10Mb, 100Mb, 1000Mb, 或者更高)。
    	DLT_IEEE802: IEEE802.5令牌环网。
    	……
    	*/
    	if (pcap_datalink(adhandle) != DLT_EN10MB) //如果不是以太网就不处理了
    	{
    		AfxMessageBox(L"
    This program works only on Ethernet networks.
    ");
    		fprintf(stderr, "
    This program works only on Ethernet networks.
    ");
    		/* 释放设备列表 */
    		pcap_freealldevs(alldevs);
    		return ;
    	}
    
    	/*类型        格式          默认子网掩码
    	     A   网络 节点 节点 节点  255.0.0.0
    		      B   网络 网络 节点 节点  255.255.0.0
    			       C   网络 网络 网络 节点  255.255.255.0*/
    	if (d->addresses != NULL)
    		/* 获得接口第一个地址的掩码 */
    		netmask = ((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;
    	else
    		/* 如果接口没有地址,那么我们假设一个C类的掩码 */
    		netmask = 0xffffff;
    
    
    	//编译过滤器pcap_compile
    	if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) <0)
    	{
    		AfxMessageBox(L"
    Unable to compile the packet filter. Check the syntax.
    ");
    		fprintf(stderr, "
    Unable to compile the packet filter. Check the syntax.
    ");
    		/* 释放设备列表 */
    		pcap_freealldevs(alldevs);
    		getchar();
    		return ;
    	}
    
    	//设置过滤器pcap_setfilter
    	if (pcap_setfilter(adhandle, &fcode)<0)
    	{
    		AfxMessageBox(L"
    Error setting the filter.
    ");
    		fprintf(stderr, "
    Error setting the filter.
    ");
    		/* 释放设备列表 */
    		pcap_freealldevs(alldevs);
    		getchar();
    		return ;
    	}
    
    	printf("
    listening on %s...
    ", d->description);
    
    	/* 释放设备列表 */
    	pcap_freealldevs(alldevs);
    
    	/* 开始捕捉并计时 */
    	QueryPerformanceFrequency(&m_nFreq); // 获取时钟周期
    	QueryPerformanceCounter(&m_nBeginTime);//获取开始捕获时,计时器的值
    
    	pcap_loop(adhandle, 0, packet_handler, NULL);
    	
    }
    
    
    void CYQPackageCaptureDlg::OnCbnSelchangeComboAdapter()
    {
    	// TODO: 在此添加控件通知处理程序代码
    	/* 跳转到已选设备 */
    	int inum = com_adapter.GetCurSel();
    	int i;
    	for (d = alldevs, i = 0; i< inum - 1; d = d->next, i++);
    	//显示网卡描述
    	CString description_str(d->description);
    	SetDlgItemText(IDC_EDIT_DESCRIPTION, description_str);
    	//SetDlgItemText(IDC_EDIT_DESCRIPTION, L"change my friend!!");
    
    }
    
    /****************************回调函数***********************************/
    void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
    {
    	//NO.   Time   Source   Destination     Protocol     Length     Info   十六进制   ASCII码   流量统计
    	//AfxMessageBox(L"抓到包了!");
    	struct tm ltime;
    	char timestr[16];
    	ip_header *ih;
    	udp_header *uh;
    	tcp_header *th;
    	u_int ip_len;
    	time_t local_tv_sec;
    	struct timeval tv_capPackage;
    	
    
    	/* 获得IP数据包头部的位置 */
    	/*因为我们需要解析IP数据包,
    	从IP数据包的首部解析到源IP地址和目的IP地址,
    	而IP数据包的首部位于MAC首部的后面,所以我们需要跳过MAC首部。
    	对于以太网而言MAC首部长度为14位*/
    
    	ih = (ip_header *)(pkt_data +
    		14); //以太网头部长度 固定14位
    	ip_len = (ih->ver_ihl & 0xf) * 4;   //ip首部有多少字节(取低四位,得到首部有多少个双字;乘4得到字节数)
    
    	/***************           显示每个包的PCI   ****************************************/
    	CString noStr;
    	noStr.Format(_T("%d"), no+1);
    
    	////插入该包数据,第0列(no)内容为1
    	CYQPackageCaptureDlg::list_package.InsertItem(no, noStr);
    
    
    	//Time
    	LARGE_INTEGER m_nTime;
    	QueryPerformanceCounter(&m_nTime);//获取当前时间
    	long long sec, next, time;   //从开始捕获,到捕获到当前包,时间差的秒,及其剩下的0.1秒;整个以微妙表示
    	time = (m_nTime.QuadPart - m_nBeginTime.QuadPart) * 1000000 / m_nFreq.QuadPart;
    	sec = time / 1000000;
    	next = time - time / 1000000 * 1000000;
    	//printf("Time:%lld.%.6lld 
    ", sec, next);
    	CString timeStr;
    	timeStr.Format(_T("%lld.%.6lld 
    "), sec, next);
    	//设置该包第1列(time)内容
    	CYQPackageCaptureDlg::list_package.SetItemText(no , 1,timeStr);
    
    	//Source
    
    	CString sourceStr;
    	sourceStr.Format(_T("%d.%d.%d.%d
    "),
    		ih->saddr.byte1,
    		ih->saddr.byte2,
    		ih->saddr.byte3,
    		ih->saddr.byte4);
    	//设置该包第2列(source)内容
    	CYQPackageCaptureDlg::list_package.SetItemText(no, 2,sourceStr);
    
    	//Destination
    
    	CString desStr;
    	desStr.Format(_T("%d.%d.%d.%d
    "),
    		ih->daddr.byte1,
    		ih->daddr.byte2,
    		ih->daddr.byte3,
    		ih->daddr.byte4);
    	//设置该包第3列(Destination)内容
    	CYQPackageCaptureDlg::list_package.SetItemText(no, 3, desStr);
    
    	//Protocol
    	/*协议字段:占8比特。指明IP层所封装的上层协议类型,
    	如ICMP(1)、IGMP(2) 、TCP(6)、UDP(17)、EIGRP(88)、OSPF(89)等。*/
    	CString protocolStr = NULL;
    	CString Str;
    
    	switch (ih->proto)
    	{
    	case 1:protocolStr = "ICMP";  break;
    	case 2:protocolStr = "IGMP";  break;
    	case 6:protocolStr = "TCP";  break;
    	case 17:protocolStr = "UDP"; break;
    	case 20:protocolStr = "HMP";  break;
    	case 88:protocolStr = "EIGRP";  break;
    	case 89:protocolStr = "OSPF";  break;
    	default: protocolStr.Format(_T("%d", ih->proto));
    	}
    	CYQPackageCaptureDlg::list_package.SetItemText(no, 4,protocolStr);
    	//printf("Protocol:%s
    ", protocol);
    
    	//Length
    	CString lenStr;
    	int wholeLen = ntohs(ih->tlen) + 14;  //将网络字节序列转换成主机字节序列,加上以太网包头的长度
    	lenStr.Format(_T("%d"), wholeLen);  
    	CYQPackageCaptureDlg::list_package.SetItemText(no, 5, lenStr);
    
    	//Info
    	CString infoStr;
    	//UDP
    	//printf("Info:
    ");
    	if (protocolStr == "UDP")
    	{
    		/* 获得UDP首部的位置 */
    
    		uh = (udp_header *)((u_char*)ih + ip_len);
    		infoStr.Format(_T("%d -> %d, Len=%d
    
    "), ntohs(uh->sport), ntohs(uh->dport), ntohs(uh->len));
    	}
    	else if (protocolStr == "TCP")
    	{
    		/* 获得TCP首部的位置 */
    		th = (tcp_header *)((u_char*)ih + ip_len);
    		infoStr.Format(_T("%d -> %d, Seq=%u, Ack=%u, Win=%d "),
    			ntohs(th->m_sSourPort),
    			ntohs(th->m_sDestPort),
    			ntohl(th->m_uiSequNum),
    			ntohl(th->m_uiAcknowledgeNum),
    			ntohs(th->m_sWindowSize)
    			);
    	}
    	CYQPackageCaptureDlg::list_package.SetItemText(no, 6, infoStr);
    
    	int list_item_count = CYQPackageCaptureDlg::list_package.GetItemCount();
    	if (list_item_count   >   0)
    		CYQPackageCaptureDlg::list_package.EnsureVisible(list_item_count - 1, FALSE);
    
    	//十六进制
    	CString hexStr,tempStr;
    	u_char *temp = (u_char *)pkt_data;
    	for (int i = 0; i < wholeLen; i++)
    	{
    		tempStr.Format(_T("%x "), *(temp++));
    		hexStr += tempStr;
    	}
    	SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_EDIT_HEX,hexStr);
    	
    	//ASCII码
    	CString asciiStr;
    	temp = (u_char *)pkt_data;
    	for (int i = 0; i < wholeLen; i++)
    	{
    		tempStr.Format(_T("%c "), *(temp++));
    		asciiStr += tempStr;
    	}
    	SetDlgItemText(AfxGetMainWnd()->m_hWnd, IDC_EDIT_ASCII, asciiStr);
    
    	//统计流量:
    	int ip_count = size(ip_flow_vec);   //已经统计过的ip源地址
    	int isNew = 1;    //之前没出现过该ip源地址
    	ip_flow new_ip_flow;
    	CString flowStr;
    	for (int i = 0; i < ip_count; i++)
    	{
    		//如果该ip地址已经出现过
    		if (ih->saddr.byte1 == ip_flow_vec[i].ipaddr.byte1
    			&&ih->saddr.byte2 == ip_flow_vec[i].ipaddr.byte2
    			&&ih->saddr.byte3 == ip_flow_vec[i].ipaddr.byte3
    			&&ih->saddr.byte4 == ip_flow_vec[i].ipaddr.byte4)
    		{
    			ip_flow_vec[i].flow += (double)wholeLen / 1024;  //单位为KB
    			isNew = 0;
    
    			flowStr.Format(_T("%.2f KB"), ip_flow_vec[i].flow);
    			CYQPackageCaptureDlg::list_flow.SetItemText(i, 1, flowStr);
    			break;
    		}
    	}
    	//如果该ip地址此前没有出现过
    	if (isNew == 1)
    	{
    		new_ip_flow.ipaddr = ih->saddr;
    		new_ip_flow.flow = (double)wholeLen / 1024;
    
    		ip_flow_vec.push_back(new_ip_flow);
    		flowStr.Format(_T("%.2f KB"),new_ip_flow.flow); 
    		//插入该IP地址,显示ip地址
    		CYQPackageCaptureDlg::list_flow.InsertItem(ip_count, sourceStr);
    		//显示流量
    		CYQPackageCaptureDlg::list_flow.SetItemText(ip_count, 1, flowStr);
    	}
    	list_item_count = CYQPackageCaptureDlg::list_flow.GetItemCount();
    	if (list_item_count   >   0)
    		CYQPackageCaptureDlg::list_flow.EnsureVisible(list_item_count - 1, FALSE);
    
    	/*把包的内容存入package_vec*/
    	temp = (u_char *)pkt_data;
    	package_info new_package_info;
    	new_package_info.package = temp;
    	new_package_info.len = wholeLen;
    	package_vec.push_back(new_package_info);
    
    	//包的个数+1
    	no++;
    	//实时显示
    	UpdateWindow(AfxGetMainWnd()->m_hWnd);
    	//CString mess;
    	//mess.Format(_T("%d"), adhandle);
    	//AfxMessageBox(mess);
    
    	//判断是否停止
    	AfxGetApp()->PumpMessage();
    	if (stopNow == 1)
    	{
    		pcap_breakloop(adhandle);  ///right here ahandle turned into 0
    	}
    }
    
    void CYQPackageCaptureDlg::OnEnChangeEditDescription()
    {
    	// TODO:  如果该控件是 RICHEDIT 控件,它将不
    	// 发送此通知,除非重写 CDialogEx::OnInitDialog()
    	// 函数并调用 CRichEditCtrl().SetEventMask(),
    	// 同时将 ENM_CHANGE 标志“或”运算到掩码中。
    
    	// TODO:  在此添加控件通知处理程序代码
    }
    
    
    void CYQPackageCaptureDlg::OnBnClickedButtonStopCap()
    {
    	// TODO: 在此添加控件通知处理程序代码
    	stopNow = 1;
    
    }
    
    
    void CYQPackageCaptureDlg::OnEnChangeEditAscii()
    {
    	// TODO:  如果该控件是 RICHEDIT 控件,它将不
    	// 发送此通知,除非重写 CDialogEx::OnInitDialog()
    	// 函数并调用 CRichEditCtrl().SetEventMask(),
    	// 同时将 ENM_CHANGE 标志“或”运算到掩码中。
    
    	// TODO:  在此添加控件通知处理程序代码
    }
    
    
    void CYQPackageCaptureDlg::OnLvnItemchangedListPackages(NMHDR *pNMHDR, LRESULT *pResult)
    {
    	LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
    	// TODO: 在此添加控件通知处理程序代码
    	NMLISTVIEW *pnml = (NMLISTVIEW*)pNMHDR;//新建一个指针
    	if (-1 != pnml->iItem)//如果指针无误
    	{
    		CString pac_no_str;
    		int pac_no;
    		pac_no_str = list_package.GetItemText(pnml->iItem, 0);//如果鼠标选中了某行,将选中的行的第0列赋给str
    		pac_no = _ttoi(pac_no_str)-1;
    		
    
    		CString hexStr, tempStr;
    		u_char *temp = (u_char *)package_vec[pac_no].package;
    		for (int i = 0; i < package_vec[pac_no].len; i++)
    		{
    			tempStr.Format(_T("%x "), *(temp++));
    			hexStr += tempStr;
    		}
    		//CString len;
    		//len.Format(_T("%d"), wholeLen);
    		//AfxMessageBox(len);
    		//SetDlgItemText(IDC_EDIT_HEX, L"exm");
    		SetDlgItemText(IDC_EDIT_HEX, hexStr);
    
    		//ASCII码
    		CString asciiStr;
    		temp = (u_char *)package_vec[pac_no].package;
    		for (int i = 0; i < package_vec[pac_no].len; i++)
    		{
    			tempStr.Format(_T("%c "), *(temp++));
    			asciiStr += tempStr;
    		}
    		//SetDlgItemText(IDC_EDIT_ASCII, L"exm");
    		SetDlgItemText(IDC_EDIT_ASCII, asciiStr);
    		
    	}
    
    
    	*pResult = 0;
    }
    
    
    
  • 相关阅读:
    个人作业——软件评测
    结对第二次作业
    寒假作业(2/2)
    寒假作业(1/2)
    markdown整理
    我们一定会在人生的更高处相见的
    时间复杂度 分析 可能算法
    有关数学 结论 规律 题目 小结
    jzyz 题库 选做 及 知识小结
    隔板法
  • 原文地址:https://www.cnblogs.com/YuQiao0303/p/8886172.html
Copyright © 2011-2022 走看看