| liang's profile阿斯提亚神殿——梦幻天子's skyPhotosBlogLists | Help |
|
December 16 TCPDUMP的使用(转载)tcpdump采用命令行方式,它的命令格式为: tcpdump [ -adeflnNOpqStvx ] [ -c 数量 ] [ -F 文件名 ] [ -i 网络接口 ] [ -r 文件名] [ -s snaplen ] [ -T 类型 ] [ -w 文件名 ] [表达式 ] 1. tcpdump的选项介绍 -a 将网络地址和广播地址转变成名字; -d 将匹配信息包的代码以人们能够理解的汇编格式给出; -dd 将匹配信息包的代码以c语言程序段的格式给出; -ddd 将匹配信息包的代码以十进制的形式给出; -e 在输出行打印出数据链路层的头部信息; -f 将外部的Internet地址以数字的形式打印出来; -l 使标准输出变为缓冲行形式; -n 不把网络地址转换成名字; -t 在输出的每一行不打印时间戳; -v 输出一个稍微详细的信息,例如在ip包中可以包括ttl和服务类型的信息; -vv 输出详细的报文信息; -c 在收到指定的包的数目后,tcpdump就会停止; -F 从指定的文件中读取表达式,忽略其它的表达式; -i 指定监听的网络接口; -r 从指定的文件中读取包(这些包一般通过-w选项产生); -w 直接将包写入文件中,并不分析和打印出来; -T 将监听到的包直接解释为指定的类型的报文,常见的类型有rpc (远程过程 调用)和snmp(简单 网络管理协议;) 2. tcpdump的表达式介绍 表达式是一个正则表达式,tcpdump利用它作为过滤报文的条件,如果一个报文满足表 达式的条件,则这个报文将会被捕获。如果没有给出任何条件,则网络上所有的信息包将会 被截获。 在表达式中一般如下几种类型的关键字,一种是关于类型的关键字,主要包括host, net,port, 例如 host 210.27.48.2,指明 210.27.48.2是一台主机,net 202.0.0.0 指明 202.0.0.0是一个网络地址,port 23 指明端口号是23。如果没有指定类型,缺省的类型是 host. 第二种是确定传输方向的关键字,主要包括src , dst ,dst or src, dst and src , 这些关键字指明了传输的方向。举例说明,src 210.27.48.2 ,指明ip包中源地址是210.27. 48.2 , dst net 202.0.0.0 指明目的网络地址是202.0.0.0 。如果没有指明方向关键字,则 缺省是src or dst关键字。 第三种是协议的关键字,主要包括fddi,ip ,arp,rarp,tcp,udp等类型。Fddi指明是在 FDDI(分布式光纤数据接口网络)上的特定的网络协议,实际上它是"ether"的别名,fddi和e ther具有类似的源地址和目的地址,所以可以将fddi协议包当作ether的包进行处理和分析。 其他的几个关键字就是指明了监听的包的协议内容。如果没有指定任何协议,则tcpdump将会 监听所有协议的信息包。 除了这三种类型的关键字之外,其他重要的关键字如下:gateway, broadcast,less, greater,还有三种逻辑运算,取非运算是 'not ' '! ', 与运算是'and','&&';或运算 是'o r' ,'||'; 这些关键字可以组合起来构成强大的组合条件来满足人们的需要,下面举几个例子来 说明。 (1)想要截获所有210.27.48.1 的主机收到的和发出的所有的数据包: #tcpdump host 210.27.48.1 (2) 想要截获主机210.27.48.1 和主机210.27.48.2 或210.27.48.3的通信,使用命令 :(在命令行中适用 括号时,一定要 #tcpdump host 210.27.48.1 and \ (210.27.48.2 or 210.27.48.3 \) (3) 如果想要获取主机210.27.48.1除了和主机210.27.48.2之外所有主机通信的ip包 ,使用命令: #tcpdump ip host 210.27.48.1 and ! 210.27.48.2 (4)如果想要获取主机210.27.48.1接收或发出的telnet包,使用如下命令: #tcpdump tcp port 23 host 210.27.48.1 3. tcpdump 的输出结果介绍 下面我们介绍几种典型的tcpdump命令的输出信息 (1) 数据链路层头信息 使用命令#tcpdump --e host ice ice 是一台装有linux的主机,她的MAC地址是0:90:27:58:AF:1A H219是一台装有SOLARIC的SUN工作站,它的MAC地址是8:0:20:79:5B:46;上一条 命令的输出结果如下所示: 21:50:12.847509 eth0 < 8:0:20:79:5b:46 0:90:27:58:af:1a ip 60: h219.33357 > ice. telne t 0:0(0) ack 22535 win 8760 (DF) 分析:21:50:12是显示的时间, 847509是ID号,eth0 <表示从网络接口eth0 接受该 数据包,eth0 >表示从网络接口设备发送数据包, 8:0:20:79:5b:46是主机H219的MAC地址,它 表明是从源地址H219发来的数据包. 0:90:27:58:af:1a是主机ICE的MAC地址,表示该数据包的 目的地址是ICE . ip 是表明该数据包是IP数据包,60 是数据包的长度, h219.33357 > ice. telnet 表明该数据包是从主机H219的33357端口发往主机ICE的TELNET(23)端口. ack 22535 表明对序列号是222535的包进行响应. win 8760表明发送窗口的大小是8760. (2) ARP包的TCPDUMP输出信息 使用命令#tcpdump arp 得到的输出结果是: 22:32:42.802509 eth0 > arp who-has route tell ice (0:90:27:58:af:1a) 22:32:42.802902 eth0 < arp reply route is-at 0:90:27:12:10:66 (0:90:27:58:af :1a) 分析: 22:32:42是时间戳, 802509是ID号, eth0 >表明从主机发出该数据包, arp表明是 ARP请求包, who-has route tell ice表明是主机ICE请求主机ROUTE的MAC地址。 0:90:27:5 8:af:1a是主机ICE的MAC地址。 (3) TCP包的输出信息 用TCPDUMP捕获的TCP包的一般输出信息是: src > dst: flags data-seqno ack window urgent options src > dst:表明从源地址到目的地址, flags是TCP包中的标志信息,S 是SYN标志, F (F IN), P (PUSH) , R (RST) "." (没有标记); data-seqno是数据包中的数据的顺序号, ack是 下次期望的顺序号, window是接收缓存的窗口大小, urgent表明数据包中是否有紧急指针. Options是选项. (4) UDP包的输出信息 用TCPDUMP捕获的UDP包的一般输出信息是: route.port1 > ice.port2: udp lenth UDP十分简单,上面的输出行表明从主机ROUTE的port1端口发出的一个UDP数据包到主机 ICE的port2端口,类型是UDP, 包的长度是lenth December 12 MFC下让控件具有XP风格(转载)方法一:
1.首先确认你在Windows XP下,因为如果在98或2K下,那除非自己重画画所有界面,要不基本上是无法实现XP风格的。
2. 新建一个文本文件,把下面这段XML代码粘贴进去 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity processorArchitecture="x86" version="5.1.0.0" type="win32" name="test.exe"/> <description>Test Application</description> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" publicKeyToken="6595b64144ccf1df" language="*" processorArchitecture="x86"/> </dependentAssembly> </dependency> </assembly> 不要问我这段代码是什么意思,我也不知道,这段代码其实和任何一种试图实现XP风格时用的XML代码没有本质区别,几乎是一样的。粘贴进去时候存盘,名字随便取一个,反正到后面还是需要修改的。 3.假设在你的目录c:\abc下有一个可执行文件abc.exe,我们把刚才建立的那个XML的文件拷贝到c:\abc下,并把名字改为abc.exe.manifest,这时候你可以运行abc.exe,看看是不是已经具有了XP风格了?依次类推,在每一个你想改为XP风格的程序的统一目录里建立一个上面说的XML文件,并把名字改为可执行文件的名字加上".manifest"的扩展名(注意,不要把那个exe去掉,就可以了,你可以试着在MSDEV.exe所在目录中搞一个medev.exe.manifest的XML文件,看看VC起了什么变化?是不是资源编辑器里的对话框都变的漂亮了? 方法二:
首先在RES目录下建一个文件,命名Master.manifest然后用记事本打开放入
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity name="Microsoft.Windows.XXXX" processorArchitecture="x86" version="5.1.0.0" type="win32"/> <description>Windows Shell</description> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df" language="*" /> </dependentAssembly> </dependency> </assembly> 保存.. 然后VC6导入资源,把这个新建的文件导入,类型为24 保存.. 用记事本打开rc 文件, 找到自定义资源的地方 改成如下 句子 IDR_MANIFEST 24 MOVEABLE PURE "res\\Master.manifest" MOVABLE PURE是一定不能少的..保存 进入VC6, 把这个自定义资源IDR_MANIFEST的ID改为1(没有引号) 编译,,看一看是不是有了XP的风格. 这个程序就不用带第一种方法的那个文件了. December 10 Filtering expression syntax(转载)Note: this document has been drawn from the tcpdump man page. The original version can be found at www.tcpdump.org.
The expression selects which packets will be dumped. If no expression is given, all packets on the net will be accepted by the kernel-level filtering engine. Otherwise, only packets for which expression is `true' will be accepted. The expression consists of one or more primitives. Primitives usually consist of an id (name or number) preceded by one or more qualifiers. There are three different kinds of qualifier:
[`fddi' is actually an alias for `ether'; the parser treats them identically as meaning ``the data link level used on the specified network interface.'' FDDI headers contain Ethernet-like source and destination addresses, and often contain Ethernet-like packet types, so you can filter on these FDDI fields just as with the analogous Ethernet fields. FDDI headers also contain other fields, but you cannot name them explicitly in a filter expression. Similarly, `tr' is an alias for `ether'; the previous paragraph's statements about FDDI headers also apply to Token Ring headers.] In addition to the above, there are some special `primitive' keywords that don't follow the pattern: gateway, broadcast, less, greater and arithmetic expressions. All of these are described below. More complex filter expressions are built up by using the words and, or and not to combine primitives. E.g., `host foo and not port ftp and not port ftp-data'. To save typing, identical qualifier lists can be omitted. E.g., `tcp dst port ftp or ftp-data or domain' is exactly the same as `tcp dst port ftp or tcp dst port ftp-data or tcp dst port domain'. Allowable primitives are:
Primitives may be combined using:
Negation has highest precedence. Alternation and concatenation have equal precedence and associate left to right. Note that explicit and tokens, not juxtaposition, are now required for concatenation. If an identifier is given without a keyword, the most recent keyword is assumed. For example, not host vs and ace is short for
not host vs and host ace which should not be confused with
not ( host vs or ace ) Expression arguments can be passed to tcpdump as either a single argument or as multiple arguments, whichever is more convenient. Generally, if the expression contains Shell metacharacters, it is easier to pass it as a single, quoted argument. Multiple arguments are concatenated with spaces before being parsed. December 09 MSN SNIFFER制作基本完成经过一段时间对MFC的学习,MSN SNIFFER程序的界面终于完成了.以下是截图:
这里特别感谢为我做TEST的朋友!
下一阶段打算测试程序的健壮性,增强嗅探能力,适应不同的网络环境.
不过呢,首先还是研究下另外一个PRP吧... December 08 在对话框中加入工具栏(转载)工具栏(ToolBar)是一种非常方便的控件,能大大增加用户操作的效率,但是基于对话框的程序,却不能像使用编辑框(Edit Box)和列表框(List Box)一样,方便地增加工具栏控件。本文将介绍一种在对话框中加入工具栏的方法。 一、 技术要点分析 所有的Windows控件(包括工具栏、编辑框等)都派生自CWnd类,这就意味着,我们可以用窗口类的Create()函数把它们“创建”并显示到另一个窗口(例如对话框)上。把工具栏加入到对话框中正是使用了这样的一种方法。 通常,我们使用CToolBarCtrl类(派生自CWnd类)来创建并管理工具栏控件。使用这个类创建一条工具栏的一般步骤如下: 1.派生一个CToolBarCtrl的对象; 2.调用CToolBarCtrl::Create函数创建工具栏对象; 3.调用CToolBarCtrl::AddBitmap()和CToolBarCtrl::AddString()为工具栏对象加入位图和提示信息; 4.派生一个TBUTTON数组对象进行工具栏中各按钮的具体设置; 5.修改主窗口的OnNotify()函数,以显示工具栏上的提示信息。 以上步骤在下面的范例代码中会有具体体现。 二、 范例程序的建立与主要代码分析 利用Visual C++ 的向导生成一个基于对话框的程序,命名为ToolBarInDial。修改主对话框样式如图1。绘出一条工具栏的位图并建立一选单,设置几个子选单项,然后建立一组工具栏的提示信息串(String Table),一旦鼠标在工具栏某项上停留,就会显示提示信息。下面给出程序中的主要代码。 在主对话框CToolBarInDialDlg的类定义中有如下的变量说明: CToolBarCtrl ToolBar; int ButtonCount; int ButtonBitmap; BOOL DoFlag; TBUTTON m_Button[5]; //设置工具栏上具体信息的变量数组 //主对话框的初始化函数 BOOL CToolBarInDialDlg::OnInitDialog() { RECT rect; //设置工具栏的显示范围 rect.top=0; rect.left=0; rect.right=48; rect.bottom=16; ToolBar.Create(WS_CHILD|WS_VISIBLE|CCS_TOP|TBSTYLE_TOOLTIPS|CCS_ADJUSTABLE,rect,this,0); //建立工具栏并设置工具栏的样式 ButtonBitmap=ToolBar.AddBitmap(5,IDB_PLAY); //加入工具栏的位图 ButtonString=ToolBar.AddString(IDS_FIRST);//加入工具栏的提示信息 //以下代码开始设置各具体的按钮 m_Buttons[ButtonCount].iBitmap= ButtonBitmap+ButtonCount; //ButtonCount初值为0 m_Buttons[ButtonCount].idCommand=ID_PLAY; //工具栏与选单上某子项对应 m_Buttons[ButtonCount].fsState=TBSTATE_ENABLED; //设置工具栏按钮为可选 m_Buttons[ButtonCount].fsStyle=TBSTYLE_BUTTON; //设置工具栏按钮为普通按钮 m_Buttons[ButtonCount].dwData=0; m_Buttons[ButtonCount].iString=IDS_LAST; ++ButtonCount; //类似地设置第二个按钮 m_Buttons[ButtonCount].iBitmap=ButtonBitmap+ButtonCount; m_Buttons[ButtonCount].idCommand=ID_STOP; m_Buttons[ButtonCount].fsState=TBSTATE_ENABLED; m_Buttons[ButtonCount].fsStyle=TBSTYLE_BUTTON; m_Buttons[ButtonCount].dwData=0; m_Buttons[ButtonCount].iString=IDS_NEXT; ++ButtonCount; ……//省略设置剩下的按钮的代码 ToolBar.AddButtons(ButtonCount,m_Buttons); //为工具栏加入按钮并显示在对话框中 return TRUE; } //当鼠标在工具栏上停留时,调用这个函数来显示提示信息 BOOL CToolBarInDialDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULTpResult) { TOOLTIPTEXTtt; tt=(TOOLTIPTEXT)lParam; CString Tip; switch(tt->hdr.code) { case TTN_NEEDTEXT: //该信息表明要求显示工具栏上的提示 switch(tt->hdr.idFrom) { case ID_PLAY: ![]() 图1 Tip.LoadString(IDS_FIRST); //设置对应于工具栏上ID_PLAY的按钮的提示信息 break; case ID_STOP: Tip.LoadString(IDS_NEXT); //IDS_FIRST,IDS_NEXT等为一系列CString串 break; ……//类似地设置剩下按钮的提示信息 } strcpy(tt->szText,(LPCSTR)Tip); //显示提示信息 break; } return CDialog::OnNotify(wParam, lParam, pResult); } //该演示程序的工具栏能由用户定制,随时增加或删除工具栏中的某一项 void CToolBarInDialDlg::OnApply() { switch(DoFlag) //用户选择了增加或删除工具栏中的“退出”按钮 { case TRUE: //增加工具栏上的“退出”按钮 m_Buttons[ButtonCount].iBitmap=ButtonBitmap+ButtonCount; m_Buttons[ButtonCount].idCommand=ID_QUIT; m_Buttons[ButtonCount].fsState=TBSTATE_ENABLED; m_Buttons[ButtonCount].fsStyle=TBSTYLE_BUTTON; m_Buttons[ButtonCount].dwData=0; m_Buttons[ButtonCount].iString=IDS_FIRST; ToolBar.InsertButton(ButtonCount,&&m_Buttons[ButtonCount]); //根据m_Buttons的信息在工具栏的尾部加上一个按钮 break; case FALSE: if(ToolBar.GetButtonCount()==4) //删除工具栏上某一特定位置的按钮 { ToolBar.DeleteButton(3); //删除工具栏上某一按钮 } break; } } void CToolBarInDialDlg::OnPlay() //响应函数举例 { …… //对应选单项的响应函数 } 以上程序在中/英文Windows 98、VC++ 6.0环境下编译通过,运行正常。图2为运行中的有工具栏的对话框程序。 ![]() 图2 December 07 CTreeCtrl中图标的使用(转载)建立一个CTreeCtrl控制成员 m_Tree;
使用图标的方法: Step1: //load icon HICON icon[4]; Icon[0]=AfxGetApp()->LoadIcon(IDI_ICON1); Icon[1]=AfxGetApp()->LoadIcon(IDI_ICON2);
Step2: //创建CImageList CImageList *ImageList4Tree = new CImageList; ImageList4Tree.Create(16,16,0,4,4); //16,16为图标分辩率,4,4为该list最多能容纳的图标数 For(int i=0;i<2;i++) { ImageList4Tree->Add(Icon[i]); //读入图标 }
Step3: //使用创建好的CImageList m_Tree.SetImageList(ImageList4Tree);
Step4: //在添加项的同时选用图标 m_Tree.InsertItem(itemName,0,1,parentItem); //第2个参数是item在添加好后的图标 //第3个参数为item在被选中后的图标 效果图如下: December 01 MFC 程序的初始化过程(转载)MFC 程序的初始化过程 MFC 程序也是个Windows 程序,它的内部一定也像第1章所述一样,有窗口注册动 作,有窗口产生动作,有消息循环动作,也有窗口函数。此刻我并不打算做出Windows 程 序,只是想交待给你一个程序流程,这个流程正是任何MFC 程序的初始化过程的简化。 以下是Frame2 范例程序的类别阶层及其成员。对于那些「除了构造式与析构式之外没 有其它成员」的类别,我就不在图中展开他们了:
(本图从Visual C++ 的「Class View 窗口」中获得) 就如我曾在第1章解释过的,InitApplication 和InitInstance 现在成了MFC 的CWinApp 的两个虚拟函数。前者负责「每一个程序只做一次」的动作,后者负责「每一个执行个 体都得做一次」的动作。通常,系统会(并且有能力)为你注册一些标准的窗口类别(当 然也就准备好了一些标准的窗口函数),你(应用程序设计者)应该在你的CMyWinApp 中改写InitInstance,并在其中把窗口产生出来-- 这样你才有机会在标准的窗口类别中 指定自己的窗口标题和菜单。下面就是我们新的main 函数: // MY.CPP CMyWinApp theApp; void main() { CWinApp* pApp = AfxGetApp(); pApp->InitApplication(); pApp->InitInstance(); pApp->Run(); } 其中pApp 指向theApp 全域对象。在这里我们开始看到了虚拟函数的妙用(还不熟练者 请快复习第2章): pApp->InitApplication() 调用的是CWinApp::InitApplication, pApp->InitInstance() 调用的是CMyWinApp::InitInstance(因为CMyWinApp 改 写它了), pApp->Run() 调用的是CWinApp::Run, 好,请注意以下CMyWinApp::InitInstance 的动作,以及它所引发的行为: BOOL CMyWinApp::InitInstance() { cout << "CMyWinApp::InitInstance \n"; m_pMainWnd = new CMyFrameWnd; // 引发CMyFrameWnd::CMyFrameWnd 构造式 return TRUE; } CMyFrameWnd::CMyFrameWnd() { Create(); // Create 是虚拟函数,但CMyFrameWnd 未改写它,所以引发父类别的 // CFrameWnd::Create } BOOL CFrameWnd::Create() { cout << "CFrameWnd::Create \n"; return TRUE; } BOOL CWnd::CreateEx() { cout << "CWnd::CreateEx \n"; PreCreateWindow(); // 这是一个虚拟函数,CWnd 中有定义,CFrameWnd 也改写了 // 它。 return TRUE; } BOOL CFrameWnd::PreCreateWindow() { cout << "CFrameWnd::PreCreateWindow \n"; return TRUE; } 以下就是Frame2 的执行结果: cl my.cpp mfc.cpp <Enter> CWinApp::InitApplication CMyWinApp::InitInstance CMyFrameWnd::CMyFrameWnd CFrameWnd::Create CWnd::CreateEx CFrameWnd::PreCreateWindow CWinApp::Run CWinThread::Run
|
|
|