故障排查——抓包 sniffer

目录

一、图形界面抓包

1、通过web界面抓包

二、抓包命令详解

2.1 interface

2.2 verbose显示内容

2.3 count

2.4.1 none

2.4.2 Tcp, udp, icmp,arp参数

2.4.4 host参数

2.4.5 port参数

2.4.8 TCP包头字段过滤

2.5 数据格式转换

2.5.2 脚本程序

2.5.2 转换操作


 

一、图形界面抓包

1、通过web界面抓包

进入 系统管理--网络--数据包捕获

如上图 数据包捕获界面,点击‘新建‘即可创建一个抓包过滤器,并进行抓包。

按上图填入需要抓取的过滤条件,ip、端口等,点击确认,添加好的数据捕获如下图。

选择添加好的数据捕获,点击“运行”开关抓包;抓取包后,可以点击“下载”将抓取的数据包保存的本地磁盘,可以用wireshark直接查看。

该方式的优点是方便,抓取的内容可以直接查看,缺点是过滤选项不够丰富。

二、抓包命令详解

命令格式:diagnose sniffer packet <interface> <'filter'> <verbose> <count>

2.1 interface

<interface> 指定实际的接口名称,可以是真实的物理接口名称,也可以是VLAN 的逻辑接口名称,当使用“any”关键字时,表示抓全部接口的数据包。 例:

#diagnose sniffer packet port1 //表示抓物理接口为port1 的所有数据包

#diagnose sniffer packet any //表示抓所有接口的所有数据包

#diagnose sniffer packet port1-v10 //当在物理接口建立一个VLAN 子接口,其逻辑 接口名为port1-v10,此时表示抓port1-v10 接口的所有数据包,此处一定注意一个问题, 由于抓包命令中的空格使用来区分参数字段的,但是在逻辑接口创建时,接口名称支持空格,考虑到今后抓包分析的方便,建议在创建逻辑接口时不要带有空格。

2.2 verbose显示内容

<verbose> 指控制抓取数据包的内容。常用选项4和6。

1: print header of packets, //只抓取IP的原地址、源端口、目的地址、目的端口和数据包的Sequence numbers, 为系统缺省设置

2: print header and data from ip of packets, //抓取包括IP、TCP或UDP及其内容层的payload。

3: print header and data from ethernet of packets) ,//抓取包括Ether、IP、TCP或UDP及其内容层的payload。 可导出到文本文件使用专用的转换工具,转换为Ethereal支持文件

4:print header of packets with interface name //与第一项类似,但包括显示收发包的接口信息

5: print header and data from ip of packets with interface name  //与第二项类似,但包括显示收发包的接口信息

6: print header and data from ethernet of packets (if available) with intf name  //与第三项类似,但包括显示收发包的接口信息

2.3 count

<count> 抓取的数据包的数量。

2.4 filter  包过滤参数

过滤器可以用一个表达式来表示,也可以是多个表达式进行组合;

当表达式为连续字符串,中间没有空格字符时,不需要加单引号或者双引号。

如diagnose sniffer packet wan1 icmp 1 10;

当过滤器表达式中间存在空格,或者是由多个过滤条表达式组合的时候,则需要将整个表达式放入单引号或者双引号之内。

如:

diagnose sniffer packet any 'host 192.168.1.11'  4  2

diagnose sniffer packet  wan1 'icmp and host 8.8.8.8' 1 10; 

2.4.1 none

None或者不写任何参数,则不做任何过滤。

Ruijie # diagnose sniffer packet wan1 none 1 3

interfaces=[wan1]

filters=[none]

0.726021 arp who-has 192.168.118.64 tell 192.168.118.1

0.726054 arp who-has 192.168.118.207 tell 192.168.118.1

0.907046 192.168.118.55.3975 -> 255.255.255.255.2654: udp 312

2.4.2 Tcp, udp, icmp,arp参数

Ruijie # diagnose sniffer packet wan1 tcp 1 3

interfaces=[wan1]

filters=[tcp]

5.854756 192.168.118.28.41972 -> 74.125.31.138.443: 1918013413 ack 2189770725

10.680845 192.168.118.28.37644 -> 106.120.151.51.80: syn 1554494232

10.681300 106.120.151.51.80 -> 192.168.118.28.37644: syn 199984742 ack 1554494

3

Ruijie # diagnose sniffer packet wan1 udp 1 3

