计算机网络课程设计(1).doc_第1页
计算机网络课程设计(1).doc_第2页
计算机网络课程设计(1).doc_第3页
计算机网络课程设计(1).doc_第4页
计算机网络课程设计(1).doc_第5页
已阅读5页,还剩34页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

计算机网络课程设计实验报告 目录一、实验内容和要求41、实验一数据包的捕获与分析42、实验二Ping程序的设计与实现4二、实验环境51、实验一数据包的捕获与分析52、实验二Ping程序的设计与实现5三、程序的需求分析与逻辑框图51、实验一数据包的捕获与分析52、实验二Ping程序的设计与实现6四、程序核心功能的实现机制71、实验一数据包的捕获与分析72、实验二Ping程序的设计与实现72.1主函数设计与实现72.2循环接收数据包函数readloop设计与实现92.3分组处理函数proc设计与实现102.4发送分组函数send设计与实现10五、程序源代码111、实验一数据包的捕获与分析112、实验二Ping程序的核心代码122.1主函数核心代码122.2循环接收数据包函数readloop核心代码152.3分组处理函数proc核心代码162.4发送分组函数send核心代码182.5计算校验和函数核心代码19六、程序扩展功能的需求分析与实现201、实验一数据包的捕获与分析的扩展功能201.1总体数据包统计:201.2特定过滤条件数据包统计信息:201.3协议分析状态:211.4会话列表选择所有ipv4会话:212、实验二Ping程序的扩展功能222.1发送指定数量得包后停止222.2发送每个数据包之间的空闲时间232.3发送指定大小的数据包232.4改变服务类型232.5伪造源地址进行DOS攻击24七、实验数据、结果分析251、实验一的结果分析251.1抓包工具wireshark启动并设置网卡为混杂模式251.2捕获数据包261.3编写过滤语句筛选数据包271.4对多种协议数据包进行分析281.5数据包信息的统计302、实验二Ping程序的结果分析312.1发送指定数量得包后停止312.2发送每个数据包之间的空闲时间312.3处理接收到得所有类型的数据包322.4发送时指定生命值332.5向广播地址发送回射请求332.6启用安静模式342.7设置数据包大小342.8设置服务类型352.9伪装源地址352.10显示帮助362.11不加任何选项的ping36八、总结37九、同组人分工情况37一、实验内容和要求1、实验一数据包的捕获与分析目的:数据包捕获技术是网络管理系统的关键技术。本实验通过Wireshark软件的安装使用,监控局域网的状态,捕获在局域网中传输的数据包,并结合在计算机网络课程中学习到的理论知识,对常用网络协议的数据包做出分析,加深网络课程知识的理解和掌握。内容和要求:Wireshark是一种开源的网络数据包的捕获和分析软件,本实验通过Wireshark软件的安装使用,监控局域网的状态,捕获在局域网中传输的数据包,并结合在计算机网络课程中学习到的理论知识,对常用网络协议的数据包做出分析,加深网络课程知识的理解和掌握。具体内容及要求如下:l Wireshark软件的安装;l Wireshark软件的启动,并设置网卡的状态为混杂状态,使得Wireshark可以监控局域网的状态;l 启动数据包的捕获,跟踪PC之间的报文,并存入文件以备重新查;l 设置过滤器过滤网络报文以检测特定数据流;l 对常用协议的数据包的报文格式进行分析,利用协议分析软件的统计工具显示网络报文的各种统计信息。2、实验二Ping程序的设计与实现 目的:1.通过设计和实现ping程序,从而使我们掌握网络层协议的原理及实现方法。对偏底层的网络程序设计,有一定的认识和理解。2.通过调用原始套接字进行编制程序,最终实现Ping程序,从而对套接字编程及网络程序设计有进一步的理解。内容和要求:本实验为ICMP实验。实验内容:Ping命令实现的扩充,在给定的Ping程序的基础上做如下功能扩充:l -h显示帮助信息l -b允许ping一个广播地址,只用于IPv4l -t 设置ttl值,只用于IPv4l -q安静模式。不显示每个收到的包的分析结果,只在结束时,显示汇总结果Ping命令的基本描述Ping的操作是向某些IP地址发送一个ICMP Echo消息,接着该节点返回一个ICMP Echo reply消息。二、实验环境1、实验一数据包的捕获与分析本实验是在windows下进行的,具体实验环境如下:操作系统:windows XP抓包工具:Wireshark网络环境:IPV4、IPV62、实验二Ping程序的设计与实现本实验是在linux下进行的,具体实验环境如下:操作系统:Ubuntu 10.10_linux-2.6.38编辑工具:Gedit编译工具:GCC调试工具:GDB网络环境:IPV4、IPV6三、程序的需求分析与逻辑框图1、实验一数据包的捕获与分析需求分析:如今,网络已经遍布了全球的大街小巷,几乎每一天我们都得和它打交道,学习、工作都得用到网络。网络是一个很庞大的系统,是系统就得有人去管理,然而要想管理好网络,那么就得对网络有非常深入的认识和了解。数据包捕获技术是网络管理系统的关键技术,所以我们可以通过学习数据包捕获技术从而达到学习网络的目的。这个实验我们需要对数据包进行捕获和分析,这恰恰对我们学习网络是有非常大的帮助的。开始安装抓包工具Wireshark启动Wireshark逻辑框图:设置网卡工作在混杂模式开始抓包编写过滤规则统计信息结束2、实验二Ping程序的设计与实现需求分析:在繁华的网络世界中,我们经常想要看看网络上的提供的各式各样的新闻、有趣的东西,我们知道,要想让自己的电脑能显示出来这些内容,就必须连入网络中,这是一个大前提,可是光有了这个前提还是不行的。我们还得保证我们与提供内容的那台服务器的连接是通畅的,这就得用到我们编写的ping程序了。在网络层中工作的ping程序,可以给远端的一个电脑发送一个回射请求,然后要是连接畅通,那么远端的电脑会给我们的电脑发送一个回射应答,然后我们的ping程序就可以输出一些信息,这样我们就可以知道我们与目标主机的连接是否通畅啦。逻辑框图:开始处理命令行参数1启动发送模块根据参数设置包格式接收应答包打印输出信息发送每个包之间的间隔时间到了吗?填充相应的ICMP头格式发送回射请求数据包是否四、程序核心功能的实现机制1、实验一数据包的捕获与分析本实验分为两大部分:一部分主要是对抓包程序的基本运用,进行简单抓包。另一部分主要是编写过滤条件对所抓到得包进行过滤,让程序只显示我们关心的包的信息。比较简单,就是启动Wireshark软件,并设置网卡的状态为混杂状态,使得Wireshark可以监控局域网的状态;启动数据包的捕获,跟踪PC之间的报文,并存入文件以备重新查。2、实验二Ping程序的设计与实现程序分为两大部分:一部分读取收到的所有消息,并输出ICMP Echo replay消息,另一部分每隔一秒钟发送一个Echo消息。另一部分由SIGALARM信号每秒驱动一次。mainreadloopsig_alarmsendrecvfromproc注册SIGALARM信号处理函数无限接收循环每隔固定秒数发送一个数据包程序首先肯定从main函数开始,然后处理完命令行参数,后把主控权交给接收消息的无限循环,在接收函数中启动发送消息的函数,并且这个发送函数在每次调用完真正的发送函数后,设置一个新的闹钟。然后闹钟到了又会调用这个函数,如此一直循环下去。概述逻辑框图如下:具体实现细节分析如下:2.1主函数设计与实现主函数是我们程序的入口,整个程序都在主函数中,执行完主函数也就意味着我们的程序结束啦。所以,在主函数中,我们应该设计的是整个程序的框架,把整个程序分成若干个模块,然后再去一点一点的实现各个模块。各模块之间的协调就得依靠主函数啦,所以,主函数的设计还是至关重要的。本程序的主函数起到了类似总线的功能,它把所有的模块都串了起来,掌控着这一切,控制着程序的稳步运行。在一开始,一个大的模块就是识别和处理命令行参数,在这一部分,我们用到了linux中的一套非常好的处理命令行参数的函数,利用getopt函数和与它相配的一些全局指针,让我们的命令行参数处理起来,非常的省事儿而且很高效。对这套函数的具体介绍如下:表头文件 #include定义函数 int getopt(int argc,char * const argv ,const char * optstring);函数说明 getopt()用来分析命令行参数。参数argc和argv是由main()传递的参数个数和内容。参数 optstring为选项字符串, 告知 getopt()可以处理哪个选项以及哪个选项需要参数,如果选项字符串里的字母后接着冒号“:”,则表示还有相关的参数,全域变量optarg 即会指向此额外参数。如果在处理期间遇到了不符合optstring指定的其他选项getopt()将显示一个错误消息,并将全域变量optopt设为“?”字符,如果不希望getopt()印出错信息,则只要将全域变量opterr设为0即可。getopt() 所设置的全局变量包括:optarg指向当前选项参数(如果有)的指针。 optind再次调用 getopt() 时的下一个 argv 指针的索引。 optopt最后一个已知选项。命令行参数处理完了就开始下一个规程了,那就是注册两个信号的处理函数,一个 是SIGALARM闹钟的处理函数,后面用于发送回射请求包。一个是SIGINT的处理函数,用于用户按了CTRL+C时显示统计信息。再后面就是根据用户输入的网络地址来得到目标主机地址信息了,用了host_serv函数,此函数又调用getaddrinfo完成了具体的获得地址信息的工作。接下来就是根据获得的地址信息,设置具体控制发送和接收数据包的结构体pr的各项成员。最后调用循环接收数据包函数readloop,等此函数退出后,整个程序退出。整个主函数的逻辑流程图如下:2.2循环接收数据包函数readloop设计与实现这个函数主要实现的是根据用户输入的命令行参数,设置IP包头选项,从而实现IP包格式的填充,然后显示的调用一下SIGALARM信号处理函数,让发送循环开始。接下来是进入无限接收循环,接收到一个分组,记录接到的时间,调用相应的处理函数,进行分组的分析。这函数就是一切之后一直做的事情,程序一直就这样运行着。整个readloop函数的逻辑流程图如下: 到了这个函数就既有了发送,又有了接收了,只是整个函数它只管接收到分组,不管后续的处理,具体是怎么分析的分组就得下面的函数来处理啦,下面主要有两个函数,一个是发送函数,主要管理着发送相关的处理;另一个是接收函数,主要管理着接收相关的处理。2.3分组处理函数proc设计与实现在接收到分组以后,readloop函数就调用本函数,并把接收到得分组和接收到的时间传送给本函数,本函数分为两个版本,一个v4版本,一个v6版本。V4版本处理的是ipv4的分组,v6版本处理的是ipv6的分组,各个版本根据相应的ip头格式和icmp的头格式,把需要的信息读取出来,并把数据段的第一个字节读取出来,因为这个字节存放的是这个分组发送时的时间,然后与结束的时间相减得出这条路线的延迟时间。整个proc函数的逻辑流程图如下:这个逻辑图是v4版本和v6版本共同的地方,v4不同于v6版本的是,v4版本在或得icmp头指针之前还得先获得ip头指针,然后把ip头分析完才到icmp头呢,而v6版本是直接就是icmp头,没有ip头,所以我们不必再去获得和分析ip头。2.4发送分组函数send设计与实现此函数与proc函数非常类似也是有v4和v6两个版本,各个版本的函数填充并发送对应版本的数据包,唯一不同的就是v4版本中如果用户指定了伪装源地址的话,是需要自己填写一个ip头的。除此之外,其他的都是共同的,主要就是填充icmp头信息和获取当前时间并把它存到数据包的第一个字节里。整个send函数的逻辑流程图如下:五、程序源代码1、实验一数据包的捕获与分析在实验一中,因为主要是抓包,所以,没有什么源代码,主要也就有一些过滤条件,可以算是代码。因此,在这里就把过滤条件说明如下:1 ip.dst = 这一个过滤代码是指发往百度的ip包。所以,把这个写到filter窗格里就可以只显示发往百度主页的ip包的信息了。2 tcp.dstport = 80这个是过滤了所有目的端口不是80的包,这样剩下的就都是发往80端口的数据包啦。3 tcp.dstport = 80 and ip.dst=过滤条件可以用与、或、非的关系运算符进行连接,所以这句就可以显示出所有发往百度主页的端口为80的数据包了。4 ip.addr !=值得注意的就是这个让我们以为对的,可是其实不是非常对的表达式,说它我们以为对是因为,我们总把它想成是把所有发给百度主页的包过滤掉,很不幸,它不会按照我们的期望进行。相反,那个表达式为真值的条件源地址或目标地址中的任意一个不等于即可。因此,那个表达式可以被读作:该包包含的ip字段值必须不为 。因为一个ip数据报同含源地址和目标地址,只要两个地址有一个不为表达式就为真。2、实验二Ping程序的核心代码2.1主函数核心代码intmain(int argc, char *argv)int c;int temp;struct addrinfo*ai;quite_mode=0;send_overtime.tv_sec=0;send_overtime.tv_usec=0; recv_overtime.tv_sec=0;recv_overtime.tv_usec=0;bzero(&false_source_addr,sizeof(struct sockaddr_in);opterr = 0;/* dont want getopt() writing to stderr */while ( (c = getopt(argc, argv, vhT:c:i:vt:hbqs:o:r:) != -1) switch (c) case v:verbose+;break;case h:printf(!*This is a Ping program*! You can use it to send ICMP ECHO_REQUEST packets to network hosts.nUsage: ping OPTION. HOST .nn Options valid for all request types:nn -c NUMBER Stop after sending NUMBER packetsn -i NUMBER Wait NUMBER seconds between sending each packetn -v Verbose outputnn Options valid for -echo requests:nn -t NUM 设置ttl值为NUM,IPv4和IPv6同时适用n -b 允许ping一个广播地址,只用于IPv4n -q 安静模式n -s Send NUMBER data octetsnn Options valid for other:nn -o NUM Sever typen 0 -最小化延迟n1 -最大化吞吐量n 2 -最大化可靠性n 3 -最小化成本n -r ipaddr 伪装的源ip地址n -h 显示帮助信息nn);return 0;case q:quite_mode=1;break;case t:en_ttl=1;ttl=atoi(optarg);if(ttl255) err_quit(The ttl value is too big! It must between 1 and 255!);break;case b:allow_broadcast=1;break;case c:ping_count=atoi(optarg);break;case i:delay=atoi(optarg);if(delay0) err_quit(The delay value is too small! It must bigger than 0!);case s:datalen=atoi(optarg);if(datalen1472 & datalen 65399) err_quit(The datalen value is too big!);break;case o:temp=atoi(optarg);if(temp3 |tempai_canonname, Sock_ntop_host(ai-ai_addr, ai-ai_addrlen), datalen);/* 4initialize according to protocol */if (ai-ai_family = AF_INET) pr = &proto_v4;#ifdefIPV6 else if (ai-ai_family = AF_INET6) pr = &proto_v6;if (IN6_IS_ADDR_V4MAPPED(&(struct sockaddr_in6 *) ai-ai_addr)-sin6_addr)err_quit(cannot ping IPv4-mapped IPv6 address);#endif elseerr_quit(unknown address family %d, ai-ai_family);if(ai-ai_family = AF_INET6 & en_false_source_addr) err_quit(-r option cannt use on ipv6!);pr-sasend = ai-ai_addr;pr-sarecv = calloc(1, ai-ai_addrlen);pr-salen = ai-ai_addrlen;readloop();exit(0);2.2循环接收数据包函数readloop核心代码 voidreadloop(void)intsize; const int en_broadcast=1;charrecvbufBUFSIZE;socklen_tlen;ssize_tn;struct timevaltval;sockfd = socket(pr-sasend-sa_family, SOCK_RAW, pr-icmpproto);setuid(getuid();/* dont need special permissions any more */size = 60 * 1024;/* OK if setsockopt fails */setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size);if(en_ttl) setsockopt(sockfd,pr-ttllevel,pr-ttloptname,&ttl,sizeof(int);if(allow_broadcast) setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&en_broadcast,sizeof(int);if(en_server_type) setsockopt(sockfd,IPPROTO_IP,IP_TOS,&server_type,sizeof(int);if(en_false_source_addr) setsockopt(sockfd,IPPROTO_IP,IP_HDRINCL,&en_broadcast,sizeof(int);sig_alrm(SIGALRM);/* send first packet */while(1) len = pr-salen;n = recvfrom(sockfd, recvbuf, sizeof(recvbuf), 0, pr-sarecv, &len);if (n fproc)(recvbuf, n, &tval);2.3分组处理函数proc核心代码1.IPV4版本voidproc_v4(char *ptr, ssize_t len, struct timeval *tvrecv)inthlen1, icmplen;doublertt;struct ip*ip;struct icmp*icmp;struct timeval*tvsend;ip = (struct ip *) ptr;/* start of IP header */hlen1 = ip-ip_hl 2;/* length of IP header */icmp = (struct icmp *) (ptr + hlen1);/* start of ICMP header */if ( (icmplen = len - hlen1) 8)err_quit(icmplen (%d) icmp_type = ICMP_ECHOREPLY) if (icmp-icmp_id != pid)return;/* not a response to our ECHO_REQUEST */if (icmplen 16)err_quit(icmplen (%d) icmp_data;tv_sub(tvrecv, tvsend);rtt = tvrecv-tv_sec * 1000.0 + tvrecv-tv_usec / 1000.0;if(!quite_mode)printf(%d bytes from %s: seq=%u, ttl=%d, rtt=%.3f msn,icmplen, Sock_ntop_host(pr-sarecv, pr-salen),icmp-icmp_seq, ip-ip_ttl, rtt);+recv_pk_num;if(rttmax_rtt) max_rtt=rtt;if(rttsarecv, pr-salen),icmp-icmp_type, icmp-icmp_code);2.IPV6版本voidproc_v6(char *ptr, ssize_t len, struct timeval* tvrecv)#ifdefIPV6inthlen1, icmp6len;doublertt;struct ip6_hdr*ip6;struct icmp6_hdr*icmp6;struct timeval*tvsend; icmp6=(struct icmp6_hdr *)ptr; if(icmp6len=len)8) /len-40err_quit(icmp6len (%d) icmp6_type = ICMP6_ECHO_REPLY) if (icmp6-icmp6_id != pid)return;/* not a response to our ECHO_REQUEST */if (icmp6len 16)err_quit(icmp6len (%d) tv_sec * 1000.0 + tvrecv-tv_usec / 1000.0;if(!quite_mode)printf(%d bytes from %s: seq=%u, rtt=%.3f msn,icmp6len, Sock_ntop_host(pr-sarecv, pr-salen),icmp6-icmp6_seq, rtt);+recv_pk_num;if(rttmax_rtt) max_rtt=rtt;if(rttsarecv, pr-salen),icmp6-icmp6_type, icmp6-icmp6_code);#endif/* IPV6 */2.4发送分组函数send核心代码1.IPV4版本voidsend_v4(void)int len;int head_len;struct icmp*icmp;struct ip *ip;if(en_false_source_addr) head_len=sizeof(struct ip)+ sizeof(struct icmp); ip=(struct ip *)sendbuf; ip-ip_v=IPVERSION; ip-ip_hl=sizeof(struct ip) 2; ip-ip_tos=server_type; ip-ip_len=head_len+datalen; ip-ip_id=0; ip-ip_off=0; ip-ip_ttl=ttl; ip-ip_p=IPPROTO_ICMP; ip-ip_sum=0; ip-ip_dst.s_addr=inet_addr(pr-sasend-sa_data); ip-ip_src.s_addr=false_source_addr.sin_addr.s_addr; icmp= (struct icmp *)(sendbuf+sizeof(struct ip);else icmp = (struct icmp *) sendbuf;icmp-icmp_type = ICMP_ECHO;icmp-icmp_code = 0;icmp-icmp_id = pid;icmp-icmp_seq = nsent+;gettimeofday(struct timeval *) icmp-icmp_data, NULL);len = 8 + datalen;/* checksum ICMP header and data */icmp-icmp_cksum = 0;icmp-icmp_cksum = in_cksum(u_short *) icmp, len);if(en_false_source_addr) len+=sizeof(struct ip);sendto(sockfd, sendbuf, len, 0, pr-sasend, pr-salen);2.IPV6版本voidsend_v6()#ifdefIPV6intlen;struct icmp6_hdr*icmp6;icmp6 = (struct icmp6_hdr *) sendbuf;icmp6-icmp6_type = ICMP6_ECHO_REQUEST;icmp6-icmp6_code = 0;icmp6-icmp6_id = pid;icmp6-icmp6_seq = nsent+;gettimeofday(struct timeval *) (icmp6 + 1), NULL);len = 8 + datalen;/* 8-byte ICMPv6 header */sendto(sockfd, sendbuf, len, 0, pr-sasend, pr-salen);/* kernel calculates and stores checksum for us */#endif/* IPV6 */2.5计算校验和函数核心代码unsigned shortin_cksum(unsigned short *addr, int len) int nleft = len; int sum = 0; unsigned short *w = addr; unsigned short answer = 0; while (nleft 1) sum += *w+; nleft -= 2; /* 4mop up an odd byte, if necessary */ if (nleft = 1) *(unsigned char *)(&answer) = *(unsigned char *)w ; sum += answer; /* 4add back carry outs from top 16 bits to low 16 bits */ sum = (sum 16) + (sum & 0xffff); /* add hi 16 to low 16 */ sum += (sum 16); /* add carry */ answer = sum; /* truncate to 16 bits */ return(answer);六、程序扩展功能的需求分析与实现1、实验一数据包的捕获与分析的扩展功能抓包实验的扩展功能,我们主要放在了利用Wireshark强大的统计功能对庞大的数据包信息的统计功能上了,其实,这是很重要的一个功能,在一个庞大吞吐量的网络环境,这尤其显得重要,我们可以知道现在最频繁的包是什么,可以知道一种包的具体信息。1.1总体数据包统计:1.2特定过滤条件数据包统计信息:1.3协议分析状态:1.4会话列表选择所有ipv4会话:2、实验二Ping程序的扩展功能这部分的内容不算很多,但是都比较有用,所以就作为扩展功能增加到了我们的ping程序中了,下面就详细的单个的介绍一下:2.1发送指定数量得包后停止要是没有这选项,我们的程序会一直不停的给目标主机发回射请求,直到用于强制退出程序,但很多时候我们都是只想直到我们的电脑和目标主机之间的网络线路是不是通畅的,所以只需发送一定数量的包就可以啦,不需要一直发。因此,我们设计了-c选项,在它后面加一个数字的参数,就是指定要发送的包的数量。具体的实现如下:在命令行参数处理部分加入如下代码:case c:ping_count=atoi(optarg);break;ping_count记录着指定的要发送的包的数量。修改SIGALARM信号处理函数如下:voidsig_alrm(int signo)if(send_pk_num=ping_count) readloopstop(SIGINT); (*pr-fsend)();+send_pk_num; alarm(delay); return; /* probably interrupts recvfrom() */这样在发送的数据包的数量到达指定的数量的时候,我们的程序就去自动调用停止函数readloopstop,此函数实现如下:Void readloopstop(int signo)printf(n*Ping statistics for %s*n%d packets transmitted, %d packets received, %5.2f% packet loss nround-trip min/avg/max = %6.3f/%6.3f/%6.3f msnn,host,send_pk_num,recv_pk_num,(double)(send_pk_num-recv_pk_num)/(double)send_pk_num)*100,min_rtt,total_rtt/recv_pk_num,max_rtt);exit(1);2.2发送每个数据包之间的空闲时间在我们的ping程序执行的时候,有的时候,我们会感觉输出的太快啦,来不及仔细的参看,其实这不是输出的太快,而其实质是发送的数据包太快啦,使得接受的数据包源源不断的来,最终造成输出的信息非常快。所以,我们加了-i选项,在它之后加一个数字的参数,指定发送每个

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论