c# 利用Log Parser制作简易可视化netmon抓包分析工具

这是本科时候的一个课程设计,要求调用Log Parser的dll实现图形界面分析Network Monitor 的抓包文件,编程语言是c#。

Log Parser 是微软的一款日志分析工具,可以支持很多格式的输入输出,但只提供命令行界面。本文采用的是Log Parser 2.2,百度可以下载,安装到c盘不然可能会出现问题,本身也才2M不大。Log Parser提供一种类似与SQL语句的查询语言,对日志文件进行分析,输出想要的结果。下图是命令行模式下的操作,可以看到查询语句基本类似与SQL,说明文档里有非常详细的操作说明,支持格式说明以及COM调用说明。IP地址在WIN7下显示有问题:

图1:

c# 利用Log Parser制作简易可视化netmon抓包分析工具_第1张图片

在Log Parser的说明文档里有关于支持格式的各字段描述,可以方便使用者了解所分析文件的结构。本文将以network monitor的抓包文件.cap文件作为分析对象。

图2:

c# 利用Log Parser制作简易可视化netmon抓包分析工具_第2张图片

使用vs2010开发,建立一个c#窗体应用工程,

图3:

c# 利用Log Parser制作简易可视化netmon抓包分析工具_第3张图片

然后在解决方案浏览器右键引用,添加引用,然后选择浏览,浏览LogParser2.2的安装目录下的LogParser.dll,添加引用。

图4:

c# 利用Log Parser制作简易可视化netmon抓包分析工具_第4张图片

然后在窗体上添加一个Button控件,一个DataGridView空间和一个Chart空间

图5:

c# 利用Log Parser制作简易可视化netmon抓包分析工具_第5张图片

然后进行代码编写:

