计算机网络课程设计_基于ICMPTCP的网段端口扫描_C语言编写.doc

上传人:牧羊曲112 文档编号:4297133 上传时间:2023-04-14 格式:DOC 页数:32 大小:591KB
返回 下载 相关 举报
计算机网络课程设计_基于ICMPTCP的网段端口扫描_C语言编写.doc_第1页
第1页 / 共32页
计算机网络课程设计_基于ICMPTCP的网段端口扫描_C语言编写.doc_第2页
第2页 / 共32页
计算机网络课程设计_基于ICMPTCP的网段端口扫描_C语言编写.doc_第3页
第3页 / 共32页
计算机网络课程设计_基于ICMPTCP的网段端口扫描_C语言编写.doc_第4页
第4页 / 共32页
计算机网络课程设计_基于ICMPTCP的网段端口扫描_C语言编写.doc_第5页
第5页 / 共32页
点击查看更多>>
资源描述

《计算机网络课程设计_基于ICMPTCP的网段端口扫描_C语言编写.doc》由会员分享,可在线阅读,更多相关《计算机网络课程设计_基于ICMPTCP的网段端口扫描_C语言编写.doc(32页珍藏版)》请在三一办公上搜索。

1、课 程 设 计 任 务 书【设计目的】 加深对TCP/IP协议的理解,熟悉Socket编程【设计任务】 实现一个扫描器,必须能够完成以下所有功能:使用TCP connect、TCP SYN和TCP FIN进行端口扫描,使用ICMP echo 扫描实现IP扫描。并把结果记录下来。【设计要求】l Windows或Linux环境下,程序在单机上运行。l 演示:使用端口扫描对一台主机进行扫描,并显示结果(一台主机上有哪些端口是打开的)。对一个网段进行IP扫描,显示结果(一个网段内有哪些主机是开机的)。l 友好的用户界面【设计要求】l 程序源代码,必须有详细的注释。l 项目设计报告。网段和端口扫描程序一

2、、 概述11.1端口扫描11.2端口扫描常用技术简介21.2.1 connect()扫描21.2.2 SYN扫描31.2.3 XMAS-TREE扫描31.3网段扫描4二、需求分析52.1 设计功能52.2 设计要求5三、概要设计53.1设计概念和处理流程53.2 结构设计73.2.1 数据结构及定义73.2.2 接口函数8四、细设设计94.1 实现原理94.1.1 connect()函数端口扫描的原理94.1.2 ICMP网段扫描的原理114.2 函数实现144.2.1 初始化winsock动态链接库144.2.3地址解析154.2.4 计算检验和154.2.5 网段扫描164.2.6 端口扫

3、描17五、 总结与体会195.1 程序运行与调试195.2 体会20六、 参考文献216.1 参考书目216.2 引用网址21一、 概述1.1端口扫描端口扫描是指利用TCP协议的面向连接的特性,使用本地计算机试图与目的主机的某个端口建立连接,以此来试探目的主机的一些端口的具体状态,如是否打开,若是打开的又运行什么样的程序(利用熟知端口很容易知道)。端口扫描有很多技术实现。其中最常用的有:connect()扫描,TCP SYN扫描,TCP FIN扫描,TCP NULL扫描,XMAS- TREE扫描(圣诞树扫描)等等。在本程序中使用的是connect()扫描。1.2端口扫描常用技术简介1.2.1

4、connect()扫描此扫描的原理是,本地计算机利用TCP协议的三次握手原理(RFC 793)试图与网络上一台主机或服务器建立TCP连接。如果目的主机或服务器回送SYN/ACK则说明该端口开放,否则该端口关闭。具体的过程:1. Client端发送SYN2. Server端发送SYN/ACK(该端口开放),或Server端发送RST/ACK(该端口关闭),若无应答可能目的主机或服务器不可达。3. Client端发送ACK,连接建立。4. Client端主动断开连接,连接关闭。过程图如下:1.2.2 SYN扫描SYN扫描前两步与connect()扫描相同,只是最后一步,Client端发送的不是AC

