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

📄 ping.c

📁 netkit-base-0.17.tar.gz linux嵌入式开发使用!
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	FD_ZERO(&mask);	/*	 * Loop forever sending pings. (Well, not quite forever.)	 */	while (1) {		if (dosend) {			dosend = 0;			pinger();			if (npackets && ntransmitted >= npackets) {				/* 				 * That was the last one.				 * Set `interval' to how long to wait for 				 * any remaining replies to roll in.				 */				interval.tv_sec = compute_waittime();				interval.tv_usec = 0;			}			/* set time to next ping: the interval */			gettimeofday(&next, NULL);			tvadd(&next, &interval);			timeout = interval;		}		else {			/* compute time left to next ping */			gettimeofday(&now, NULL);			timeout = next;			tvsub(&timeout, &now);		}		FD_SET(sock, &mask);		if (select(sock+1, &mask, NULL, NULL, &timeout) < 1) {			/* Timed out - exit if none left to send. */			if (npackets && ntransmitted >= npackets) {				break;			}			/* Otherwise, send another */			dosend = 1;			continue;		}		/* A packet's come in, get it */		fromlen = sizeof(from);		packlen = recvfrom(sock, inpack, sizeof(inpack), 0,				   (struct sockaddr *)&from, &fromlen);		if (packlen < 0) {			if (errno == EINTR)				continue;			perror("recvfrom");			continue;		}		if (pr_pack(packlen, &from)) {			/*			 * In flood mode, getting a packet back instantly			 * triggers the next one.			 */			if (options & F_FLOOD) {				dosend = 1;			}		}		if (npackets && nreceived >= npackets) {			/*			 * Got all the replies - stop.			 */			break;		}	}}/********************* setup code ********************/staticintdosockopt(int code1, int code2, int val){	return setsockopt(sock, code1, code2, &val, sizeof(val));}staticvoid settarget(const char *target){	struct hostent *hp;	static char namebuf[MAXHOSTNAMELEN];	memset(&whereto, 0, sizeof(whereto));	hp = gethostbyname(target);	if (!hp) {		fprintf(stderr, "ping: unknown host %s\n", target);		exit(2);	}	whereto.sin_family = hp->h_addrtype;	if (hp->h_length > (int)sizeof(whereto.sin_addr)) {		hp->h_length = sizeof(whereto.sin_addr);	}	memcpy(&whereto.sin_addr, hp->h_addr, hp->h_length);	strncpy(namebuf, hp->h_name, sizeof(namebuf) - 1);	namebuf[sizeof(namebuf)-1] = 0;	hostname = namebuf;}/* * Handle -p option. */staticvoidfill(const char *patstr){	size_t i;	int j, patlen;	int pat[16];	for (i=0; patstr[i]; i++) {		if (!isxdigit(patstr[i])) {			fprintf(stderr, "ping: patterns for -p must be "				"specified as hex digits.\n");			exit(2);		}	}	patlen = sscanf(patstr,	    "%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]);	/*	 * Just fill the whole output packet with the pattern, rather	 * than just the data section. The part at the beginning will get	 * overlaid with the icmp header and whatnot.	 *	 * This means we don't have to know yet if we're sending the	 * timeval (which depends on the selected packet size), which 	 * is good since get called from option processing and the -s	 * option might not have turned up yet.	 */	if (patlen > 0) {		for (i=0,j=0; i<sizeof(outpack); i++, j=(j+1)%patlen) {			outpack[i] = pat[j];		}	}	if (!(options & F_QUIET)) {		printf("PATTERN: 0x");		for (j=0; j<patlen; j++) {			printf("%02x", pat[j]&0xFF);		}		printf("\n");	}}staticvoidusage(void){	fprintf(stderr,		"usage: ping [-LRdfnqrv] [-c count] [-i wait] [-l preload]\n"		"\t[-p pattern] [-s packetsize] [-t ttl] "		"[-I interface address] host\n");	exit(2);}staticintsecure_startup(void){	int am_i_root;	struct protoent *proto;	static char *null = NULL;	/*	 * Clear environment.	 * (This protects against various problems with libc.)	 */	__environ = &null;	/*	 * Certain options require that the man behind the curtain be	 * root. Since we should be setuid root anyway, check real uid.	 */	am_i_root = (getuid()==0);	/*	 * Look up ICMP.	 */	proto = getprotobyname("icmp");	if (!proto) {		fprintf(stderr, "ping: unknown protocol icmp.\n");		exit(2);	}	/*	 * Open the raw socket.	 */	sock = socket(AF_INET, SOCK_RAW, proto->p_proto);	if (sock < 0) {		if (errno==EPERM) {			fprintf(stderr, "ping: ping must run as root\n");		}		else {			perror("ping: socket");		}		exit(2);	}	/*	 * If someone's messing with us, bail.	 * It would be nice to issue an error message, but to where? 	 */	if (sock==STDIN_FILENO || sock==STDOUT_FILENO || sock==STDERR_FILENO) {		exit(255);	}	/* 	 * See discussion at the top of this file.	 * It's not crucial if this fails.	 */#ifdef SAFE_TO_DROP_ROOT	setuid(getuid());#endif	return am_i_root;}intmain(int argc, char *argv[]){	struct in_addr ifaddr;	int i;	int ch, preload, stoptime=0;	u_char ttl=0, loop;	int am_i_root;	char rspace[3 + 4 * NROUTES + 1];	/* record route space */	am_i_root = secure_startup();	preload = 0;	while ((ch = getopt(argc, argv, "I:LRc:dfh:i:l:np:qrs:t:vw:"))!=EOF) {		switch(ch) {		case 'c':			npackets = atoi(optarg);			if (npackets <= 0) {				fprintf(stderr, 					"ping: bad number of "					"packets to transmit.\n");				exit(2);			}			break;		case 'd':			options |= F_SO_DEBUG;			break;		case 'f':			if (!am_i_root) {				fprintf(stderr, "ping: %s\n", strerror(EPERM));				exit(2);			}			options |= F_FLOOD;			setbuf(stdout, NULL);			break;		case 'i':		/* wait between sending packets */			intervalsecs = atoi(optarg);			if (intervalsecs <= 0) {				fprintf(stderr,"ping: bad timing interval.\n");				exit(2);			}			options |= F_INTERVAL;			break;		case 'l':			if (!am_i_root) {				fprintf(stderr, "ping: %s\n", strerror(EPERM));				exit(2);			}			preload = atoi(optarg);			if (preload < 0) {				fprintf(stderr, "ping: bad preload count.\n");				exit(2);			}			break;		case 'n':			options |= F_NUMERIC;			break;		case 'p':		/* fill buffer with user pattern */			options |= F_PINGFILLED;			fill(optarg);			break;		case 'q':			options |= F_QUIET;			break;		case 'R':			options |= F_RROUTE;			break;		case 'r':			options |= F_SO_DONTROUTE;			break;		case 's':		/* size of packet to send */			if (!am_i_root) {				fprintf(stderr, "ping: %s\n", strerror(EPERM));				exit(2);			}			datalen = atoi(optarg);			if (datalen > MAXPAYLOAD) {				fprintf(stderr, 					"ping: packet size too large.\n");				exit(2);			}			if (datalen <= 0) {				fprintf(stderr,"ping: illegal packet size.\n");				exit(2);			}			break;		case 'v':			options |= F_VERBOSE;			break;		case 'w':			stoptime = atoi(optarg);			if (stoptime <= 0) {				fprintf(stderr,"ping: illegal timeout.\n");				exit(2);			}			break;		case 'L':			moptions |= MULTICAST_NOLOOP;			loop = 0;			break;		case 't':			moptions |= MULTICAST_TTL;			i = atoi(optarg);			if (i < 0 || i > 255) {				fprintf(stderr, 					"ping: ttl %d out of range\n", i);				exit(2);			}			ttl = i;			break;		case 'I':			moptions |= MULTICAST_IF;			if (!inet_aton(optarg, &ifaddr)) {				fprintf(stderr, 					"ping: bad interface address '%s'\n",					optarg);				exit(2);			}			break;		default:			usage();		}	}	if (options & F_FLOOD && options & F_INTERVAL) {		fprintf(stderr, "ping: -f and -i: Incompatible options.\n");		exit(2);	}	argc -= optind;	argv += optind;		if (argc != 1) {		usage();	}	settarget(argv[0]);	/* if there's space for the time, we can time the transfer */	if (datalen >= (int)sizeof(struct timeval)) {		timing = 1;	}	/* If an explicit pattern wasn't set, use a default fill. */	if ((options & F_PINGFILLED)==0) {		int i;		u_int8_t *ptr = OUTPACK_PAYLOAD;		for (i = 0; i < datalen; i++) {			ptr[i] = i;		}	}	/* Use this code to identify this ping process */	ident = getpid() & 0xFFFF;	if (options & F_SO_DEBUG) {		dosockopt(SOL_SOCKET, SO_DEBUG, 1);	}	if (options & F_SO_DONTROUTE) {		dosockopt(SOL_SOCKET, SO_DONTROUTE, 1);	}	/* this is necessary for broadcast pings to work */	dosockopt(SOL_SOCKET, SO_BROADCAST, 1);	/* record route option */	if (options & F_RROUTE) {	        memset(rspace, 0, sizeof(rspace));		rspace[IPOPT_OPTVAL] = IPOPT_RR;		rspace[IPOPT_OLEN] = sizeof(rspace)-1;		rspace[IPOPT_OFFSET] = IPOPT_MINOFF;		if (setsockopt(sock, IPPROTO_IP, IP_OPTIONS, rspace,		    sizeof(rspace)) < 0) {			perror("ping: record route");			exit(2);		}	}	/*	 * When pinging the broadcast address, you can get a lot of answers.	 * Doing something so evil is useful if you are trying to stress the	 * ethernet, or just want to fill the arp cache to get some stuff for	 * /etc/ethers.	 */	dosockopt(SOL_SOCKET, SO_RCVBUF, 64*1024);	if (moptions & MULTICAST_NOLOOP) {		if (dosockopt(IPPROTO_IP, IP_MULTICAST_LOOP, 0)) {			perror("can't disable multicast loopback");			exit(92);		}	}	if (moptions & MULTICAST_TTL) {		if (dosockopt(IPPROTO_IP, IP_MULTICAST_TTL, ttl)) {			perror("can't set multicast time-to-live");			exit(93);		}	}	if (moptions & MULTICAST_IF) {		if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF,			       &ifaddr, sizeof(ifaddr))) {			perror("can't set multicast source interface");			exit(94);		}	}	if (whereto.sin_family == AF_INET) {		printf("PING %s (%s): %d octets data\n", 		       hostname, inet_ntoa(whereto.sin_addr), datalen);	}	else {		printf("PING %s: %d octets data\n", hostname, datalen);	}	signal(SIGINT, finish);	if (stoptime) {		signal(SIGALRM, finish);		alarm(stoptime);	}	while (preload--) {		/* fire off them quickies */		pinger();	}	doping();	finish(0);	/* NOTREACHED */	return 0;}

⌨️ 快捷键说明

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