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

📄 ping.c

📁 This is a short linux ping program
💻 C
📖 第 1 页 / 共 3 页
字号:
		t1->tv_sec++;		t1->tv_usec -= 1000000;	}}static voidsec_to_timeval(const double sec, struct timeval *tp){	tp->tv_sec = sec;	tp->tv_usec = (sec - tp->tv_sec) * 1000000.0;}static doubletimeval_to_sec(const struct timeval *tp){	return tp->tv_sec + tp->tv_usec / 1000000.0;}/* * Print statistics. * Heavily buffered STDIO is used here, so that all the statistics * will be written with 1 sys-write call.  This is nice when more * than one copy of the program is running on a terminal;  it prevents * the statistics output from becomming intermingled. */static voidsummary(int header){	jiggle_flush(1);	if (header)		(void)printf("\n----%s PING Statistics----\n", hostname);	(void)printf("%d packets transmitted, ", ntransmitted);	(void)printf("%d packets received, ", nreceived);	if (nrepeats)		(void)printf("+%d duplicates, ", nrepeats);	if (ntransmitted) {		if (nreceived > ntransmitted)			(void)printf("-- somebody's duplicating packets!");		else			(void)printf("%.1f%% packet loss",				     (((ntransmitted-nreceived)*100.0) /					    ntransmitted));	}	(void)printf("\n");	if (nreceived && (pingflags & F_TIMING)) {		double n = nreceived + nrepeats;		double avg = (tsum / n);		double variance = 0.0;		if (n>1)			variance = (tsumsq - n*avg*avg) /(n-1);		printf("round-trip min/avg/max/stddev = "			"%.3f/%.3f/%.3f/%.3f ms\n",			tmin * 1000.0, avg * 1000.0,			tmax * 1000.0, sqrt(variance) * 1000.0);		if (pingflags & F_FLOOD) {			double r = diffsec(&last_rx, &first_rx);			double t = diffsec(&last_tx, &first_tx);			if (r == 0)				r = 0.0001;			if (t == 0)				t = 0.0001;			(void)printf("  %.1f packets/sec sent, "				     " %.1f packets/sec received\n",				     ntransmitted/t, nreceived/r);		}	}}/* * Print statistics when SIGINFO is received. *//* ARGSUSED */static voidprtsig(int dummy){	summary(0);#ifdef SIGINFO	(void)signal(SIGINFO, prtsig);#else	(void)signal(SIGQUIT, prtsig);#endif}/* * On the first SIGINT, allow any outstanding packets to dribble in */static voidprefinish(int dummy){	if (lastrcvd			/* quit now if caught up */	    || nreceived == 0)		/* or if remote is dead */		finish(0);	(void)signal(dummy, finish);	/* do this only the 1st time */	if (npackets > ntransmitted)	/* let the normal limit work */		npackets = ntransmitted;}/* * Print statistics and give up. *//* ARGSUSED */static voidfinish(int dummy){#if defined(SIGINFO) && defined(NOKERNINFO)	struct termios ts;	if (reset_kerninfo && tcgetattr (0, &ts) != -1) {		ts.c_lflag &= ~NOKERNINFO;		tcsetattr (STDIN_FILENO, TCSANOW, &ts);	}	(void)signal(SIGINFO, SIG_IGN);#else	(void)signal(SIGQUIT, SIG_DFL);#endif	summary(1);	exit(nreceived > 0 ? 0 : 2);}static int				/* 0=do not print it */ck_pr_icmph(struct icmp *icp,	    struct sockaddr_in *from,	    int cc,	    int override)		/* 1=override VERBOSE if interesting */{	int	hlen;	struct ip ipb, *ip = &ipb;	struct icmp icp2b, *icp2 = &icp2b;	int res;	if (pingflags & F_VERBOSE) {		res = 1;		jiggle_flush(1);	} else {		res = 0;	}	(void) memcpy(ip, icp->icmp_data, sizeof(*ip));	hlen = ip->ip_hl << 2;	if (ip->ip_p == IPPROTO_ICMP	    && hlen + 6 <= cc) {		(void) memcpy(icp2, &icp->icmp_data[hlen], sizeof(*icp2));		if (icp2->icmp_id == ident) {			/* remember to clear route cached in kernel			 * if this non-Echo-Reply ICMP message was for one			 * of our packets.			 */			clear_cache.tv_sec = 0;			if (!res && override			    && (pingflags & (F_QUIET|F_SEMI_QUIET)) == 0) {				jiggle_flush(1);				(void)printf("%d bytes from %s: ",					     cc, pr_addr(&from->sin_addr));				res = 1;			}		}	}	return res;}/* *  Print a descriptive string about an ICMP header other than an echo reply. */static int				/* 0=printed nothing */pr_icmph(struct icmp *icp,	 struct sockaddr_in *from,	 int cc){	switch (icp->icmp_type ) {	case ICMP_UNREACH:		if (!ck_pr_icmph(icp, from, cc, 1))			return 0;		switch (icp->icmp_code) {		case ICMP_UNREACH_NET:			(void)printf("Destination Net Unreachable");			break;		case ICMP_UNREACH_HOST:			(void)printf("Destination Host Unreachable");			break;		case ICMP_UNREACH_PROTOCOL:			(void)printf("Destination Protocol Unreachable");			break;		case ICMP_UNREACH_PORT:			(void)printf("Destination Port Unreachable");			break;		case ICMP_UNREACH_NEEDFRAG:			(void)printf("frag needed and DF set.  Next MTU=%d",			       ntohs(icp->icmp_nextmtu));			break;		case ICMP_UNREACH_SRCFAIL:			(void)printf("Source Route Failed");			break;		case ICMP_UNREACH_NET_UNKNOWN:			(void)printf("Unreachable unknown net");			break;		case ICMP_UNREACH_HOST_UNKNOWN:			(void)printf("Unreachable unknown host");			break;		case ICMP_UNREACH_ISOLATED:			(void)printf("Unreachable host isolated");			break;		case ICMP_UNREACH_NET_PROHIB:			(void)printf("Net prohibited access");			break;		case ICMP_UNREACH_HOST_PROHIB:			(void)printf("Host prohibited access");			break;		case ICMP_UNREACH_TOSNET:			(void)printf("Bad TOS for net");			break;		case ICMP_UNREACH_TOSHOST:			(void)printf("Bad TOS for host");			break;		case 13:			(void)printf("Communication prohibited");			break;		case 14:			(void)printf("Host precedence violation");			break;		case 15:			(void)printf("Precedence cutoff");			break;		default:			(void)printf("Bad Destination Unreachable Code: %d",				     icp->icmp_code);			break;		}		/* Print returned IP header information */		pr_retip(icp, cc);		break;	case ICMP_SOURCEQUENCH:		if (!ck_pr_icmph(icp, from, cc, 1))			return 0;		(void)printf("Source Quench");		pr_retip(icp, cc);		break;	case ICMP_REDIRECT:		if (!ck_pr_icmph(icp, from, cc, 1))			return 0;		switch (icp->icmp_code) {		case ICMP_REDIRECT_NET:			(void)printf("Redirect Network");			break;		case ICMP_REDIRECT_HOST:			(void)printf("Redirect Host");			break;		case ICMP_REDIRECT_TOSNET:			(void)printf("Redirect Type of Service and Network");			break;		case ICMP_REDIRECT_TOSHOST:			(void)printf("Redirect Type of Service and Host");			break;		default:			(void)printf("Redirect--Bad Code: %d", icp->icmp_code);			break;		}		(void)printf(" New router addr: %s",			     pr_addr(&icp->icmp_hun.ih_gwaddr));		pr_retip(icp, cc);		break;	case ICMP_ECHO:		if (!ck_pr_icmph(icp, from, cc, 0))			return 0;		(void)printf("Echo Request: ID=%d seq=%d",			     ntohs(icp->icmp_id), ntohs(icp->icmp_seq));		break;	case ICMP_ECHOREPLY:		/* displaying other's pings is too noisey */#if 0		if (!ck_pr_icmph(icp, from, cc, 0))			return 0;		(void)printf("Echo Reply: ID=%d seq=%d",			     ntohs(icp->icmp_id), ntohs(icp->icmp_seq));		break;#else		return 0;#endif	case ICMP_ROUTERADVERT:		if (!ck_pr_icmph(icp, from, cc, 0))			return 0;		(void)printf("Router Discovery Advert");		break;	case ICMP_ROUTERSOLICIT:		if (!ck_pr_icmph(icp, from, cc, 0))			return 0;		(void)printf("Router Discovery Solicit");		break;	case ICMP_TIMXCEED:		if (!ck_pr_icmph(icp, from, cc, 1))			return 0;		switch (icp->icmp_code ) {		case ICMP_TIMXCEED_INTRANS:			(void)printf("Time To Live exceeded");			break;		case ICMP_TIMXCEED_REASS:			(void)printf("Frag reassembly time exceeded");			break;		default:			(void)printf("Time exceeded, Bad Code: %d",				     icp->icmp_code);			break;		}		pr_retip(icp, cc);		break;	case ICMP_PARAMPROB:		if (!ck_pr_icmph(icp, from, cc, 1))			return 0;		(void)printf("Parameter problem: pointer = 0x%02x",			     icp->icmp_hun.ih_pptr);		pr_retip(icp, cc);		break;	case ICMP_TSTAMP:		if (!ck_pr_icmph(icp, from, cc, 0))			return 0;		(void)printf("Timestamp");		break;	case ICMP_TSTAMPREPLY:		if (!ck_pr_icmph(icp, from, cc, 0))			return 0;		(void)printf("Timestamp Reply");		break;	case ICMP_IREQ:		if (!ck_pr_icmph(icp, from, cc, 0))			return 0;		(void)printf("Information Request");		break;	case ICMP_IREQREPLY:		if (!ck_pr_icmph(icp, from, cc, 0))			return 0;		(void)printf("Information Reply");		break;	case ICMP_MASKREQ:		if (!ck_pr_icmph(icp, from, cc, 0))			return 0;		(void)printf("Address Mask Request");		break;	case ICMP_MASKREPLY:		if (!ck_pr_icmph(icp, from, cc, 0))			return 0;		(void)printf("Address Mask Reply");		break;	default:		if (!ck_pr_icmph(icp, from, cc, 0))			return 0;		(void)printf("Bad ICMP type: %d", icp->icmp_type);		if (pingflags & F_VERBOSE)			pr_iph(icp, cc);	}	return 1;}/* *  Print an IP header with options. */static voidpr_iph(struct icmp *icp,       int cc){	int	hlen;	u_char	*cp;	struct ip ipb, *ip = &ipb;	(void) memcpy(ip, icp->icmp_data, sizeof(*ip));	hlen = ip->ip_hl << 2;	cp = (u_char *) &icp->icmp_data[20];	/* point to options */	(void)printf("\n Vr HL TOS  Len   ID Flg  off TTL Pro  cks      Src	     Dst\n");	(void)printf("  %1x  %1x  %02x %04x %04x",		     ip->ip_v, ip->ip_hl, ip->ip_tos, ip->ip_len, ip->ip_id);	(void)printf("   %1x %04x",		     ((ip->ip_off)&0xe000)>>13, (ip->ip_off)&0x1fff);	(void)printf("  %02x  %02x %04x",		     ip->ip_ttl, ip->ip_p, ip->ip_sum);	(void)printf(" %15s ",		     inet_ntoa(*(struct in_addr *)&ip->ip_src.s_addr));	(void)printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->ip_dst.s_addr));	/* dump any option bytes */	while (hlen-- > 20 && cp < (u_char*)icp+cc) {		(void)printf("%02x", *cp++);	}}/* * Print an ASCII host address starting from a string of bytes. */static voidpr_saddr(u_char *cp){	n_long l;	struct in_addr addr;	l = (u_char)*++cp;	l = (l<<8) + (u_char)*++cp;	l = (l<<8) + (u_char)*++cp;	l = (l<<8) + (u_char)*++cp;	addr.s_addr = htonl(l);	(void)printf("\t%s", (l == 0) ? "0.0.0.0" : pr_addr(&addr));}/* *  Return an ASCII host address *  as a dotted quad and optionally with a hostname */static char *pr_addr(struct in_addr *addr)		/* in network order */{	struct	hostent	*hp;	static	char buf[MAXHOSTNAMELEN+4+16+1];	if ((pingflags & F_NUMERIC)	    || !(hp = gethostbyaddr((char *)addr, sizeof(*addr), AF_INET))) {		(void)snprintf(buf, sizeof(buf), "%s", inet_ntoa(*addr));	} else {		(void)snprintf(buf, sizeof(buf), "%s (%s)", hp->h_name,		    inet_ntoa(*addr));	}	return buf;}/* *  Dump some info on a returned (via ICMP) IP packet. */static voidpr_retip(struct icmp *icp,	 int cc){	int	hlen;	u_char	*cp;	struct ip ipb, *ip = &ipb;	(void) memcpy(ip, icp->icmp_data, sizeof(*ip));	if (pingflags & F_VERBOSE)		pr_iph(icp, cc);	hlen = ip->ip_hl << 2;	cp = (u_char *) &icp->icmp_data[hlen];	if (ip->ip_p == IPPROTO_TCP) {		if (pingflags & F_VERBOSE)			(void)printf("\n  TCP: from port %u, to port %u",				     (*cp*256+*(cp+1)), (*(cp+2)*256+*(cp+3)));	} else if (ip->ip_p == IPPROTO_UDP) {		if (pingflags & F_VERBOSE)			(void)printf("\n  UDP: from port %u, to port %u",				     (*cp*256+*(cp+1)), (*(cp+2)*256+*(cp+3)));	} else if (ip->ip_p == IPPROTO_ICMP) {		struct icmp icp2;		(void) memcpy(&icp2, cp, sizeof(icp2));		if (icp2.icmp_type == ICMP_ECHO) {			if (pingflags & F_VERBOSE)				(void)printf("\n  ID=%u icmp_seq=%u",					     ntohs((u_int16_t)icp2.icmp_id),					     ntohs((u_int16_t)icp2.icmp_seq));			else				(void)printf(" for icmp_seq=%u",					     ntohs((u_int16_t)icp2.icmp_seq));		}	}}static voidfill(void){	int i, j, k;	char *cp;	int pat[16];	for (cp = fill_pat; *cp != '\0'; cp++) {		if (!isxdigit((unsigned char)*cp))			break;	}	if (cp == fill_pat || *cp != '\0' || (cp-fill_pat) > 16*2) {		(void)fflush(stdout);		errx(1, "\"-p %s\": patterns must be specified with"		     " 1-32 hex digits\n",		     fill_pat);	}	i = sscanf(fill_pat,		   "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",		    &pat[0], &pat[1], &pat[2], &pat[3],		    &pat[4], &pat[5], &pat[6], &pat[7],		    &pat[8], &pat[9], &pat[10], &pat[11],		    &pat[12], &pat[13], &pat[14], &pat[15]);	for (k=PHDR_LEN, j = 0; k <= datalen; k++) {		opack_icmp.icmp_data[k] = pat[j];		if (++j >= i)			j = 0;	}	if (!(pingflags & F_QUIET)) {		(void)printf("PATTERN: 0x");		for (j=0; j<i; j++)			(void)printf("%02x",				     (u_char)opack_icmp.icmp_data[PHDR_LEN+j]);		(void)printf("\n");	}}static voidrnd_fill(void){	static u_int32_t rnd;	int i;	for (i = PHDR_LEN; i < datalen; i++) {		rnd = (3141592621U * rnd + 663896637U);		opack_icmp.icmp_data[i] = rnd>>24;	}}static voidgethost(const char *arg,	const char *name,	struct sockaddr_in *sa,	char *realname,	int realname_len){	struct hostent *hp;	(void)memset(sa, 0, sizeof(*sa));	sa->sin_family = AF_INET;	sa->sin_len = sizeof(struct sockaddr_in);	/* If it is an IP address, try to convert it to a name to	 * have something nice to display.	 */	if (inet_aton(name, &sa->sin_addr) != 0) {		if (realname) {			if (pingflags & F_NUMERIC)				hp = 0;			else				hp = gethostbyaddr((char *)&sa->sin_addr,						   sizeof(sa->sin_addr),						   AF_INET);			(void)strlcpy(realname, hp ? hp->h_name : name,			    realname_len);		}		return;	}		hp = gethostbyname(name);	if (!hp)		errx(1, "Cannot resolve \"%s\" (%s)",name,hstrerror(h_errno));	if (hp->h_addrtype != AF_INET)		errx(1, "%s only supported with IP", arg);	(void)memcpy(&sa->sin_addr, hp->h_addr, sizeof(sa->sin_addr));	if (realname)		(void)strlcpy(realname, hp->h_name, realname_len);}static voidusage(void){#ifdef IPSEC#ifdef IPSEC_POLICY_IPSEC#define IPSECOPT	"\n     [-E policy] "#else#define IPSECOPT	"\n     [-AE] "#endif /*IPSEC_POLICY_IPSEC*/#else#define IPSECOPT	""#endif /*IPSEC*/	(void)fprintf(stderr, "usage: \n"	    "%s [-adDfLnoPqQrRv] [-c count] [-g gateway] [-h host]"	    " [-i interval] [-I addr]\n"	    "     [-l preload] [-p pattern] [-s size] [-t tos] [-T ttl]"	    " [-w maxwait] " IPSECOPT "host\n",	    getprogname());	exit(1);}

⌨️ 快捷键说明

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