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

📄 traceroute.h

📁 traceroute
💻 H
📖 第 1 页 / 共 2 页
字号:
		}

	return(0);
}


/*------------------------------------------------------------------------

 * print - 根据nflag的值,打印域名或ip地址,主程序中调用

 *------------------------------------------------------------------------

 */
void print(register u_char *buf, register int cc, register struct sockaddr_in *from)
{
	register struct ip *ip;
	register int hlen;

	ip = (struct ip *) buf;
	hlen = ip->ip_hl << 2;
	cc -= hlen;

	if (nflag)
		printf(" %s", inet_ntoa(from->sin_addr));
	else
		printf(" %s (%s)", inetname(from->sin_addr),
		    inet_ntoa(from->sin_addr));

}


 /*------------------------------------------------------------------------

 * in_cksum - 校验和函数

 *------------------------------------------------------------------------

 */
u_short in_cksum(register u_short *addr, register int len)
{
	register int nleft = len;
	register u_short *w = addr;
	register u_short answer;
	register int sum = 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)
		sum += *(u_char *)w;

	/*
	 * 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 - 计算两个时间差值,存入第一个变量(假设out>= in)

 *------------------------------------------------------------------------

 */
void tvsub(register struct timeval *out, register struct timeval *in)
{

	if ((out->tv_usec -= in->tv_usec) < 0)   {
		--out->tv_sec;
		out->tv_usec += 1000000;
	}
	out->tv_sec -= in->tv_sec;
}


 /*------------------------------------------------------------------------

 * inetname - 获得网络地址,假如nflag为真,则提供数字形式,
 *			  否则则为字符形式,函数print()中调用

 *------------------------------------------------------------------------

 */
char * inetname(struct in_addr in)
{
	register char *cp;
	register struct hostent *hp;
	static int first = 1;
	static char domain[MAXHOSTNAMELEN + 1], line[MAXHOSTNAMELEN + 1];

	if (first && !nflag) {
		first = 0;
		if (gethostname(domain, sizeof(domain) - 1) < 0)
			domain[0] = '\0';
		else {
			cp = strchr(domain, '.');
			if (cp == NULL) {
				hp = gethostbyname(domain);
				if (hp != NULL)
					cp = strchr(hp->h_name, '.');
			}
			if (cp == NULL)
				domain[0] = '\0';
			else {
				++cp;
				(void)strncpy(domain, cp, sizeof(domain) - 1);
				domain[sizeof(domain) - 1] = '\0';
			}
		}
	}
	if (!nflag && in.s_addr != INADDR_ANY) {
		hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
		if (hp != NULL) {
			if ((cp = strchr(hp->h_name, '.')) != NULL &&
			    strcmp(cp + 1, domain) == 0)
				*cp = '\0';
			(void)strncpy(line, hp->h_name, sizeof(line) - 1);
			line[sizeof(line) - 1] = '\0';
			return (line);
		}
	}
	return (inet_ntoa(in));
}

/*------------------------------------------------------------------------

 * hostinfo - 根据目的节点的hostname填充struct hostinfo结构信息

 *------------------------------------------------------------------------

 */
struct hostinfo * gethostinfo(register char *hostname)
{
	register int n;
	register struct hostent *hp;
	register struct hostinfo *hi;
	register char **p;
	register u_int32_t addr, *ap;

	if (strlen(hostname) > 64) 
			errexit("%s: hostname \"%.32s...\" is too long\n", prog, hostname);		
	
	hi = calloc(1, sizeof(*hi));
	if (hi == NULL) 
			errexit("%s: calloc %s\n", prog, strerror(errno));

	/*hostname为点分十进制ip地址形式*/
	addr = inet_addr(hostname);
	if ((int32_t)addr != -1) 
		{
			hi->name = strdup(hostname);
			hi->n = 1;
			hi->addrs = calloc(1, sizeof(hi->addrs[0]));

			if (hi->addrs == NULL) 
					errexit("%s: calloc %s\n", prog, strerror(errno));
		
			hi->addrs[0] = addr;
			return (hi);
		}

	/*hostname为域名形式*/
	hp = gethostbyname(hostname);
	if (hp == NULL) 
			errexit("%s: unknown host %s\n", prog, hostname);
		
	if (hp->h_addrtype != AF_INET || hp->h_length != 4) 
			errexit("%s: bad host %s\n", prog, hostname);
		
	hi->name = strdup(hp->h_name);
	
	for (n = 0, p = hp->h_addr_list; *p != NULL; ++n, ++p)
			continue;

	hi->n = n;
	hi->addrs = calloc(n, sizeof(hi->addrs[0]));
	if (hi->addrs == NULL) 
		errexit("%s: calloc %s\n", prog, strerror(errno));
		
	for (ap = hi->addrs, p = hp->h_addr_list; *p != NULL; ++ap, ++p)
			memcpy(ap, *p, sizeof(*ap));

	return (hi);
}


/*------------------------------------------------------------------------

 * freehostinfo - 释放hostinfo结构

 *------------------------------------------------------------------------

 */
void freehostinfo(register struct hostinfo *hi)
{
	if (hi->name != NULL) 
		{
			free(hi->name);
			hi->name = NULL;
		}

	free((char *)hi->addrs);
	free((char *)hi);
}

/*------------------------------------------------------------------------

 * getaddr - 把hostname所指的ip地址存入ap字符串中,主程序中调用,
 *			 用于从命令选项中获得gateway

 *------------------------------------------------------------------------

 */
void getaddr(register u_int32_t *ap, register char *hostname)
{
	register struct hostinfo *hi;

	hi = gethostinfo(hostname);
	*ap = hi->addrs[0];
	freehostinfo(hi);
}


/*------------------------------------------------------------------------

 * setsin - 初始化sockaddr_in结构信息

 *------------------------------------------------------------------------

 */
void setsin(register struct sockaddr_in *sin, register u_int32_t addr)
{

	memset(sin, 0, sizeof(*sin));

#ifdef HAVE_SOCKADDR_SA_LEN
	sin->sin_len = sizeof(*sin);
#endif

	sin->sin_family = AF_INET;
	sin->sin_addr.s_addr = addr;
}


/*------------------------------------------------------------------------

 * str2val - 字符串转换为十六进制或十进制

 *------------------------------------------------------------------------

 */
int str2val(register const char *str, register const char *what,
    register int mi, register int ma)
{
	register const char *cp;
	register int val;
	char *ep;

	if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) 
		{
			cp = str + 2;
			val = (int)strtol(cp, &ep, 16);
		} 
	else
		val = (int)strtol(str, &ep, 10);

	if (*ep != '\0') 
			errexit("%s: \"%s\" bad value for %s \n", prog, str, what);
		
	if (val < mi && mi >= 0) 
		{
			if (mi == 0)
					errexit(stderr, "%s: %s must be >= %d\n", prog, what, mi);
			else
					errexit("%s: %s must be > %d\n", prog, what, mi - 1);		
		}

	if (val > ma && ma >= 0) 
			errexit("%s: %s must be <= %d\n", prog, what, ma);
		
	return (val);
}

⌨️ 快捷键说明

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