⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ping.c

📁 netkit-base-0.17.tar.gz linux嵌入式开发使用!
💻 C
📖 第 1 页 / 共 3 页
字号:
			       icp->icmp_code);			break;		}		/* Print returned IP header information */		pr_retip((struct ip *)icp->icmp_data);		break;	case ICMP_SOURCE_QUENCH:		printf("Source Quench\n");		pr_retip((struct ip *)icp->icmp_data);		break;	case ICMP_REDIRECT:		switch(icp->icmp_code) {		case ICMP_REDIR_NET:			printf("Redirect Network");			break;		case ICMP_REDIR_HOST:			printf("Redirect Host");			break;		case ICMP_REDIR_NETTOS:			printf("Redirect Type of Service and Network");			break;		case ICMP_REDIR_HOSTTOS:			printf("Redirect Type of Service and Host");			break;		default:			printf("Redirect, Bad Code: %d", icp->icmp_code);			break;		}		printf("(New addr: %s)\n", inet_ntoa(icp->icmp_gwaddr));		pr_retip((struct ip *)icp->icmp_data);		break;	case ICMP_ECHO:		printf("Echo Request\n");		/* XXX ID + Seq + Data */		break;	case ICMP_TIME_EXCEEDED:		switch(icp->icmp_code) {		case ICMP_EXC_TTL:			printf("Time to live exceeded\n");			break;		case ICMP_EXC_FRAGTIME:			printf("Frag reassembly time exceeded\n");			break;		default:			printf("Time exceeded, Bad Code: %d\n",			    icp->icmp_code);			break;		}		pr_retip((struct ip *)icp->icmp_data);		break;	case ICMP_PARAMETERPROB:		printf("Parameter problem: IP address = %s\n",		       inet_ntoa(icp->icmp_gwaddr));		pr_retip((struct ip *)icp->icmp_data);		break;	case ICMP_TIMESTAMP:		printf("Timestamp\n");		/* XXX ID + Seq + 3 timestamps */		break;	case ICMP_TIMESTAMPREPLY:		printf("Timestamp Reply\n");		/* XXX ID + Seq + 3 timestamps */		break;	case ICMP_INFO_REQUEST:		printf("Information Request\n");		/* XXX ID + Seq */		break;	case ICMP_INFO_REPLY:		printf("Information Reply\n");		/* XXX ID + Seq */		break;#ifdef ICMP_MASKREQ	case ICMP_MASKREQ:		printf("Address Mask Request\n");		break;#endif#ifdef ICMP_MASKREPLY	case ICMP_MASKREPLY:		printf("Address Mask Reply\n");		break;#endif	default:		printf("Bad ICMP type: %d\n", icp->icmp_type);	}}staticvoidpr_opts(void){	static int old_rrlen;	static char old_rr[MAX_IPOPTLEN];	int i,j,k;	u_int32_t addr;	u_int8_t *cp = INPACK_OPTS;	for (i=0; i<ipoptlen; i++) {		switch (cp[i]) {		case IPOPT_EOL:			return;		case IPOPT_LSRR:			printf("\nLSRR: ");			j = cp[++i];			i++; /* ? */			if (j > IPOPT_MINOFF) {				while (i<ipoptlen) {					memcpy(&addr, &cp[i+1], sizeof(addr));					printf("\t%s", pr_addr(ntohl(addr)));					i += sizeof(addr);					j -= sizeof(addr);					if (j <= IPOPT_MINOFF)						break;					putchar('\n');				}			}			break;		case IPOPT_RR:			j = cp[++i];		/* get length */			k = cp[++i];		/* and pointer */			if (k > j)				k = j;			k -= IPOPT_MINOFF;			if (k <= 0)				continue;			if (k == old_rrlen			    && i==2			    && !memcmp(cp+i, old_rr, k)			    && !(options & F_FLOOD)) {				printf("\t(same route)");				k = ((k + 3) / 4) * 4;				i += k;				break;			}			if (k < MAX_IPOPTLEN) {				old_rrlen = k;				memcpy(old_rr, cp+i, k);			} 			else {				old_rrlen = 0;			}			j=0;			printf("\nRR: ");			for (;;) {				memcpy(&addr, &cp[i+1], sizeof(addr));				printf("\t%s", pr_addr(ntohl(addr)));				i += 4;				j += 4;				k -= 4;				if (k <= 0)					break;				if (j >= MAX_IPOPTLEN) {					printf("\t(truncated route)");					break;				}				putchar('\n');			}			break;		case IPOPT_NOP:			printf("\nNOP");			break;		default:			printf("\nunknown option %x", cp[i]);			break;		}	}}staticvoidcheck_packet_data(void){	u_int8_t *cp, *dp;	int i;	cp = INPACK_PAYLOAD;	dp = OUTPACK_PAYLOAD;	for (i=0; i<datalen-ICMP_MINLEN; i++) {		if (cp[i] != dp[i]) {			printf("\n");			printf("wrong data byte #%d should be 0x%x "			       "but was 0x%x",			       i, dp[i], cp[i]);			for (i=0; i<datalen-ICMP_MINLEN; i++) {				if ((i % 32) == 8)					printf("\n\t");				printf("%x ", cp[i]);			}			return;		}	}}/* * pr_pack * * Print out the packet, if it came from us. *  * This check is necessary because ALL readers of the ICMP socket get a  * copy of ALL ICMP packets which arrive ('tis only fair).  This permits  * multiple copies of this program to be run without having intermingled  * output (or statistics!). * * Returns nonzero if it was one of our echo replies. */staticintpr_pack(int packlen, struct sockaddr_in *from){	struct ip *ip;	struct icmp *icp;	struct timeval now, packettv, *tp;	long triptime = 0;	int hlen, dupflag;	int rv;	gettimeofday(&now, NULL);	/* Check the IP header */	ip = INPACK_IP;	hlen = ip->ip_hl << 2;	if (hlen < (int)sizeof(struct ip)) {		if (options & F_VERBOSE) {			fprintf(stderr,				"ping: packet too short (%d octets with "				"IP header) from %s\n", 				packlen, inet_ntoa(from->sin_addr));		}		return 0;	}	if (hlen > packlen) {		if (options & F_VERBOSE) {			fprintf(stderr,				"ping: partial packet (%d octets IP header, "				"whole packet only %d) from %s\n", 				hlen, packlen, inet_ntoa(from->sin_addr));		}		return 0;	}	ipoptlen = hlen - sizeof(struct ip);	packlen -= hlen;	icp = INPACK_ICMP;	/* ICMP_MINLEN is the size of the icmp header (8 octets) */	if (packlen < ICMP_MINLEN + datalen) {		if (options & F_VERBOSE) {			fprintf(stderr,				"ping: packet too short (%d octets) from %s\n",				packlen, inet_ntoa(from->sin_addr));		}		return 0;	}	/* Now the ICMP part */	if (icp->icmp_type == ICMP_ECHOREPLY) {		if (icp->icmp_id != ident)			return 0;		/* 'Twas not our ECHO */		nreceived++;		if (timing) {			tp = (struct timeval *)icp->icmp_data;			memcpy(&packettv, tp, sizeof(struct timeval));			tvsub(&now, &packettv);			/* precision: tenths of milliseconds */			triptime = now.tv_sec * 10000 + (now.tv_usec / 100);			tsum += triptime;			if (triptime < tmin)				tmin = triptime;			if (triptime > tmax)				tmax = triptime;		}		if (TST(icp->icmp_seq % mx_dup_ck)) {			++nrepeats;			--nreceived;			dupflag = 1;		} 		else {			SET(icp->icmp_seq % mx_dup_ck);			dupflag = 0;		}		if (options & F_QUIET) {			return 1;		}		rv = 1;		if (options & F_FLOOD) {			write(STDOUT_FILENO, &BSPACE, 1);		}		else {			printf("%d octets from %s: icmp_seq=%u", packlen,			       inet_ntoa(from->sin_addr), icp->icmp_seq);			printf(" ttl=%d", ip->ip_ttl);			if (timing) {				printf(" time=%ld.%ld ms", triptime/10,				       triptime%10);			}			if (dupflag) {				printf(" (DUP!)");			}			/* check the data */			check_packet_data();		}	} 	else {		/* We've got something other than an ECHOREPLY */		if ((options & F_VERBOSE)==0) {			return 0;		}		printf("%d octets from %s: ", packlen,		       pr_addr(from->sin_addr.s_addr));		pr_icmph(icp);		rv = 0;	}	/* Display any IP options */	pr_opts();	if ((options & F_FLOOD)==0) {		putchar('\n');		fflush(stdout);	}	return rv;}/********************* pinging code ********************//* * finish -- *	Print out statistics, and give up. */staticvoidfinish(int ignore){	(void)ignore;	signal(SIGINT, SIG_IGN);	putchar('\n');	fflush(stdout);	printf("--- %s ping statistics ---\n", hostname);	printf("%ld packets transmitted, ", ntransmitted);	printf("%ld packets received, ", nreceived);	if (nrepeats) {		printf("+%ld duplicates, ", nrepeats);	}	if (ntransmitted) {		if (nreceived > ntransmitted)			printf("-- somebody's printing up packets!");		else			printf("%ld%% packet loss",			       ((ntransmitted - nreceived) * 100) /				ntransmitted);	}	putchar('\n');	if (nreceived && timing) {		printf("round-trip min/avg/max = %ld.%ld/%lu.%lu/%ld.%ld ms\n",			tmin/10, tmin%10,			(tsum / (nreceived + nrepeats))/10,			(tsum / (nreceived + nrepeats))%10,			tmax/10, tmax%10);	}	if (nreceived==0) exit(1);	exit(0);}/* * pinger * 	 * Compose and transmit an ICMP ECHO REQUEST packet.  The IP header * will be added on by the kernel.  The ID field is our UNIX process ID, * and the sequence number is an ascending integer.  The first few bytes * of the data portion are used to hold a UNIX "timeval" struct, to  * compute the round-trip time.  */staticvoidpinger(void){	struct icmp *icp;	size_t packlen;	int sentlen;	icp = OUTPACK_ICMP;	icp->icmp_type = ICMP_ECHO;	icp->icmp_code = 0;	icp->icmp_cksum = 0;	icp->icmp_seq = ntransmitted++;	icp->icmp_id = ident;	CLR(icp->icmp_seq % mx_dup_ck);	if (timing) {		struct timeval tmptm;		gettimeofday(&tmptm, NULL);		memcpy(OUTPACK_TIME, &tmptm, sizeof(tmptm));	}	/* get total length of outpack (datalen is total length of payload) */	packlen = datalen + (OUTPACK_PAYLOAD - outpack);	/* compute ICMP checksum here */	icp->icmp_cksum = in_cksum((u_short *)outpack, packlen);	sentlen = sendto(sock, outpack, packlen, 0,			 (struct sockaddr *)&whereto, sizeof(whereto));	if (sentlen != (int)packlen)  {		if (sentlen < 0) {			perror("sendto");		}		printf("ping: sent %d octets to %s, ret=%d\n", 		       (int)packlen, hostname, sentlen);	}	if ((options & F_QUIET)==0 && (options & F_FLOOD)) {		write(STDOUT_FILENO, &DOT, 1);	}}staticintcompute_waittime(void){	int waittime;	if (nreceived) {		waittime = 2 * tmax / 1000;		if (!waittime)			waittime = 1;		if (waittime > MAXWAIT)			waittime = MAXWAIT;	} 	else {		waittime = MAXWAIT;	}	return waittime;}staticvoiddoping(void){	struct sockaddr_in from;	socklen_t fromlen;	struct timeval interval, next, now, timeout;	fd_set mask;	int dosend=1, packlen;	if (options & F_FLOOD) {		interval.tv_sec = 0;		interval.tv_usec = 10000;	}	else {		interval.tv_sec = intervalsecs;		interval.tv_usec = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -