1. 系统描述
1.1. 设计目标
进行网络管理时,常常需要确定当前网络中处理活动状态的主机。本设计的目标就是编制程序,利用ICMP的回送请求和回送应答消息,来发现指定网段中的活动主机,即ping消息的请求和应答。
1.2. 设计功能
编写程序,其功能是发送ICMP数据包,以获取指定网段中的活动主机,并将结果显示在标准输出上。程序具体要求如下:
1)用命令行形式运行:scanhost Start_IP End_IP
其中scanhost为程序名,Start_IP为被搜索网段的开始IP地址,End_IP为被搜索网段的结束IP地址。
2)输出格式为:
活动主机1
活动主机2
……….
1.3. 设计原理
本设计的主体思想是使用ICMPECHO数据包来探测指定网段内的活动主机。
具体方法是:通过简单的发送一个ICMPECHO(Type 8)数据包到目标主机,如果ICMPECHOReply(ICMPtype0)数据包接受到,说明主机是存活状态。如果没有就可以初步判断主机没有在线或者使用了某些过滤设备过滤了ICMP的REPLY。
2. 原理介绍
2.1. ICMP协议
为了提高IP数据报交付成功的机会,在网际层使用了ICMP协议。ICMP全称Internet Control Message Protocol,即网际控制报文协议,工作在OSI的网络层。ICMP允许主机或路由器报告差错情况和提供有关异常情况的报告。由于ICMP报文是作为IP层数据报的数据,因此需要加上IP数据报的首部,封装在IP数据报内部才能传输。其结构如(图一)所示。
图一: ICMP数据报与IP数据报的关系
ICMP 报文的种类有两种,即ICMP差错报告报文和ICMP询问报文。ICMP报文的前4个字节是统一的格式,共有三个字段:即0-7位的类型字段、8-15位的代码字段、16-31位的校验和字段。其中,校验和字段为2个字节,校验的范围是整个ICMP报文。接着的4个字节的内容与ICMP的类型有关。而其他字节互不相同。其结构如(图二、三)所示。本设计仅用到类型为0和8的ICMP报文,关于这两种类型报文的具体描述详见(图三)。
2.2. 主机存活扫描技术
主机扫描的目的是确定在目标网络上的主机是否可达。这是信息收集的初级阶段,其效果直接影响到后续的扫描。Ping就是最原始的主机存活扫描技术,利用icmp的echo字段,发出的请求如果收到回应的话代表主机存活。
常用的传统扫描手段有:
1. ICMP Echo扫描:精度相对较高。通过简单地向目标主机发送ICMP Echo Request 数据包,并等待回复的ICMP Echo Reply 包,如Ping。
2. ICMP Sweep扫描:sweep这个词的动作很像机枪扫射,icmp进行扫射式的扫描,就是并发性扫描,使用ICMP Echo Request一次探测多个目标主机。通常这种探测包会并行发送,以提高探测效率,适用于大范围的评估。
3. Broadcast ICMP扫描:广播型icmp扫描,利用了一些主机在icmp实现上的差异,设置ICMP请求包的目标地址为广播地址或网络地址,则可以探测广播域或整个网络范围内的主机,子网内所有存活主机都会给以回应。但这种情况只适合于UNIX/Linux系统。
4.Non-Echo ICMP扫描:在ICMP协议中不光光只有ICMP ECHO的ICMP查询信息类型,在ICMP扫描 技术中也用到Non-ECHO ICMP技术(不仅仅能探测主机,也可以探测网络设备如路由)。利用了ICMP的服务类型(Timestamp和Timestamp Reply 、Information Request和Information Reply 、Address Mask Request 和Address Mask Reply)。
本程序使用的是ICMP EChO扫描技术。
2.3. TCP协议
TCP是一种面向连接的,可靠的传输层协议。一次正常的TCP传输需要通过在客户端和服务器之间建立特定的虚电路连接来完成,该过程通常被称为“三次握手”。TCP通过数据分段中的序列号保障所有传输的数据可以在远端按照正常的次序进行重组,而且通过确认保证数据传输的完整性。
2.4. 端口扫描技术
在完成主机存活性判断之后,就应该去判定主机开放信道的状态,端口就是在主机上面开放的信道,0-1024为知名端口,端口总数是65535。端口实际上就是从网络层映射到进程的通道。通过这个关系就可以掌握什么样的进程使用了什么样的通信,在这个过程里面,能够通过进程取得的信息,就为查找后门、了解系统状态提供了有力的支撑。
本程序利用三次握手过程与目标主机建立完整或不完整的TCP连接。
2.5. 原始套接字
原始套接字(SOCKET_RAW)允许对较低层次的协议直接访问,比如IP、ICMP协议,它常用于检验新的协议实现,或者访问现有服务中配置的新设备,因为RAW SOCKET可以自如地控制Windows下的多种协议,能够对网络底层的传输机制进行控制,所以可以应用原始套接字来操纵网络层和传输层应用。
2.6. 实现方法
本设计使用原始套接字生成ICMP报文来进行活动主机的探测。设计的大体思想是把报文类型设置为回送请求,将它发送给网络上的一个IP地址,如果这个IP地址已被占用,那么使用这个IP地址的主机上的TCP/IP软件就能够接收到这个ICMP回送请求,并返回一个ICMP回送响应信息。由于接收到的回送响应ICMP包是封装在IP包内,就需要解析该IP包,从中找到ICMP数据信息。相反,如果这个IP地址没有人使用,那么发送的ICMP回送请求在设定的时延内就不可能得到响应。
在初始化原始套接字后,程序就要开始在一个IP网段内寻找活动主机。由于在某网段内需要发现的主机很多,为提高效率,采用了多线程编程。
3. 系统设计
3.1. 数据结构设计
3.1.1. 定义IP数据报首部结构
由于socket发送和捕获的是IP包,因此要分别定义IP首部和ICMP首部
typedef struct iphdr{ //IP头
unsigned int headlen:4; //IP头长度
unsigned int version:4; //IP版本号
unsigned