interfaces=[wan1]

filters=[udp]

0.851497 192.168.118.39.58839 -> 234.34.23.234.33674: udp 20

0.880828 192.168.118.28.38299 -> 8.8.8.8.53: udp 37

0.951063 192.168.118.55.4045 -> 255.255.255.255.2654: udp 312

Ruijie # diagnose sniffer packet wan1 icmp 1 3

interfaces=[wan1]

filters=[icmp]

5.831862 192.168.118.28 -> 119.254.12.21: icmp: echo request

5.833274 119.254.12.21 -> 192.168.118.28: icmp: echo reply

6.836748 192.168.118.28 -> 119.254.12.21: icmp: echo request

Ruijie # diagnose sniffer packet wan1 arp 1 3

interfaces=[wan1]

filters=[arp]

0.835697 arp who-has 192.168.118.211 tell 192.168.118.1

0.955753 arp who-has 192.168.118.64 tell 192.168.118.1

0.955780 arp who-has 192.168.118.207 tell 192.168.118.1

2.4.3 Src,dst参数

指定源IP  或者目的IP。

Ruijie # diag sniffer pa any 'src 192.168.118.45 and dst 4.2.2.1'

interfaces=[any]

filters=[src 192.168.118.45 and dst 4.2.2.1]

3.053283 SE in 192.168.118.45 -> 4.2.2.1: icmp: echo request

4.055621 SE in 192.168.118.45 -> 4.2.2.1: icmp: echo request

5.057185 SE in 192.168.118.45 -> 4.2.2.1: icmp: echo request

6.059751 SE in 192.168.118.45 -> 4.2.2.1: icmp: echo request

2.4.4 host参数

指定主机,抓取包括该host IP地址的数据包,可以是源地址,也可以是目标地址。

Ruijie # diagnose sniffer  packet  wan1 'host 8.8.8.8' 1 10

interfaces=[wan1]

filters=[host 8.8.8.8]

5.793921 192.168.118.28 -> 8.8.8.8: icmp: echo request     //目标地址

5.833691 8.8.8.8 -> 192.168.118.28: icmp: echo reply      //源地址

2.4.5 port参数

根据数据包源端口或者目标端口进行抓包。

Ruijie # diagnose sniffer packet wan1 'port 80' 1 3

interfaces=[wan1]

filters=[port 80]

5.391804 192.168.118.28.8977 -> 83.145.92.172.80: syn 3438827760

5.392339 83.145.92.172.80 -> 192.168.118.28.8977: syn 4238988927 ack 3438827761

5.392842 192.168.118.28.8977 -> 83.145.92.172.80: ack 4238988928

2.4.6 proto参数

可以通过协议号进行抓包,1:ICMP, 6:TCP , 17:UDP, 89: OSPF等。

Ruijie # diagnose sniffer  packet  wan1 'proto 1' 1 10

interfaces=[wan1]

filters=[proto 1]

5.193085 192.168.118.28 -> 8.8.8.8: icmp: echo request

5.233840 8.8.8.8 -> 192.168.118.28: icmp: echo reply

6.193968 192.168.118.28 -> 8.8.8.8: icmp: echo request

6.234911 8.8.8.8 -> 192.168.118.28: icmp: echo reply

Ruijie # diagnose sniffer  packet  wan1 'proto 17' 1 10

interfaces=[wan1]

filters=[proto 17]

1.291398 192.168.118.48.1786 -> 255.255.255.255.2654: udp 312

1.307764 192.168.118.48.1787 -> 255.255.255.255.2654: udp 322

2.813556 192.168.118.55.3735 -> 255.255.255.255.2654: udp 312

2.815426 192.168.118.55.3736 -> 255.255.255.255.2654: udp 324

2.4.7 and 和or 参数

表达式连接符号and为“与”的关系,or为“或”的关系。通过这个2参数可以将多个过滤表达式组合成一个更精确的抓包过滤器。

Ruijie # diagnose sniffer  packet  wan1 'host 8.8.8.8 and udp and port 53’  1 10

interfaces=[wan1]

filters=[host 8.8.8.8 and udp and port 53]

9.161057 192.168.118.28.25758 -> 8.8.8.8.53: udp 30

9.200929 8.8.8.8.53 -> 192.168.118.28.25758: udp 273

Ruijie # diagnose sniffer packet wan1 'host 8.8.8.8 or udp' 1 6

