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

  1. /*
  2.  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 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-domain.c,v 1.35 96/07/23 14:17:22 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. #ifndef __EMX__
  42. #include <netinet/ip_var.h>
  43. #endif
  44. #include <netinet/udp.h>
  45. #include <netinet/udp_var.h>
  46. #include <netinet/tcp.h>
  47. #ifndef __EMX__
  48. #include <netinet/tcpip.h>
  49. #endif
  50.  
  51. #undef NOERROR                                  /* Solaris sucks */
  52. #undef T_UNSPEC                                 /* SINIX does too */
  53. #include <arpa/nameser.h>
  54.  
  55. #include <stdio.h>
  56.  
  57. #include "interface.h"
  58. #include "addrtoname.h"
  59. #include "extract.h"                    /* must come after interface.h */
  60.  
  61. /* Compatibility */
  62. #ifndef T_TXT
  63. #define T_TXT           16              /* text strings */
  64. #endif
  65. #ifndef T_RP
  66. #define T_RP            17              /* responsible person */
  67. #endif
  68. #ifndef T_AFSDB
  69. #define T_AFSDB         18              /* AFS cell database */
  70. #endif
  71. #ifndef T_X25
  72. #define T_X25           19              /* X_25 calling address */
  73. #endif
  74. #ifndef T_ISDN
  75. #define T_ISDN          20              /* ISDN calling address */
  76. #endif
  77. #ifndef T_RT
  78. #define T_RT            21              /* router */
  79. #endif
  80. #ifndef T_NSAP
  81. #define T_NSAP          22              /* NSAP address */
  82. #endif
  83. #ifndef T_NSAP_PTR
  84. #define T_NSAP_PTR      23              /* reverse NSAP lookup (deprecated) */
  85. #endif
  86. #ifndef T_SIG
  87. #define T_SIG           24              /* security signature */
  88. #endif
  89. #ifndef T_KEY
  90. #define T_KEY           25              /* security key */
  91. #endif
  92. #ifndef T_PX
  93. #define T_PX            26              /* X.400 mail mapping */
  94. #endif
  95. #ifndef T_GPOS
  96. #define T_GPOS          27              /* geographical position (withdrawn) */
  97. #endif
  98. #ifndef T_AAAA
  99. #define T_AAAA          28              /* IP6 Address */
  100. #endif
  101. #ifndef T_LOC
  102. #define T_LOC           29              /* Location Information */
  103. #endif
  104.  
  105. #ifndef T_UNSPEC
  106. #define T_UNSPEC        103             /* Unspecified format (binary data) */
  107. #endif
  108. #ifndef T_UNSPECA
  109. #define T_UNSPECA       104             /* "unspecified ascii". Ugly MIT hack */
  110. #endif
  111.  
  112. #ifndef C_CHAOS
  113. #define C_CHAOS         3               /* for chaos net (MIT) */
  114. #endif
  115. #ifndef C_HS
  116. #define C_HS            4               /* for Hesiod name server (MIT) (XXX) */
  117. #endif
  118.  
  119. static char *ns_ops[] = {
  120.         "", " inv_q", " stat", " op3", " notify", " op5", " op6", " op7",
  121.         " op8", " updataA", " updateD", " updateDA",
  122.         " updateM", " updateMA", " zoneInit", " zoneRef",
  123. };
  124.  
  125. static char *ns_resp[] = {
  126.         "", " FormErr", " ServFail", " NXDomain",
  127.         " NotImp", " Refused", " Resp6", " Resp7",
  128.         " Resp8", " Resp9", " Resp10", " Resp11",
  129.         " Resp12", " Resp13", " Resp14", " NoChange",
  130. };
  131.  
  132. /* skip over a domain name */
  133. static const u_char *
  134. ns_nskip(register const u_char *cp, register const u_char *bp)
  135. {
  136.         register u_char i;
  137.  
  138.         if (((i = *cp++) & INDIR_MASK) == INDIR_MASK)
  139.                 return (cp + 1);
  140.         while (i && cp < snapend) {
  141.                 cp += i;
  142.                 i = *cp++;
  143.         }
  144.         return (cp);
  145. }
  146.  
  147. /* print a <domain-name> */
  148. static const u_char *
  149. ns_nprint(register const u_char *cp, register const u_char *bp)
  150. {
  151.         register u_int i;
  152.         register const u_char *rp;
  153.         register int compress;
  154.  
  155.         i = *cp++;
  156.         rp = cp + i;
  157.         if ((i & INDIR_MASK) == INDIR_MASK) {
  158.                 rp = cp + 1;
  159.                 compress = 1;
  160.         } else
  161.                 compress = 0;
  162.         if (i != 0)
  163.                 while (i && cp < snapend) {
  164.                         if ((i & INDIR_MASK) == INDIR_MASK) {
  165.                                 cp = bp + (((i << 8) | *cp) & 0x3fff);
  166.                                 i = *cp++;
  167.                                 continue;
  168.                         }
  169.                         if (fn_printn(cp, i, snapend))
  170.                                 break;
  171.                         cp += i;
  172.                         putchar('.');
  173.                         i = *cp++;
  174.                         if (!compress)
  175.                                 rp += i + 1;
  176.                 }
  177.         else
  178.                 putchar('.');
  179.         return (rp);
  180. }
  181.  
  182. /* print a <character-string> */
  183. static const u_char *
  184. ns_cprint(register const u_char *cp, register const u_char *bp)
  185. {
  186.         register u_int i;
  187.  
  188.         i = *cp++;
  189.         (void)fn_printn(cp, i, snapend);
  190.         return (cp + i);
  191. }
  192.  
  193. static struct tok type2str[] = {
  194.         { T_A,          "A" },
  195.         { T_NS,         "NS" },
  196.         { T_MD,         "MD" },
  197.         { T_MF,         "MF" },
  198.         { T_CNAME,      "CNAME" },
  199.         { T_SOA,        "SOA" },
  200.         { T_MB,         "MB" },
  201.         { T_MG,         "MG" },
  202.         { T_MR,         "MR" },
  203.         { T_NULL,       "NULL" },
  204.         { T_WKS,        "WKS" },
  205.         { T_PTR,        "PTR" },
  206.         { T_HINFO,      "HINFO" },
  207.         { T_MINFO,      "MINFO" },
  208.         { T_MX,         "MX" },
  209.         { T_TXT,        "TXT" },
  210.         { T_RP,         "RP" },
  211.         { T_AFSDB,      "AFSDB" },
  212.         { T_X25,        "X25" },
  213.         { T_ISDN,       "ISDN" },
  214.         { T_RT,         "RT" },
  215.         { T_NSAP,       "NSAP" },
  216.         { T_NSAP_PTR,   "NSAP_PTR" },
  217.         { T_SIG,        "SIG" },
  218.         { T_KEY,        "KEY" },
  219.         { T_PX,         "PX" },
  220.         { T_GPOS,       "GPOS" },
  221.         { T_AAAA,       "AAAA" },
  222.         { T_LOC ,       "LOC " },
  223.         { T_UINFO,      "UINFO" },
  224.         { T_UID,        "UID" },
  225.         { T_GID,        "GID" },
  226.         { T_UNSPEC,     "UNSPEC" },
  227.         { T_UNSPECA,    "UNSPECA" },
  228.         { T_AXFR,       "AXFR" },
  229.         { T_MAILB,      "MAILB" },
  230.         { T_MAILA,      "MAILA" },
  231.         { T_ANY,        "ANY" },
  232.         { 0,            NULL }
  233. };
  234.  
  235. static struct tok class2str[] = {
  236.         { C_IN,         "IN" },         /* Not used */
  237.         { C_CHAOS,      "CHAOS)" },
  238.         { C_HS,         "HS" },
  239.         { C_ANY,        "ANY" },
  240.         { 0,            NULL }
  241. };
  242.  
  243. /* print a query */
  244. static void
  245. ns_qprint(register const u_char *cp, register const u_char *bp)
  246. {
  247.         register const u_char *np = cp;
  248.         register u_int i;
  249.  
  250.         cp = ns_nskip(cp, bp);
  251.  
  252.         if (cp + 4 > snapend)
  253.                 return;
  254.  
  255.         /* print the qtype and qclass (if it's not IN) */
  256.         i = *cp++ << 8;
  257.         i |= *cp++;
  258.         printf(" %s", tok2str(type2str, "Type%d", i));
  259.         i = *cp++ << 8;
  260.         i |= *cp++;
  261.         if (i != C_IN)
  262.                 printf(" %s", tok2str(class2str, "(Class %d)", i));
  263.  
  264.         fputs("? ", stdout);
  265.         ns_nprint(np, bp);
  266. }
  267.  
  268. /* print a reply */
  269. static const u_char *
  270. ns_rprint(register const u_char *cp, register const u_char *bp)
  271. {
  272.         register u_int i;
  273.         register u_short typ, len;
  274.         register const u_char *rp;
  275.  
  276.         if (vflag) {
  277.                 putchar(' ');
  278.                 cp = ns_nprint(cp, bp);
  279.         } else
  280.                 cp = ns_nskip(cp, bp);
  281.  
  282.         if (cp + 10 > snapend)
  283.                 return (snapend);
  284.  
  285.         /* print the type/qtype and class (if it's not IN) */
  286.         typ = *cp++ << 8;
  287.         typ |= *cp++;
  288.         i = *cp++ << 8;
  289.         i |= *cp++;
  290.         if (i != C_IN)
  291.                 printf(" %s", tok2str(class2str, "(Class %d)", i));
  292.  
  293.         /* ignore ttl */
  294.         cp += 4;
  295.  
  296.         len = *cp++ << 8;
  297.         len |= *cp++;
  298.  
  299.         rp = cp + len;
  300.  
  301.         printf(" %s", tok2str(type2str, "Type%d", typ));
  302.         switch (typ) {
  303.  
  304.         case T_A:
  305.                 printf(" %s", ipaddr_string(cp));
  306.                 break;
  307.  
  308.         case T_NS:
  309.         case T_CNAME:
  310.         case T_PTR:
  311.                 putchar(' ');
  312.                 (void)ns_nprint(cp, bp);
  313.                 break;
  314.  
  315.         case T_MX:
  316.                 putchar(' ');
  317.                 (void)ns_nprint(cp + 2, bp);
  318.                 printf(" %d", EXTRACT_16BITS(cp));
  319.                 break;
  320.  
  321.         case T_TXT:
  322.                 putchar(' ');
  323.                 (void)ns_cprint(cp, bp);
  324.                 break;
  325.  
  326.         case T_UNSPECA:         /* One long string */
  327.                 printf(" %.*s", len, cp);
  328.                 break;
  329.         }
  330.         return (rp);            /* XXX This isn't always right*/
  331. }
  332.  
  333. void
  334. ns_print(register const u_char *bp, u_int length)
  335. {
  336.         register const HEADER *np;
  337.         register int qdcount, ancount, nscount, arcount;
  338.         register const u_char *cp;
  339.  
  340.         np = (const HEADER *)bp;
  341.         /* get the byte-order right */
  342.         qdcount = ntohs(np->qdcount);
  343.         ancount = ntohs(np->ancount);
  344.         nscount = ntohs(np->nscount);
  345.         arcount = ntohs(np->arcount);
  346.  
  347.         if (np->qr) {
  348.                 /* this is a response */
  349.                 printf(" %d%s%s%s%s%s",
  350.                         ntohs(np->id),
  351.                         ns_ops[np->opcode],
  352.                         ns_resp[np->rcode],
  353.                         np->aa? "*" : "",
  354.                         np->ra? "" : "-",
  355.                         np->tc? "|" : "");
  356.                 if (qdcount != 1)
  357.                         printf(" [%dq]", qdcount);
  358.                 /* Print QUESTION section on -vv */
  359.                 if (vflag > 1) {
  360.                             fputs(" q: ", stdout);
  361.                             cp = ns_nprint((const u_char *)(np + 1), bp);
  362.                 } else
  363.                             cp = ns_nskip((const u_char *)(np + 1), bp);
  364.                 printf(" %d/%d/%d", ancount, nscount, arcount);
  365.                 if (ancount--) {
  366.                         cp = ns_rprint(cp + 4, bp);
  367.                         while (ancount-- && cp < snapend) {
  368.                                 putchar(',');
  369.                                 cp = ns_rprint(cp, bp);
  370.                         }
  371.                 }
  372.         }
  373.         else {
  374.                 /* this is a request */
  375.                 printf(" %d%s%s",
  376.                         ntohs(np->id),
  377.                         ns_ops[np->opcode],
  378.                         np->rd? "+" : "");
  379.  
  380.                 /* any weirdness? */
  381.                 if (*(((u_short *)np)+1) & htons(0x6ff))
  382.                         printf(" [b2&3=0x%x]", ntohs(*(((u_short *)np)+1)));
  383.  
  384.                 if (np->opcode == IQUERY) {
  385.                         if (qdcount)
  386.                                 printf(" [%dq]", qdcount);
  387.                         if (ancount != 1)
  388.                                 printf(" [%da]", ancount);
  389.                 }
  390.                 else {
  391.                         if (ancount)
  392.                                 printf(" [%da]", ancount);
  393.                         if (qdcount != 1)
  394.                                 printf(" [%dq]", qdcount);
  395.                 }
  396.                 if (nscount)
  397.                         printf(" [%dn]", nscount);
  398.                 if (arcount)
  399.                         printf(" [%dau]", arcount);
  400.  
  401.                 ns_qprint((const u_char *)(np + 1), (const u_char *)np);
  402.         }
  403.         printf(" (%d)", length);
  404. }
  405.