5、K确认报文而是RST报文,这样三次握手过程就没有完成,Client与Server也就没有建立TCP连接,因此前述过程不会被Sever端记录到系统日志中,扫描更加隐蔽。过程图如下:1.2.3 XMAS-TREE扫描通过发送带有以下标志位TCP数据包URG,PSH,FIN来试探主机。在目标端口开放的情况下不放回任何信息。端口开放:发送URG/PSH/FIN,没有响应。端口关闭:1.发送URG/PSH/FIN,没有响应。2响应RST。1.3网段扫描网段扫描是指利用ICMP(因特网控制报文协议)对某一网段的所有IP地址发送ICMP报文,测试IP地址所对应的主机具体情况(如是否开机等)。所以对目的主机回

6、答的ICMP报文进行分析是网段扫描的关键。常见的报文类型有:类型(type)代码(code)描述差错查询00回显回答*31主机不可达*3端口不可达*80请求回显*二、需求分析2.1 设计功能实现一个扫描器,使用TCP connect、TCP SYN或TCP SYN进行端口扫描,使用 ICMP echo扫描实现IP扫描,并记录结果。2.2 设计要求Windows或Linux环境下,程序应在单机上运行。使用端口扫描对一台主机进行扫描,并显示结果,在一定的端口范围内,该主机由哪些端口是打开的。对一个网段进行IP扫描,显示结果,该网段的哪些主机是开机的。友好的界面,便于用户操作,完成全部设计功能。三、

7、概要设计3.1设计概念和处理流程程序使用Windows Sockets API编程,利用winsock2库函数提供的函数实现与主机间的连接,发送ICMP报文。详见Winsock Referen:用户首先选择要使用的功能,程序共有两大功能:端口扫描和IP网段扫描。端口扫描的主要功能有,根据用户输入的主机名或IP地址以及端口范围进行connect()扫描。当用户输入完必要的信息并击确认后,程序进行扫描,不过不建议端口区间过于庞大,等待一段时间后用户界面会显示所指定IP地址主机的端口使用情况,哪些端口是打开的,哪些是关闭的。IP网段扫描的主要功能有,用户输入某个网段起始IP地址和结束IP地址,确认后

8、,程序根据所输入的网段号,对网段类的每一个IP地址发送ICMP请求回显报文,如果主机处于开机状态那么将会回送回答报文;如果主机不可达(在同一个网内),则就能够判断该IP所对应的主机处于关机状态。当用户选择退出功能时,释放资源,程序关闭。程序流程图3.2 结构设计3.2.1 数据结构及定义所使用的宏定义,#define ICMP_ECHO_REQUEST_TYPE 8 /ICMP请求类型#define ICMP_ECHO_REQUEST_CODE 0 /ICMP请求代码#define ICMP_ECHO_REPLY_TYPE 0#define ICMP_ECHO_REPLY_CODE 0#def

9、ine ICMP_MINIMUM_HEADER 8IP数据报首部,首部固定20字节,数据结构定义如下:typedef struct ip_hdrunsigned char iphVerLen; / 版本号和头长度(各占4位)unsigned char ipTOS; / 服务类型 unsigned short ipLength; / 封包总长度,即整个IP报的长度unsigned short ipID; / 封包标识,惟一标识发送的每一个数据报unsigned short ipFlags; / 标志unsigned char ipTTL; / 生存时间,就是TTLunsigned char ip

10、Protocol; / 协议,可能是TCP、UDP、ICMP等unsigned short ipChecksum; / 校验和unsigned long ipSource; / 源IP地址unsigned long ipDestination; / 目标IP地址IP_HDR,*PIP_HDR;IP数据报格式ICMP报文首部格式,8个字节,数据结构定义如下:typedef struct icmp_hdrunsigned char icmp_type; /类型unsigned char icmp_code; /代码unsigned short icmp_checksum; /检验和unsigned

