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

📄 ping.c

📁 netkit-base-0.17.tar.gz linux嵌入式开发使用!
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 1989 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * Mike Muuss. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */char copyright[] =  "@(#) Copyright (c) 1989 The Regents of the University of California.\n"  "All rights reserved.\n";/* * From: @(#)ping.c	5.9 (Berkeley) 5/12/91 */char rcsid[] = "$Id: ping.c,v 1.39 2000/07/23 04:16:21 dholland Exp $";#include "../version.h"/* *			P I N G . C * * Using the InterNet Control Message Protocol (ICMP) "ECHO" facility, * measure round-trip-delays and packet loss across network paths. * * Author - *	Mike Muuss *	U. S. Army Ballistic Research Laboratory *	December, 1983 * * Status - *	Public Domain.  Distribution Unlimited. * Bugs - *	More statistics could always be gathered. *	This program has to run SUID to ROOT to access the ICMP socket. */#include <sys/param.h>#include <sys/socket.h>#include <sys/file.h>#include <sys/time.h>#include <sys/signal.h>#include <netinet/in.h>#include <netinet/ip.h>#include <netinet/ip_icmp.h>#include <arpa/inet.h>#include <netdb.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <stdio.h>#include <ctype.h>#include <errno.h>/* * Note: on some systems dropping root makes the process dumpable or * traceable. In that case if you enable dropping root and someone * traces ping, they get control of a raw socket and can start * spoofing whatever packets they like. SO BE CAREFUL. */#ifdef __linux__#define SAFE_TO_DROP_ROOT#endif/********************* Garble for libc5 ********************/#if !defined(__GLIBC__) || (__GLIBC__ < 2)#ifdef __linux__/* * The Linux kernel definitions of icmp and ip header structures are * different from traditional BSD. Linux libcs prior to libc6 don't  * provide the BSD versions. Get them from the included file. */#include "pingpack.h"#endif /* __linux__ */#endif /* __GLIBC__ *//********************* Defs. *********************//* default data length: 64 byte icmp packet */#define	DEFDATALEN	(64 - ICMP_MINLEN)/* maximum length of IP header (including options) */#define	MAXIPLEN	60/* max packet contents size */#define	MAXPAYLOAD	(IP_MAXPACKET - MAXIPLEN - ICMP_MINLEN)/* max seconds to wait for response */#define	MAXWAIT		10/* number of record route slots */#define	NROUTES		9/* various options */static int options;#define	F_FLOOD		0x001#define	F_INTERVAL	0x002#define	F_NUMERIC	0x004#define	F_PINGFILLED	0x008#define	F_QUIET		0x010#define	F_RROUTE	0x020#define	F_SO_DEBUG	0x040#define	F_SO_DONTROUTE	0x080#define	F_VERBOSE	0x100/* multicast options */static int moptions;#define MULTICAST_NOLOOP	0x001#define MULTICAST_TTL		0x002#define MULTICAST_IF		0x004/* * bitarray for remembering duplicates * * MAX_DUP_CHK is the number of bits in received table, i.e. the maximum * number of received sequence numbers we can keep track of.  Change 128 * to 8192 for complete accuracy... */#define	MAX_DUP_CHK	(8 * 128)static int mx_dup_ck = MAX_DUP_CHK;static char rcvd_tbl[MAX_DUP_CHK / 8];#define	A(bit)		rcvd_tbl[(bit)>>3]	/* identify byte in array */#define	B(bit)		(1 << ((bit) & 0x07))	/* identify bit in byte */#define	SET(bit)	(A(bit) |= B(bit))#define	CLR(bit)	(A(bit) &= (~B(bit)))#define	TST(bit)	(A(bit) & B(bit))/* characters written for flood */static const char BSPACE = '\b';static const char DOT = '.';/* transmission */static int sock;		/* socket file descriptor */static int ident;		/* process id to identify our packets *//* destination */static struct sockaddr_in whereto;	/* who to ping */static const char *hostname;/* * input buffer * * inpack contains: *         ip header    (20 octets) *         ip options   (0-40 octets (ipoptlen)) *         icmp header  (8 octets) *         timeval      (8 or 12 octets, only if timing==1) *         other data */static u_int8_t inpack[IP_MAXPACKET];static int ipoptlen;#define INPACK_IP       ((struct ip *)inpack)#define INPACK_OPTS     (inpack+sizeof(struct ip))#define INPACK_ICMP     ((struct icmp *)(inpack+sizeof(struct ip)+ipoptlen))#define INPACK_PAYLOAD  (INPACK_ICMP->icmp_data)#define INPACK_TIME     ((struct timeval *)INPACK_PAYLOAD)#define INPACK_DATA     (INPACK_PAYLOAD+(timing ? sizeof(struct timeval) : 0))/*  * output buffer * * outpack contains: *         icmp header  (8 octets) *         timeval      (8 or 12 octets, only if timing==1) *         other data * * datalen is the length of the other data plus the timeval. * note: due to alignment problems don't assign to OUTPACK_TIME, use memcpy. */static u_int8_t outpack[IP_MAXPACKET];static int datalen = DEFDATALEN;#define OUTPACK_ICMP    ((struct icmp *)outpack)#define OUTPACK_PAYLOAD (OUTPACK_ICMP->icmp_data)#define OUTPACK_TIME    ((struct timeval *)OUTPACK_PAYLOAD)#define OUTPACK_DATA    (OUTPACK_PAYLOAD+(timing ? sizeof(struct timeval) : 0))/* counters */static long npackets;		/* max packets to transmit */static long nreceived;		/* # of packets we got back */static long nrepeats;		/* number of duplicates */static long ntransmitted;	/* sequence # for outbound packets = #sent */static int intervalsecs = 1;	/* interval between packets (seconds) *//* timing */static int timing;		/* flag to do timing */static long tmin = LONG_MAX;	/* minimum round trip time */static long tmax = 0;		/* maximum round trip time */static u_long tsum;		/* sum of all times, for doing average *//********************* utility code ********************//* * in_cksum * * Checksum routine for Internet Protocol family headers (C version) */static u_int16_tin_cksum(u_int16_t *addr, int len){	int nleft = len;	u_int16_t *w = addr;	u_int32_t sum = 0;	u_int16_t answer = 0;	/*	 * Our algorithm is simple, using a 32 bit accumulator (sum), we add	 * sequential 16 bit words to it, and at the end, fold back all the	 * carry bits from the top 16 bits into the lower 16 bits.	 */	while (nleft > 1)  {		sum += *w++;		nleft -= 2;	}	/* mop up an odd byte, if necessary */	if (nleft == 1) {		answer=0;		*(u_char *)(&answer) = *(u_char *)w ;		sum += answer;	}	/* add back carry outs from top 16 bits to low 16 bits */	sum = (sum >> 16) + (sum & 0xffff);	/* add hi 16 to low 16 */	sum += (sum >> 16);			/* add carry */	answer = ~sum;				/* truncate to 16 bits */	return(answer);}/* * tvsub * * Subtract 2 timeval structs:  out = out - in.   */staticvoidtvsub(struct timeval *out, const struct timeval *in){	if ((out->tv_usec -= in->tv_usec) < 0) {		out->tv_sec--;		out->tv_usec += 1000000;	}	out->tv_sec -= in->tv_sec;	/*	 * Just in case, clamp to 0.	 */	if (out->tv_sec<0) {		out->tv_sec = 0;		out->tv_usec = 0;	}}/* * tvadd * * Add 2 timeval structs:  out = out + in.   */staticvoidtvadd(struct timeval *out, const struct timeval *in){	if ((out->tv_usec += in->tv_usec) >= 1000000) {		out->tv_sec++;		out->tv_usec -= 1000000;	}	out->tv_sec += in->tv_sec;}/********************* printing code ********************//* * pr_addr -- *	Return an ascii host address as a dotted quad and optionally with * a hostname. */static const char *pr_addr(u_int32_t l){	struct hostent *hp;	static char buf[256];	struct in_addr addr;	if (l==0) {		return "0.0.0.0";	}	addr.s_addr = l;	if ((options & F_NUMERIC)==0) {		hp = gethostbyaddr((char *)&l, 4, AF_INET);		if (hp) {			snprintf(buf, sizeof(buf), "%s (%s)", hp->h_name,				 inet_ntoa(addr));			return buf;		}	}	return inet_ntoa(addr);}/* * pr_iph -- *	Print an IP header with options. */staticvoidpr_iph(struct ip *ip){	u_int hlen;	u_char *cp;	hlen = ip->ip_hl << 2;	cp = ((u_char *)ip) + sizeof(struct ip);	/* point to options */	printf("Vr HL TOS  Len   ID Flg  off TTL Pro  cks      "	       "Src      Dst Data\n");	printf(" %1x  %1x  %02x %04x %04x",	       ip->ip_v, ip->ip_hl, ip->ip_tos, ip->ip_len, ip->ip_id);	printf("   %1x %04x", ((ip->ip_off) & 0xe000) >> 13,	       (ip->ip_off) & 0x1fff);	printf("  %02x  %02x %04x", ip->ip_ttl, ip->ip_p, ip->ip_sum);	printf(" %s ", inet_ntoa(ip->ip_src));	printf(" %s ", inet_ntoa(ip->ip_dst));	/* dump any option bytes */	while (hlen-- > sizeof(struct ip)) {		printf("%02x", *cp++);	}	putchar('\n');}/* * pr_retip -- *	Dump some info on a returned (via ICMP) IP packet. */static voidpr_retip(struct ip *ip){	int hlen;	u_char *cp;	pr_iph(ip);	hlen = ip->ip_hl << 2;	/* 	 * theoretically, ip->ip_hl is a 4-bit unsigned value, so 	 * 0 <= hlen < 64 and cp cannot point outside inpack.	 */	cp = (u_char *)ip + hlen;	if (ip->ip_p == 6) {		printf("TCP: from port %u, to port %u (decimal)\n",		       (*cp * 256 + *(cp + 1)), (*(cp + 2) * 256 + *(cp + 3)));	}	else if (ip->ip_p == 17) {		printf("UDP: from port %u, to port %u (decimal)\n",		       (*cp * 256 + *(cp + 1)), (*(cp + 2) * 256 + *(cp + 3)));	}}/* * pr_icmph -- *	Print a descriptive string about an ICMP header. */static voidpr_icmph(struct icmp *icp){	switch(icp->icmp_type) {	case ICMP_ECHOREPLY:		/* This is not used - we only call this for non-replies. */		printf("Echo Reply (!?)\n");		break;	case ICMP_DEST_UNREACH:		switch(icp->icmp_code) {		case ICMP_NET_UNREACH:			printf("Destination Net Unreachable\n");			break;		case ICMP_HOST_UNREACH:			printf("Destination Host Unreachable\n");			break;		case ICMP_PROT_UNREACH:			printf("Destination Protocol Unreachable\n");			break;		case ICMP_PORT_UNREACH:			printf("Destination Port Unreachable\n");			break;		case ICMP_FRAG_NEEDED:			printf("frag needed and DF set\n");			break;		case ICMP_SR_FAILED:			printf("Source Route Failed\n");			break;		case ICMP_NET_UNKNOWN:			printf("Network Unknown\n");			break;		case ICMP_HOST_UNKNOWN:			printf("Host Unknown\n");			break;		case ICMP_HOST_ISOLATED:			printf("Host Isolated\n");			break;		case ICMP_NET_UNR_TOS:			printf("Destination Network Unreachable at this TOS\n");			break;		case ICMP_HOST_UNR_TOS:			printf("Destination Host Unreachable at this TOS\n");			break;#ifdef ICMP_PKT_FILTERED		case ICMP_PKT_FILTERED:			printf("Packet Filtered\n");			break;#endif#ifdef ICMP_PREC_VIOLATION		case ICMP_PREC_VIOLATION:			printf("Precedence Violation\n");			break;#endif#ifdef ICMP_PREC_CUTOFF		case ICMP_PREC_CUTOFF:			printf("Precedence Cutoff\n");			break;#endif		default:			printf("Dest Unreachable, Unknown Code: %d\n",

⌨️ 快捷键说明

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