+
+#if 0
+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 /* 0 */
+
+/*
+ * Print a descriptive string about an ICMP header.
+ */
+pr_icmph( icp )
+struct icmp *icp;
+{
+ switch( icp->icmp_type ) {
+ case ICMP_ECHOREPLY:
+ printf("Echo Reply\n");
+ /* XXX ID + Seq + Data */
+ break;
+ case ICMP_UNREACH:
+ switch( icp->icmp_code ) {
+ case ICMP_UNREACH_NET:
+ printf("Destination Net Unreachable\n");
+ break;
+ case ICMP_UNREACH_HOST:
+ printf("Destination Host Unreachable\n");
+ break;
+ case ICMP_UNREACH_PROTOCOL:
+ printf("Destination Protocol Unreachable\n");
+ break;
+ case ICMP_UNREACH_PORT:
+ printf("Destination Port Unreachable\n");
+ break;
+ case ICMP_UNREACH_NEEDFRAG:
+ printf("frag needed and DF set\n");
+ break;
+ case ICMP_UNREACH_SRCFAIL:
+ printf("Source Route Failed\n");
+ break;
+ default:
+ printf("Dest Unreachable, Bad Code: %d\n", icp->icmp_code );
+ break;
+ }
+ /* Print returned IP header information */
+#ifndef icmp_data
+ pr_retip( &icp->icmp_ip );
+#else
+ pr_retip( (struct ip *)icp->icmp_data );
+#endif
+ break;
+ case ICMP_SOURCEQUENCH:
+ printf("Source Quench\n");
+#ifndef icmp_data
+ pr_retip( &icp->icmp_ip );
+#else
+ pr_retip( (struct ip *)icp->icmp_data );
+#endif
+ break;
+ case ICMP_REDIRECT:
+ switch( icp->icmp_code ) {
+ case ICMP_REDIRECT_NET:
+ printf("Redirect Network");
+ break;
+ case ICMP_REDIRECT_HOST:
+ printf("Redirect Host");
+ break;
+ case ICMP_REDIRECT_TOSNET:
+ printf("Redirect Type of Service and Network");
+ break;
+ case ICMP_REDIRECT_TOSHOST:
+ printf("Redirect Type of Service and Host");
+ break;
+ default:
+ printf("Redirect, Bad Code: %d", icp->icmp_code );
+ break;
+ }
+ printf(" (New addr: 0x%08x)\n", icp->icmp_hun.ih_gwaddr );
+#ifndef icmp_data
+ pr_retip( &icp->icmp_ip );
+#else
+ pr_retip( (struct ip *)icp->icmp_data );
+#endif
+ break;
+ case ICMP_ECHO:
+ printf("Echo Request\n");
+ /* XXX ID + Seq + Data */
+ break;
+ case ICMP_TIMXCEED:
+ switch( icp->icmp_code ) {
+ case ICMP_TIMXCEED_INTRANS:
+ printf("Time to live exceeded\n");
+ break;
+ case ICMP_TIMXCEED_REASS:
+ printf("Frag reassembly time exceeded\n");
+ break;
+ default:
+ printf("Time exceeded, Bad Code: %d\n", icp->icmp_code );
+ break;
+ }
+#ifndef icmp_data
+ pr_retip( &icp->icmp_ip );
+#else
+ pr_retip( (struct ip *)icp->icmp_data );
+#endif
+ break;
+ case ICMP_PARAMPROB:
+ printf("Parameter problem: pointer = 0x%02x\n",
+ icp->icmp_hun.ih_pptr );
+#ifndef icmp_data
+ pr_retip( &icp->icmp_ip );
+#else
+ pr_retip( (struct ip *)icp->icmp_data );
+#endif
+ break;
+ case ICMP_TSTAMP:
+ printf("Timestamp\n");
+ /* XXX ID + Seq + 3 timestamps */
+ break;
+ case ICMP_TSTAMPREPLY:
+ printf("Timestamp Reply\n");
+ /* XXX ID + Seq + 3 timestamps */
+ break;
+ case ICMP_IREQ:
+ printf("Information Request\n");
+ /* XXX ID + Seq */
+ break;
+ case ICMP_IREQREPLY:
+ printf("Information Reply\n");
+ /* XXX ID + Seq */
+ break;
+#ifdef ICMP_MASKREQ
+ case ICMP_MASKREQ:
+ printf("Address Mask Request\n");
+ break;
+#endif
+#ifdef ICMP_MASKREPLY
+ case ICMP_MASKREPLY:
+ printf("Address Mask Reply\n");
+ break;
+#endif
+ default:
+ printf("Bad ICMP type: %d\n", icp->icmp_type);
+ }
+}
+
+/*
+ * Print an IP header with options.
+ */
+pr_iph( ip )
+struct ip *ip;
+{
+ int hlen;
+ unsigned char *cp;
+
+ hlen = ip->ip_hl << 2;
+ cp = (unsigned char *)ip + 20; /* 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(*(struct in_addr *)&ip->ip_src.s_addr));
+ printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->ip_dst.s_addr));
+ /* dump and option bytes */
+ while( hlen-- > 20 ) {
+ printf( "%02x", *cp++ );
+ }
+ printf("\n");
+}
+
+/*
+ * Return an ascii host address
+ * as a dotted quad and optionally with a hostname
+ */
+char *
+pr_addr( l )
+unsigned long l;
+{
+ struct hostent *hp;
+ static char buf[80];
+
+ if( (pingflags & NUMERIC) || (hp = gethostbyaddr((char *)&l, 4, AF_INET)) == NULL )
+ sprintf( buf, "%s", inet_ntoa(*(struct in_addr *)&l) );
+ else
+ sprintf( buf, "%s (%s)", hp->h_name, inet_ntoa(*(struct in_addr *)&l) );
+
+ return( buf );
+}
+
+/*
+ * Dump some info on a returned (via ICMP) IP packet.
+ */
+pr_retip( ip )
+struct ip *ip;
+{
+ int hlen;
+ unsigned char *cp;
+
+ pr_iph( ip );
+ hlen = ip->ip_hl << 2;
+ cp = (unsigned char *)ip + hlen;
+
+ if( ip->ip_p == 6 ) {
+ printf( "TCP: from port %d, to port %d (decimal)\n",
+ (*cp*256+*(cp+1)), (*(cp+2)*256+*(cp+3)) );
+ } else if( ip->ip_p == 17 ) {
+ printf( "UDP: from port %d, to port %d (decimal)\n",
+ (*cp*256+*(cp+1)), (*(cp+2)*256+*(cp+3)) );
+ }
+}
+
+fill(bp, patp)
+char *bp, *patp;
+{
+ register int ii,jj,kk;
+ char *cp;
+ int pat[16];
+
+ for (cp=patp; *cp; cp++)
+ if (!isxdigit(*cp)) {
+ printf("\"-p %s\" ???: ", patp);
+ printf("patterns must be specified as hex digits\n");
+ exit(1);
+ }
+
+ 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 (!(pingflags & QUIET)) {
+ printf("PATTERN: 0x");
+ for (jj=0; jj<ii; jj++)
+ printf("%02x", bp[jj]&0xFF);
+ printf("\n");
+ }
+
+}