interfaces=[wan1]

filters=[host 8.8.8.8 or udp]

0.406682 192.168.118.28 -> 8.8.8.8: icmp: echo request

0.446384 8.8.8.8 -> 192.168.118.28: icmp: echo reply

1.408758 192.168.118.28 -> 8.8.8.8: icmp: echo request

1.447828 192.168.118.48.2345 -> 255.255.255.255.2654: udp 312

1.448329 8.8.8.8 -> 192.168.118.28: icmp: echo reply

1.467194 192.168.118.48.2346 -> 255.255.255.255.2654: udp 324

2.4.8 TCP包头字段过滤

Ruijie # diag sniff packet any 'tcp[13]==2' 4 10  

interfaces=[any]

filters=[tcp[13]==2]

0.566163 SE in 192.168.118.44.51011 -> 118.67.120.53.80: syn 1443461665

0.566253 port13 out 59.108.29.180.65483 -> 118.67.120.53.80: syn 1443461665

0.566476 SE in 192.168.118.44.51012 -> 118.67.120.37.80: syn 2381613524

0.566569 port13 out 59.108.29.180.65484 -> 118.67.120.37.80: syn 2381613524

TCP包头的13字节内容==2, 即00000010。包头的第一个字节序号为0,依次次往后数,13就是Flag位置所在的字节,该字节的倒数第二位为SYN位,所以该命令的就是抓取所有syn包为1,其他flag位为0的数据包。

同理:diagnose sniffer packet any "tcp[13] & 4 != 0" 3 10 抓FIN为1的包。

因为FIN位为1的数据包,ACK也置位1,通过tcp[13]& 4 != 0,即通过做与运算不等于0.也就是说只要FIN为1,其他位任意。

diagnose sniffer packet any "tcp[13] & 2 != 0" 4 10 SYN位为1的,其他位置可以为任意值的数据包,(SYN,SYN ACK包)。

2.4.9 IP包头字段过滤

16进制0x59为十进制的89,IP头第9字节为协议字节,协议号89则为OSPF.

Ruijie # diagnose sniffer packet any "ip[9]==0x59" 1 10 

interfaces=[any]

filters=[ip[9]==0x59]

0.601194 192.168.118.28 -> 224.0.0.5:  ip-proto-89 44

11.601206 192.168.118.28 -> 224.0.0.5:  ip-proto-89 44

2 packets received by filter

0 packets dropped by kernel

Ruijie # diagnose sniffer packet any "ip[9]==89" 1 10

interfaces=[any]

filters=[ip[9]==89]

2.601194 192.168.118.28 -> 224.0.0.5:  ip-proto-89 44

12.601208 192.168.118.28 -> 224.0.0.5:  ip-proto-89 44

2.4.10 Ethernet包头字段过滤

以太网包头的第6字节开始的4个连续字节为源MAC地址字段位置。下面的命令为抓取所有源MAC地址为0x00090fdf的数据包。

Ruijie # diagnose sniffer packet SE "(ether[6:4]=0x00090fdf) and (ether[10:2]=0xe8e3)" 3 3

interfaces=[SE]

filters=[(ether[6:4]=0x00090fdf) and (ether[10:2]=0xe8e3)]

0.632650 192.168.118.45.62528 -> 192.168.118.1.22: ack 2277714159

0x0000   0009 0fcd 9f48 0009 0fdf e8e3 0800 4500        .....H........E.

