ping程序-c语言实现

创建时间: 2017-08-17
最后修改时间: 2017-08-17

因个人水平有限,文章中存在不足,错误之处,还望指正

实验环境
Linux 2.6.32
gcc version 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC)

引言

本ping程序并没有提供网络上公开可得的ping程序那样强大的功能(支持众多不同的选项),而是仅实现最基本的功能来了解我们所关注的问题:网络编程的概念和技巧。

ping程序简介

ping程序可以用来测试网络上的节点是否可达或网络连接速度。该程序发送一个ICMP回显请求给目的端,并等待其返回ICMP回显应答。

一般来说,如果不能ping到某主机,那么就不能Telnet到该主机。但这并不是绝对的,随着Internet安全意识的增强,出现了提供访问控制的路由器和防火墙,一台主机的可达性可能不只取决于IP层是否可达,还取决于使用何种协议以及端口。ping程序运行结果显示某台主机不可达,但我们却可以用Telnet远程登录该主机。

IP和ICMP协议简介

IP(Internet Protocol),网际协议,是TCP/IP协议族中最为核心的协议。所有TCP、UDP、ICMP及IGMP数据都以IP数据报格式传输。

它提供不可靠、无连接的数据报传送服务。

不可靠的意思是它不能保证IP数据报能成功地到达目的地。如果发生某种错误时,如某个路由器的缓冲区已满,IP有一个简单的错误处理方法:丢弃该数据报,然后发送ICMP消息给源端。任何要求的可靠性必须由上层服务来提供,如TCP。

无连接的意思是IP并不维护任何关于后续数据报信息。每个数据报的处理是相互独立的。这说明,IP数据报可以不按发送顺序接收。如果源端向目的端发送两个连续的数据报A、B,每个数据报都是独立进行路由选择,可能选择不同的线路,因此B可能在A之前先到达。

IP首部

0       4       8               16    19                        32 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version|  IHL  |Type Of Service|    Total Length(in bytes)     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Identification        |Flags|    Fragment Offset      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time To Live  |    Protocol   |       Header Checksum         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Source Ipv4 Address                     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                     Destination Ipv4 Address                  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
~                          Options (if any)                     ~
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
~                             Data                              ~
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                            IPv4首部

ICMP(Internet Control Message Protocol),Internet控制消息协议,是TCP/IP协议族的一个子协议,属于网络层协议,用于传递差错报文以及其他需要注意的信息。

ICMP报文在IP数据报内部被传输的。如下:

|-------------------------   IP数据报    ------------------------|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     IP首部      |                ICMP报文                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

ICMP报文有许多种类型,这里只列出我们所关注的报文格式:

0               8               16                              32 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Type      |      Code     |          Checksum             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           Identifier          |        Sequence Number        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
~                          Option Data                          ~
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                   ICMP回显请求和回显应答报文首部


Type                ICMP报文类型
Code                代码
Checksum            检验和
Identifier          标识符,由源端设定,应答报文的Identifier与请求报文的保持一致
Sequence Number     序列号,由源端设定,一般是递增的,应答报文的Sequence Number与请求报文的保持一致
Option Data         数据,应答报文的Option Data与请求报文的保持一致
与IP和ICMP首部相关的结构

在/usr/include/目录下可找到这些头文件。

ip结构体在头文件 “netinet/ip.h”中定义如下:


struct ip
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
    unsigned int ip_hl:4;               /* header length */
    unsigned int ip_v:4;                /* version */
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
    unsigned int ip_v:4;                /* version */
    unsigned int ip_hl:4;               /* header length */
#endif
    u_int8_t ip_tos;                    /* type of service */
    u_short ip_len;                     /* total length */
    u_short ip_id;                      /* identification */
    u_short ip_off;                     /* fragment offset field */
#define IP_RF 0x8000                    /* reserved fragment flag */
#define IP_DF 0x4000                    /* dont fragment flag */
#define IP_MF 0x2000                    /* more fragments flag */
#define IP_OFFMASK 0x1fff               /* mask for fragmenting bits 
*/
    u_int8_t ip_ttl;                    /* time to live */
    u_int8_t ip_p;                      /* protocol */
    u_short ip_sum;                     /* checksum */
    struct in_addr ip_src, ip_dst;      /* source and dest address */
};

icmp结构体在头文件”netinet/ip_icmp.h”中定义如下:


struct icmp
{
  u_int8_t  icmp_type;  /* type of message, see below */
  u_int8_t  icmp_code;  /* type sub code */
  u_int16_t icmp_cksum; /* ones complement checksum of struct */
  union
  {
    u_char ih_pptr;             /* ICMP_PARAMPROB */
    struct in_addr ih_gwaddr;   /* gateway address */
    struct ih_idseq             /* echo datagram */
    {
      u_int16_t icd_id;
      u_int16_t icd_seq;
    } ih_idseq;
    u_int32_t ih_void;

    /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */
    struct ih_pmtu
    {
      u_in
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值