📄 traceroute.h
字号:
}
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 + -