本文就介绍了如何使用原始套接字生成自己的ICMP报文来进行IP使用状况的探查,这也是ping程序的工作原理。本文中的程序源代码和应用程序(IpFinder2)可以在我的主页上下载。如果你发现其中的错误或者觉得有更好的实现方法请给我E-MAIL。
因为在实际的网络使用过程中,尤其是固定IP分配的网络上,IP争抢现象非常严重。而手工用PING命令逐一去查找IP地址是让人生畏的。于是我写了这么一个多线程的IP查找器,它使用PING的工作原理,多线程同时发送ICMP数据报给网络上的每一台计算机,通过观察它们是否响应来判断IP是否空闲,还是被占用。然而这个程序爆发式的数据发送方式使得网络上的许多人同时使用它时就象Nimida病毒发作一样让网络拥挤不堪。只要将它梢作改写,就可以对本地网络构成非常大的危害。同时,ICMP数据报还有一个非常严重的缺陷。这是后面要讲的,同时我还会在以后介绍一种更新,更准确的IP查找方法。无论如何,用这个程序可以统计网络上任意时刻用户的数目,单单这个功能就是非常有趣的事情。
我没有篇幅也没有足够的胆子来讲TCP/IP协议。如果你不明白基本的TCP/IP知识,我建议你先看看《使用TCP/IP协议实现网际互连》(电子工业出版社 DOUGLAS E.COMER著)的第一卷。再也没有第二个人能将TCP/IP协议解释得如此透彻而详细了(这本书是CCIE的推荐教材)。同时你也应该对基本的sock编程有所了解。
ICMP 的全称为(Internet Control Message Protocal)。它是一种差错报告机制,可以被用来向目的主机报告或者请求各种网络信息。这些信息包括回送应答,目的地不可达,源站抑制,回送请求,掩码请求和掩码应答等等,这些信息是用ICMP数据报报头中一个字节长度的类型码来区别的。其中对我们的这个程序来说有用的是回送请求与应答信息。程序的大致思想是把ICMP的数据包类型设置为回送请求,将它发送给网络上的一个IP地址,如果这个IP地址已经被占用的话,那么使用这个IP地址的主机上的TCP/IP软件就能够接收到这个ICMP回送请求(ECHO REQUEST),从而返回一个ICMP回送应答(ECHO REPLY)信息。相反的,如果这个IP地址没有人使用,那么发出去的ICMP回送请求在我们设定的延时内就不可能得到响应。
ICMP的数据报是封装在IP报头里的。与其它协议的数据报一样,它也是由报头加上数据部分构成的,其报头的格式可以用一个结构体来表示:
typedef struct _ihdr {
BYTE i_type;//ICMP 类型码,回送请求的类型码为8
BYTE i_code; /* 子类型码,保存与特定ICMP 报文类型相关的细节信息 */
USHORT i_cksum;/* 校验和 */
USHORT i_id;/* ICMP数据报的ID号*/
USHORT i_seq;/*ICMP 数据报的序列号*/
/* 下面应该是可选数据部分,我们可以忽略它们 */
ULONG timestamp;
}IcmpHeader;