📄 ping.c
字号:
(void)printf("\nNOP");
break;
default:
(void)printf("\nunknown option %x", *cp);
break;
}
/*#endif*/
if (!(options & F_FLOOD)) {
(void)putchar('\n');
(void)fflush(stdout);
}
}
/*
* in_cksum --
* Checksum routine for Internet Protocol family headers (C Version)
*/
static int
in_cksum(u_short *addr, int len)
{
register int nleft = len;
register u_short *w = addr;
register int sum = 0;
u_short 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) {
*(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. Out is assumed to
* be >= in.
*/
static 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;
}
/*
* finish --
* Print out statistics, and give up.
*/
static void
finish(int ignore)
{
(void)ignore;
(void)signal(SIGINT, SIG_IGN);
(void)putchar('\n');
(void)fflush(stdout);
(void)printf("--- %s ping statistics ---\n", hostname);
(void)printf("%ld packets transmitted, ", ntransmitted);
(void)printf("%ld packets received, ", nreceived);
if (nrepeats)
(void)printf("+%ld duplicates, ", nrepeats);
if (ntransmitted)
if (nreceived > ntransmitted)
(void)printf("-- somebody's printing up packets!");
else
(void)printf("%d%% packet loss",
(int) (((ntransmitted - nreceived) * 100) /
ntransmitted));
(void)putchar('\n');
if (nreceived && timing)
(void)printf("round-trip min/avg/max = %ld.%ld/%lu.%ld/%ld.%ld ms\n",
tmin/10, tmin%10,
(tsum / (nreceived + nrepeats))/10,
(tsum / (nreceived + nrepeats))%10,
tmax/10, tmax%10);
if (nreceived==0) exit(1);
exit(0);
}
#ifdef notdef
static char *ttab[] = {
"Echo Reply", /* ip + seq + udata */
"Dest Unreachable", /* net, host, proto, port, frag, sr + IP */
"Source Quench", /* IP */
"Redirect", /* redirect type, gateway, + IP */
"Echo",
"Time Exceeded", /* transit, frag reassem + IP */
"Parameter Problem", /* pointer + IP */
"Timestamp", /* id + seq + three timestamps */
"Timestamp Reply", /* " */
"Info Request", /* id + sq */
"Info Reply" /* " */
};
#endif
/*
* pr_icmph --
* Print a descriptive string about an ICMP header.
*/
static void
pr_icmph(struct icmphdr *icp)
{
switch(icp->icmp_type) {
case ICMP_ECHOREPLY:
(void)printf("Echo Reply\n");
/* XXX ID + Seq + Data */
break;
case ICMP_DEST_UNREACH:
switch(icp->icmp_code) {
case ICMP_NET_UNREACH:
(void)printf("Destination Net Unreachable\n");
break;
case ICMP_HOST_UNREACH:
(void)printf("Destination Host Unreachable\n");
break;
case ICMP_PROT_UNREACH:
(void)printf("Destination Protocol Unreachable\n");
break;
case ICMP_PORT_UNREACH:
(void)printf("Destination Port Unreachable\n");
break;
case ICMP_FRAG_NEEDED:
(void)printf("frag needed and DF set\n");
break;
case ICMP_SR_FAILED:
(void)printf("Source Route Failed\n");
break;
case ICMP_NET_UNKNOWN:
(void)printf("Network Unknown\n");
break;
case ICMP_HOST_UNKNOWN:
(void)printf("Host Unknown\n");
break;
case ICMP_HOST_ISOLATED:
(void)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:
(void)printf("Packet Filtered\n");
break;
#endif
#ifdef ICMP_PREC_VIOLATION
case ICMP_PREC_VIOLATION:
(void)printf("Precedence Violation\n");
break;
#endif
#ifdef ICMP_PREC_CUTOFF
case ICMP_PREC_CUTOFF:
(void)printf("Precedence Cutoff\n");
break;
#endif
default:
(void)printf("Dest Unreachable, Unknown Code: %d\n",
icp->icmp_code);
break;
}
/* Print returned IP header information */
#ifndef icmp_data
pr_retip((struct iphdr *)(icp + 1));
#else
pr_retip((struct iphdr *)icp->icmp_data);
#endif
break;
case ICMP_SOURCE_QUENCH:
(void)printf("Source Quench\n");
#ifndef icmp_data
pr_retip((struct iphdr *)(icp + 1));
#else
pr_retip((struct iphdr *)icp->icmp_data);
#endif
break;
case ICMP_REDIRECT:
switch(icp->icmp_code) {
case ICMP_REDIR_NET:
(void)printf("Redirect Network");
break;
case ICMP_REDIR_HOST:
(void)printf("Redirect Host");
break;
case ICMP_REDIR_NETTOS:
(void)printf("Redirect Type of Service and Network");
break;
case ICMP_REDIR_HOSTTOS:
(void)printf("Redirect Type of Service and Host");
break;
default:
(void)printf("Redirect, Bad Code: %d", icp->icmp_code);
break;
}
(void)printf("(New addr: %s)\n",
inet_ntoa(icp->icmp_gwaddr));
#ifndef icmp_data
pr_retip((struct iphdr *)(icp + 1));
#else
pr_retip((struct iphdr *)icp->icmp_data);
#endif
break;
case ICMP_ECHO:
(void)printf("Echo Request\n");
/* XXX ID + Seq + Data */
break;
case ICMP_TIME_EXCEEDED:
switch(icp->icmp_code) {
case ICMP_EXC_TTL:
(void)printf("Time to live exceeded\n");
break;
case ICMP_EXC_FRAGTIME:
(void)printf("Frag reassembly time exceeded\n");
break;
default:
(void)printf("Time exceeded, Bad Code: %d\n",
icp->icmp_code);
break;
}
#ifndef icmp_data
pr_retip((struct iphdr *)(icp + 1));
#else
pr_retip((struct iphdr *)icp->icmp_data);
#endif
break;
case ICMP_PARAMETERPROB:
(void)printf("Parameter problem: IP address = %s\n",
inet_ntoa (icp->icmp_gwaddr));
#ifndef icmp_data
pr_retip((struct iphdr *)(icp + 1));
#else
pr_retip((struct iphdr *)icp->icmp_data);
#endif
break;
case ICMP_TIMESTAMP:
(void)printf("Timestamp\n");
/* XXX ID + Seq + 3 timestamps */
break;
case ICMP_TIMESTAMPREPLY:
(void)printf("Timestamp Reply\n");
/* XXX ID + Seq + 3 timestamps */
break;
case ICMP_INFO_REQUEST:
(void)printf("Information Request\n");
/* XXX ID + Seq */
break;
case ICMP_INFO_REPLY:
(void)printf("Information Reply\n");
/* XXX ID + Seq */
break;
#ifdef ICMP_MASKREQ
case ICMP_MASKREQ:
(void)printf("Address Mask Request\n");
break;
#endif
#ifdef ICMP_MASKREPLY
case ICMP_MASKREPLY:
(void)printf("Address Mask Reply\n");
break;
#endif
default:
(void)printf("Bad ICMP type: %d\n", icp->icmp_type);
}
}
/*
* pr_iph --
* Print an IP header with options.
*/
static void
pr_iph(struct iphdr *ip)
{
int hlen;
u_char *cp;
hlen = ip->ip_hl << 2;
cp = (u_char *)ip + 20; /* point to options */
(void)printf("Vr HL TOS Len ID Flg off TTL Pro cks Src Dst Data\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(" %s ", inet_ntoa(*((struct in_addr *) &ip->ip_src)));
(void)printf(" %s ", inet_ntoa(*((struct in_addr *) &ip->ip_dst)));
/* dump and option bytes */
while (hlen-- > 20) {
(void)printf("%02x", *cp++);
}
(void)putchar('\n');
}
/*
* pr_addr --
* Return an ascii host address as a dotted quad and optionally with
* a hostname.
*/
static char *
pr_addr(u_long l)
{
struct hostent *hp;
static char buf[256];
if ((options & F_NUMERIC) ||
!(hp = gethostbyaddr((char *)&l, 4, AF_INET)))
(void)snprintf(buf, sizeof(buf), "%s",
inet_ntoa(*(struct in_addr *)&l));
else
(void)snprintf(buf, sizeof(buf), "%s (%s)", hp->h_name,
inet_ntoa(*(struct in_addr *)&l));
return(buf);
}
/*
* pr_retip --
* Dump some info on a returned (via ICMP) IP packet.
*/
static void
pr_retip(struct iphdr *ip)
{
int hlen;
u_char *cp;
pr_iph(ip);
hlen = ip->ip_hl << 2;
cp = (u_char *)ip + hlen;
if (ip->ip_p == 6)
(void)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)
(void)printf("UDP: from port %u, to port %u (decimal)\n",
(*cp * 256 + *(cp + 1)), (*(cp + 2) * 256 + *(cp + 3)));
}
static void
fill(void *bp1, char *patp)
{
register int ii, jj, kk;
int pat[16];
char *cp, *bp = (char *)bp1;
for (cp = patp; *cp; cp++)
if (!isxdigit(*cp)) {
(void)fprintf(stderr,
"ping: patterns must be specified as hex digits.\n");
exit(2);
}
ii = sscanf(patp,
"%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]);
if (ii > 0)
for (kk = 0; kk <= MAXPACKET - (8 + ii); kk += ii)
for (jj = 0; jj < ii; ++jj)
bp[jj + kk] = pat[jj];
if (!(options & F_QUIET)) {
(void)printf("PATTERN: 0x");
for (jj = 0; jj < ii; ++jj)
(void)printf("%02x", bp[jj] & 0xFF);
(void)printf("\n");
}
}
static void
usage(void)
{
(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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -