简易ping程序

原创 2012年03月31日 08:40:23

当我把icmp的检验和设置成0时,ping百度是可以有echo返回。但是ping其他主机是没有返回响应。

手动添加检验和后正常。

原因:可能是baidu服务器并没有检测校验和就返回一个echo,这样可以减少服务器的负担。

而其他一些站点都会校验。


注意点:IPV4的icmp,在原始套接字收到后,收到的是包含IP头在内的完整数据报

IPV6的icmp,则是去除所有ip头和扩展头部的净载荷。

#include "unp.h"
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <assert.h>
char 	sendbuf[MAXLINE], recvbuf[MAXLINE];
int 		datalen = 56,	 nseq = 0;
int 		sockfd;
struct sockaddr_in	dst, src;
socklen_t 		dstlen, srclen;


void callfunc(int signo) ;
void send_icmp( ) ;
void  recv_icmp();
unsigned short icmp_cksum(unsigned short *addr, int len);

int	main( int argc, char **argv) {
	if(argc  != 2) {
		err_quit("args");
	}
	char buf[100];
	struct addrinfo *addr, hints, *next;
	struct sockaddr *servaddr;
	struct sockaddr_in *temp;
	bzero(&hints, sizeof(struct addrinfo));
	hints.ai_family = AF_UNSPEC;
	getaddrinfo(argv[1], NULL, &hints, &addr);
	for(; addr != NULL; addr = addr->ai_next) {
		temp = (struct sockaddr_in *)(addr->ai_addr);
		dst = *temp;
		dstlen = srclen = sizeof(struct sockaddr);
		 printf("the dst ip is %s\n", inet_ntop(AF_INET, &(temp->sin_addr), buf, sizeof(buf)));
		break;
	}
	sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
	setuid(getuid());
	signal(SIGALRM, callfunc);
	callfunc(SIGALRM);
	for(;;) {
		recv_icmp();
	}
}
void callfunc(int signo) {
	send_icmp();
	alarm(1);
}
void send_icmp( ) {
	struct icmp		*icmp;
	/*		struct timeval		*timeval;*/
	icmp = (struct icmp *)sendbuf;
	icmp->icmp_type = 8;
	icmp->icmp_code = 0;
	icmp->icmp_cksum = 0;
	icmp->icmp_id = 88;
	icmp->icmp_seq = nseq ++;
	gettimeofday((struct timeval *)(icmp->icmp_data), NULL);
	icmp->icmp_cksum = icmp_cksum((u_short *)icmp, 56+8);
	sendto(sockfd, sendbuf, 56+8, 0, (SA *)&dst, dstlen);
	return;
}
void cal_time(struct timeval *time1, struct timeval *time2) { /*大 小*/
	time1->tv_usec = ((time1->tv_usec)/1000) + ((time1->tv_sec)*1000);
	time2->tv_usec = ((time2->tv_usec)/1000) + ((time2->tv_sec)*1000);
	time1->tv_usec = (time1->tv_usec) -(time2->tv_usec);
}
void  recv_icmp() {
	struct ip		*ip;
	struct icmp	*icmp;
	struct timeval *rtime;
	int			n,hl;
	char 	buf[100];
	again:
	if(( n = recvfrom(sockfd, recvbuf, sizeof(recvbuf), 0, (SA *)&src, &srclen) ) < 0) {
		if(errno == EINTR)
			goto again;
		else
			exit(0);
	}
	//printf("return a echo\n");

	ip = (struct ip *)recvbuf;
	hl = ip->ip_hl;
	hl = hl<< 2;
	icmp = (struct icmp *)(recvbuf + hl);
	if(icmp == NULL)
		printf("icmp is null\n");
	assert(icmp);
	assert(recvbuf);
	rtime = (struct timeval *)malloc(sizeof(struct timeval));
	if((icmp->icmp_type == 0) && (icmp->icmp_code == 0) &&(icmp->icmp_id == 88)){
		gettimeofday(rtime, NULL);
		cal_time(rtime, (struct timeval *)(icmp->icmp_data));
		printf("The seq %d ,", icmp->icmp_seq);
		printf("Ping the ip is %s :", inet_ntop(AF_INET,&( (&src)->sin_addr), buf, sizeof(buf)));
		printf("ttl  %d  ms\n", rtime->tv_usec);
		
	}
}

unsigned short icmp_cksum(unsigned short *addr, int len)
{
	int				nleft = len;
	int				sum = 0;
	unsigned short	*w = addr;
	unsigned short	answer = 0;
	while (nleft > 1)  {
		sum += *w++;
		nleft -= 2;
	}
	if (nleft == 1) {
		*(unsigned char *)(&answer) = *(unsigned char *)w ;
		sum += answer;
	}
	sum = (sum >> 16) + (sum & 0xffff);	
	sum += (sum >> 16);			
	answer = ~sum;				
	return(answer);
}

详解Ping程序

ping程序编写的目的是为了测试另外一台主机是否可达。程序发送的是一份ICMP回显请求报文给目的主机,并等待ICMP回显应答。...
  • a5503308
  • a5503308
  • 2016年04月29日 00:37
  • 1638

Windows下PING程序实现

跟着网上的代码试着敲了一遍,熟悉Ping的过程。 Ping.h //Ping.h //Define the header of IP and ICMP #pragma pack(1) #define ...
  • Hearthougan
  • Hearthougan
  • 2016年06月12日 14:33
  • 1498

如何写一个简单的ping程序

今天翻硬盘时,发现自己很久之前写的ping程序。突然想不如把ping程序放上来做一下也算让之前自己写的东西重见天日,当时还是花了挺多时间来写,感触良多。首先呢,ping用到的协议是网络层的ICMP协议...
  • chenpidaxia
  • chenpidaxia
  • 2017年09月02日 20:05
  • 1076

粗略实现Ping程序

最近一直在看《TCP/IP详解》这本书,也许因为我不是计算机专业的缘故,总感觉看了跟没看一样,想着写写博客,能加深印象,结果简直是尴尬。所以想着不如自己动手来实现一个Ping程序,当是学习学习吧,几年...
  • cairo123
  • cairo123
  • 2016年11月17日 21:29
  • 837

自己写个ping程序玩玩---附带抓包

ping功能很常用, 在Windows/Linux上, 我们经常用ping功能来探测对方是否在线。 那么, ping到底是怎么实现的呢? 在本文中, 我们自己来写一个ping, 当然, 功能肯定没有W...
  • stpeace
  • stpeace
  • 2015年02月01日 18:59
  • 5694

Ping程序C++实现

学习内容,参见《Windows网络编程》第13章原始套接字   Ping程序实现步骤 创建类型为SOCK_RAW的一个套接字,同时设定协议IPPROTO_ICMP。创建并初始化ICMP头...
  • segen_jaa
  • segen_jaa
  • 2012年05月15日 17:31
  • 10107

C#写的一个ping程序

C#写的一个ping程序 ICMP就是所谓的Internet控制报文协议(Internet Control Message Protocol),在网络中,一般用它来传递差...
  • handsing
  • handsing
  • 2011年08月12日 17:40
  • 1979

ping 程序(vc6.0 原始套接字实现)

#include #include #include #include //IP_TTL #pragma comment(lib,"ws2_32.lib") //ICMP首部结构体 typ...
  • mashen1989
  • mashen1989
  • 2012年06月26日 10:59
  • 1995

在linux中用C语言实现ping命令

运用C语言编写模拟常用网络命令ping命令实现一个基于linux原始套接字和ICMP协议的ping程序。该程序能用于检测主机或路由器工作是否正常。 程序中主要的函数 void alarm_hand...
  • u010979030
  • u010979030
  • 2016年01月27日 13:57
  • 2905

使用原始套接字编程实现简单的ping程序

程序实现步骤: 1、初始化Windows Sockets网络环境   WSADATA    wsa; WSAStartup(MAKEWORD(2,2),&wsa); 2、构造目的端Socket...
  • zhangxiaofangtongxue
  • zhangxiaofangtongxue
  • 2015年07月20日 10:59
  • 1454
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:简易ping程序
举报原因:
原因补充:

(最多只允许输入30个字)