已阅读5页,还剩12页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
关于关于 ARP 协议的基础知识协议的基础知识 1 ARP 的工作原理 本来我不想在此重复那些遍地都是的关于 ARP 的基本常识 但是为了保持文章的完整性以 及照顾初学者 我就再啰嗦一些文字吧 资深读者可以直接跳过此节 我们都知道以太网设备比如网卡都有自己全球唯一的 MAC 地址 它们是以 MAC 地址来 传输以太网数据包的 但是它们却识别不了我们 IP 包中的 IP 地址 所以我们在以太网中 进行 IP 通信的时候就需要一个协议来建立 IP 地址与 MAC 地址的对应关系 以使 IP 数据 包能发到一个确定的地方去 这就是 ARP Address Resolution Protocol 地址解析协议 讲到此处 我们可以在命令行窗口中 输入 arp a 来看一下效果 类似于这样的条目 210 118 45 100 00 0b 5f e6 c5 d7 dynamic 就是我们电脑里存储的关于 IP 地址与 MAC 地址的对应关系 dynamic 表示是临时存储在 ARP 缓存中的条目 过一段时间就会超时被删除 xp 2003 系统是 2 分钟 这样一来 比如我们的电脑要和一台机器比如 210 118 45 1 通信的时候 它会首先去检查 arp 缓存 查找是否有对应的 arp 条目 如果没有 它就会给这个以太网络发 ARP 请求包请求包 广播询问 210 118 45 1 的对应 MAC 地址 当然 网络中每台电脑都会收到这个请求包 但 是它们发现 210 118 45 1 并非自己 就不会做出相应 而 210 118 45 1 就会给我们的电脑回 复一个 ARP 应答包应答包 告诉我们它的 MAC 地址是 xx xx xx xx xx xx 于是我们电脑的 ARP 缓存就会相应刷新 多了这么一条 210 118 45 1 xx xx xx xx xx xx dynamic 为什么要有这么一个 ARP 缓存呢 试想一下如果没有缓存 我们每发一个 IP 包都要发个 广播查询地址 岂不是又浪费带宽又浪费资源 而且我们的网络设备是无法识别 ARP 包的真伪的 如果我们按照 ARP 的格式来发送数 据包 只要信息有效计算机就会根据包中的内容做相应的反应 试想一下 如果我们按照 ARP 响应包的相应的内容来刷新自己的 ARP 缓存中的列表 嘿嘿 那我们岂不是可以根据这点在没有安全防范的网络中玩些 ARP 包的小把戏了 在后面的文 章里我就手把手来教你们如何填充发送 ARP 包 不过先别急 我们再继续学点基础知识 2 ARP 包的格式包的格式 既然我们要来做一个我们自己的 ARP 包 当然首先要学习一下 ARP 包的格式 从网络底层看来 一个 ARP 包是分为两个部分的 前面一个是物理帧头物理帧头 后面一个才 是 ARP 帧帧 首先 物理帧头 它将存在于任何一个协议数据包的前面 我们称之为 DLC Header 因为这个帧头是在数据链路层构造的 并且其主要内容为收发双方的物理地址 以便硬件设备识别 DLC Header 字段 长度 Byte 默认值备注 接收方 MAC6 广播时 为 ff ff ff ff ff ff 发送方 MAC6 Ethertype20 x08060 x0806 是 ARP 帧的类型值 图 1 物理帧头格式 图 1 是需要我们填充的物理帧头的格式 我们可以看到需要我们填充的仅仅是发送端和 接收端的物理地址罢了 是不是很简单呢 接下来我们看一下 ARP 帧的格式 ARP Frame 字段 长度 Byte 默认值备注 硬件类型20 x1以太网类型值 上层协议类型20 x0800上层协议为 IP 协议 MAC 地址长度 10 x6以太网 MAC 地址长度为 6 IP 地址长度10 x4IP 地址长度为 4 操作码2 0 x1 表示 ARP 请求包 0 x2 表示应答包 发送方 MAC6 发送方 IP4 接收方 MAC6 接收方 IP4 填充数据18 因为物理帧最小长度为 64 字节 前面的 42 字节 再加上 4 个 CRC 校验字节 还差 18 个字节 图 2 ARP 帧格式 我们可以看到需要我们填充的同样也只是 MAC IP 再加上一个 1 或 2 的操作码而已 3 ARP 包的填充包的填充 1 请求包的填充 比如我们的电脑 MAC 地址为 aa aa aa aa aa aa IP 为 192 168 0 1 我们想要查询 192 168 0 99 的 MAC 地址 应该怎么来做呢 首先填充 DLC Header 通过前面的学习我们知道 想要知道某个计算机对应的 MAC 地 址是要给全网发送广播的 所以接收方接收方 MAC 肯定是 ffffffffffff 发送方发送方 MAC 当然是自己 啦 于是我们的 DLC Header 就填充完成了 如图 加粗的是我们要手动输入的值 当然我 编的程序比较智能 会根据你选择的 ARP 包类型帮你自动填入一些字段 你一用便知 DLC Header 字段 长度 Byte 填充值 接收方 MAC6ffffffffffff 发送方 MAC6aaaaaaaaaaaa Ethertype20 x0806 图 3 ARP 请求包中 DLC Header 内容 接下来是 ARP 帧 请求包的操作码操作码当然是 1 发送方的发送方的 MAC 以及 IP 当然填入我们自己 的 然后要注意一下 这里的接收方接收方 IP 填入我们要查询的那个 IP 地址 就是 192 168 0 99 了 而接收方接收方 MAC 填入任意值就行 不起作用 于是 如图 ARP Frame 字段 长度 Byte 填充值 硬件类型21 上层协议类型20800 MAC 地址长度 16 IP 地址长度14 操作码21 发送方 MAC6aaaaaaaaaaaa 发送方 IP4192 168 0 1 接收方 MAC6任意值任意值 xxxxxxxxxxxx 接收方 IP4192 168 0 99 填充数据180 图 4 ARP 请求包中 ARP 帧的内容 如果我们构造一个这样的包发送出去 如果 192 168 0 99 存在且是活动的 我们马上就 会收到一个 192 168 0 99 发来的一个响应包 我们可以查看一下我们的 ARP 缓存列表 是 不是多了一项类似这样的条目 192 168 0 99 bb bb bb bb bb bb 是不是很神奇呢 我们再来看一下 ARP 响应包的构造 2 响应包的填充响应包的填充 有了前面详细的解说 你肯定就能自己说出响应包的填充方法来了吧 所以我就不细说 了 列两个表就好了 比如说给 192 168 0 99 MAC 为 bb bb bb bb bb bb 发一个 ARP 响应包 告诉它我们 的 MAC 地址为 aa aa aa aa aa aa 就是如此来填充各个字段 DLC Header 字段 长度 Byte 填充值 接收方 MAC6bbbbbbbbbbbb 发送方 MAC6aaaaaaaaaaaa Ethertype20 x0806 图 5 ARP 响应包中 DLC Header 内容 ARP Frame 字段 长度 Byte 填充值 硬件类型21 上层协议类型20800 MAC 地址长度 16 IP 地址长度14 操作码22 发送方 MAC6aaaaaaaaaaaa 发送方 IP4192 168 0 1 接收方 MAC6bbbbbbbbbbbb 接收方 IP4192 168 0 99 填充数据180 图 6 ARP 响应包中 ARP 帧的内容 这样 192 168 0 99 的 ARP 缓存中就会多了一条关于我们 192 168 0 1 的地址映射 好了 终于到了编程实现它的时候了 二 发送 ARP 包的编程实现 1 填充数据包 上面的那些关于 ARP 包各个字段的表格 对应在程序里就是结构体 对应于上面的表格 于是我们需要三个下面这样的结构体 DLC Header typedef struct tagDLCHeader unsigned char DesMAC 6 destination HW addrress unsigned char SrcMAC 6 source HW addresss unsigned short Ethertype ethernet type DLCHEADER PDLCHEADER ARP Frame typedef struct tagARPFrame unsigned short HW Type hardware address unsigned short Prot Type protocol address unsigned char HW Addr Len length of hardware address unsigned char Prot Addr Len length of protocol address unsigned short Opcode ARP RARP unsigned char Send HW Addr 6 sender hardware address unsigned long Send Prot Addr sender protocol address unsigned char Targ HW Addr 6 target hardware address unsigned long Targ Prot Addr target protocol address unsigned char padding 18 ARPFRAME PARPFRAME ARP Packet DLC header ARP Frame typedef struct tagARPPacket DLCHEADER dlcHeader ARPFRAME arpFrame ARPPACKET PARPPACKET 这些结构体一定能看懂吧 在程序中就是对号入座就好了 1 填充数据包 下面我举个填充包头的例子 我首先定义个了一个转换字符的函数 如下 Name unsigned char c strlwr lpHWAddrStr 转换成小写 for i 0 i 0 strTemp Device NPF strTemp 加上前缀 list InsertItem nAdapterIndex strTemp strcpy AdapterList nAdapterIndex szDeviceName strTemp IP strcpy AdapterList nAdapterIndex szIPAddrStr pAdapter IpAddressList IpAddress String list SetItemText nAdapterIndex 1 AdapterList nAdapterIndex szIPAddrStr MAC formatMACToStr AdapterList nAdapterIndex szHWAddrStr pAdapter Address list SetItemText nAdapterIndex 2 AdapterLis nAdapterIndex szHWAddrStr 网卡编号 AdapterList nAdapterIndex dwIndex pAdapter Index pAdapter pAdapter Next nAdapterIndex delete pAdapterListBuffer 2 获取 ARP 条目列表 ARP 条目信息 typedef struct tagARPInfo char szIPAddrStr 16 IP char szHWAddrStr 18 MAC DWORD dwType 类型 INFO ARP PINFO ARP Name DWORD dwListSize 1 DWORD dwRet in addr inaddr list DeleteAllItems dwRet GetIpNetTable PMIB IPNETTABLE 关键 函数 if dwRet ERROR INSUFFICIENT BUFFER PMIB IPNETTABLE pIpNetTable PMIB IPNETTABLE new char dwListSize dwRet GetIpNetTable pIpNetTable if dwRet ERROR SUCCESS for int i 0 idwNumEntries i IP inaddr S un S addr pIpNetTable table i dwAddr strcpy ARPList i szIPAddrStr inet ntoa inaddr MAC formatMACToStr ARPList i szHWAddrStr pIpNetTable table i bPhysAddr Type ARPList i dwType pIpNetTable table i dwType if AdapterList nAdapterIndex dwIndex pIpNetTable table i dwIndex continue list InsertItem i ARPList i szIPAddrStr list SetItemText i 1 ARPList i szHWAddrStr switch ARPList i dwType 根据 type 的值来转换成字符显示 case 3 list SetItemText i 2 Dynamic break case 4 list SetItemText i 2 Static break case 1 list SetItemText i 2 Invalid default list SetItemText i 2 Other delete pIpNetTable 这样一来 我们基本上大功告成了 其他还有一些东西在这里就不讲了 大家可以下 载我的代码看看就好了 下面我们来用 ARP 包玩一些小把戏 四 ARP 包的游戏 既然我们可以自己来填充数据包 那么来玩些 ARP 的 小游戏 欺骗就是易如反掌了 当然 是在没有安全防护的网络里 比如只有 hub 或者交换机把你们相连 而没有路由分 段 下面我就由浅入深的讲一些介绍一些关于 ARP 的小伎俩 1 小伎俩 1 你可以试着发一个请求包广播 其中的 ARP 帧里关于你的信息填成这样 为了节省篇幅 我只写需要特别指出的填充字段 发送方 MAC6随便乱填一个错误的随便乱填一个错误的 发送方 IP4 填上你的填上你的 IP 出现什么结果 是不是弹出一个 IP 地址冲突的提示 呵呵 同样的道理 如果发送方 IP 填成别人的 然后每隔 1 秒发一次 b 2 比如你们都靠一个网关 192 168 0 1 上网 如果你想让 192 168 0 77 上不了网 就 可以伪装成网关给 192 168 0 77 发一个错误的 ARP 响应包 like this 发送方 MAC6随便乱填一个错误的随便乱填一个错误的 发送方 IP4 网关网关 IP 192 168 0 1 接收方就填 192 168 0 77 的相关信息 发送之后 它还能上网不 这样能折腾他好一阵子了 只要它的系统得不到正确的到网关的 ARP 映射表它就一直上不 了网了 呵呵类似的伎俩还有很多 不过只停留在这点东西上也没什么意思 还是看看稍微高 深一点的吧 ULONG PacketGetAdapterNames PTSTR pStr PULONG BufferSize 例 01 通常 这应该是第一个与适配器建立通信的函数 该函数将系统中适配器的名字返回到用 户分配的缓冲区 pStr 中 在适配器名字后 pStr 还含有描述适配器的字符串 BufferSize 表示缓冲区的长度 注意 这个函数的结果是通过查询操作系统注册表得到 因此 在 Windows NT 2000 中返 回结果的格式与 Windows 95 98 ME 返回的有所不同 在 Windows 9X 系统中对字符串采用 ASCII 编码方式 而在 Windows NTx 系统中通常采用 UNICODE 编码方式 在 Windows 95x 中调用 PacketGetAdapterNames 函数后 pStr 获得由单字节 ASCII 符 0 分 隔开的适配器名字字符串 随后是一个双字节 ASCII 字符 0 接着是一个由单字节 ASCII 符 0 分隔开的对适配器进行描述的 ASCII 字符串 最后以一个双字节 ASCII 字符 0 结束 在 Windows NTx 中调用 PacketGetAdapterNames 函数后 pStr 获得由单字节 0 符分隔的适 配器名字字符串 以 UNICODE 格式表示 随后是一个双字节 UNICODE 字符 0 接着是 一个由单字节 ASCII 符 0 分隔开的对适配器进行描述的 ASCII 格式字符串 最后以一个 双字节 ASCII 字符 0 结束 LPADAPTER PacketOpenAdapter LPTSTR AdapterName 例 02 这个函数接收一个含有适配器名的字符串 如成功打开一个适配器 该函数返回一个指 向已正确初始化的 ADAPTER 结构体指针 适配器名可通过 PacketGetAdapterNames 函数 取得 注意 Windows95 版本的捕获驱动程序是以 ASCII 格式运行 而 Windows NT 版本的则 以 UNICODE 格式运行 因此 在 Windows95 中 AdapterName 应该为 ASCII 字符串 在 Windows NT 中应该为 UNICODE 字符串 如果 AdapterName 字符串是通过 PacketGetAdapetNames 函数取得 则可不考虑此问题 因为该函数已将适配器名按正确格 式返回 但当字符串是通过 scanf 这类 ANSI C 函数获得 则会在 Windows NT 环境下出现 问题 因为这类函数使用的是 ASCII 格式 在 UNIX 平台下输入命令行时也会出现类似问 题 为避免这种问题产生 我们在 Windows NT 版本的 PacketOpenAdapter 函数中包含了一 个将字符串从 ASCII 转换为 UNICODE 格式的程序 这样 Windows NT 版本的 PacketOpenAdapter 函数能接受 ASCII 或 UNICODE 格式的字符串 如果传入一个 ASCII 字 符串 PACKET DLL 会将这个字符串转换为 UNICODE 格式再传到驱动 VOID PacketCloseAdapter LPADAPTER lpAdapter 例 03 这个函数释放 ADAPTER 结构体变量 lpAdapter 并关闭该指针变量指向的适配器 LPPACKET PacketAllocatePacket void 例 04 该函数给 PACKET 结构体分配内存大小并返回一个指向该结构体的指针 返回的结构体 要通过调用 PacketInitPacket 函数来进行正确的初始化 注意 分配存放结构体 PACKET 的缓冲区的大小不使用这个函数 而是靠程序员自己分 配 与 PACKET 结构体相关联的调用 PacketInitPacket 函数分配 VOID PacketInitPacket LPPACKET lpPacket PVOID Buffer UINT Length 例 05 该函数初始化一个 PACKET 结构体 它有三个输入参数 lpPacket 要进行初始化的 PACKET 结构体 Buffer 由用户分配的存放数据包的缓冲区 Length 缓冲区的大小 这是通过只读方式将数据从缓冲区转移到应用程序的最大缓冲大 小 注意 与 PACKET 结构体关联的缓冲区大小是一个会明显影响捕获数据包过程的参数 因为这个缓冲区中存放了从驱动传来的捕获的数据包 而驱动能通过只读调用 参见 PacketReceivePacket 函数 返回几个捕获的数据包 而一次调用可传给应用程序的包数量 与缓冲区大小有关 这个缓冲区与进行读取的 PACKET 结构体关联 因此 用 PacketInitPacket 函数设置较大的缓冲区可以减少系统调用的次数 提高捕获包的速度 VOID PacketFreePacket LPPACKET lpPacket 例 06 这个函数释放指向 PACKET 结构体的指针 lpPacket 注意 这个函数不能释放结构体 PACKET 的变量 Buffer 必须明确地由程序员释放 BOOLEAN PacketReceivePacket LPADAPTER AdapterObject LPPACKET lpPacket BOOLEAN Sync 例 07 利用这个函数可以捕获一组数据包 该函数有以下三个输入参数 AdapterObject 指向 ADAPTER 结构体的指针 指定接收数据包的网络适配器 lpPacket 指向一个 PACKET 结构体的指针 该结构体存放收到的数据包 Sync 说明操作是同步方式还是异步方式的标识符 这个参数较陈旧 因为对适配器的使 用总是同步的 所以在新近版本的 PACKET DLL 中可忽略该参数 用这个函数获得的数据包的数量是变化的 它依赖于实际存储在驱动缓冲区中的数据包 的数目 依赖于数据包的大小 依赖于和 lpPacket 相关的缓冲区大小 图 1 显示了驱动传 递给应用程序的数据包的格式 图 1 数据包编码方式 捕获的数据包存放在与 PACKET 结构体关联的 lpPacket 缓冲区中 每个包都有一个 bpf hdr 结构体组成的报头 说明了数据包的长度和捕获包的时间戳 填充变量校验缓冲区 中的数据 提高接收包的速度 bpf hdr 结构体中的 bh datalen 和 bh hdrlen 参数可以将数 据包从缓冲区中提取出来 在例程 TestApp cpp 和 pcap win32 c 文件的 pcap read 函数中 都可找到例子 Lippcap 正确的提取每一个捕获的数据包并传给应用程序 因此运用程序不 必再进行这些操作 用 PacketSetReadTimeout 函数可以在读取数据时设置等待时间 这样 即使没有捕获包 但设置的等待时间已过 读取调用也会返回 BOOLEAN PacketSetMinToCopy LPADAPTER AdapterObject int nbytes 例 08 这个函数能定义内核缓冲区最小的数据空间大小 这会导致驱动释放进程中的一个读取 调用 例如 PacketReceivePacket 函数 Nbytes 就规定了内核的这个缓冲区大小 AdapterObject 是一个指向 ADAPTER 结构体的指针 给 nbytes 设定一个较大的值 内核会在接收到几个数据包后在将数据复制给用户 这保 证了系统的低调用率 例如 CPU 较低的使用率 较高的性能 这样对 sniffer Vice versa 这类应用程序有利 反之 如果 nbytes 值较小的话 应用程序已准备好接收 内核会把数 据包复制给它 对于象网桥这种要内核有较快回应的实时应用程序 建议将 nbytes 设置得 较小 注意 这个函数仅对 Windows NTx 有效 Windows95X 的驱动不支持这种操作 因此 PacketSetMinToCopy 函数只能在这种系统下执行 BOOLEAN PacketSendPacket LPADAPTER AdapterObject LPPACKET pPacket BOOLEAN Sync 例 09 利用这个函数 可通过该函数传入的 AdapterObject 参数指定的网络适配器将原始数据包 发到网络中 所谓 原始数据包 是指程序员要自己构造各种报头 因为这个函数会将数据 包按照其现有的样子发送到网络中 程序员不必在数据包前加 bpf hdr 数据头 也不必计 算 CRC 并将其加到包中 因为它已经通过网络接口加到了数据包尾部 PacketSendPacket 函数的语法与 PacketReceivePacket 函数的相同 PacketSendPacket 函数的作用会受到 PacketSetNumWriters 函数的影响 用 PacketSetNumWrites 函数可以设置只写数据反复的次数 如果这个数设置为 1 每个 PacketSendPacket 函数会响应一个发送到网络中的数据包 如果这个值比 1 大 例如是 1000 则应用程序写在驱动设备文件上的每一个原始数据包将会向网络发送 1000 次 这个 特性可以减少环境转换时的系统开销 从而产生高速通信 这对测试网络 路由器 服务 器的工具特别有用 注意 构造多重数据包目前只能在 Windows NTx 版本的驱动中才能实现 在 Windows 95 98 Me 系统中 这可以仿效 PACKET DLL 中的用户级实现 这意味着在 Windows 9X 系 统中应用程序也可以使用构造多重数据包方法 但与 Windows NTx 相比 速度就非常慢了 最优化发送过程局限于一次发送一个包 不能一次发送多重数据包 BOOLEAN PacketSetHwFilter LPADAPTER AdapterObject ULONG Filter 例 10 通过这个函数给引入的数据包设置硬件过滤器 定义过滤器的常量在 ntddndis h 头文件 中申明了 输入的参数是设置过滤器的网络适配器和过滤器的标示符 如果运行成功则 返 回 TRUE 值 以下是最有用的过滤器的列表 NDIS PACKET TYPE PROMISCUOUS 将网络适配器设置为混杂模式 这样网络适配 器会接收每一个数据包 NDIS PACKET TYPE DIRECTED 将网络适配器设置为直接模式 这样网络适配器接 收发送到该工作站的数据包 NDIS PACKET TYPE BROADCAST 将网络适配器设置为广播模式 这样网络适配器 会接收网络中广播数据包 NDIS PACKET TYPE MULTICAST 将网络适配器设置为组播模式 这样网络适配器能 接收属于该组成员的组播数据包 NDIS PACKET TYPE ALL MULTICAST 将网卡设置为该模式 可以接收所有的组播 数据包 NDIS PACKET TYPE ALL LOCAL 将网络适配器设置为本地模式 这样网络适配器可 以接收所有本地的数据包 例如 NDIS PACEKT TYPE DIRECTED NDIS PACEKT TYPE BROADCAST NDIS PACKET TYPE MULTICAST BOOLEAN PacketRequest LPADAPTER AdapterObject BOOLEAN Set PPACKET OID DATA OidData 这个函数对 AdapeterObject 指向的网络适配器执行查询 设置操作 通过这个函数 可以获 得或定义网络适配器的各种参数 比如内核缓冲区的大小 连接速度或错误的数据包的计 数器 第二个参数规定如果操作是设置 Set TRUE 时 或询问 Set FALSE 时 第三个 参数是一个指向 PACKET OID DATA 结构体 参见数据结构体部分 的指针 如果该函 数完成而不发生任何错误 则返回值为 TRUE 定义操作方式的常量在 ntddndis h 头文件 中申明 这部分的详细内容可参见 Microsoft DDK 提供的文档 注意 不是所有的网络适配器都执行所有的询问 设置函数 有一套托管 OID 函数和一套 特许函数能够在各种适配器上运行 但不是所有适配器都提供 查询 DDKs 可知哪些函 数是托管的 如果你使用了特许函数 你要将这个函数放到 if 语句中检查其结果 BOOLEAN PacketSetBuff LPADAPTER AdapterObject int dim 例 11 通过这个函数 可以设置 AdapterObject 指向的与网络适配器关联的驱动程序缓冲区的大小 参数 dim 指定设置缓冲区的大小 用 byte 表示 如果成功完成设置 该函数返回 TRUE 值 如果没有足够的内存分配给新的缓冲区 则该函数返回 FALSE 值 当设置一个新的 缓冲区大小 存放在原缓冲区中的数据会被丢弃 导致存放的数据包会被丢失 注意 驱动中缓冲区的大小对捕获数据包进程有很大的影响 一个捕获包的应用程序要对 每一个数据包进行操作 特别是当 CPU 还要同时处理多个任务 因此当网络通信繁忙或突 然爆发时 同时由于其他程序使得 CPU 符合较重时 这个应用程序就不能按照网络速度工 作了 这种问题在速度较慢的机器上显得更明显 另一方面 驱动以内核模式工作 并且 对捕获的数据包进行读写 这样速度会很快 通常也不会丢失数据包 因此驱动中有足够 的缓冲区就会在应用程序忙时存放捕获的包 这样弥补了应用程序反应慢和避免了网络高 吞吐量时数据包的丢失 当打开一个驱动实例时 缓冲区的大小设置为 0 所以程序员一 定要记住个驱动设置一个合适的缓冲区大小 Libpcap 调用这个函数 并在捕获包前将缓冲 区设置为 1MB 因此调用 libpcap 编写的程序通常不必处理这个问题 BOOLEAN PacketSetBpf LPADAPTER AdapterObject struct bpf program fp 这个函数将一个新的 BPF 过滤器和一个网络适配器 AdapterObject 关联起来 fp 指向的过 滤器是一套指令 通过这些指令 驱动中的 BPF 注册机会处理每一个捕获的包 BPF 过滤 器的有关细节可参阅 McCanne and Jacobson 1993 如果驱动设置成功 这个函数返回 TRUE 值 如果发生错误或者过滤器程序没有接收 就返回 FALSE 值 为了避免由于这些 程序造成系统崩溃 驱动会对每一个新的过滤器进行检查 并拒绝无效的过滤器 利用 libpcap 库中的 pcap compile 函数可以自动创建一个过滤器 这个函数通过 WinDump 详 见 WinDump 手册 的语法可以将个一个文本过滤器转换为 BPF 格式 如果你不想用 libpcap 库 但却要知道过滤器的代码 你可以通过参数 d dd 或 ddd 来启动 WinDump 从而获得过滤器的伪代码 BOOLEAN PacketGetStats LPADAPTER AdapterObject struct bpf stat s 利用这个函数 程序员可以得到驱动中两个内部变量的值 由 AdapterObject 指向的网络适配器所收到的数据包的数量 开始的时间是当 PacketOpenAdapter 函数打开一个网络适配器时 网络适配器接收到但内核丢弃掉的数据包的数量 当用户应用程序未做好接收准备 与适 配器相关联的内核缓冲区占满时 会丢弃掉一个数据包 这两个值是通过应用程序中复制 bpf stat 结构体得到的 这两个值对了解网络状态和捕获 包的过程都很有用 BOOLEAN PacketGetNetType LPADAPTER AdapterObject NetType type 这个函数可以将 AdapterObject 指向的网络适配器的类型返回到 NetType 结构体中 这个函 数可以将连接类型参数 LinkType 设置为以下几个值 NdisMedium802 3 Ethernet 802 3 NdisMedium802 5 Token Ring 802 5 NdisMediumFddi FDDI NdisMediumWan WAN NdisMediumLocalTalk LocalTalk NdisMediumDix DIX NidsMediumAtm ATM NdisMediumArcnetRaw ARCNET raw NdisMediumArcnet878 2 ARCNET 878 2 NdisMediumWirelessWan Various types of NdisWirelessXxx media BPF 捕获包驱动程序支持 NidsMediumWan NdisMedium802 3 NdisMedium802 5 NdisMediumFddi NdisMedium Arcnet878 2 和 NdisMediumAtm 连接速度参数 LinkSpeed 说明网络速度 单位 比特 秒 如果该函数成功调用 返回一 个非零值 BOOLEAN PacketSetReadTimeout LPADAPTER AdapterObject int timeout 这个函数设置了 AdapterObject 指向的网络适配器的读取数据超时的值 参数 timeout 设 定 PacketReceivePacket 返回后 或者驱动没有捕获到包 超时的长度 单位 毫秒 将 timeout 设置为 0 表示没有超时设定 例如 如果没有接收到数据包 PacketReceivePacket 不返回值 将 timeout 设置为 1 则 PacketReceive 总是立刻返回 在网络适配器处于统计 工作模式下 这个函数仍然有效 它可以用来设置内部两个统计报告之间的间隔时间 BOOLEAN PacketSetMode LPADAPTER AdapterObject int mode 这个函数设置 AdapterObject 指向的网络适配器的工作模式 mode 参数由下面两种可能 的值 PACKET MODE CAPT 标准捕获模式 调用 PacketOpenAdapter 后 这被设置为网络适 配器的默认工作模式 PACKET MODE STAT 统计模式 这是 BPF 捕获包驱动程序特有的工作模式 它可以 对网络流量进行实时统计 当处在统计模式下 驱动程序并不去捕获包 而只是统计包的 数量及符合用户定义的 BPF 过滤器的比特总数 这些计数器可以通过标准的 PacketReceivePacket 函数取得 并且每次达到超时设定的时间时取得一次 默认的超时设定 为 1 秒 但也可以通过 PacketSetReadTimeout 函数设定为其他任意的值 可以精确到 1 毫 秒 这些计数器先封装在 bpf hdr 结构体中再传给应用程序 为了与用 libpcap 库捕获数 据包的时间格式统一 也可以用精确到微秒的时间戳 这种模式下的捕获数据包过程对系 统的影响很小 如果一个程序要使用统计模式
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 建筑幕墙检测实战试题集及解析手册
- 渔业生态安全课件
- 广西大学期末试题库及答案
- 地理气候知识风向和风力的认识与应用试题集详解版
- 开学攻略入学测试题型解析与答案
- 电子信息类电子通信技术测试卷与答案详解
- 矿物微量元素分析实战题库及答案
- 家庭冲突解决自测题及应对方法建立和谐家庭环境
- 开学首月舞蹈考试试题及答案解析
- 航空航天领域安全操作规范测试题库及解答
- 修理扫帚课件
- 2025年成都市团校入团考试题库(含答案)
- 毛绒玩具课件讲解
- 监理安全知识岗前培训课件
- 霹雳舞教学课件图片
- 特种设备管理课件
- 某市美术馆建设项目可行性研究报告
- 2025年国网湖北电力考试笔试试题(含答案)
- 中小企业融资计划书模板
- 2025至2030年中国包醛氧淀粉行业市场深度分析及发展趋势预测报告
- 小儿流行性腮腺炎护理查房
评论
0/150
提交评论