//ping.h头文件如下所示:
#define ICMP_ECHOREPLY 0 /*ECHO应答*/ #define ICMP_ECHO 8 /*ECHO请求*/ #define BUFSIZE 1500 /*发送缓存最大值*/ #define DEFAULT_LEN 56 /*ping 消息数据默认大小*/ /*数据类型别名*/ typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; /*ICMP消息头部*/ struct icmphdr { u8 type; u8 code; u16 checksum; union { struct { u16 id; u16 sequence; } echo; u32 gateway; struct { u16 unused; u16 mtu; } frag; /*pmtu发现*/ } un; /*ICMP 数据占位符*/ u8 data[0]; #define icmp_id un.echo.id #define icmp_seq un.echo.sequence }; #define ICMP_HSIZE sizeof(struct icmphdr) struct iphdr { u8 hlen: 4, ver: 4; u8 tos; u16 tot_len; u16 id; u16 frag_off; u8 ttl; u8 protocol; u16 check; u32 saddr; u32 daddr; }; char *hostname;/*被ping的主机*/ int datalen = DEFAULT_LEN; /*ICMP消息携带的数据长度*/ char sendbuf[BUFSIZE]; char recvbuf[BUFSIZE]; int nsent;/*发送的ICMP信息序号*/ int nrecv; pid_t pid;/*ping程序的进程PID*/ struct timeval recvtime;/*收到ICMP应答的时间戳*/ int sockfd;/*发送和接收原始套接字*/ struct sockaddr_in dest;/*被ping主机的IP*/ struct sockaddr_in from;/*发送ping应答消息的主机IP*/ struct sigaction act_alarm; struct sigaction act_int; /*函数原型*/ void alarm_handler(int);/*SIGALARM处理程序*/ void int_handler(int);/*SIGINT处理程序*/ void set_sighandler();/*设置信号处理程序*/ void send_ping();/*发送ping应答消息*/ void recv_reply();/*接受ping 应答*/ u16 checksum(u8 *buf, int len); /*计算校验和*/ int handle_pkt();/*ICMP应答消息处理*/ void get_statistics(int, int); /*统计ping命令的检测结果*/ void bail(const char *);/*错误报告*/
运行结果如下:
1:如果想要在GCC中使用C扩展的话,所用的参数都是gnuXX类型的,
C99使用GCC的C扩展:-std=gnu99
2:因为原始套接字的创建需要root用户权限,所以为了能让所有的其他用户也可以使用该程序,需要通过如下命令设置myping的set-user-id位。