代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;    //新添加
namespace LogParserTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //文件操作
            OpenFileDialog file1 = new OpenFileDialog(); //定义新的文件打开位置控件
            file1.Filter = "Netmon抓包文件|*.cap";
            if (file1.ShowDialog() == DialogResult.OK)
            {
                string sql = @"SELECT Frame,FrameBytes,DateTime,SrcIP,SrcPort ,DstIP,DstPort,
                             FrameBytes,SrcMac,DstMac,IPVersion,TCPFlags,PayloadBytes FROM " + file1.FileName;  //完整的查询语句 
                DataTable dt = OpenLog(sql);

                //对表中载荷单位进行处理
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    double temppayloadbyte = double.Parse(dt.Rows[i]["有效载荷大小"].ToString());
                    double tempframebyte = int.Parse(dt.Rows[i]["帧大小"].ToString());

                    dt.Rows[i]["有效载荷大小"] = (temppayloadbyte / 1024).ToString("0.00") + "KB";


                    dt.Rows[i]["帧大小"] = (tempframebyte / 1024).ToString("0.00") + "KB";

                }

                //绑定数据源,实现表格显示
                dataGridView1.DataSource = dt;

                //计算流量实现流量统计
                string TimeSql = @"SELECT QUANTIZE(DateTime, 1) AS Second, SUM(FrameBytes) AS FrameNum FROM "+ file1.FileName +" GROUP BY Second";
                DataTable dt2 = TimeFromLog(TimeSql);

                //将dt2中帧字节数转为KB
                for (int i = 0; i < dt2.Rows.Count; i++)
                {
                    //string CovStr = dt4.Rows[i]["流量"].ToString();   //获得美秒字节数
                    Int32 CovInt = Int32.Parse(dt2.Rows[i]["流量"].ToString());
                    CovInt /= 1024; //单位转为KB
                    dt2.Rows[i]["流量"] = CovInt.ToString();
                }

                // Set series chart type  
                chart1.Series[0].ChartType = SeriesChartType.Line;
                // Show as 3D  
                chart1.ChartAreas[0].Area3DStyle.Enable3D = false;
                // Draw as 3D Cylinder  
                //chart3.Series[0]["DrawingStyle"] = "Cylinder";
                //chart1.BackColor = Color.Azure; //图表背景色  
                //chart1.Titles.Add("IP协议分布"); //图表标题  
                //设置图表的数据源              
                chart1.DataSource = dt2;
                //设置图表Y轴对应项  
                chart1.Series[0].YValueMembers = "流量";
                //Chart1.Series[1].YValueMembers = "Volume2";  
                //设置图表X轴对应项  
                chart1.Series[0].XValueMember = "时间";
                chart1.Series[0].IsValueShownAsLabel = false; //是否显示数据  
                chart1.Series[0].IsVisibleInLegend = false; //是否显示数据说明  
                chart1.Series[0].MarkerStyle = MarkerStyle.Circle; //线条上的数据点标志类型  
                chart1.Series[0].MarkerSize = 0; //标志大小  
                chart1.ChartAreas[0].AxisX.LineColor = Color.Red; //X 轴颜色  
                chart1.ChartAreas[0].AxisY.LineColor = Color.Red; //Y 轴颜色  
                chart1.ChartAreas[0].AxisX.LineWidth = 2; //X 轴宽度  
                chart1.ChartAreas[0].AxisY.LineWidth = 2; //Y 轴宽度  
                chart1.ChartAreas[0].AxisY.Title = "流量 KB"; //Y 轴标题 
                chart1.ChartAreas[0].AxisX.Title = "时间"; //X 轴标题  
                chart1.ChartAreas[0].CursorX.IsUserEnabled = true;//启用x轴游标
                chart1.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
                chart1.ChartAreas[0].CursorY.IsUserEnabled = true;//启用y轴游标
                chart1.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
                //绑定数据  
                chart1.DataBind();
            }
        }

        public DataTable OpenLog(string sql)
        {
            try
            {
                DataTable datat = new DataTable();

                datat.Columns.Add("帧号", typeof(string));
                datat.Columns.Add("时间", typeof(string));
                datat.Columns.Add("源Mac", typeof(string));
                datat.Columns.Add("源地址", typeof(string));
                datat.Columns.Add("源端口", typeof(string));
                datat.Columns.Add("目标地址", typeof(string));
                datat.Columns.Add("目标Mac", typeof(string));
                datat.Columns.Add("目标端口", typeof(string));
                datat.Columns.Add("IP版本", typeof(string));
                datat.Columns.Add("TCP Flags", typeof(string));
                datat.Columns.Add("帧大小", typeof(string));
                datat.Columns.Add("有效载荷大小", typeof(string));

                // Instantiate the LogQuery object    
                MSUtil.ILogQuery oLogQuery = new MSUtil.LogQueryClass();
                // Instantiate the Netmon Input Format object  
                MSUtil.ICOMNetMonInputContext oEvtInputFormat = new MSUtil.COMNetMonInputContextClass();

                oEvtInputFormat.fMode = "TCPIP";    //这是netmon输入格式的模式之一,LogParser说明文档有详细介绍
                oEvtInputFormat.binaryFormat = "ASC";

                // Create the query    
                string query = sql;
                // Execute the query    
                //object o=null;
                MSUtil.ILogRecordset oRecordSet = oLogQuery.Execute(query, oEvtInputFormat);  //oEvtInputFormat

                while (!oRecordSet.atEnd())
                {
                    var itemData = oRecordSet.getRecord();
                    DataRow dr = datat.NewRow();
                    dr["帧号"] = itemData.getValue("Frame").ToString();
                    dr["时间"] = itemData.getValue("DateTime").ToString();
                    dr["源端口"] = itemData.getValue("SrcPort").ToString();
                    dr["源Mac"] = itemData.getValue("SrcMAC").ToString();
                    dr["源地址"] = itemData.getValue("SrcIP").ToString();
                    dr["目标地址"] = itemData.getValue("DstIP").ToString();
                    dr["目标端口"] = itemData.getValue("DstPort").ToString();
                    dr["目标Mac"] = itemData.getValue("DstMAC").ToString();
                    dr["IP版本"] = itemData.getValue("IPVersion").ToString();
                    dr["TCP Flags"] = itemData.getValue("TCPFlags").ToString();
                    dr["帧大小"] = itemData.getValue("FrameBytes").ToString();
                    dr["有效载荷大小"] = itemData.getValue("PayloadBytes").ToString();
                    datat.Rows.Add(dr);
                    oRecordSet.moveNext();
                }

                // Close the recordset    
                oRecordSet.close();
                return datat;
            }
            catch (System.Runtime.InteropServices.COMException exc)
            {
                MessageBox.Show("Unexpected error: " + exc.Message);
                return null;
            }
        }

        public DataTable TimeFromLog(string sql)
        {
            try
            {
                DataTable datat = new DataTable();


                datat.Columns.Add("时间", typeof(string));
                datat.Columns.Add("流量", typeof(string));


                // Instantiate the LogQuery object    
                MSUtil.ILogQuery oLogQuery = new MSUtil.LogQueryClass();
                // Instantiate the Netmon Input Format object  
                MSUtil.ICOMNetMonInputContext oEvtInputFormat = new MSUtil.COMNetMonInputContextClass();

                oEvtInputFormat.fMode = "TCPIP";
                oEvtInputFormat.binaryFormat = "ASC";

                // Create the query    
                string query = sql;
                // Execute the query    
                //object o=null;
                MSUtil.ILogRecordset oRecordSet = oLogQuery.Execute(query, oEvtInputFormat);  //oEvtInputFormat

                while (!oRecordSet.atEnd())
                {
                    var itemData = oRecordSet.getRecord();
                    DataRow dr = datat.NewRow();

                    dr["时间"] = itemData.getValue("Second").ToString();
                    dr["流量"] = itemData.getValue("FrameNum").ToString();
                    datat.Rows.Add(dr);
                    oRecordSet.moveNext();
                }

                // Close the recordset    
                oRecordSet.close();
                return datat;
            }
            catch (System.Runtime.InteropServices.COMException exc)
            {
                MessageBox.Show("Unexpected error: " + exc.Message);
                return null;
            }
        }
    }


}


运行结果如下图。经验证,IP地址无论是命令行还是COM调用都无法在WIN7、win8、win10显示,XP显示正常。支持netmon3.2,3.3,3.4以及MMA的.cap文件,wireshark的文件未验证:

图6:

c# 利用Log Parser制作简易可视化netmon抓包分析工具_第6张图片

你可能感兴趣的:(c#)