0x0010   0028 2383 4000 7f06 6acd c0a8 762d c0a8        .(#.@...j...v-..

0x0020   7601 f440 0016 16b9 4e62 87c3 28ef 5010        v..@....Nb..(.P.

0x0030   3fa0 f88f 0000                                 ?.....

0.633263 192.168.118.45.62528 -> 192.168.118.1.22: ack 2277714383

0x0000   0009 0fcd 9f48 0009 0fdf e8e3 0800 4500        .....H........E.

0x0010   0028 2384 4000 7f06 6acc c0a8 762d c0a8        .(#.@...j...v-..

0x0020   7601 f440 0016 16b9 4e62 87c3 29cf 5010        v..@....Nb..).P.

0x0030   3ec0 f88f 0000                                 >.....

抓取目标MAC = 00:09:0f:cd:9f:48数据包

Ruijie # diagnose sniffer packet SE "(ether[0:4]=0x00090fcd) and (ether[4:2]=0x9f48)" 3 3

interfaces=[SE]

filters=[(ether[6:4]=0x00090fdf) and (ether[10:2]=0xe8e3)]

0.632650 192.168.118.45.62528 -> 192.168.118.1.22: ack 2277714159

0x0000   0009 0fcd 9f48 0009 0fdf e8e3 0800 4500        .....H........E.

0x0010   0028 2383 4000 7f06 6acd c0a8 762d c0a8        .(#.@...j...v-..

0x0020   7601 f440 0016 16b9 4e62 87c3 28ef 5010        v..@....Nb..(.P.

0x0030   3fa0 f88f 0000                                 ?.....

2.5 数据格式转换

首先,通过该命令抓取数据包,会直接输出到屏幕上,需要通过SecureCRT 相关工具进行抓包数据的收集。

其次,使用抓包命令的<verbose>级别为6时,导出的文件才能被Wireshark识别。

第三,要获取大量抓包信息时,SecureCRT 工具应通过远程TELNET/SSH连接到防火墙。如果使用主机串口来抓包,由于串口速率低,获取大量数据时速度非常慢。

第四,使用单独提供的脚本程序文件进行转换,主机必须提前安装Perl的解释程序和Wireshark软件,并在提供的转换脚本程序中做必要的路径指向。

2.5.1 SecureCRT配置

正常安装SecureCRT 软件,并通过远程方式登陆到防火墙。

1、配置SecureCRT:File > Log Session,选择配置文件存储的路径,文件格式为*.txt

2、防火墙上执行抓包命令

Ruijie # diagnose sniffer packet< interface><'filter'>6<count>

其中6 代表抓到的包输出文件支持经过转换为Wireshark格式文件。

2.5.2 脚本程序

在此页下面附件内下载ruijiet2eth.pl文件,并使用编辑器进行编辑。由于文件转换成pacp文件格式需要使用到抓包软件的text2pacp.exe程序,比如Wireshark的text2pacp.exe,所以需要在脚本中指明text2pcap.exe的路径。text2pcap.exe所在路径是Wireshark的安装路径。找到如下行,按实际情况修改红色部分,注意路径需要用两个"\",即“\\”.

# Path to the windows text2pcap.exe

# You need to double character '\'

  my $text2pcapdirwin   = "c:\\Progra~1\\Ethereal";

  # Use wireshark text2pcap if installed

  $text2pcapdirwin   = "D:\\Program Files\\Wireshark" if -e "D:\\Program Files\\Wireshark\\text2pcap.exe";

2.5.2 转换操作

1、安装perl解释器

转换前需要安装Perl 解释器,下载链接Download & Install Perl - ActiveState

2、准备好脚本和抓包文件

假设抓包文件为packet.txt。在C盘建立一个工作目录,比如c:\pacp,把脚本ruijiet2eth.pl文件和抓包文件packet.txt拷贝到c:\pacp

3、转换工作

进入cmd命令行,进入perl解释器执行程序目录,然后按如下命令执行转换:

执行命令后,回车,在c:\pacp下自动生成1.pacp文件,1.pcap就是转换为Wireshark识别的格式文件。用Wireshark打开后即可进行详细分析。直接输入perl Ruijiet2eth.pl –help获得帮助信息

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
// ipmonDlg.cpp : implementation file // #include "stdafx.h" #include "ipmon.h" #include "ipmonDlg.h" #include "mstcpip.h" #include "afxsock.h" #include "Iphlpapi.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About PROTN2T aOfProto [ PROTO_NUM + 1] = { { IPPROTO_IP , "IP" }, { IPPROTO_ICMP , "ICMP" }, { IPPROTO_IGMP , "IGMP" }, { IPPROTO_GGP , "GGP" }, { IPPROTO_TCP , "TCP" }, { IPPROTO_PUP , "PUP" }, { IPPROTO_UDP , "UDP" }, { IPPROTO_IDP , "IDP" }, { IPPROTO_ND , "NP" }, { IPPROTO_RAW , "RAW" }, { IPPROTO_MAX , "MAX" }, { NULL , "" } } ; char *get_proto_name( unsigned char proto ) { BOOL bFound = FALSE ; for( int i = 0 ; i < PROTO_NUM ; i++ ) { if( aOfProto[i].proto == proto ) { bFound = TRUE ; break ; } } if( bFound ) return aOfProto[i].pprototext ; return aOfProto[PROTO_NUM].pprototext ; } 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() ///////////////////////////////////////////////////////////////////////////// // CIpmonDlg dialog CIpmonDlg::CIpmonDlg(CWnd* pParent /*=NULL*/) : CDialog(CIpmonDlg::IDD, pParent) { //{{AFX_DATA_INIT(CIpmonDlg) //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_threadID = 0 ; m_Multihomed = FALSE ; m_Local = TRUE ; } void CIpmonDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CIpmonDlg) DDX_Control(pDX, IDC_LIST, m_ctrList); DDX_Control(pDX, IDC_LOOKUP, m_start); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CIpmonDlg, CDialog) //{{AFX_MSG_MAP(CIpmonDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_LOOKUP, OnLookUp) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CIpmonDlg message handlers BOOL CIpmonDlg::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 // TODO: Add extra initialization here CHAR szHostName[128] = {0}; HOSTENT* pHost = NULL; CHAR* pszIp = NULL; int iNum = 0; if(AfxSocketInit(NULL)==FALSE) { AfxMessageBox("Sorry, socket load error!"); return FALSE; } if(gethostname(szHostName, 128)==0) { pHost = gethostbyname(szHostName); if(pHost != NULL) { pszIp = inet_ntoa(*(in_addr*)pHost->h_addr_list[iNum]); m_ipsource = inet_addr(pszIp); } else AfxMessageBox("pHost = NULL!"); } else AfxMessageBox("can't find host name!"); // ListView initialize DWORD dwStyle=GetWindowLong(m_ctrList.GetSafeHwnd(),GWL_STYLE); dwStyle&=~LVS_TYPEMASK; dwStyle|=LVS_REPORT; SetWindowLong(m_ctrList.GetSafeHwnd(),GWL_STYLE,dwStyle); m_ctrList.InsertColumn(0,"数据",LVCFMT_LEFT,525); m_ctrList.InsertColumn(0,"大小",LVCFMT_LEFT,80); m_ctrList.InsertColumn(0,"端口",LVCFMT_LEFT,40); m_ctrList.InsertColumn(0,"目的地址",LVCFMT_LEFT,100); m_ctrList.InsertColumn(0,"端口",LVCFMT_LEFT,40); m_ctrList.InsertColumn(0,"源地址",LVCFMT_LEFT,100); m_ctrList.InsertColumn(0,"协议",LVCFMT_LEFT,50); ::SendMessage(m_ctrList.m_hWnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT); // Here read all IPs of this host DWORD dwSize = 0 ; GetIpAddrTable( NULL , &dwSize, FALSE ) ; PMIB_IPADDRTABLE pIpAddrTable = (PMIB_IPADDRTABLE )new BYTE [ dwSize ] ; if( pIpAddrTable ) { if( GetIpAddrTable( (PMIB_IPADDRTABLE)pIpAddrTable, // // buffer for IP table &dwSize, // size of buffer FALSE // sort by IP address ) == NO_ERROR ) { if( pIpAddrTable->dwNumEntries > 2 ) // Second is MS TCP loopback IP ( 127.0.0.1 ) { m_Multihomed = TRUE ; char szIP[16]; for( int i = 0 ; i < (int)pIpAddrTable->dwNumEntries ; i++ ) { in_addr ina ; ina.S_un.S_addr = pIpAddrTable->table[i].dwAddr ; char *pIP = inet_ntoa( ina ) ; strcpy( szIP , pIP ) ; if( stricmp( szIP , "127.0.0.1" ) ) m_IPArr.Add(pIpAddrTable->table[i].dwAddr) ; } } } delete [] pIpAddrTable ; } return TRUE; // return TRUE unless you set the focus to a control } void CIpmonDlg::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 CIpmonDlg::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 CIpmonDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } UINT threadFunc ( LPVOID p ) { CIpmonDlg *pDlg = static_cast<CIpmonDlg *>(p) ; char buf [1000] , *bufwork ; MSG msg ; int iRet ; DWORD dwErr ; char *pSource , *pDest ; IPHEADER *pIpHeader ; in_addr ina ; char szSource [16] , szDest[16] , szErr [ 50 ]; char *pLastBuf = NULL ; int HdrLen, totallen; WORD sourport, destport; struct TCPPacketHead *pTCPHead; struct ICMPPacketHead *pICMPHead; struct UDPPacketHead *pUDPHead; BYTE *pdata = NULL; /*---------------------------------------------------------------------*/ PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE) ; // Force to make the queue pDlg->m_threadID = GetCurrentThreadId() ; while( TRUE ) { if( PeekMessage( &msg , 0 , WM_CLOSE,WM_CLOSE,PM_NOREMOVE ) ) { closesocket( pDlg->m_s ) ; pDlg->m_threadID = 0 ; pDlg->m_start.EnableWindow(TRUE) ; break ; } memset( buf , 0 , sizeof(buf) ) ; iRet = recv( pDlg->m_s , buf , sizeof( buf ) , 0 ) ; if( iRet == SOCKET_ERROR ) { dwErr = WSAGetLastError() ; sprintf( szErr , "Error recv() = %ld " , dwErr ) ; continue ; } else if( *buf ) { bufwork = buf ; pIpHeader = (IPHEADER *)bufwork ; WORD iLen = ntohs(pIpHeader->total_len) ; while( TRUE ) { if( iLen <= iRet ) { ina.S_un.S_addr = pIpHeader->sourceIP ; pSource = inet_ntoa( ina ) ; strcpy( szSource , pSource ) ; ina.S_un.S_addr = pIpHeader->destIP ; pDest = inet_ntoa( ina ) ; strcpy( szDest , pDest ) ; CString str, strProto, strSourPort, strDestPort, strData, strSize; strProto = get_proto_name( pIpHeader->proto ); /*-------------------zhuwei add(2002.11.9)-----------------------------*/ HdrLen = pIpHeader->header_len&0xf; HdrLen *= 4; totallen = ntohs(pIpHeader->total_len); totallen-=HdrLen; switch(pIpHeader->proto) { case IPPROTO_ICMP: { pICMPHead=(struct ICMPPacketHead *)(buf+HdrLen); //strL4.Format(" type:%d code:%d\n",pICMPHead->Type,pICMPHead->Code); strSourPort = "-"; strDestPort = "-"; pdata=((BYTE *)pICMPHead)+ICMP_HEAD_LEN; totallen -= ICMP_HEAD_LEN; break; } case IPPROTO_TCP: { pTCPHead=(struct TCPPacketHead *)(buf+HdrLen); sourport = ntohs(pTCPHead->SourPort); destport = ntohs(pTCPHead->DestPort); //strL4.Format(" sour port:%d,dest port:%d",sourport,destport); strSourPort.Format("%d",sourport); strDestPort.Format("%d",destport); HdrLen = (pTCPHead->HLen)>>4; //in fact only 4 bits HdrLen *= 4; pdata=((BYTE *)pTCPHead)+HdrLen; totallen -= HdrLen; break; } case IPPROTO_UDP: { pUDPHead=(struct UDPPacketHead *)(buf+HdrLen); sourport = ntohs(pUDPHead->SourPort); destport = ntohs(pUDPHead->DestPort); //strL4.Format(" sour port:%d,dest port:%d",sourport,destport); strSourPort.Format("%d",sourport); strDestPort.Format("%d",destport); pdata=((BYTE *)pUDPHead)+UDP_HEAD_LEN; totallen -= UDP_HEAD_LEN; break; } } if(pIpHeader->proto == IPPROTO_ICMP) strData.Format("type:%d code:%d data:%s",pICMPHead->Type,pICMPHead->Code,pdata); else strData.Format(" %s",pdata); strSize.Format("%d",totallen); pDlg->AddData(strProto,szSource,strSourPort,szDest,strDestPort,strSize,strData); if( iLen < iRet ) { iRet -= iLen ; bufwork += iLen ; pIpHeader = (IPHEADER *)bufwork ; } else break ; // pIpHeader->total_len == iRet and go out } else { // read last part of buf. I wrote it , but always recv() read exactly // the lenght of the packet int iLast = iLen - iRet ; pLastBuf = new char [ iLen ] ; int iReaden = iRet ; memcpy( pLastBuf , bufwork , iReaden ) ; iRet = recv( pDlg->m_s , pLastBuf + iReaden , iLast , 0 ) ; if( iRet == SOCKET_ERROR ) { dwErr = WSAGetLastError() ; sprintf( szErr , "Error recv() = %ld " , dwErr ) ; break ; } else { bufwork = pLastBuf ; pIpHeader = (IPHEADER *)bufwork ; if( iRet == iLast ) iRet = iLen ; else { // read all last data iReaden += iRet ; iLast -= iRet ; while( TRUE ) { iRet = recv( pDlg->m_s , pLastBuf +iReaden , iLast , 0 ) ; if( iRet == SOCKET_ERROR ) { dwErr = WSAGetLastError() ; sprintf( szErr , "Error recv() = %ld " , dwErr ) ; break ; } else { iReaden += iRet ; iLast -= iRet ; if( iLast <= 0 ) break ; } } // while } } } } // while if( pLastBuf ) delete [ ] pLastBuf ; } else { AfxMessageBox( "No data on network" ) ; continue ; } } return TRUE ; } void CIpmonDlg::OnLookUp() { // TODO: Add your control notification handler code here char szErr [ 50 ] , szHostName[MAX_PATH]; DWORD dwErr ; SOCKADDR_IN sa; gethostname(szHostName, sizeof(szHostName)) ; m_iphostsource = m_ipsource ; m_ipcheckedhost = ntohl(m_iphost) ; if( 0 == m_threadID ) { SetDlgItemText(IDC_LOOKUP,"停止查看!" ); } else { if( m_threadID ) { PostThreadMessage(m_threadID,WM_CLOSE,0,0) ; SetDlgItemText(IDC_LOOKUP,"开始查看!"); m_start.EnableWindow(FALSE) ; } return ; } DWORD dwBufferLen[10] ; DWORD dwBufferInLen= 1 ; DWORD dwBytesReturned = 0 ; m_s = socket( AF_INET , SOCK_RAW , IPPROTO_IP ) ; if( INVALID_SOCKET == m_s ) { dwErr = WSAGetLastError() ; sprintf( szErr , "Error socket() = %ld " , dwErr ) ; AfxMessageBox( szErr ) ; closesocket( m_s ) ; return ; } int rcvtimeo = 5000 ; if( setsockopt( m_s , SOL_SOCKET , SO_RCVTIMEO , (const char *)&rcvtimeo , sizeof(rcvtimeo) ) == SOCKET_ERROR) { dwErr = WSAGetLastError() ; sprintf( szErr , "Error WSAIoctl = %ld " , dwErr ) ; AfxMessageBox( szErr ) ; closesocket( m_s ) ; return ; } sa.sin_family = AF_INET; sa.sin_port = htons(7000); sa.sin_addr.s_addr= m_iphostsource; if (bind(m_s,(PSOCKADDR)&sa, sizeof(sa)) == SOCKET_ERROR) { dwErr = WSAGetLastError() ; sprintf( szErr , "Error bind() = %ld " , dwErr ) ; AfxMessageBox( szErr ) ; closesocket( m_s ) ; return ; } if( SOCKET_ERROR != WSAIoctl( m_s, SIO_RCVALL , &dwBufferInLen, sizeof(dwBufferInLen), &dwBufferLen, sizeof(dwBufferLen), &dwBytesReturned , NULL , NULL ) ) AfxBeginThread( threadFunc , (LPVOID)this ); else { dwErr = WSAGetLastError() ; sprintf( szErr , "Error WSAIoctl = %ld " , dwErr ) ; AfxMessageBox( szErr ) ; closesocket( m_s ) ; return ; } } void CIpmonDlg::OnOK() { // TODO: Add extra validation here if( NULL != m_threadID ) PostThreadMessage(m_threadID,WM_CLOSE,0,0) ; if( m_IPArr.GetSize() ) m_IPArr.RemoveAll() ; CDialog::OnOK(); } void CIpmonDlg::AddData(CString s0,CString s1, CString s2, CString s3, CString s4, CString s5, CString s6) { int index; index = m_ctrList.InsertItem(0,s0); m_ctrList.SetItem(index,1,LVIF_TEXT,s1, 0, 0, 0,0); m_ctrList.SetItem(index,2,LVIF_TEXT,s2, 0, 0, 0,0); m_ctrList.SetItem(index,3,LVIF_TEXT,s3, 0, 0, 0,0); m_ctrList.SetItem(index,4,LVIF_TEXT,s4, 0, 0, 0,0); m_ctrList.SetItem(index,5,LVIF_TEXT,s5, 0, 0, 0,0); m_ctrList.SetItem(index,6,LVIF_TEXT,s6, 0, 0, 0,0); }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你可知这世上再难遇我

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值