home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / tcpdumpb.zip / print-icmp.c < prev    next >
C/C++ Source or Header  |  1997-02-14  |  14KB  |  359 lines

  1. /*
  2.  * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996
  3.  *      The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  */
  21.  
  22. #ifndef lint
  23. static char rcsid[] =
  24.     "@(#) $Header: print-icmp.c,v 1.36 96/07/23 14:17:24 leres Exp $ (LBL)";
  25. #endif
  26.  
  27. #include <sys/param.h>
  28. #include <sys/time.h>
  29. #include <sys/socket.h>
  30.  
  31. #if __STDC__
  32. struct mbuf;
  33. struct rtentry;
  34. #endif
  35. #include <net/if.h>
  36.  
  37. #include <netinet/in.h>
  38. #include <netinet/if_ether.h>
  39. #include <netinet/in_systm.h>
  40. #include <netinet/ip.h>
  41. #include <netinet/ip_icmp.h>
  42. #ifndef __EMX__
  43. #include <netinet/ip_var.h>
  44. #endif
  45. #include <netinet/udp.h>
  46. #include <netinet/udp_var.h>
  47. #include <netinet/tcp.h>
  48. #ifndef __EMX__
  49. #include <netinet/tcpip.h>
  50. #endif
  51.  
  52. #include <stdio.h>
  53. #include <string.h>
  54.  
  55. #include "interface.h"
  56. #include "addrtoname.h"
  57. #include "extract.h"                    /* must come after interface.h */
  58.  
  59. /* rfc1700 */
  60. #ifndef ICMP_UNREACH_NET_UNKNOWN
  61. #define ICMP_UNREACH_NET_UNKNOWN        6       /* destination net unknown */
  62. #endif
  63. #ifndef ICMP_UNREACH_HOST_UNKNOWN
  64. #define ICMP_UNREACH_HOST_UNKNOWN       7       /* destination host unknown */
  65. #endif
  66. #ifndef ICMP_UNREACH_ISOLATED
  67. #define ICMP_UNREACH_ISOLATED           8       /* source host isolated */
  68. #endif
  69. #ifndef ICMP_UNREACH_NET_PROHIB
  70. #define ICMP_UNREACH_NET_PROHIB         9       /* admin prohibited net */
  71. #endif
  72. #ifndef ICMP_UNREACH_HOST_PROHIB
  73. #define ICMP_UNREACH_HOST_PROHIB        10      /* admin prohibited host */
  74. #endif
  75. #ifndef ICMP_UNREACH_TOSNET
  76. #define ICMP_UNREACH_TOSNET             11      /* tos prohibited net */
  77. #endif
  78. #ifndef ICMP_UNREACH_TOSHOST
  79. #define ICMP_UNREACH_TOSHOST            12      /* tos prohibited host */
  80. #endif
  81.  
  82. /* rfc1716 */
  83. #ifndef ICMP_UNREACH_FILTER_PROHIB
  84. #define ICMP_UNREACH_FILTER_PROHIB      13      /* admin prohibited filter */
  85. #endif
  86. #ifndef ICMP_UNREACH_HOST_PRECEDENCE
  87. #define ICMP_UNREACH_HOST_PRECEDENCE    14      /* host precedence violation */
  88. #endif
  89. #ifndef ICMP_UNREACH_PRECEDENCE_CUTOFF
  90. #define ICMP_UNREACH_PRECEDENCE_CUTOFF  15      /* precedence cutoff */
  91. #endif
  92.  
  93. /* rfc1256 */
  94. #ifndef ICMP_ROUTERADVERT
  95. #define ICMP_ROUTERADVERT               9       /* router advertisement */
  96. #endif
  97. #ifndef ICMP_ROUTERSOLICIT
  98. #define ICMP_ROUTERSOLICIT              10      /* router solicitation */
  99. #endif
  100.  
  101. /* Most of the icmp types */
  102. static struct tok icmp2str[] = {
  103.         { ICMP_ECHOREPLY,               "echo reply" },
  104.         { ICMP_SOURCEQUENCH,            "source quench" },
  105.         { ICMP_ECHO,                    "echo request" },
  106.         { ICMP_ROUTERSOLICIT,           "router solicitation" },
  107.         { ICMP_TSTAMP,                  "time stamp request" },
  108.         { ICMP_TSTAMPREPLY,             "time stamp reply" },
  109.         { ICMP_IREQ,                    "information request" },
  110.         { ICMP_IREQREPLY,               "information reply" },
  111.         { ICMP_MASKREQ,                 "address mask request" },
  112.         { 0,                            NULL }
  113. };
  114.  
  115. /* Formats for most of the ICMP_UNREACH codes */
  116. static struct tok unreach2str[] = {
  117.         { ICMP_UNREACH_NET,             "net %s unreachable" },
  118.         { ICMP_UNREACH_HOST,            "host %s unreachable" },
  119.         { ICMP_UNREACH_SRCFAIL,
  120.             "%s unreachable - source route failed" },
  121.         { ICMP_UNREACH_NET_UNKNOWN,     "net %s unreachable - unknown" },
  122.         { ICMP_UNREACH_HOST_UNKNOWN,    "host %s unreachable - unknown" },
  123.         { ICMP_UNREACH_ISOLATED,
  124.             "%s unreachable - source host isolated" },
  125.         { ICMP_UNREACH_NET_PROHIB,
  126.             "net %s unreachable - admin prohibited" },
  127.         { ICMP_UNREACH_HOST_PROHIB,
  128.             "host %s unreachable - admin prohibited" },
  129.         { ICMP_UNREACH_TOSNET,
  130.             "net %s unreachable - tos prohibited" },
  131.         { ICMP_UNREACH_TOSHOST,
  132.             "host %s unreachable - tos prohibited" },
  133.         { ICMP_UNREACH_FILTER_PROHIB,
  134.             "host %s unreachable - admin prohibited filter" },
  135.         { ICMP_UNREACH_HOST_PRECEDENCE,
  136.             "host %s unreachable - host precedence violation" },
  137.         { ICMP_UNREACH_PRECEDENCE_CUTOFF,
  138.             "host %s unreachable - precedence cutoff" },
  139.         { 0,                            NULL }
  140. };
  141.  
  142. /* Formats for the ICMP_REDIRECT codes */
  143. static struct tok type2str[] = {
  144.         { ICMP_REDIRECT_NET,            "redirect %s to net %s" },
  145.         { ICMP_REDIRECT_HOST,           "redirect %s to host %s" },
  146.         { ICMP_REDIRECT_TOSNET,         "redirect-tos %s to net %s" },
  147.         { ICMP_REDIRECT_TOSHOST,        "redirect-tos %s to net %s" },
  148.         { 0,                            NULL }
  149. };
  150.  
  151. /* rfc1191 */
  152. struct mtu_discovery {
  153.         short unused;
  154.         short nexthopmtu;
  155. };
  156.  
  157. /* rfc1256 */
  158. struct ih_rdiscovery {
  159.         u_char ird_addrnum;
  160.         u_char ird_addrsiz;
  161.         u_short ird_lifetime;
  162. };
  163.  
  164. struct id_rdiscovery {
  165.         u_int32_t ird_addr;
  166.         u_int32_t ird_pref;
  167. };
  168.  
  169. void
  170. icmp_print(register const u_char *bp, register const u_char *bp2)
  171. {
  172.         register char *cp;
  173.         register const struct icmp *dp;
  174.         register const struct ip *ip;
  175.         register const char *str, *fmt;
  176.         register const struct ip *oip;
  177.         register const struct udphdr *ouh;
  178.         register u_int hlen, dport, mtu;
  179.         char buf[256];
  180.  
  181.         dp = (struct icmp *)bp;
  182.         ip = (struct ip *)bp2;
  183.         str = buf;
  184.  
  185.         (void)printf("%s > %s: ",
  186.                 ipaddr_string(&ip->ip_src),
  187.                 ipaddr_string(&ip->ip_dst));
  188.  
  189.         TCHECK(dp->icmp_code);
  190.         switch (dp->icmp_type) {
  191.  
  192.         case ICMP_UNREACH:
  193.                 TCHECK(dp->icmp_ip.ip_dst);
  194.                 switch (dp->icmp_code) {
  195.  
  196.                 case ICMP_UNREACH_PROTOCOL:
  197.                         TCHECK(dp->icmp_ip.ip_p);
  198.                         (void)sprintf(buf, "%s protocol %d unreachable",
  199.                                        ipaddr_string(&dp->icmp_ip.ip_dst),
  200.                                        dp->icmp_ip.ip_p);
  201.                         break;
  202.  
  203.                 case ICMP_UNREACH_PORT:
  204.                         TCHECK(dp->icmp_ip.ip_p);
  205.                         oip = &dp->icmp_ip;
  206.                         hlen = oip->ip_hl * 4;
  207.                         ouh = (struct udphdr *)(((u_char *)oip) + hlen);
  208.                         dport = ntohs(ouh->uh_dport);
  209.                         switch (oip->ip_p) {
  210.  
  211.                         case IPPROTO_TCP:
  212.                                 (void)sprintf(buf,
  213.                                         "%s tcp port %s unreachable",
  214.                                         ipaddr_string(&oip->ip_dst),
  215.                                         tcpport_string(dport));
  216.                                 break;
  217.  
  218.                         case IPPROTO_UDP:
  219.                                 (void)sprintf(buf,
  220.                                         "%s udp port %s unreachable",
  221.                                         ipaddr_string(&oip->ip_dst),
  222.                                         udpport_string(dport));
  223.                                 break;
  224.  
  225.                         default:
  226.                                 (void)sprintf(buf,
  227.                                         "%s protocol %d port %d unreachable",
  228.                                         ipaddr_string(&oip->ip_dst),
  229.                                         oip->ip_p, dport);
  230.                                 break;
  231.                         }
  232.                         break;
  233.  
  234.                 case ICMP_UNREACH_NEEDFRAG:
  235.                         {
  236.                         register const struct mtu_discovery *mp;
  237.  
  238.                         mp = (struct mtu_discovery *)&dp->icmp_void;
  239.                         mtu = EXTRACT_16BITS(&mp->nexthopmtu);
  240.                         if (mtu)
  241.                             (void)sprintf(buf,
  242.                                 "%s unreachable - need to frag (mtu %d)",
  243.                                 ipaddr_string(&dp->icmp_ip.ip_dst), mtu);
  244.                         else
  245.                             (void)sprintf(buf,
  246.                                 "%s unreachable - need to frag",
  247.                                 ipaddr_string(&dp->icmp_ip.ip_dst));
  248.                         }
  249.                         break;
  250.  
  251.                 default:
  252.                         fmt = tok2str(unreach2str, "#%d %%s unreachable",
  253.                             dp->icmp_code);
  254.                         (void)sprintf(buf, fmt,
  255.                             ipaddr_string(&dp->icmp_ip.ip_dst));
  256.                         break;
  257.                 }
  258.                 break;
  259.  
  260.         case ICMP_REDIRECT:
  261.                 TCHECK(dp->icmp_ip.ip_dst);
  262.                 fmt = tok2str(type2str, "redirect-#%d %%s to net %%s",
  263.                     dp->icmp_code);
  264.                 (void)sprintf(buf, fmt,
  265.                     ipaddr_string(&dp->icmp_ip.ip_dst),
  266.                     ipaddr_string(&dp->icmp_gwaddr));
  267.                 break;
  268.  
  269.         case ICMP_ROUTERADVERT:
  270.                 {
  271.                 register const struct ih_rdiscovery *ihp;
  272.                 register const struct id_rdiscovery *idp;
  273.                 u_int lifetime, num, size;
  274.  
  275.                 (void)strcpy(buf, "router advertisement");
  276.                 cp = buf + strlen(buf);
  277.  
  278.                 ihp = (struct ih_rdiscovery *)&dp->icmp_void;
  279.                 TCHECK(*ihp);
  280.                 (void)strcpy(cp, "lifetime ");
  281.                 cp = buf + strlen(buf);
  282.                 lifetime = EXTRACT_16BITS(&ihp->ird_lifetime);
  283.                 if (lifetime < 60)
  284.                         (void)sprintf(cp, "%u", lifetime);
  285.                 else if (lifetime < 60 * 60)
  286.                         (void)sprintf(cp, "%u:%02u",
  287.                             lifetime / 60, lifetime % 60);
  288.                 else
  289.                         (void)sprintf(cp, "%u:%02u:%02u",
  290.                             lifetime / 3600,
  291.                             (lifetime % 3600) / 60,
  292.                             lifetime % 60);
  293.                 cp = buf + strlen(buf);
  294.  
  295.                 num = ihp->ird_addrnum;
  296.                 (void)sprintf(cp, " %d:", num);
  297.                 cp = buf + strlen(buf);
  298.  
  299.                 size = ihp->ird_addrsiz;
  300.                 if (size != 2) {
  301.                         (void)sprintf(cp, " [size %d]", size);
  302.                         break;
  303.                 }
  304.                 idp = (struct id_rdiscovery *)&dp->icmp_data;
  305.                 while (num-- > 0) {
  306.                         TCHECK(*idp);
  307.                         (void)sprintf(cp, " {%s %u}",
  308.                             ipaddr_string(&idp->ird_addr),
  309.                             EXTRACT_32BITS(&idp->ird_pref));
  310.                         cp = buf + strlen(buf);
  311.                 }
  312.                 }
  313.                 break;
  314.  
  315.         case ICMP_TIMXCEED:
  316.                 TCHECK(dp->icmp_ip.ip_dst);
  317.                 switch (dp->icmp_code) {
  318.  
  319.                 case ICMP_TIMXCEED_INTRANS:
  320.                         str = "time exceeded in-transit";
  321.                         break;
  322.  
  323.                 case ICMP_TIMXCEED_REASS:
  324.                         str = "ip reassembly time exceeded";
  325.                         break;
  326.  
  327.                 default:
  328.                         (void)sprintf(buf, "time exceeded-#%d", dp->icmp_code);
  329.                         break;
  330.                 }
  331.                 break;
  332.  
  333.         case ICMP_PARAMPROB:
  334.                 if (dp->icmp_code)
  335.                         (void)sprintf(buf, "parameter problem - code %d",
  336.                                         dp->icmp_code);
  337.                 else {
  338.                         TCHECK(dp->icmp_pptr);
  339.                         (void)sprintf(buf, "parameter problem - octet %d",
  340.                                         dp->icmp_pptr);
  341.                 }
  342.                 break;
  343.  
  344.         case ICMP_MASKREPLY:
  345.                 TCHECK(dp->icmp_mask);
  346.                 (void)sprintf(buf, "address mask is 0x%08x",
  347.                     (u_int32_t)ntohl(dp->icmp_mask));
  348.                 break;
  349.  
  350.         default:
  351.                 str = tok2str(icmp2str, "type-#%d", dp->icmp_type);
  352.                 break;
  353.         }
  354.         (void)printf("icmp: %s", str);
  355.         return;
  356. trunc:
  357.         fputs("[|icmp]", stdout);
  358. }
  359.