




已阅读5页,还剩196页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
WinPcap 中文技术文档4.0.1 作者: The WinPcap Team 作者主页: 模块 WinPcap用户指南 o 定义 o 输出函数 o 过滤串表达式的语法 o 使用WinPcap编程 o WinPcap教程: 循序渐进教您使用WinPcap 获取设备列表 获取已安装设备的高级信息 打开适配器并捕获数据包 不用回调方法捕获数据包 过滤数据包 分析数据包 处理脱机堆文件 发送数据包 收集并统计网络流量 WinPcap核心资料 o NPF驱动核心指南 NPF结构与定义 NPF函数o Packet.dll - 数据包驱动API o 如何编译WinPcap 远程捕获 o 输出结构与定义 o 外部函数. 对于提供远程捕获的函数引用, 请参阅WinPcap 输出函数 章节的 Windows-specific Extensions . o 核心数据结构与定义 介绍本手册提供了WinPcap编程接口的描述及其源代码。它与详尽的WinPcap核心资料一起,为编程人员提供了详细的函数与结构的描述,同时也提供了若干教程和程序范例。 您可以点击页面顶部的导航链接,或者使用页面左边的树形控件,来跳转到您感兴趣的内容。 本文档使用 the Doxygen documentation system创建,您可以登录 阅览相关内容。 什么是WinPcapWinPcap是一个基于Win32平台的,用于捕获网络数据包并进行分析的开源库.大多数网络应用程序通过被广泛使用的操作系统元件来访问网络,比如sockets。 这是一种简单的实现方式,因为操作系统已经妥善处理了底层具体实现细节(比如协议处理,封装数据包等等),并且提供了一个与读写文件类似的,令人熟悉的接口。 然而,有些时候,这种“简单的方式”并不能满足任务的需求,因为有些应用程序需要直接访问网络中的数据包。也就是说,那些应用程序需要访问原始数据包,即没有被操作系统利用网络协议处理过的数据包。WinPcap产生的目的,就是为Win32应用程序提供这种访问方式; WinPcap提供了以下功能 捕获原始数据包,无论它是发往某台机器的,还是在其他设备(共享媒介)上进行交换的 在数据包发送给某应用程序前,根据用户指定的规则过滤数据包 将原始数据包通过网络发送出去 收集并统计网络流量信息 以上这些功能需要借助安装在Win32内核中的网络设备驱动程序才能实现,再加上几个动态链接库DLL。所有这些功能都能通过一个强大的编程接口来表现出来,易于开发,并能在不同的操作系统上使用。这本手册的主要目标是在一些程序范例的帮助下,叙述这些编程接口的使用。 如果您现在就想开始摸索这些功能,您可以直接进入 WinPcap用户手册.哪些程序在使用WinPcapWinPcap可以被用来制作许多类型的网络工具,比如具有分析,解决纷争,安全和监视功能的工具。特别地,一些基于WinPcap的典型应用有: 网络与协议分析器 (network and protocol analyzers) 网络监视器 (network monitors) 网络流量记录器 (traffic loggers) 网络流量发生器 (traffic generators) 用户级网桥及路由 (user-level bridges and routers) 网络入侵检测系统 (network intrusion detection systems (NIDS) 网络扫描器 (network scanners) 安全工具 (security tools) 什么是WinPcap做不到的WinPcap能 独立地 通过主机协议发送和接受数据,如同TCP-IP。这就意味着WinPcap不能阻止、过滤或操纵同一机器上的其他应用程序的通讯:它仅仅能简单地监视在网络上传输的数据包。所以,它不能提供类似网络流量控制、服务质量调度和个人防火墙之类的支持。 本手册的目标本手册的目的是提供一个全面而简单的方法来让您浏览WinPcap的设计文档。你会找到两个主要部分: WinPcap用户指南 和 WinPcap核心资料.第一部分内容主要适合那些需要利用WinPcap开发应用程序的编程人员: 它包含了WinPcap API的所有函数和数据结构的信息, 说明部分解释了如何编写一个数据包过滤器,而另一个页面则解释了如何将它包含到应用程序中。一个教程也提供了若干个程序范例,您可以使用它来循序渐进地学习WinPcap API的基本使用方法,不过有时候,它也会提供一些高级应用的代码片断。 第二部分内容主要为WinPcap的开发、维护人员,以及那些希望了解系统工作原理的人士而准备。它描述了WinPcap的主要设计方法,并解释了它是如何工作的。另外,它阐述了完整的设备驱动的数据结构及源代码,packet.dll的接口以及底层的WinPcap的API。如果您想了解WinPcap内部发生了什么,或者您想去扩展它,那么请您阅读此部分内容。 附加文档最新最及时的文档,请访问 /docs/ 特别地,如果您对WinPcap的系统结构和核心内容感兴趣,我们建议您阅读下列内容 Fulvio Risso, Loris Degioanni, An Architecture for High Performance Network Analysis, Proceedings of the 6th IEEE Symposium on Computers and Communications (ISCC 2001), Hammamet, Tunisia, July 2001 Loris Degioanni, Mario Baldi, Fulvio Risso and Gianluca Varenni, Profiling and Optimization of Software-Based Network-Analysis Applications, Proceedings of the 15th IEEE Symposium on Computer Architecture and High Performance Computing (SBAC-PAD 2003), Sao Paulo, Brasil, November 2003 Loris Degioanni, Development of an Architecture for Packet Capture and Network Traffic Analysis, Graduation Thesis, Politecnico Di Torino (Turin, Italy, Mar. 2000) 术语 为了文献的一致性, 我们会使用术语 数据包(packet) ,尽管用术语 帧(frame) 会更加准确,因为捕获过程是在数据链路层完成的,并且数据链路首部也包含在被捕获的数据中。 本文档中使用的术语 Win9x 表示与Windows95同一体系的微软操作系统,如Windows 98和Windows ME。 术语 WinNTx 表示基于NT内核的操作系统,从Windows NT 4开始,包含了Windows 2000,Windows XP,Windows Server 2003等 附注我们主要会致力于开发基于Windows NT/2000/XP/2003版本的WinPcap及其相关文档。这一选择是基于这样一个事实,大多数WinPcap用户都工作在NTx系统上,而且9x技术已经被微软放弃。此外,我们假定,使用PC机来完成类似网络分析这样高级任务的用户,都会安装高级的操作系统。鉴于这个原因,本文档将参考WinNTx的驱动和API。Win9x版本在概念上很类似,不过有时在执行上有些不同。在有些场合,Win9x版本的API缺少一些高级功能。这本手册会给出一个完整的API描述,并会指出那些只有WinNTx才得到支持的函数。 Last Modified: Sunday, July 23, 2007 WinPcap 教程: 循序渐进教您使用WinPcap本节将向您展示如何使用WinPcap API的一些特性。 这部分教程细化成若干节课,以循序渐进的方式介绍给读者,让读者从最基本的部分(获得设备列表)到最复杂的部分(控制发送队列并收集和统计网络流量)来了解如何使用WinPcap进行程序开发。 有时,我们会给出一些简单使用的代码片断,但同时,我们提供完整程序的链接:所有的源代码包含一些指向手册其他地方的链接,这可以让您很方便地通过点击鼠标来跳转到您想查看的函数和数据结构的内容中去。 范例程序都是用纯C语言编写, 所以,掌握基本的C语言编程知识是必须的,而且,这是一部关于处理原始网络数据包的教程,因为,我们希望读者拥有良好的网络及网络协议的知识。获取设备列表通常,编写基于WinPcap应用程序的第一件事情,就是获得已连接的网络适配器列表。libpcap和WinPcap都提供了 pcap_findalldevs_ex() 函数来实现这个功能: 这个函数返回一个 pcap_if 结构的链表, 每个这样的结构都包含了一个适配器的详细信息。值得注意的是,数据域 name 和 description 表示一个适配器名称和一个可以让人们理解的描述。 下列代码能获取适配器列表,并在屏幕上显示出来,如果没有找到适配器,将打印错误信息。 #include pcap.hmain() pcap_if_t *alldevs; pcap_if_t *d; int i=0; char errbufPCAP_ERRBUF_SIZE; /* 获取本地机器设备列表 */ if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL /* auth is not needed */, &alldevs, errbuf) = -1) fprintf(stderr,Error in pcap_findalldevs_ex: %sn, errbuf); exit(1); /* 打印列表 */ for(d= alldevs; d != NULL; d= d-next) printf(%d. %s, +i, d-name); if (d-description) printf( (%s)n, d-description); else printf( (No description available)n); if (i = 0) printf(nNo interfaces found! Make sure WinPcap is installed.n); return; /* 不再需要设备列表了,释放它 */ pcap_freealldevs(alldevs);有关这段代码的一些说明 首先, pcap_findalldevs_ex() ,和其他libpcap函数一样,有一个 errbuf 参数。一旦发生错误,这个参数将会被libpcap写入字符串类型的错误信息。 第二要记住,不是所有的操作系统都支持libpcap提供的网络程序接口,因此,如果我们想编写一个可移植的应用程序,我们就必须考虑在什么情况下, description 是 null。本程序中,我们遇到这种情况时,会打印提示语句No description available。 最后要记住,当我们完成了设备列表的使用,我们要调用 pcap_freealldevs() 函数将其占用的内存资源释放。 让我们编译并运行我们的第一个示例程序吧! 为了能在Unix或Cygwin平台上编译这段程序,需要简单输入: gcc -o testprog testprog.c -lpcap在Windows平台上,您需要创建一个工程,并按照 使用WinPcap编程 里的步骤做。 然而,我们建议您使用WinPcap developers pack ( 详情请访问WinPcap网站, ), 因为它提供了很多已经配置好的范例,包括本教程中的所有示例代码,以及在编译运行时需要的 包含文件(include) 和 库(libraries) jiash假设我们已经完成了对程序的编译,那让我们来运行它吧。在某台WinXP的电脑上,我们得到的结果是: 1. DeviceNPF_4E273621-5161-46C8-895A-48D0E52A0B83 (Realtek RTL8029(AS) Ethernet Adapter) 2. DeviceNPF_5D24AE04-C486-4A96-83FB-8B5EC6C7F430 (3Com EtherLink PCI) 正如您看到的,Windows平台下的网络适配器的名字读起来相当容易,可见,解释性的描述是多么有帮助阿!获取已安装设备的高级信息在第1讲中, (获取设备列表) 我们展示了如何获取适配器的基本信息 (如设备的名称和描述)。 事实上,WinPcap提供了其他更高级的信息。 特别需要指出的是, 由 pcap_findalldevs_ex() 返回的每一个 pcap_if 结构体,都包含一个 pcap_addr 结构体,这个结构体由如下元素组成: 一个地址列表 一个掩码列表 (each of which corresponds to an entry in the addresses list). 一个广播地址列表 (each of which corresponds to an entry in the addresses list). 一个目的地址列表 (each of which corresponds to an entry in the addresses list).另外,函数 pcap_findalldevs_ex() 还能返回远程适配器信息和一个位于所给的本地文件夹的pcap文件列表。 下面的范例使用了ifprint()函数来打印出 pcap_if 结构体中所有的内容。程序对每一个由 pcap_findalldevs_ex() 函数返回的pcap_if,都调用ifprint()函数来实现打印。 /* * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Politecnico di Torino, CACE Technologies * nor the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */#include pcap.h#ifndef WIN32 #include #include #else #include #endif/ 函数原型void ifprint(pcap_if_t *d);char *iptos(u_long in);char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen);int main() pcap_if_t *alldevs; pcap_if_t *d; char errbufPCAP_ERRBUF_SIZE+1; char sourcePCAP_ERRBUF_SIZE+1; printf(Enter the device you want to list:n rpcap:/ = lists interfaces in the local machinen rpcap:/hostname:port = lists interfaces in a remote machinen (rpcapd daemon must be up and runningn and it must accept null authentication)n file:/foldername = lists all pcap files in the give foldernn Enter your choice: ); fgets(source, PCAP_ERRBUF_SIZE, stdin); sourcePCAP_ERRBUF_SIZE = 0; /* 获得接口列表 */ if (pcap_findalldevs_ex(source, NULL, &alldevs, errbuf) = -1) fprintf(stderr,Error in pcap_findalldevs: %sn,errbuf); exit(1); /* 扫描列表并打印每一项 */ for(d=alldevs;d;d=d-next) ifprint(d); pcap_freealldevs(alldevs); return 1;/* 打印所有可用信息 */void ifprint(pcap_if_t *d) pcap_addr_t *a; char ip6str128; /* 设备名(Name) */ printf(%sn,d-name); /* 设备描述(Description) */ if (d-description) printf(tDescription: %sn,d-description); /* Loopback Address*/ printf(tLoopback: %sn,(d-flags & PCAP_IF_LOOPBACK)?yes:no); /* IP addresses */ for(a=d-addresses;a;a=a-next) printf(tAddress Family: #%dn,a-addr-sa_family); switch(a-addr-sa_family) case AF_INET: printf(tAddress Family Name: AF_INETn); if (a-addr) printf(tAddress: %sn,iptos(struct sockaddr_in *)a-addr)-sin_addr.s_addr); if (a-netmask) printf(tNetmask: %sn,iptos(struct sockaddr_in *)a-netmask)-sin_addr.s_addr); if (a-broadaddr) printf(tBroadcast Address: %sn,iptos(struct sockaddr_in *)a-broadaddr)-sin_addr.s_addr); if (a-dstaddr) printf(tDestination Address: %sn,iptos(struct sockaddr_in *)a-dstaddr)-sin_addr.s_addr); break; case AF_INET6: printf(tAddress Family Name: AF_INET6n); if (a-addr) printf(tAddress: %sn, ip6tos(a-addr, ip6str, sizeof(ip6str); break; default: printf(tAddress Family Name: Unknownn); break; printf(n);/* 将数字类型的IP地址转换成字符串类型的 */#define IPTOSBUFFERS 12char *iptos(u_long in) static char outputIPTOSBUFFERS3*4+3+1; static short which; u_char *p; p = (u_char *)∈ which = (which + 1 = IPTOSBUFFERS ? 0 : which + 1); sprintf(outputwhich, %d.%d.%d.%d, p0, p1, p2, p3); return outputwhich;char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen) socklen_t sockaddrlen; #ifdef WIN32 sockaddrlen = sizeof(struct sockaddr_in6); #else sockaddrlen = sizeof(struct sockaddr_storage); #endif if(getnameinfo(sockaddr, sockaddrlen, address, addrlen, NULL, 0, NI_NUMERICHOST) != 0) address = NULL; return address;打开适配器并捕获数据包现在,我们已经知道如何获取适配器的信息了,那我们就开始一项更具意义的工作,打开适配器并捕获数据包。在这讲中,我们会编写一个程序,将每一个通过适配器的数据包打印出来。 打开设备的函数是 pcap_open()。下面是参数 snaplen, flags 和 to_ms 的解释说明 snaplen 制定要捕获数据包中的哪些部分。 在一些操作系统中 (比如 xBSD 和 Win32), 驱动可以被配置成只捕获数据包的初始化部分: 这样可以减少应用程序间复制数据的量,从而提高捕获效率。本例中,我们将值定为65535,它比我们能遇到的最大的MTU还要大。因此,我们确信我们总能收到完整的数据包。 flags: 最最重要的flag是用来指示适配器是否要被设置成混杂模式。 一般情况下,适配器只接收发给它自己的数据包, 而那些在其他机器之间通讯的数据包,将会被丢弃。 相反,如果适配器是混杂模式,那么不管这个数据包是不是发给我的,我都会去捕获。也就是说,我会去捕获所有的数据包。 这意味着在一个共享媒介(比如总线型以太网),WinPcap能捕获其他主机的所有的数据包。 大多数用于数据捕获的应用程序都会将适配器设置成混杂模式,所以,我们也会在下面的范例中,使用混杂模式。 to_ms 指定读取数据的超时时间,以毫秒计(1s=1000ms)。在适配器上进行读取操作(比如用 pcap_dispatch() 或 pcap_next_ex() 都会在 to_ms 毫秒时间内响应,即使在网络上没有可用的数据包。 在统计模式下,to_ms 还可以用来定义统计的时间间隔。 将 to_ms 设置为0意味着没有超时,那么如果没有数据包到达的话,读操作将永远不会返回。 如果设置成-1,则情况恰好相反,无论有没有数据包到达,读操作都会立即返回。 #include pcap.h/* packet handler 函数原型 */void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);main()pcap_if_t *alldevs;pcap_if_t *d;int inum;int i=0;pcap_t *adhandle;char errbufPCAP_ERRBUF_SIZE; /* 获取本机设备列表 */ if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) = -1) fprintf(stderr,Error in pcap_findalldevs: %sn, errbuf); exit(1); /* 打印列表 */ for(d=alldevs; d; d=d-next) printf(%d. %s, +i, d-name); if (d-description) printf( (%s)n, d-description); else printf( (No description available)n); if(i=0) printf(nNo interfaces found! Make sure WinPcap is installed.n); return -1; printf(Enter the interface number (1-%d):,i); scanf(%d, &inum); if(inum i) printf(nInterface number out of range.n); /* 释放设备列表 */ pcap_freealldevs(alldevs); return -1; /* 跳转到选中的适配器 */ for(d=alldevs, i=0; inext, i+); /* 打开设备 */if ( (adhandle= pcap_open( d-name, / 设备名 65536, / 65535保证能 /捕获到不同数据链路层上的 /每个数据包的全部内容 PCAP_OPENFLAG_PROMISCUOUS, / 混杂模式 1000, / 读取超时时间 NULL, / 远程机器验证 errbuf / 错误缓冲池 ) ) = NULL) fprintf(stderr,nUnable to open the adapter. %s is not supported by WinPcapn, d-name); /* 释放设备列表 */ pcap_freealldevs(alldevs); return -1; printf(nlistening on %s.n, d-description); /* 释放设备列表 */ pcap_freealldevs(alldevs); /* 开始捕获 */ pcap_loop(adhandle, 0, packet_handler, NULL); return 0;/* 每次捕获到数据包时,libpcap都会自动调用这个回调函数 */void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) struct tm *ltime; char timestr16; time_t local_tv_sec; /* 将时间戳转换成可识别的格式 */ local_tv_sec = header-ts.tv_sec; ltime=localtime(&local_tv_sec); strftime( timestr, sizeof timestr, %H:%M:%S, ltime); printf(%s,%.6d len:%dn, timestr, header-ts.tv_usec, header-len); 当适配器被打开,捕获工作就可以用 pcap_dispatch() 或 pcap_loop()进行。 这两个函数非常的相似,区别就是 pcap_ dispatch() 当超时时间到了(timeout expires)就返回 (尽管不能保证) ,而 pcap_loop() 不会因此而返回,只有当 cnt 数据包被捕获,所以,pcap_loop()会在一小段时间内,阻塞网络的利用。pcap_loop()对于我们这个简单的范例来说,可以满足需求,不过, pcap_dispatch() 函数一般用于比较复杂的程序中。 这两个函数都有一个 回调 参数, packet_handler指向一个可以接收数据包的函数。 这个函数会在收到每个新的数据包并收到一个通用状态时被libpcap所调用 ( 与函数 pcap_loop() 和 pcap_dispatch() 中的 user 参数相似),数据包的首部一般有一些诸如时间戳,数据包长度的信息,还有包含了协议首部的实际数据。 注意:冗余校验码CRC不再支持,因为帧到达适配器,并经过校验确认以后,适配器就会将CRC删除,与此同时,大部分适配器会直接丢弃CRC错误的数据包,所以,WinPcap没法捕获到它们。 上面的程序将每一个数据包的时间戳和长度从 pcap_pkthdr 的首部解析出来,并打印在屏幕上。 请注意,使用 pcap_loop() 函数可能会遇到障碍,主要因为它直接由数据包捕获驱动所调用。因此,用户程序是不能直接控制它的。另一个实现方法(也是提高可读性的方法),是使用 pcap_next_ex() 函数。有关这个函数的使用,我们将在下一讲为您展示。 (不用回调方法捕获数据包).不用回调方法捕获数据包本讲的范例程序所实现的功能和效果和上一讲的非常相似 (打开适配器并捕获数据包), 但本讲将用 pcap_next_ex() 函数代替上一讲的 pcap_loop()函数。 pcap_loop()函数是基于回调的原理来进行数据捕获,这是一种精妙的方法,并且在某些场合中,它是一种很好的选择。 然而,处理回调有时候并不实用 - 它会增加程序的复杂度,特别是在拥有多线程的C+程序中。 可以通过直接调用pcap_next_ex() 函数来获得一个数据包 - 只有当编程人员使用了 pcap_next_ex() 函数才能收到数据包。 这个函数的参数和捕获回调函数的参数是一样的 - 它包含一个网络适配器的描述符和两个可以初始化和返回给用户的指针 (一个指向 pcap_pkthdr 结构体,另一个指向数据报数据的缓冲)。 在下面的程序中,我们会再次用到上一讲中的有关回调方面的代码,只是我们将它放入了main()函数,之后调用 pcap_next_ex()函数。 #include pcap.hmain()pcap_if_t *alldevs;pcap_if_t *d;int inum;int i=0;pcap_t *adhandle;int res;char errbufPCAP_ERRBUF_SIZE;struct tm *ltime;char timestr16;struct pcap_pkthdr *header;const u_char *pkt_data;time_t local_tv_sec; /* 获取本机设备列表 */ if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) = -1) fprintf(stderr,Error in pcap_findalldevs: %sn, errbuf); exit(1); /* 打印列表 */ for(d=alldevs; d; d=d-next) printf(%d. %s, +i, d-name); if (d-description) printf( (%s)n, d-description); else printf( (No description available)n); if(i=0) printf(nNo interfaces found! Make sure WinPcap is installed.n); return -1; printf(Enter the interface number (1-%d):,i); scanf(%d, &inum); if(inum i) printf(nInterface number out of range.n); /* 释放设备列表 */ pcap_freealldevs(alldevs); return -1; /* 跳转到已选中的适配器 */ for(d=alldevs, i=0; inext, i+); /* 打开设备 */ if ( (adhandle= pcap_open(d-name, / 设备名 65536, / 要捕捉的数据包的部分 / 65535保证能捕获到不同数据链路层上的每个数据包的全部内容 PCAP_OPENFLAG_PROMISCUOUS, / 混杂模式 1000, / 读取超时时间 NULL, / 远程机器
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 无线电监测与设备运维员抗压考核试卷及答案
- 人体实验的伦理问题-洞察及研究
- 香港公司股权转让手续及企业培训与咨询服务合同
- 预制静压桩基础工程施工合同履约期限与续签合同
- 医疗大数据在公共卫生事件分析中的应用-洞察及研究
- 项目管理法律风险防控与习题集编制合同
- 矿山救护工作业指导书
- 农业科技企业研发人员聘用与科技成果转化协议
- 信息通信营业员质量管控考核试卷及答案
- 2025年二硫化亚铁行业研究报告及未来行业发展趋势预测
- 学校购买文具用品的供货合同2025年
- 物业保安各岗位培训
- iso28000-2022供应链安全管理手册程序文件表单一整套
- 小学二年级下安全课件
- T-CSEA 25-2022 批量热浸镀锌行业含锌固废资源化利用技术规范
- 继发性肥胖症的临床特征
- DB21∕T 3149-2019 玉米秸秆还田机械化作业技术规程
- 报价函(工程项目招标文件资料)
- 2024年中级通信专业实务(终端与业务)考试题库大全(含答案)
- 中小学幼儿园食堂食品安全培训课件
- 《国际商务单证》课件
评论
0/150
提交评论