11、 short icmp_id; /唯一请求ID,通常使用进程PIDunsigned short icmp_sequence; /序列号unsigned long icmp_timestamp; /时间戳 ICMP_HDR,*PICMP_HDR;3.2.2 接口函数Void InitializeWinsock(),初始化Winsock动态链接库。Void Resolove(char hostname),解析主机名(或IP地址),该函数是公共接口函数,端口扫描和IP网段扫描都使用该函数解析地址。函数首先判断用户输入的IP是十进制点分地址还是域名地址,然后分别调用inet_addr()和gethos

12、tbyname()库函数处理成unsigned long型数据。Void ResoloveIPAddr(char starthost,char endhost,int *start,int *end),此函数用户IP网段扫描,将用户输入的起始IP地址和结束IP地址转换为int类型数据。Char * Assemble(char startehost,int cur),将当前IP地址转化为字符串类型的IP地址。void SegmentScan(char starthost,char endhost),通过发送ICMP,检测某个网段上主机的具体状态。函数的两个参数starthost、endhost分

13、别代表用户给定的起始IP地址和结尾IP地址。该函数内部调用了InitializeWinsock()、Resolove()、ResoloveIPAddr()、Assemble()、以及库函数sendto()和recvfrom()。通过这些函数的调用实现了对指定网络区间的ICMP扫描。connectScan(char startport,char endport,hostname),该函数把用户输入的主机名(或IP地址)写入sin_addr.s_addr,起始端口写入sin_port中。函数调用了InitializeWinsock()、Resolove()以及库函数connect()、shutdo

14、wn()。实现了利用connect()系统函数对指定主机端口区间扫描。四、细设设计4.1 实现原理4.1.1 connect()函数端口扫描的原理首先要明白TCP报文段的首部格式。现在分别介绍各个字段的具体含义。(1)源端口和目的端口 各占两个字节。端口是运输层与应用层的服务。(2)序号 占4个字节。TCP把传送的数据流中的每一个字节都编上一个序号。(3)确认号 占4个字节。是指期望对方的下一个报文段的数据的第一个字节的序号。(5)数据偏移 占4位。它指出TCP报文段的数据起始处距离TCP报文段的起始距离有多远。(6)保留。(7)紧急比特URG 当URG=1时,表明紧急指针字段有效。告诉系统有

15、紧急数据,应尽快发送。(8)确认比特ACK 只有当ACK=1时确认号字段才有效。(9)推送比特PSH 将数据流尽快的推送给应用进程。而不是等到缓冲区满后才将数据送至应用程序。(10)复位比特RST 当RST=1时,表明TCP出现错误,必须释放连接,然后重新建立运输连接。复位比特还用来拒绝一个非法报文或拒绝打开一个连接。(11)同步比特SYN 当SYN=1而ACK=0是表明这是一个请求连接报文,若同意连接则对方应该回送SYN=1,ACK=1。(12)终止比特 FIN。用于释放一个连接。(13)检验和 占2个字节。设客户进程运行在本地计算机上。它首先向其TCP发出主动打开(active open)

16、命令,表明要与某个IP地址的某个端口建立运输连接。首先发送SYN=1,SEQ=X的报文给目标主机的某端口,当本地计算机收到SYN=1,ACK=1的报文时,表明对方主机同意连接,这是还需发送一个ACK以确认连接。这样,经过三次握手,一条TCP连接链路就建立完成。在Winsock2环境下,系统类库提供了connect()接口函数。一下是函数原型:connect functionint connect( _In_ SOCKET s, _In_ const struct sockaddr *name, _In_ int namelen);s表示一个为连接的socket,name表示一个指向sockad

17、dr的结构体指针,namelen是sockaddr中name域的比特长度。利用此函数,可以非常方便的连接一个套接字。4.1.2 ICMP网段扫描的原理因特网控制报文协议ICMP(Internet Control Message Protocol)【RFC792】。ICMP允许主机或路由器报告差错情况和提供有关异常情况的报告。ICMP报文作为IP层数据报的数据,加上数据报的首部,组成数据发送出去。ICMP报文的种类有两种,即ICMP差错报告报文和ICMP询问报文。ICMP报文的前4个字节是统一格式,共有三个字段:类型,代码和检验和。对网段的主机扫描就是利用了这三个字段。根据主机发回的不同类型和代

18、码对主机的状态进行判断。ICMP的差错报文共有5种:(1) 终点不可达 终点不可达分为:网络不可达,主机不可达,协议不可达,端口不可达。(2) 源站抑制 当路由器或主机由于拥塞而丢弃数据包时,就向源站发生源站抑制报文。(3) 时间超时 当路由器手打生存时间为零的数据包时,除丢弃该数据报外,还向源站发送时间超过报文。(4) 参数问题(5) 改变路由(重定向)对一个网段扫描时,主要利用(1)和(3)两种报文。ICMP的询问报文主要有4种:(1) 回送请求和回答(Ping)(2) 时间戳和回答(常用来记录一个主机到另一个主机的延迟)(3) 掩码请求和回答(4) 路由询问和回答同样,主要利用(1)和(

19、2)两种报文。Winsock2提供sendto()和recvfrom()两个函数分别来发送IP层数据报。函数原型分别为:sendto functionint sendto( _In_ SOCKET s, _In_ const char *buf, _In_ int len, _In_ int flags, _In_ const struct sockaddr *to, _In_ int tolen);recvfrom functionint recvfrom( _In_ SOCKET s, _Out_ char *buf, _In_ int len, _In_ int flags, _Out_

20、 struct sockaddr *from, _Inout_opt_ int *fromlen);结合原始套接字可以很方便做到将一个ICMP数据包封装到IP数据包中,以及从一个IP数据报中解析出包含ICMP报文。下面对原始套接字做下简单的介绍。原始套接字提供普通的TCP和UDP套接字所不提供的一下3个功能。v 有了原始套接字,进程可以读写ICMP和IGMP等分组。举例来说ping程序就是使用原始套接字收发ICMP分组,网段扫描也是基于这个原理。v 有了原始套接字,进程可以读写内核不处理其协议字段的IPv4数据包。v 有了原始套接字,进程还可以使用IP_HDRINCL套接字选项自行构造IPv4

21、首部。这一点是非常强大的。在利用Winsock编写原始套接字时要注意程序应该取得管理员权限,因为大多数操作系统对原始套接字的创建有较为严格的限制。如果没有取得管理员权限,那么在创建原始套接字的时候会报出10013-Permission denied.的错误,从而无法创建套接字。4.2 函数实现4.2.1 初始化winsock动态链接库void InitializeWinsock()int status;WSADATA wsa;if (status=WSAStartup(MAKEWORD(2,2),&wsa)!=0)printf(Failed to WSAStartup(): %d.n,WSAG

22、etLastError();exit(EXIT_FAILURE);函数调用Winsock2提供的WSAStartup()函数,初始化动态链接库。4.2.2 初始化ICMP首部void InitIcmpHeader(ICMP_HDR* icmp_hdr)char buffsizeof(ICMP_HDR) + 32; /ICMP报文类型,类型为8,代码为0icmp_hdr-icmp_type = ICMP_ECHO_REQUEST_TYPE; / 请求回显icmp_hdr-icmp_code = ICMP_ECHO_REQUEST_CODE;icmp_hdr-icmp_id = (USHORT)G

23、etCurrentProcessId();icmp_hdr-icmp_checksum = 0;icmp_hdr-icmp_sequence = 0;icmp_hdr-icmp_timestamp= GetTickCount();/往ICMP头部填充信息memset(&buffsizeof(ICMP_HDR), E, 32);函数为ICMP报文首部中各个字段赋值,达到初始化的目的。其中比较重要的语句有icmp_hdr-icmp_type = ICMP_ECHO_REQUEST_TYPE; / 请求回显icmp_hdr-icmp_code = ICMP_ECHO_REQUEST_CODE;这样赋

24、值后,就把ICMP报文设置成ICMP询问报文,回送请求和回答。4.2.3地址解析void Resolove(char hostname)if(isdigit(hostname0)/判断主机名是否为数字 /printf(执行inet_addr().n);dest.sin_addr.s_addr = inet_addr(hostname); /将主机地址写入s_addr/printf(%dn,WSAGetLastError(); else if( (host=gethostbyname(hostname) != 0)/判断所给主机名是否与host中的一致/printf(执行gethostbynam

25、e().n);strncpy(char *)&dest.sin_addr , (char *)host-h_addr_list0 , sizeof dest.sin_addr);/printf(完成。n);elseprintf(解析主机失败。n);exit(EXIT_FAILURE);根据用户输入地址字符串转化成相应的地址字段,写入dest.sin_addr中。如果用户输入的点分十进制。则就会调用相应的inet_addr()函数,否则调用gethostbyname(),在写入地址字段。4.2.4 计算检验和unsigned short checksum(unsigned short *buff

26、er, int size) unsigned long cksum=0;while (size 1) cksum += *buffer+;size -= sizeof(USHORT);if (size) cksum += *(UCHAR*)buffer;cksum = (cksum 16) + (cksum & 0xffff);cksum += (cksum 16);return (USHORT)(cksum);根据TCP/IP协议,IP数据报在传输过程前必须计算检验和,对收到的数据也要计算检验和。该函数实现了首部的检验和计算。4.2.5 网段扫描主要语句如下:for(i = startpor

27、t ; i= endport ; i+)sock = socket(AF_INET , SOCK_STREAM , IPPROTO_TCP); /创建一个Socketif(sock=INVALID_SOCKET) printf(Create socket failed: %dn,WSAGetLastError(); exit(EXIT_FAILURE); /主机字节序转换为网络字节序dest.sin_port = htons(i);/用此Socket连接目的主机,核心代码status = connect(sock , (struct sockaddr *)&dest , sizeof dest

28、);if(status = SOCKET_ERROR) /连接失败switch(WSAGetLastError()case 10060:printf(%st%dtERRORttConnection timed outn , hostname , i );break;case 10061:printf(%st%dtERRORttConnection refusedn , hostname , i );break;default:printf(%st%dtERRORtCode:n,WSAGetLastError();break;/fflush(stdout);else /连接成功printf(%s

29、t%dtPORT OPENn , hostname ,i);/关闭收发服务if( shutdown( sock ,SD_BOTH ) = SOCKET_ERROR )printf(Failed to shutdown the connect: %dn,WSAGetLastError();exit(EXIT_FAILURE); closesocket(sock); /关闭Socket,回收资源/WSACleanup();利用一个for(;)循环,对确定的起始和终止IP地址的内的所有可能存在的主机发送,请求回显的ICMP报文,并对返回的ICMP报文进行分析,提取出type和code字段,根据ICM

30、P报文格式所定义的数值,对各个主机判断,并打印信息。4.2.6 端口扫描for(i = startport ; i= endport ; i+)sock = socket(AF_INET , SOCK_STREAM , IPPROTO_TCP); /创建一个Socketif(sock=INVALID_SOCKET) printf(Create socket failed: %dn,WSAGetLastError(); exit(EXIT_FAILURE); /主机字节序转换为网络字节序dest.sin_port = htons(i);/用此Socket连接目的主机,核心代码status = c

31、onnect(sock , (struct sockaddr *)&dest , sizeof dest);if(status = SOCKET_ERROR) /连接失败switch(WSAGetLastError()case 10060:printf(%st%dtERRORttConnection timed outn , hostname , i );break;case 10061:printf(%st%dtERRORttConnection refusedn , hostname , i );break;default:printf(%st%dtERRORtCode:n,WSAGetL

32、astError();break;/fflush(stdout);else /连接成功printf(%st%dtPORT OPENn , hostname ,i);/关闭收发服务if( shutdown( sock ,SD_BOTH ) = SOCKET_ERROR )printf(Failed to shutdown the connect: %dn,WSAGetLastError();exit(EXIT_FAILURE); closesocket(sock); /关闭Socket,回收资源/WSACleanup();函数同样利用一个for(;)循环对给定的主机的端口区间扫描。调用WSAGe

33、tLastError()库函数判断端口是否连接,根据相应的ERROR CODE判断端口的具体情况。以下是主要的ERROR CODE:WSAETIMEDOUT10060Connection timed out.A connection attempt failed because the connected party did not properly respond after a period of time, or the established connection failed because the connected host has failed to respond.WSAEC

34、ONNREFUSED10061Connection refused.No connection could be made because the target computer actively refused it. This usually results from trying to connect to a service that is inactive on the foreign hostthat is, one with no server application running.WSAELOOP10062Cannot translate name.Cannot transl

35、ate a name.摘自:五、 总结与体会5.1 程序调试与运行程序主界面IP网段扫描端口扫描5.2 体会通过本次的课程设计加深了本人对TCP/IP协议特别是网络层协议,IP首部格式,ICMP首部格式的理解。对Windows网络编程也有初步的了解,掌握了基本的套接字程序的编写。理解原始套接字的运行机制,加深一些协议字段的理解。编写过程遇到的困难也不少,但是依靠钻研精神,逐步对网络编程步骤产生了整体的印象,这对以后的学习也是一笔宝贵的财富。以前学习总是停留在纸面上理论上,虽然貌似一些概念是清楚了,但是这样的记忆是不长久的。只有通过理论联系实际,编写一些代码,实现一些功能,才能加强记忆,学以致用

36、。六、 参考文献6.1 参考书目1 W.Richard Stevens,Bill Fenner,Andrew M.Rudoff. Unix Network Programming Volume1:The Sockets Networking API,Third Edition. Pearson Education,20102 Wnthony Jones,Jim Ohlund. Network Programming for Microsoft Windows,Second Edition.Microsoft Press,20023 谢希仁.计算机网络(第四版).电子工业出版社,20034 周鸣

37、争,严楠,丁刚等.计算机网络教程.清华大学出版社,20116.2 引用网址http:/www.ietf.org/rfc.htmlhttp:/datatracker.ietf.org/doc/rfc792/http:/zh.wikipedia.org/zh-cn/RFC源代码Scanner,h/IP首部typedef struct ip_hdrunsigned char iphVerLen; / 版本号和头长度(各占4位)unsigned char ipTOS; / 服务类型 unsigned short ipLength; / 封包总长度,即整个IP报的长度unsigned short ipI

38、D; / 封包标识,惟一标识发送的每一个数据报unsigned short ipFlags; / 标志unsigned char ipTTL; / 生存时间,就是TTLunsigned char ipProtocol; / 协议,可能是TCP、UDP、ICMP等unsigned short ipChecksum; / 校验和unsigned long ipSource; / 源IP地址unsigned long ipDestination; / 目标IP地址IP_HDR,*PIP_HDR;/ICMP首部typedef struct icmp_hdrunsigned char icmp_type

39、; /类型unsigned char icmp_code; /代码unsigned short icmp_checksum; /检验和unsigned short icmp_id; /唯一请求ID,通常使用进程PIDunsigned short icmp_sequence; /序列号unsigned long icmp_timestamp; /时间戳 ICMP_HDR,*PICMP_HDR;Scanner.c#include #include #include #include #include #pragma comment(lib,ws2_32.lib);#include Scanner.

40、h#define ICMP_ECHO_REQUEST_TYPE 8 /ICMP请求类型#define ICMP_ECHO_REQUEST_CODE 0 /ICMP请求代码#define ICMP_ECHO_REPLY_TYPE 0#define ICMP_ECHO_REPLY_CODE 0#define ICMP_MINIMUM_HEADER 8struct hostent *host; /记录主机信息struct sockaddr_in dest; /存储目的主机信息struct sockaddr_in from; /用于回显/注释:常见的ICMP报文类型/ 类型 代码 描述/ 0 0 回显回答/ 3 1 主机

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号