1998-09-16 02:39:15 +00:00
|
|
|
/* packet-dns.c
|
|
|
|
* Routines for DNS packet disassembly
|
|
|
|
*
|
2002-08-02 23:36:07 +00:00
|
|
|
* $Id: packet-dns.c,v 1.90 2002/08/02 23:35:48 jmayer Exp $
|
1998-09-16 03:22:19 +00:00
|
|
|
*
|
1998-09-16 02:39:15 +00:00
|
|
|
* Ethereal - Network traffic analyzer
|
2001-04-23 18:05:19 +00:00
|
|
|
* By Gerald Combs <gerald@ethereal.com>
|
1998-09-16 02:39:15 +00:00
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
2002-07-16 22:50:48 +00:00
|
|
|
#ifdef NEED_SNPRINTF_H
|
|
|
|
# include "snprintf.h"
|
|
|
|
#endif
|
|
|
|
|
1999-03-23 03:14:46 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <memory.h>
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1999-03-23 03:14:46 +00:00
|
|
|
#include <glib.h>
|
2002-01-21 07:37:49 +00:00
|
|
|
#include <epan/packet.h>
|
2001-04-17 06:29:14 +00:00
|
|
|
#include "ipproto.h"
|
2002-01-21 07:37:49 +00:00
|
|
|
#include <epan/resolv.h>
|
1998-10-14 19:35:00 +00:00
|
|
|
#include "packet-dns.h"
|
Make a "tcp_dissect_pdus()" with the standard loop for a TCP segment,
extracting PDUs from it and possibly doing reassembly. Make the COPS,
DNS, DSI, Gryphon, and SCCP dissectors use it.
Add "set_actual_length()", "tcp_dissect_pdus()",
"decode_boolean_bitfield()", "decode_numeric_bitfield()", and
"decode_enumerated_bitfield()" to the list of routines available to
dissectors on platforms where routines in the main program aren't
available to dynamically-loaded code.
Declare routines in "to_str.h" as "extern"; as I remember, that's
necessary to allow the "decode_XXX_bitfield()" routines declared therein
to be made available to plugins as per the above.
Note that new exported routines should be added to the end of the table
if that's the only change being made to the table.
Create a new "plugin_api_decls.h" header file, used to declare both the
"p_" variables and the "p_" structure members in the routine-exporting
mechanism; this reduces the number of places you have to change to
change the list of exported routines.
svn path=/trunk/; revision=5394
2002-05-05 00:16:38 +00:00
|
|
|
#include "packet-tcp.h"
|
2001-09-17 02:07:00 +00:00
|
|
|
#include "prefs.h"
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1999-07-29 05:47:07 +00:00
|
|
|
static int proto_dns = -1;
|
2001-07-02 07:29:03 +00:00
|
|
|
static int hf_dns_length = -1;
|
1999-10-16 15:08:11 +00:00
|
|
|
static int hf_dns_flags = -1;
|
2002-05-15 07:24:20 +00:00
|
|
|
static int hf_dns_flags_response = -1;
|
|
|
|
static int hf_dns_flags_opcode = -1;
|
|
|
|
static int hf_dns_flags_authoritative = -1;
|
|
|
|
static int hf_dns_flags_truncated = -1;
|
|
|
|
static int hf_dns_flags_recdesired = -1;
|
|
|
|
static int hf_dns_flags_recavail = -1;
|
|
|
|
static int hf_dns_flags_authenticated = -1;
|
|
|
|
static int hf_dns_flags_checkdisable = -1;
|
|
|
|
static int hf_dns_flags_rcode = -1;
|
1999-10-16 15:08:11 +00:00
|
|
|
static int hf_dns_transaction_id = -1;
|
|
|
|
static int hf_dns_count_questions = -1;
|
|
|
|
static int hf_dns_count_answers = -1;
|
|
|
|
static int hf_dns_count_auth_rr = -1;
|
|
|
|
static int hf_dns_count_add_rr = -1;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1999-11-16 11:44:20 +00:00
|
|
|
static gint ett_dns = -1;
|
|
|
|
static gint ett_dns_qd = -1;
|
|
|
|
static gint ett_dns_rr = -1;
|
|
|
|
static gint ett_dns_qry = -1;
|
|
|
|
static gint ett_dns_ans = -1;
|
|
|
|
static gint ett_dns_flags = -1;
|
1999-11-27 08:59:28 +00:00
|
|
|
static gint ett_t_key_flags = -1;
|
1999-11-16 11:44:20 +00:00
|
|
|
|
2001-09-17 02:07:00 +00:00
|
|
|
/* desegmentation of DNS over TCP */
|
|
|
|
static gboolean dns_desegment = TRUE;
|
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
/* DNS structs and definitions */
|
|
|
|
|
2000-10-11 04:12:06 +00:00
|
|
|
/* Ports used for DNS. */
|
2000-04-04 06:17:30 +00:00
|
|
|
#define UDP_PORT_DNS 53
|
2000-10-11 04:12:06 +00:00
|
|
|
#define TCP_PORT_DNS 53
|
2000-04-04 06:17:30 +00:00
|
|
|
|
1999-01-04 09:13:46 +00:00
|
|
|
/* Offsets of fields in the DNS header. */
|
|
|
|
#define DNS_ID 0
|
|
|
|
#define DNS_FLAGS 2
|
|
|
|
#define DNS_QUEST 4
|
1999-10-07 07:44:29 +00:00
|
|
|
#define DNS_ANS 6
|
1999-01-04 09:13:46 +00:00
|
|
|
#define DNS_AUTH 8
|
1999-10-07 07:44:29 +00:00
|
|
|
#define DNS_ADD 10
|
1999-01-04 09:13:46 +00:00
|
|
|
|
|
|
|
/* Length of DNS header. */
|
|
|
|
#define DNS_HDRLEN 12
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
/* type values */
|
|
|
|
#define T_A 1 /* host address */
|
1999-03-22 23:31:05 +00:00
|
|
|
#define T_NS 2 /* authoritative name server */
|
|
|
|
#define T_MD 3 /* mail destination (obsolete) */
|
|
|
|
#define T_MF 4 /* mail forwarder (obsolete) */
|
1998-09-16 02:39:15 +00:00
|
|
|
#define T_CNAME 5 /* canonical name */
|
|
|
|
#define T_SOA 6 /* start of authority zone */
|
1999-03-22 23:31:05 +00:00
|
|
|
#define T_MB 7 /* mailbox domain name (experimental) */
|
|
|
|
#define T_MG 8 /* mail group member (experimental) */
|
|
|
|
#define T_MR 9 /* mail rename domain name (experimental) */
|
|
|
|
#define T_NULL 10 /* null RR (experimental) */
|
1998-09-16 02:39:15 +00:00
|
|
|
#define T_WKS 11 /* well known service */
|
|
|
|
#define T_PTR 12 /* domain name pointer */
|
|
|
|
#define T_HINFO 13 /* host information */
|
1999-03-22 23:31:05 +00:00
|
|
|
#define T_MINFO 14 /* mailbox or mail list information */
|
1998-09-16 02:39:15 +00:00
|
|
|
#define T_MX 15 /* mail routing information */
|
|
|
|
#define T_TXT 16 /* text strings */
|
1999-03-22 23:31:05 +00:00
|
|
|
#define T_RP 17 /* responsible person (RFC 1183) */
|
|
|
|
#define T_AFSDB 18 /* AFS data base location (RFC 1183) */
|
|
|
|
#define T_X25 19 /* X.25 address (RFC 1183) */
|
|
|
|
#define T_ISDN 20 /* ISDN address (RFC 1183) */
|
|
|
|
#define T_RT 21 /* route-through (RFC 1183) */
|
|
|
|
#define T_NSAP 22 /* OSI NSAP (RFC 1706) */
|
|
|
|
#define T_NSAP_PTR 23 /* PTR equivalent for OSI NSAP (RFC 1348 - obsolete) */
|
2000-10-11 04:12:06 +00:00
|
|
|
#define T_SIG 24 /* digital signature (RFC 2535) */
|
|
|
|
#define T_KEY 25 /* public key (RFC 2535) */
|
1999-03-22 23:31:05 +00:00
|
|
|
#define T_PX 26 /* pointer to X.400/RFC822 mapping info (RFC 1664) */
|
|
|
|
#define T_GPOS 27 /* geographical position (RFC 1712) */
|
|
|
|
#define T_AAAA 28 /* IPv6 address (RFC 1886) */
|
|
|
|
#define T_LOC 29 /* geographical location (RFC 1876) */
|
2000-10-11 04:12:06 +00:00
|
|
|
#define T_NXT 30 /* "next" name (RFC 2535) */
|
1999-03-22 23:31:05 +00:00
|
|
|
#define T_EID 31 /* ??? (Nimrod?) */
|
|
|
|
#define T_NIMLOC 32 /* ??? (Nimrod?) */
|
|
|
|
#define T_SRV 33 /* service location (RFC 2052) */
|
|
|
|
#define T_ATMA 34 /* ??? */
|
|
|
|
#define T_NAPTR 35 /* naming authority pointer (RFC 2168) */
|
2000-10-11 04:12:06 +00:00
|
|
|
#define T_KX 36 /* Key Exchange (RFC 2230) */
|
|
|
|
#define T_CERT 37 /* Certificate (RFC 2538) */
|
2000-08-18 09:05:02 +00:00
|
|
|
#define T_A6 38 /* IPv6 address with indirection (RFC 2874) */
|
2000-10-02 17:42:38 +00:00
|
|
|
#define T_DNAME 39 /* Non-terminal DNS name redirection (RFC 2672) */
|
2000-03-30 01:33:10 +00:00
|
|
|
#define T_OPT 41 /* OPT pseudo-RR (RFC 2671) */
|
2000-10-11 04:12:06 +00:00
|
|
|
#define T_TKEY 249 /* Transaction Key (RFC 2930) */
|
|
|
|
#define T_TSIG 250 /* Transaction Signature (RFC 2845) */
|
2000-07-21 01:29:04 +00:00
|
|
|
#define T_WINS 65281 /* Microsoft's WINS RR */
|
|
|
|
#define T_WINS_R 65282 /* Microsoft's WINS-R RR */
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2000-08-09 07:15:19 +00:00
|
|
|
/* Class values */
|
|
|
|
#define C_IN 1 /* the Internet */
|
|
|
|
#define C_CS 2 /* CSNET (obsolete) */
|
|
|
|
#define C_CH 3 /* CHAOS */
|
|
|
|
#define C_HS 4 /* Hesiod */
|
2000-10-11 04:12:06 +00:00
|
|
|
#define C_NONE 254 /* none */
|
|
|
|
#define C_ANY 255 /* any */
|
2000-08-09 07:15:19 +00:00
|
|
|
|
1999-01-04 09:13:46 +00:00
|
|
|
/* Bit fields in the flags */
|
|
|
|
#define F_RESPONSE (1<<15) /* packet is response */
|
|
|
|
#define F_OPCODE (0xF<<11) /* query opcode */
|
2002-05-15 07:24:20 +00:00
|
|
|
#define OPCODE_SHIFT 11
|
1999-01-04 09:13:46 +00:00
|
|
|
#define F_AUTHORITATIVE (1<<10) /* response is authoritative */
|
|
|
|
#define F_TRUNCATED (1<<9) /* response is truncated */
|
|
|
|
#define F_RECDESIRED (1<<8) /* recursion desired */
|
|
|
|
#define F_RECAVAIL (1<<7) /* recursion available */
|
2000-04-26 12:01:50 +00:00
|
|
|
#define F_AUTHENTIC (1<<5) /* authentic data (RFC2535) */
|
|
|
|
#define F_CHECKDISABLE (1<<4) /* checking disabled (RFC2535) */
|
1999-01-04 09:13:46 +00:00
|
|
|
#define F_RCODE (0xF<<0) /* reply code */
|
|
|
|
|
2002-05-15 07:24:20 +00:00
|
|
|
static const true_false_string tfs_flags_response = {
|
|
|
|
"Message is a response",
|
|
|
|
"Message is a query"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const true_false_string tfs_flags_authoritative = {
|
|
|
|
"Server is an authority for domain",
|
|
|
|
"Server is not an authority for domain"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const true_false_string tfs_flags_truncated = {
|
|
|
|
"Message is truncated",
|
|
|
|
"Message is not truncated"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const true_false_string tfs_flags_recdesired = {
|
|
|
|
"Do query recursively",
|
|
|
|
"Don't do query recursively"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const true_false_string tfs_flags_recavail = {
|
|
|
|
"Server can do recursive queries",
|
|
|
|
"Server can't do recursive queries"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const true_false_string tfs_flags_authenticated = {
|
|
|
|
"Answer/authority portion was authenticated by the server",
|
|
|
|
"Answer/authority portion was not authenticated by the server"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const true_false_string tfs_flags_checkdisable = {
|
|
|
|
"Non-authenticated data is acceptable",
|
|
|
|
"Non-authenticated data is unacceptable"
|
|
|
|
};
|
|
|
|
|
1999-01-04 09:13:46 +00:00
|
|
|
/* Opcodes */
|
2002-05-15 07:24:20 +00:00
|
|
|
#define OPCODE_QUERY 0 /* standard query */
|
|
|
|
#define OPCODE_IQUERY 1 /* inverse query */
|
|
|
|
#define OPCODE_STATUS 2 /* server status request */
|
|
|
|
#define OPCODE_NOTIFY 4 /* zone change notification */
|
|
|
|
#define OPCODE_UPDATE 5 /* dynamic update */
|
|
|
|
|
|
|
|
static const value_string opcode_vals[] = {
|
|
|
|
{ OPCODE_QUERY, "Standard query" },
|
|
|
|
{ OPCODE_IQUERY, "Inverse query" },
|
|
|
|
{ OPCODE_STATUS, "Server status request" },
|
|
|
|
{ OPCODE_NOTIFY, "Zone change notification" },
|
|
|
|
{ OPCODE_UPDATE, "Dynamic update" },
|
|
|
|
{ 0, NULL } };
|
1999-01-04 09:13:46 +00:00
|
|
|
|
|
|
|
/* Reply codes */
|
2002-05-15 07:24:20 +00:00
|
|
|
#define RCODE_NOERROR 0
|
|
|
|
#define RCODE_FORMERR 1
|
|
|
|
#define RCODE_SERVFAIL 2
|
|
|
|
#define RCODE_NXDOMAIN 3
|
|
|
|
#define RCODE_NOTIMPL 4
|
|
|
|
#define RCODE_REFUSED 5
|
|
|
|
#define RCODE_YXDOMAIN 6
|
|
|
|
#define RCODE_YXRRSET 7
|
|
|
|
#define RCODE_NXRRSET 8
|
|
|
|
#define RCODE_NOTAUTH 9
|
|
|
|
#define RCODE_NOTZONE 10
|
2000-10-11 04:12:06 +00:00
|
|
|
|
|
|
|
static const value_string rcode_vals[] = {
|
|
|
|
{ RCODE_NOERROR, "No error" },
|
|
|
|
{ RCODE_FORMERR, "Format error" },
|
|
|
|
{ RCODE_SERVFAIL, "Server failure" },
|
|
|
|
{ RCODE_NXDOMAIN, "No such name" },
|
|
|
|
{ RCODE_NOTIMPL, "Not implemented" },
|
|
|
|
{ RCODE_REFUSED, "Refused" },
|
|
|
|
{ RCODE_YXDOMAIN, "Name exists" },
|
|
|
|
{ RCODE_YXRRSET, "RRset exists" },
|
|
|
|
{ RCODE_NXRRSET, "RRset does not exist" },
|
|
|
|
{ RCODE_NOTAUTH, "Not authoritative" },
|
|
|
|
{ RCODE_NOTZONE, "Name out of zone" },
|
|
|
|
{ 0, NULL } };
|
|
|
|
|
|
|
|
/* TSIG/TKEY extended errors */
|
|
|
|
#define TSIGERROR_BADSIG (16)
|
|
|
|
#define TSIGERROR_BADKEY (17)
|
|
|
|
#define TSIGERROR_BADTIME (18)
|
|
|
|
#define TSIGERROR_BADMODE (19)
|
|
|
|
#define TSIGERROR_BADNAME (20)
|
|
|
|
#define TSIGERROR_BADALG (21)
|
|
|
|
|
|
|
|
static const value_string tsigerror_vals[] = {
|
|
|
|
{ TSIGERROR_BADSIG, "Bad signature" },
|
|
|
|
{ TSIGERROR_BADKEY, "Bad key" },
|
|
|
|
{ TSIGERROR_BADTIME, "Bad time failure" },
|
|
|
|
{ TSIGERROR_BADMODE, "Bad mode such name" },
|
|
|
|
{ TSIGERROR_BADNAME, "Bad name implemented" },
|
|
|
|
{ TSIGERROR_BADALG, "Bad algorithm" },
|
|
|
|
{ 0, NULL } };
|
|
|
|
|
|
|
|
#define TKEYMODE_SERVERASSIGNED (1)
|
|
|
|
#define TKEYMODE_DIFFIEHELLMAN (2)
|
|
|
|
#define TKEYMODE_GSSAPI (3)
|
|
|
|
#define TKEYMODE_RESOLVERASSIGNED (4)
|
|
|
|
#define TKEYMODE_DELETE (5)
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2000-07-21 01:29:04 +00:00
|
|
|
/* See RFC 1035 for all RR types for which no RFC is listed, except for
|
|
|
|
the ones with "???", and for the Microsoft WINS and WINS-R RRs, for
|
|
|
|
which one should look at
|
|
|
|
|
2000-07-21 01:40:41 +00:00
|
|
|
http://www.windows.com/windows2000/en/server/help/sag_DNS_imp_UsingWinsLookup.htm
|
2000-07-21 01:29:04 +00:00
|
|
|
|
|
|
|
and
|
|
|
|
|
|
|
|
http://www.microsoft.com/windows2000/library/resources/reskit/samplechapters/cncf/cncf_imp_wwaw.asp
|
|
|
|
|
|
|
|
which discuss them to some extent. */
|
1998-09-16 02:39:15 +00:00
|
|
|
static char *
|
2002-08-02 23:36:07 +00:00
|
|
|
dns_type_name (guint type)
|
1998-09-16 02:39:15 +00:00
|
|
|
{
|
2000-03-30 01:33:10 +00:00
|
|
|
char *type_names[] = {
|
1999-03-22 23:31:05 +00:00
|
|
|
"unused",
|
|
|
|
"A",
|
|
|
|
"NS",
|
|
|
|
"MD",
|
|
|
|
"MF",
|
|
|
|
"CNAME",
|
|
|
|
"SOA",
|
|
|
|
"MB",
|
|
|
|
"MG",
|
|
|
|
"MR",
|
|
|
|
"NULL",
|
|
|
|
"WKS",
|
|
|
|
"PTR",
|
|
|
|
"HINFO",
|
|
|
|
"MINFO",
|
|
|
|
"MX",
|
|
|
|
"TXT",
|
|
|
|
"RP", /* RFC 1183 */
|
|
|
|
"AFSDB", /* RFC 1183 */
|
|
|
|
"X25", /* RFC 1183 */
|
|
|
|
"ISDN", /* RFC 1183 */
|
|
|
|
"RT", /* RFC 1183 */
|
|
|
|
"NSAP", /* RFC 1706 */
|
|
|
|
"NSAP-PTR", /* RFC 1348 */
|
2000-10-11 04:12:06 +00:00
|
|
|
"SIG", /* RFC 2535 */
|
|
|
|
"KEY", /* RFC 2535 */
|
1999-03-22 23:31:05 +00:00
|
|
|
"PX", /* RFC 1664 */
|
|
|
|
"GPOS", /* RFC 1712 */
|
|
|
|
"AAAA", /* RFC 1886 */
|
|
|
|
"LOC", /* RFC 1876 */
|
2000-10-11 04:12:06 +00:00
|
|
|
"NXT", /* RFC 2535 */
|
1999-03-22 23:31:05 +00:00
|
|
|
"EID",
|
|
|
|
"NIMLOC",
|
|
|
|
"SRV", /* RFC 2052 */
|
|
|
|
"ATMA",
|
2000-03-30 01:33:10 +00:00
|
|
|
"NAPTR", /* RFC 2168 */
|
2000-10-11 04:12:06 +00:00
|
|
|
"KX", /* RFC 2230 */
|
|
|
|
"CERT", /* RFC 2538 */
|
2000-08-18 09:05:02 +00:00
|
|
|
"A6", /* RFC 2874 */
|
2000-10-02 17:42:38 +00:00
|
|
|
"DNAME", /* RFC 2672 */
|
2000-03-30 01:33:10 +00:00
|
|
|
NULL,
|
|
|
|
"OPT" /* RFC 2671 */
|
1998-09-16 02:39:15 +00:00
|
|
|
};
|
|
|
|
|
2000-03-30 01:33:10 +00:00
|
|
|
if (type < sizeof(type_names)/sizeof(type_names[0]))
|
|
|
|
return type_names[type] ? type_names[type] : "unknown";
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
/* special cases */
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
/* non standard */
|
|
|
|
case 100:
|
|
|
|
return "UINFO";
|
|
|
|
case 101:
|
|
|
|
return "UID";
|
|
|
|
case 102:
|
|
|
|
return "GID";
|
|
|
|
case 103:
|
|
|
|
return "UNSPEC";
|
2000-07-21 01:29:04 +00:00
|
|
|
case T_WINS:
|
|
|
|
return "WINS";
|
|
|
|
case T_WINS_R:
|
|
|
|
return "WINS-R";
|
|
|
|
|
2000-10-11 04:12:06 +00:00
|
|
|
/* meta */
|
|
|
|
case T_TKEY:
|
|
|
|
return "TKEY";
|
|
|
|
case T_TSIG:
|
|
|
|
return "TSIG";
|
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
/* queries */
|
|
|
|
case 251:
|
1999-03-22 23:31:05 +00:00
|
|
|
return "IXFR"; /* RFC 1995 */
|
1998-09-16 02:39:15 +00:00
|
|
|
case 252:
|
|
|
|
return "AXFR";
|
|
|
|
case 253:
|
|
|
|
return "MAILB";
|
|
|
|
case 254:
|
|
|
|
return "MAILA";
|
|
|
|
case 255:
|
|
|
|
return "ANY";
|
2000-07-21 01:29:04 +00:00
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
1999-11-27 08:59:28 +00:00
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
return "unknown";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-03-22 23:31:05 +00:00
|
|
|
static char *
|
2002-08-02 23:36:07 +00:00
|
|
|
dns_long_type_name (guint type)
|
1999-03-22 23:31:05 +00:00
|
|
|
{
|
2000-03-30 01:33:10 +00:00
|
|
|
char *type_names[] = {
|
1999-03-22 23:31:05 +00:00
|
|
|
"unused",
|
|
|
|
"Host address",
|
|
|
|
"Authoritative name server",
|
|
|
|
"Mail destination",
|
|
|
|
"Mail forwarder",
|
|
|
|
"Canonical name for an alias",
|
|
|
|
"Start of zone of authority",
|
|
|
|
"Mailbox domain name",
|
|
|
|
"Mail group member",
|
|
|
|
"Mail rename domain name",
|
|
|
|
"Null resource record",
|
|
|
|
"Well-known service description",
|
|
|
|
"Domain name pointer",
|
|
|
|
"Host information",
|
|
|
|
"Mailbox or mail list information",
|
|
|
|
"Mail exchange",
|
|
|
|
"Text strings",
|
|
|
|
"Responsible person", /* RFC 1183 */
|
|
|
|
"AFS data base location", /* RFC 1183 */
|
|
|
|
"X.25 address", /* RFC 1183 */
|
|
|
|
"ISDN number", /* RFC 1183 */
|
|
|
|
"Route through", /* RFC 1183 */
|
|
|
|
"OSI NSAP", /* RFC 1706 */
|
|
|
|
"OSI NSAP name pointer", /* RFC 1348 */
|
2000-10-11 04:12:06 +00:00
|
|
|
"Signature", /* RFC 2535 */
|
|
|
|
"Public key", /* RFC 2535 */
|
1999-03-22 23:31:05 +00:00
|
|
|
"Pointer to X.400/RFC822 mapping info", /* RFC 1664 */
|
|
|
|
"Geographical position", /* RFC 1712 */
|
|
|
|
"IPv6 address", /* RFC 1886 */
|
|
|
|
"Location", /* RFC 1876 */
|
2000-10-11 04:12:06 +00:00
|
|
|
"Next", /* RFC 2535 */
|
1999-03-22 23:31:05 +00:00
|
|
|
"EID",
|
|
|
|
"NIMLOC",
|
|
|
|
"Service location", /* RFC 2052 */
|
|
|
|
"ATMA",
|
2000-03-30 01:33:10 +00:00
|
|
|
"Naming authority pointer", /* RFC 2168 */
|
2000-10-11 04:12:06 +00:00
|
|
|
"Key Exchange", /* RFC 2230 */
|
|
|
|
"Certificate", /* RFC 2538 */
|
2000-08-18 09:05:02 +00:00
|
|
|
"IPv6 address with indirection", /* RFC 2874 */
|
2000-10-02 17:42:38 +00:00
|
|
|
"Non-terminal DNS name redirection", /* RFC 2672 */
|
2000-03-30 01:33:10 +00:00
|
|
|
NULL,
|
|
|
|
"EDNS0 option" /* RFC 2671 */
|
1999-03-22 23:31:05 +00:00
|
|
|
};
|
|
|
|
static char unkbuf[7+1+2+1+4+1+1+10+1+1]; /* "Unknown RR type (%d)" */
|
|
|
|
|
2000-03-30 01:33:10 +00:00
|
|
|
if (type < sizeof(type_names)/sizeof(type_names[0]))
|
|
|
|
return type_names[type] ? type_names[type] : "unknown";
|
1999-03-22 23:31:05 +00:00
|
|
|
|
|
|
|
/* special cases */
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
/* non standard */
|
|
|
|
case 100:
|
|
|
|
return "UINFO";
|
|
|
|
case 101:
|
|
|
|
return "UID";
|
|
|
|
case 102:
|
|
|
|
return "GID";
|
|
|
|
case 103:
|
|
|
|
return "UNSPEC";
|
2000-07-21 01:29:04 +00:00
|
|
|
case T_WINS:
|
|
|
|
return "WINS";
|
|
|
|
case T_WINS_R:
|
|
|
|
return "WINS-R";
|
|
|
|
|
2000-10-11 04:12:06 +00:00
|
|
|
/* meta */
|
|
|
|
case T_TKEY:
|
|
|
|
return "Transaction Key";
|
|
|
|
case T_TSIG:
|
|
|
|
return "Transaction Signature";
|
|
|
|
|
1999-03-22 23:31:05 +00:00
|
|
|
/* queries */
|
|
|
|
case 251:
|
|
|
|
return "Request for incremental zone transfer"; /* RFC 1995 */
|
|
|
|
case 252:
|
|
|
|
return "Request for full zone transfer";
|
|
|
|
case 253:
|
|
|
|
return "Request for mailbox-related records";
|
|
|
|
case 254:
|
|
|
|
return "Request for mail agent resource records";
|
|
|
|
case 255:
|
|
|
|
return "Request for all records";
|
|
|
|
}
|
|
|
|
|
|
|
|
sprintf(unkbuf, "Unknown RR type (%d)", type);
|
|
|
|
return unkbuf;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-10-14 19:35:00 +00:00
|
|
|
char *
|
1998-09-16 02:39:15 +00:00
|
|
|
dns_class_name(int class)
|
|
|
|
{
|
|
|
|
char *class_name;
|
|
|
|
|
|
|
|
switch (class) {
|
2000-08-09 07:15:19 +00:00
|
|
|
case C_IN:
|
1998-09-16 02:39:15 +00:00
|
|
|
class_name = "inet";
|
|
|
|
break;
|
2000-08-09 07:15:19 +00:00
|
|
|
case C_CS:
|
|
|
|
class_name = "csnet";
|
|
|
|
break;
|
|
|
|
case C_CH:
|
1998-09-16 02:39:15 +00:00
|
|
|
class_name = "chaos";
|
|
|
|
break;
|
2000-08-09 07:15:19 +00:00
|
|
|
case C_HS:
|
1998-09-16 02:39:15 +00:00
|
|
|
class_name = "hesiod";
|
|
|
|
break;
|
2000-10-11 04:12:06 +00:00
|
|
|
case C_NONE:
|
|
|
|
class_name = "none";
|
|
|
|
break;
|
|
|
|
case C_ANY:
|
|
|
|
class_name = "any";
|
|
|
|
break;
|
1998-09-16 02:39:15 +00:00
|
|
|
default:
|
|
|
|
class_name = "unknown";
|
|
|
|
}
|
|
|
|
|
|
|
|
return class_name;
|
|
|
|
}
|
|
|
|
|
1999-05-27 05:35:08 +00:00
|
|
|
int
|
2001-07-02 07:11:40 +00:00
|
|
|
get_dns_name(tvbuff_t *tvb, int offset, int dns_data_offset,
|
1999-10-07 07:44:29 +00:00
|
|
|
char *name, int maxname)
|
1998-09-16 02:39:15 +00:00
|
|
|
{
|
2001-07-02 07:11:40 +00:00
|
|
|
int start_offset = offset;
|
1999-05-27 05:35:08 +00:00
|
|
|
char *np = name;
|
|
|
|
int len = -1;
|
2000-04-12 06:59:28 +00:00
|
|
|
int chars_processed = 0;
|
2001-07-02 07:11:40 +00:00
|
|
|
int data_size = tvb_reported_length_remaining(tvb, dns_data_offset);
|
2001-06-18 01:49:17 +00:00
|
|
|
int component_len;
|
2001-07-02 07:11:40 +00:00
|
|
|
int indir_offset;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2002-05-11 18:46:38 +00:00
|
|
|
const int min_len = 1; /* Minimum length of encoded name (for root) */
|
|
|
|
/* If we're about to return a value (probably negative) which is less
|
|
|
|
* than the minimum length, we're looking at bad data and we're liable
|
|
|
|
* to put the dissector into a loop. Instead we throw an exception */
|
|
|
|
|
1999-05-27 05:35:08 +00:00
|
|
|
maxname--; /* reserve space for the trailing '\0' */
|
1999-10-07 07:44:29 +00:00
|
|
|
for (;;) {
|
2001-07-02 07:11:40 +00:00
|
|
|
component_len = tvb_get_guint8(tvb, offset);
|
1999-10-07 07:44:29 +00:00
|
|
|
offset++;
|
|
|
|
if (component_len == 0)
|
|
|
|
break;
|
2000-04-12 06:59:28 +00:00
|
|
|
chars_processed++;
|
1999-05-27 05:35:08 +00:00
|
|
|
switch (component_len & 0xc0) {
|
|
|
|
|
|
|
|
case 0x00:
|
|
|
|
/* Label */
|
|
|
|
if (np != name) {
|
|
|
|
/* Not the first component - put in a '.'. */
|
|
|
|
if (maxname > 0) {
|
|
|
|
*np++ = '.';
|
|
|
|
maxname--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (component_len > 0) {
|
|
|
|
if (maxname > 0) {
|
2001-07-02 07:11:40 +00:00
|
|
|
*np++ = tvb_get_guint8(tvb, offset);
|
1999-05-27 05:35:08 +00:00
|
|
|
maxname--;
|
|
|
|
}
|
|
|
|
component_len--;
|
1999-10-07 07:44:29 +00:00
|
|
|
offset++;
|
2000-04-12 06:59:28 +00:00
|
|
|
chars_processed++;
|
1999-05-27 05:35:08 +00:00
|
|
|
}
|
|
|
|
break;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1999-05-27 05:35:08 +00:00
|
|
|
case 0x40:
|
2000-10-02 17:42:38 +00:00
|
|
|
/* Extended label (RFC 2673) */
|
|
|
|
switch (component_len & 0x3f) {
|
|
|
|
|
|
|
|
case 0x01:
|
|
|
|
/* Bitstring label */
|
|
|
|
{
|
|
|
|
int bit_count;
|
|
|
|
int label_len;
|
2002-06-15 20:38:34 +00:00
|
|
|
int print_len;
|
2000-10-02 17:42:38 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
bit_count = tvb_get_guint8(tvb, offset);
|
|
|
|
offset++;
|
2000-10-02 17:42:38 +00:00
|
|
|
label_len = (bit_count - 1) / 8 + 1;
|
|
|
|
|
2002-06-15 20:38:34 +00:00
|
|
|
if (maxname > 0) {
|
|
|
|
print_len = snprintf(np, maxname + 1, "\\[x");
|
|
|
|
if (print_len != -1) {
|
|
|
|
/* Some versions of snprintf return -1 if they'd truncate
|
|
|
|
the output. */
|
|
|
|
np += print_len;
|
|
|
|
maxname -= print_len;
|
|
|
|
} else {
|
|
|
|
/* Nothing printed, as there's no room.
|
|
|
|
Suppress all subsequent printing. */
|
|
|
|
maxname = 0;
|
|
|
|
}
|
|
|
|
}
|
2000-10-02 17:42:38 +00:00
|
|
|
while(label_len--) {
|
2002-06-15 20:38:34 +00:00
|
|
|
if (maxname > 0) {
|
|
|
|
print_len = snprintf(np, maxname + 1, "%02x",
|
|
|
|
tvb_get_guint8(tvb, offset));
|
|
|
|
if (print_len != -1) {
|
|
|
|
/* Some versions of snprintf return -1 if they'd truncate
|
|
|
|
the output. */
|
|
|
|
np += print_len;
|
|
|
|
maxname -= print_len;
|
|
|
|
} else {
|
|
|
|
/* Nothing printed, as there's no room.
|
|
|
|
Suppress all subsequent printing. */
|
|
|
|
maxname = 0;
|
|
|
|
}
|
|
|
|
}
|
2001-07-02 07:11:40 +00:00
|
|
|
offset++;
|
2000-10-02 17:42:38 +00:00
|
|
|
}
|
2002-06-15 20:38:34 +00:00
|
|
|
if (maxname > 0) {
|
|
|
|
print_len = snprintf(np, maxname + 1, "/%d]", bit_count);
|
|
|
|
if (print_len != -1) {
|
|
|
|
/* Some versions of snprintf return -1 if they'd truncate
|
|
|
|
the output. */
|
|
|
|
np += print_len;
|
|
|
|
maxname -= print_len;
|
|
|
|
} else {
|
|
|
|
/* Nothing printed, as there's no room.
|
|
|
|
Suppress all subsequent printing. */
|
|
|
|
maxname = 0;
|
|
|
|
}
|
|
|
|
}
|
2000-10-02 17:42:38 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
strcpy(name, "<Unknown extended label>");
|
|
|
|
/* Parsing will propably fail from here on, since the */
|
|
|
|
/* label length is unknown... */
|
2002-05-11 18:46:38 +00:00
|
|
|
len = offset - start_offset;
|
|
|
|
if (len < min_len)
|
|
|
|
THROW(ReportedBoundsError);
|
|
|
|
return len;
|
2000-10-02 17:42:38 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
1999-05-27 05:35:08 +00:00
|
|
|
case 0x80:
|
2002-05-11 18:46:38 +00:00
|
|
|
THROW(ReportedBoundsError);
|
1999-05-27 05:35:08 +00:00
|
|
|
|
|
|
|
case 0xc0:
|
|
|
|
/* Pointer. */
|
2001-07-02 07:11:40 +00:00
|
|
|
indir_offset = dns_data_offset +
|
|
|
|
(((component_len & ~0xc0) << 8) | tvb_get_guint8(tvb, offset));
|
|
|
|
offset++;
|
2000-04-12 06:59:28 +00:00
|
|
|
chars_processed++;
|
|
|
|
|
1999-05-27 05:35:08 +00:00
|
|
|
/* If "len" is negative, we are still working on the original name,
|
|
|
|
not something pointed to by a pointer, and so we should set "len"
|
|
|
|
to the length of the original name. */
|
|
|
|
if (len < 0)
|
2001-07-02 07:11:40 +00:00
|
|
|
len = offset - start_offset;
|
2000-04-12 06:59:28 +00:00
|
|
|
|
|
|
|
/* If we've looked at every character in the message, this pointer
|
|
|
|
will make us look at some character again, which means we're
|
|
|
|
looping. */
|
|
|
|
if (chars_processed >= data_size) {
|
|
|
|
strcpy(name, "<Name contains a pointer that loops>");
|
2002-05-11 18:46:38 +00:00
|
|
|
if (len < min_len)
|
|
|
|
THROW(ReportedBoundsError);
|
2000-04-12 06:59:28 +00:00
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
offset = indir_offset;
|
1999-05-27 05:35:08 +00:00
|
|
|
break; /* now continue processing from there */
|
|
|
|
}
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
1999-05-27 05:35:08 +00:00
|
|
|
|
|
|
|
*np = '\0';
|
|
|
|
/* If "len" is negative, we haven't seen a pointer, and thus haven't
|
|
|
|
set the length, so set it. */
|
|
|
|
if (len < 0)
|
2001-07-02 07:11:40 +00:00
|
|
|
len = offset - start_offset;
|
1999-05-27 05:35:08 +00:00
|
|
|
/* Zero-length name means "root server" */
|
|
|
|
if (*name == '\0')
|
|
|
|
strcpy(name, "<Root>");
|
2002-05-11 18:46:38 +00:00
|
|
|
if (len < min_len)
|
|
|
|
THROW(ReportedBoundsError);
|
1998-09-16 02:39:15 +00:00
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2001-07-02 07:11:40 +00:00
|
|
|
get_dns_name_type_class(tvbuff_t *tvb, int offset, int dns_data_offset,
|
1999-10-07 07:44:29 +00:00
|
|
|
char *name_ret, int *name_len_ret, int *type_ret, int *class_ret)
|
1998-09-16 02:39:15 +00:00
|
|
|
{
|
|
|
|
int len;
|
|
|
|
int name_len;
|
|
|
|
int type;
|
|
|
|
int class;
|
|
|
|
char name[MAXDNAME];
|
1999-10-07 07:44:29 +00:00
|
|
|
int start_offset = offset;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
name_len = get_dns_name(tvb, offset, dns_data_offset, name, sizeof(name));
|
1999-10-07 09:21:38 +00:00
|
|
|
offset += name_len;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
type = tvb_get_ntohs(tvb, offset);
|
1999-10-07 07:44:29 +00:00
|
|
|
offset += 2;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
class = tvb_get_ntohs(tvb, offset);
|
1999-10-07 07:44:29 +00:00
|
|
|
offset += 2;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
strcpy (name_ret, name);
|
|
|
|
*type_ret = type;
|
|
|
|
*class_ret = class;
|
1998-10-14 19:35:00 +00:00
|
|
|
*name_len_ret = name_len;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1999-10-07 07:44:29 +00:00
|
|
|
len = offset - start_offset;
|
1998-09-16 02:39:15 +00:00
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
1999-09-21 07:15:38 +00:00
|
|
|
static double
|
2001-07-02 07:11:40 +00:00
|
|
|
rfc1867_size(tvbuff_t *tvb, int offset)
|
1999-09-21 07:15:38 +00:00
|
|
|
{
|
2001-07-02 07:11:40 +00:00
|
|
|
guint8 val;
|
1999-09-21 07:15:38 +00:00
|
|
|
double size;
|
|
|
|
guint32 exponent;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
val = tvb_get_guint8(tvb, offset);
|
1999-10-07 07:44:29 +00:00
|
|
|
size = (val & 0xF0) >> 4;
|
|
|
|
exponent = (val & 0x0F);
|
1999-09-21 07:15:38 +00:00
|
|
|
while (exponent != 0) {
|
|
|
|
size *= 10;
|
|
|
|
exponent--;
|
|
|
|
}
|
|
|
|
return size / 100; /* return size in meters, not cm */
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
2001-07-02 07:11:40 +00:00
|
|
|
rfc1867_angle(tvbuff_t *tvb, int offset, const char *nsew)
|
1999-09-21 07:15:38 +00:00
|
|
|
{
|
|
|
|
guint32 angle;
|
|
|
|
char direction;
|
|
|
|
guint32 degrees, minutes, secs, tsecs;
|
|
|
|
static char buf[10+1+3+1 + 2+1+3+1 + 2+1+3+1+3+1 + 1 + 1];
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
angle = tvb_get_ntohl(tvb, offset);
|
1999-09-21 07:15:38 +00:00
|
|
|
|
|
|
|
if (angle < 0x80000000U) {
|
|
|
|
angle = 0x80000000U - angle;
|
|
|
|
direction = nsew[1];
|
|
|
|
} else {
|
|
|
|
angle = angle - 0x80000000U;
|
|
|
|
direction = nsew[0];
|
|
|
|
}
|
|
|
|
tsecs = angle % 1000;
|
|
|
|
angle = angle / 1000;
|
|
|
|
secs = angle % 60;
|
|
|
|
angle = angle / 60;
|
|
|
|
minutes = angle % 60;
|
|
|
|
degrees = angle / 60;
|
|
|
|
sprintf(buf, "%u deg %u min %u.%03u sec %c", degrees, minutes, secs,
|
|
|
|
tsecs, direction);
|
|
|
|
return buf;
|
|
|
|
}
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
static int
|
2001-07-02 07:11:40 +00:00
|
|
|
dissect_dns_query(tvbuff_t *tvb, int offset, int dns_data_offset,
|
2001-12-10 00:26:21 +00:00
|
|
|
column_info *cinfo, proto_tree *dns_tree)
|
1998-09-16 02:39:15 +00:00
|
|
|
{
|
|
|
|
int len;
|
|
|
|
char name[MAXDNAME];
|
1998-10-14 19:35:00 +00:00
|
|
|
int name_len;
|
1998-09-16 02:39:15 +00:00
|
|
|
int type;
|
|
|
|
int class;
|
|
|
|
char *class_name;
|
|
|
|
char *type_name;
|
1999-03-22 23:31:05 +00:00
|
|
|
char *long_type_name;
|
2001-07-02 07:11:40 +00:00
|
|
|
int data_offset;
|
|
|
|
int data_start;
|
1999-03-23 03:14:46 +00:00
|
|
|
proto_tree *q_tree;
|
|
|
|
proto_item *tq;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
data_start = data_offset = offset;
|
1998-10-14 19:35:00 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
len = get_dns_name_type_class(tvb, offset, dns_data_offset, name, &name_len,
|
1998-10-14 19:35:00 +00:00
|
|
|
&type, &class);
|
2001-07-02 07:11:40 +00:00
|
|
|
data_offset += len;
|
1999-10-07 02:26:45 +00:00
|
|
|
|
1998-10-15 06:40:51 +00:00
|
|
|
type_name = dns_type_name(type);
|
|
|
|
class_name = dns_class_name(class);
|
1999-03-22 23:31:05 +00:00
|
|
|
long_type_name = dns_long_type_name(type);
|
1998-10-15 06:40:51 +00:00
|
|
|
|
2001-12-10 00:26:21 +00:00
|
|
|
if (cinfo != NULL)
|
|
|
|
col_append_fstr(cinfo, COL_INFO, " %s %s", type_name, name);
|
1999-11-07 21:00:40 +00:00
|
|
|
if (dns_tree != NULL) {
|
2001-07-02 07:11:40 +00:00
|
|
|
tq = proto_tree_add_text(dns_tree, tvb, offset, len, "%s: type %s, class %s",
|
1998-10-15 06:40:51 +00:00
|
|
|
name, type_name, class_name);
|
1999-11-16 11:44:20 +00:00
|
|
|
q_tree = proto_item_add_subtree(tq, ett_dns_qd);
|
1998-10-15 06:40:51 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(q_tree, tvb, offset, name_len, "Name: %s", name);
|
1999-11-07 21:00:40 +00:00
|
|
|
offset += name_len;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(q_tree, tvb, offset, 2, "Type: %s", long_type_name);
|
1999-11-07 21:00:40 +00:00
|
|
|
offset += 2;
|
1998-10-14 19:35:00 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(q_tree, tvb, offset, 2, "Class: %s", class_name);
|
1999-11-07 21:00:40 +00:00
|
|
|
offset += 2;
|
|
|
|
}
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
return data_offset - data_start;
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-03-23 03:14:46 +00:00
|
|
|
proto_tree *
|
2001-07-02 07:11:40 +00:00
|
|
|
add_rr_to_tree(proto_item *trr, int rr_type, tvbuff_t *tvb, int offset,
|
|
|
|
const char *name, int namelen, const char *type_name, const char *class_name,
|
2002-08-02 23:36:07 +00:00
|
|
|
guint ttl, gushort data_len)
|
1998-10-14 19:35:00 +00:00
|
|
|
{
|
1999-03-23 03:14:46 +00:00
|
|
|
proto_tree *rr_tree;
|
1998-10-14 19:35:00 +00:00
|
|
|
|
1999-07-07 22:52:57 +00:00
|
|
|
rr_tree = proto_item_add_subtree(trr, rr_type);
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, offset, namelen, "Name: %s", name);
|
1998-10-14 19:35:00 +00:00
|
|
|
offset += namelen;
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, offset, 2, "Type: %s", type_name);
|
1998-10-14 19:35:00 +00:00
|
|
|
offset += 2;
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, offset, 2, "Class: %s", class_name);
|
1998-10-14 19:35:00 +00:00
|
|
|
offset += 2;
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, offset, 4, "Time to live: %s",
|
1999-01-28 21:29:36 +00:00
|
|
|
time_secs_to_str(ttl));
|
1998-10-14 19:35:00 +00:00
|
|
|
offset += 4;
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, offset, 2, "Data length: %u", data_len);
|
1998-10-14 19:35:00 +00:00
|
|
|
return rr_tree;
|
|
|
|
}
|
|
|
|
|
2000-03-30 01:52:40 +00:00
|
|
|
static proto_tree *
|
2001-07-02 07:11:40 +00:00
|
|
|
add_opt_rr_to_tree(proto_item *trr, int rr_type, tvbuff_t *tvb, int offset,
|
|
|
|
const char *name, int namelen, const char *type_name, int class,
|
2002-08-02 23:36:07 +00:00
|
|
|
guint ttl, gushort data_len)
|
2000-03-30 01:33:10 +00:00
|
|
|
{
|
|
|
|
proto_tree *rr_tree;
|
|
|
|
|
|
|
|
rr_tree = proto_item_add_subtree(trr, rr_type);
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, offset, namelen, "Name: %s", name);
|
2000-03-30 01:33:10 +00:00
|
|
|
offset += namelen;
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, offset, 2, "Type: %s", type_name);
|
2000-03-30 01:33:10 +00:00
|
|
|
offset += 2;
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, offset, 2, "UDP payload size: %u",
|
2000-03-30 01:33:10 +00:00
|
|
|
class & 0xffff);
|
|
|
|
offset += 2;
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, offset, 1, "Higher bits in extended RCODE: 0x%x",
|
2000-03-30 01:33:10 +00:00
|
|
|
(ttl >> 24) & 0xff0);
|
|
|
|
offset++;
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, offset, 1, "EDNS0 version: %u",
|
2000-03-30 01:33:10 +00:00
|
|
|
(ttl >> 16) & 0xff);
|
|
|
|
offset++;
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, offset, 2, "Must be zero: 0x%x", ttl & 0xffff);
|
2000-03-30 01:33:10 +00:00
|
|
|
offset += 2;
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, offset, 2, "Data length: %u", data_len);
|
2000-03-30 01:33:10 +00:00
|
|
|
return rr_tree;
|
|
|
|
}
|
|
|
|
|
1999-11-27 08:59:28 +00:00
|
|
|
/*
|
2000-10-11 04:12:06 +00:00
|
|
|
* SIG, KEY, and CERT RR algorithms.
|
1999-11-27 08:59:28 +00:00
|
|
|
*/
|
2000-07-18 16:53:51 +00:00
|
|
|
#define DNS_ALGO_RSAMD5 1 /* RSA/MD5 */
|
|
|
|
#define DNS_ALGO_DH 2 /* Diffie-Hellman */
|
|
|
|
#define DNS_ALGO_DSA 3 /* DSA */
|
|
|
|
#define DNS_ALGO_ECC 4 /* Elliptic curve crypto */
|
|
|
|
#define DNS_ALGO_INDIRECT 252 /* Indirect key */
|
|
|
|
#define DNS_ALGO_PRIVATEDNS 253 /* Private, domain name */
|
|
|
|
#define DNS_ALGO_PRIVATEOID 254 /* Private, OID */
|
1999-11-27 08:59:28 +00:00
|
|
|
|
|
|
|
static const value_string algo_vals[] = {
|
2000-07-18 16:53:51 +00:00
|
|
|
{ DNS_ALGO_RSAMD5, "RSA/MD5" },
|
|
|
|
{ DNS_ALGO_DH, "Diffie-Hellman" },
|
|
|
|
{ DNS_ALGO_DSA, "DSA" },
|
|
|
|
{ DNS_ALGO_ECC, "Elliptic curve crypto" },
|
|
|
|
{ DNS_ALGO_INDIRECT, "Indirect key" },
|
|
|
|
{ DNS_ALGO_PRIVATEDNS, "Private, domain name" },
|
|
|
|
{ DNS_ALGO_PRIVATEOID, "Private, OID" },
|
|
|
|
{ 0, NULL }
|
1999-11-27 08:59:28 +00:00
|
|
|
};
|
|
|
|
|
2000-10-11 04:12:06 +00:00
|
|
|
#define DNS_CERT_PGP 1 /* PGP */
|
|
|
|
#define DNS_CERT_PKIX 2 /* PKIX */
|
|
|
|
#define DNS_CERT_SPKI 3 /* SPKI */
|
|
|
|
#define DNS_CERT_PRIVATEURI 253 /* Private, URI */
|
|
|
|
#define DNS_CERT_PRIVATEOID 254 /* Private, OID */
|
|
|
|
|
|
|
|
static const value_string cert_vals[] = {
|
|
|
|
{ DNS_CERT_PGP, "PGP" },
|
|
|
|
{ DNS_CERT_PKIX, "PKIX" },
|
|
|
|
{ DNS_CERT_SPKI, "SPKI" },
|
|
|
|
{ DNS_CERT_PRIVATEURI, "Private, URI" },
|
|
|
|
{ DNS_CERT_PRIVATEOID, "Private, OID" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
static int
|
2001-07-02 07:11:40 +00:00
|
|
|
dissect_dns_answer(tvbuff_t *tvb, int offset, int dns_data_offset,
|
2001-12-10 00:26:21 +00:00
|
|
|
column_info *cinfo, proto_tree *dns_tree)
|
1998-09-16 02:39:15 +00:00
|
|
|
{
|
|
|
|
int len;
|
|
|
|
char name[MAXDNAME];
|
1998-10-14 19:35:00 +00:00
|
|
|
int name_len;
|
1998-09-16 02:39:15 +00:00
|
|
|
int type;
|
|
|
|
int class;
|
|
|
|
char *class_name;
|
|
|
|
char *type_name;
|
1999-03-22 23:31:05 +00:00
|
|
|
char *long_type_name;
|
2001-07-02 07:11:40 +00:00
|
|
|
int data_offset;
|
1999-10-07 07:44:29 +00:00
|
|
|
int cur_offset;
|
2001-07-02 07:11:40 +00:00
|
|
|
int data_start;
|
2002-08-02 23:36:07 +00:00
|
|
|
guint ttl;
|
|
|
|
gushort data_len;
|
2000-03-07 05:57:13 +00:00
|
|
|
proto_tree *rr_tree = NULL;
|
|
|
|
proto_item *trr = NULL;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
data_start = data_offset = offset;
|
1999-10-07 07:44:29 +00:00
|
|
|
cur_offset = offset;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
len = get_dns_name_type_class(tvb, offset, dns_data_offset, name, &name_len,
|
1998-10-14 19:35:00 +00:00
|
|
|
&type, &class);
|
2001-07-02 07:11:40 +00:00
|
|
|
data_offset += len;
|
1999-10-07 07:44:29 +00:00
|
|
|
cur_offset += len;
|
1999-10-07 02:26:45 +00:00
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
type_name = dns_type_name(type);
|
|
|
|
class_name = dns_class_name(class);
|
1999-03-22 23:31:05 +00:00
|
|
|
long_type_name = dns_long_type_name(type);
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
ttl = tvb_get_ntohl(tvb, data_offset);
|
|
|
|
data_offset += 4;
|
1999-10-07 07:44:29 +00:00
|
|
|
cur_offset += 4;
|
1998-10-14 19:35:00 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
data_len = tvb_get_ntohs(tvb, data_offset);
|
|
|
|
data_offset += 2;
|
1999-10-07 07:44:29 +00:00
|
|
|
cur_offset += 2;
|
1998-10-14 19:35:00 +00:00
|
|
|
|
2001-12-10 00:26:21 +00:00
|
|
|
if (cinfo != NULL)
|
|
|
|
col_append_fstr(cinfo, COL_INFO, " %s", type_name);
|
2000-03-21 06:21:37 +00:00
|
|
|
if (dns_tree != NULL) {
|
Get rid of "proto_tree_add_notext()" - if you create a subtree using it,
but, before you set the text, you throw an exception while putting stuff
under the subtree, you end up with an absolutely blank protocol tree
item, which is really gross. Instead of calling
"proto_tree_add_notext()", call "proto_tree_add_text()" with at least a
minimal label - yes, it does mean you do some work that will probably be
unnecessary, but, absent a scheme to arrange to do that work if it *is*
necessary (e.g., catching exceptions), the alternative is an ugly
protocol tree display.
svn path=/trunk/; revision=3879
2001-08-28 08:28:19 +00:00
|
|
|
trr = proto_tree_add_text(dns_tree, tvb, offset,
|
|
|
|
(data_offset - data_start) + data_len,
|
|
|
|
"%s: type %s, class %s",
|
|
|
|
name, type_name, class_name);
|
2000-03-30 01:33:10 +00:00
|
|
|
if (type != T_OPT) {
|
2001-07-02 07:11:40 +00:00
|
|
|
rr_tree = add_rr_to_tree(trr, ett_dns_rr, tvb, offset, name, name_len,
|
2000-03-21 06:21:37 +00:00
|
|
|
long_type_name, class_name, ttl, data_len);
|
2000-03-30 01:33:10 +00:00
|
|
|
} else {
|
2001-07-02 07:11:40 +00:00
|
|
|
rr_tree = add_opt_rr_to_tree(trr, ett_dns_rr, tvb, offset, name, name_len,
|
2000-03-30 01:33:10 +00:00
|
|
|
long_type_name, class, ttl, data_len);
|
|
|
|
}
|
2000-03-21 06:21:37 +00:00
|
|
|
}
|
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
switch (type) {
|
2000-03-21 06:21:37 +00:00
|
|
|
|
1999-05-27 05:35:08 +00:00
|
|
|
case T_A:
|
2001-07-02 07:11:40 +00:00
|
|
|
{
|
|
|
|
const guint8 *addr;
|
|
|
|
guint32 addr_int;
|
|
|
|
|
|
|
|
addr = tvb_get_ptr(tvb, cur_offset, 4);
|
2001-12-10 00:26:21 +00:00
|
|
|
if (cinfo != NULL)
|
|
|
|
col_append_fstr(cinfo, COL_INFO, " %s", ip_to_str(addr));
|
2000-03-21 06:21:37 +00:00
|
|
|
if (dns_tree != NULL) {
|
2001-08-29 00:51:10 +00:00
|
|
|
proto_item_append_text(trr, ", addr %s", ip_to_str(addr));
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Addr: %s",
|
|
|
|
ip_to_str(addr));
|
|
|
|
}
|
|
|
|
if (class == C_IN) {
|
|
|
|
memcpy(&addr_int, addr, sizeof(addr_int));
|
|
|
|
add_host_name(addr_int, name);
|
|
|
|
}
|
2000-08-08 16:21:24 +00:00
|
|
|
}
|
1998-09-16 02:39:15 +00:00
|
|
|
break;
|
|
|
|
|
1999-05-27 05:35:08 +00:00
|
|
|
case T_NS:
|
1998-09-16 02:39:15 +00:00
|
|
|
{
|
|
|
|
char ns_name[MAXDNAME];
|
1998-10-14 19:35:00 +00:00
|
|
|
int ns_name_len;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
ns_name_len = get_dns_name(tvb, cur_offset, dns_data_offset, ns_name, sizeof(ns_name));
|
2001-12-10 00:26:21 +00:00
|
|
|
if (cinfo != NULL)
|
|
|
|
col_append_fstr(cinfo, COL_INFO, " %s", ns_name);
|
1999-11-07 21:00:40 +00:00
|
|
|
if (dns_tree != NULL) {
|
2001-08-29 00:51:10 +00:00
|
|
|
proto_item_append_text(trr, ", ns %s", ns_name);
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, ns_name_len, "Name server: %s",
|
1999-10-07 07:44:29 +00:00
|
|
|
ns_name);
|
1999-11-07 21:00:40 +00:00
|
|
|
}
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
1999-05-27 05:35:08 +00:00
|
|
|
case T_CNAME:
|
1999-03-22 23:31:05 +00:00
|
|
|
{
|
|
|
|
char cname[MAXDNAME];
|
|
|
|
int cname_len;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
cname_len = get_dns_name(tvb, cur_offset, dns_data_offset, cname, sizeof(cname));
|
2001-12-10 00:26:21 +00:00
|
|
|
if (cinfo != NULL)
|
|
|
|
col_append_fstr(cinfo, COL_INFO, " %s", cname);
|
1999-11-07 21:00:40 +00:00
|
|
|
if (dns_tree != NULL) {
|
2001-08-29 00:51:10 +00:00
|
|
|
proto_item_append_text(trr, ", cname %s", cname);
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, cname_len, "Primary name: %s",
|
1999-10-07 07:44:29 +00:00
|
|
|
cname);
|
1999-11-07 21:00:40 +00:00
|
|
|
}
|
1999-05-27 05:35:08 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case T_SOA:
|
|
|
|
{
|
|
|
|
char mname[MAXDNAME];
|
|
|
|
int mname_len;
|
|
|
|
char rname[MAXDNAME];
|
|
|
|
int rname_len;
|
|
|
|
guint32 serial;
|
|
|
|
guint32 refresh;
|
|
|
|
guint32 retry;
|
|
|
|
guint32 expire;
|
|
|
|
guint32 minimum;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
mname_len = get_dns_name(tvb, cur_offset, dns_data_offset, mname, sizeof(mname));
|
2001-12-10 00:26:21 +00:00
|
|
|
if (cinfo != NULL)
|
|
|
|
col_append_fstr(cinfo, COL_INFO, " %s", mname);
|
1999-11-07 21:00:40 +00:00
|
|
|
if (dns_tree != NULL) {
|
2001-08-29 00:51:10 +00:00
|
|
|
proto_item_append_text(trr, ", mname %s", mname);
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, mname_len, "Primary name server: %s",
|
1999-11-07 21:00:40 +00:00
|
|
|
mname);
|
|
|
|
cur_offset += mname_len;
|
1999-10-07 07:44:29 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
rname_len = get_dns_name(tvb, cur_offset, dns_data_offset, rname, sizeof(rname));
|
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, rname_len, "Responsible authority's mailbox: %s",
|
1999-11-07 21:00:40 +00:00
|
|
|
rname);
|
|
|
|
cur_offset += rname_len;
|
1999-10-07 07:44:29 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
serial = tvb_get_ntohl(tvb, cur_offset);
|
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Serial number: %u",
|
1999-11-07 21:00:40 +00:00
|
|
|
serial);
|
|
|
|
cur_offset += 4;
|
1999-10-07 07:44:29 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
refresh = tvb_get_ntohl(tvb, cur_offset);
|
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Refresh interval: %s",
|
1999-11-07 21:00:40 +00:00
|
|
|
time_secs_to_str(refresh));
|
|
|
|
cur_offset += 4;
|
1999-10-07 07:44:29 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
retry = tvb_get_ntohl(tvb, cur_offset);
|
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Retry interval: %s",
|
1999-11-07 21:00:40 +00:00
|
|
|
time_secs_to_str(retry));
|
|
|
|
cur_offset += 4;
|
1999-10-07 07:44:29 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
expire = tvb_get_ntohl(tvb, cur_offset);
|
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Expiration limit: %s",
|
1999-11-07 21:00:40 +00:00
|
|
|
time_secs_to_str(expire));
|
|
|
|
cur_offset += 4;
|
1999-10-07 07:44:29 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
minimum = tvb_get_ntohl(tvb, cur_offset);
|
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Minimum TTL: %s",
|
1999-11-07 21:00:40 +00:00
|
|
|
time_secs_to_str(minimum));
|
1999-10-07 07:44:29 +00:00
|
|
|
}
|
1999-03-22 23:31:05 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
1999-05-27 05:35:08 +00:00
|
|
|
case T_PTR:
|
1999-03-22 23:31:05 +00:00
|
|
|
{
|
|
|
|
char pname[MAXDNAME];
|
|
|
|
int pname_len;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
pname_len = get_dns_name(tvb, cur_offset, dns_data_offset, pname, sizeof(pname));
|
2001-12-10 00:26:21 +00:00
|
|
|
if (cinfo != NULL)
|
|
|
|
col_append_fstr(cinfo, COL_INFO, " %s", pname);
|
1999-11-07 21:00:40 +00:00
|
|
|
if (dns_tree != NULL) {
|
2001-08-29 00:51:10 +00:00
|
|
|
proto_item_append_text(trr, ", ptr %s", pname);
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, pname_len, "Domain name: %s",
|
1999-10-07 07:44:29 +00:00
|
|
|
pname);
|
1999-11-07 21:00:40 +00:00
|
|
|
}
|
1999-03-22 23:31:05 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
1999-09-21 07:15:38 +00:00
|
|
|
|
2000-03-21 05:15:12 +00:00
|
|
|
case T_WKS:
|
|
|
|
{
|
|
|
|
int rr_len = data_len;
|
2001-07-02 07:11:40 +00:00
|
|
|
const guint8 *wks_addr;
|
2000-03-21 05:15:12 +00:00
|
|
|
guint8 protocol;
|
|
|
|
guint8 bits;
|
2000-03-21 06:21:37 +00:00
|
|
|
int mask;
|
2000-03-21 05:15:12 +00:00
|
|
|
int port_num;
|
|
|
|
int i;
|
|
|
|
char bitnames[128+1];
|
|
|
|
char portnumstring[10+1];
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
wks_addr = tvb_get_ptr(tvb, cur_offset, 4);
|
2001-12-10 00:26:21 +00:00
|
|
|
if (cinfo != NULL)
|
|
|
|
col_append_fstr(cinfo, COL_INFO, " %s", ip_to_str(wks_addr));
|
2000-03-21 05:15:12 +00:00
|
|
|
if (dns_tree != NULL) {
|
2001-08-29 00:51:10 +00:00
|
|
|
proto_item_append_text(trr, ", addr %s", ip_to_str(wks_addr));
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Addr: %s",
|
|
|
|
ip_to_str(wks_addr));
|
2000-03-21 05:15:12 +00:00
|
|
|
cur_offset += 4;
|
|
|
|
rr_len -= 4;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
protocol = tvb_get_guint8(tvb, cur_offset);
|
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Protocol: %s",
|
2000-03-21 05:15:12 +00:00
|
|
|
ipprotostr(protocol));
|
|
|
|
cur_offset += 1;
|
|
|
|
rr_len -= 1;
|
|
|
|
|
|
|
|
port_num = 0;
|
|
|
|
while (rr_len != 0) {
|
2001-07-02 07:11:40 +00:00
|
|
|
bits = tvb_get_guint8(tvb, cur_offset);
|
2000-03-21 05:15:12 +00:00
|
|
|
if (bits != 0) {
|
2000-03-21 06:21:37 +00:00
|
|
|
mask = 1<<7;
|
2000-03-21 05:15:12 +00:00
|
|
|
bitnames[0] = '\0';
|
2000-03-21 06:21:37 +00:00
|
|
|
for (i = 0; i < 8; i++) {
|
|
|
|
if (bits & mask) {
|
2000-03-21 05:15:12 +00:00
|
|
|
if (bitnames[0] != '\0')
|
|
|
|
strcat(bitnames, ", ");
|
|
|
|
switch (protocol) {
|
|
|
|
|
|
|
|
case IP_PROTO_TCP:
|
|
|
|
strcat(bitnames, get_tcp_port(port_num));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IP_PROTO_UDP:
|
|
|
|
strcat(bitnames, get_udp_port(port_num));
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
sprintf(portnumstring, "%u", port_num);
|
|
|
|
strcat(bitnames, portnumstring);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2000-03-21 06:21:37 +00:00
|
|
|
mask >>= 1;
|
2000-03-21 05:15:12 +00:00
|
|
|
port_num++;
|
|
|
|
}
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 1,
|
2000-03-21 05:15:12 +00:00
|
|
|
"Bits: 0x%02x (%s)", bits, bitnames);
|
|
|
|
} else
|
|
|
|
port_num += 8;
|
|
|
|
cur_offset += 1;
|
|
|
|
rr_len -= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
1999-11-12 22:43:32 +00:00
|
|
|
case T_HINFO:
|
|
|
|
{
|
|
|
|
int cpu_offset;
|
|
|
|
int cpu_len;
|
2001-07-02 07:11:40 +00:00
|
|
|
const guint8 *cpu;
|
1999-11-12 22:43:32 +00:00
|
|
|
int os_offset;
|
|
|
|
int os_len;
|
2001-07-02 07:11:40 +00:00
|
|
|
const guint8 *os;
|
1999-11-12 22:43:32 +00:00
|
|
|
|
|
|
|
cpu_offset = cur_offset;
|
2001-07-02 07:11:40 +00:00
|
|
|
cpu_len = tvb_get_guint8(tvb, cpu_offset);
|
|
|
|
cpu = tvb_get_ptr(tvb, cpu_offset + 1, cpu_len);
|
1999-11-12 22:43:32 +00:00
|
|
|
os_offset = cpu_offset + 1 + cpu_len;
|
2001-07-02 07:11:40 +00:00
|
|
|
os_len = tvb_get_guint8(tvb, os_offset);
|
|
|
|
os = tvb_get_ptr(tvb, os_offset + 1, os_len);
|
2001-12-10 00:26:21 +00:00
|
|
|
if (cinfo != NULL)
|
|
|
|
col_append_fstr(cinfo, COL_INFO, " %.*s %.*s", cpu_len, cpu,
|
2001-07-02 07:11:40 +00:00
|
|
|
os_len, os);
|
1999-11-12 22:43:32 +00:00
|
|
|
if (dns_tree != NULL) {
|
2001-08-29 00:51:10 +00:00
|
|
|
proto_item_append_text(trr, ", CPU %.*s, OS %.*s",
|
2001-07-02 07:11:40 +00:00
|
|
|
cpu_len, cpu, os_len, os);
|
|
|
|
proto_tree_add_text(rr_tree, tvb, cpu_offset, 1 + cpu_len, "CPU: %.*s",
|
|
|
|
cpu_len, cpu);
|
|
|
|
proto_tree_add_text(rr_tree, tvb, os_offset, 1 + os_len, "OS: %.*s",
|
|
|
|
os_len, os);
|
1999-11-12 22:43:32 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
1999-09-21 07:15:38 +00:00
|
|
|
case T_MX:
|
|
|
|
{
|
1999-10-07 07:44:29 +00:00
|
|
|
guint16 preference = 0;
|
1999-09-21 07:15:38 +00:00
|
|
|
char mx_name[MAXDNAME];
|
|
|
|
int mx_name_len;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
preference = tvb_get_ntohs(tvb, cur_offset);
|
|
|
|
mx_name_len = get_dns_name(tvb, cur_offset + 2, dns_data_offset, mx_name, sizeof(mx_name));
|
2001-12-10 00:26:21 +00:00
|
|
|
if (cinfo != NULL)
|
|
|
|
col_append_fstr(cinfo, COL_INFO, " %u %s", preference, mx_name);
|
1999-11-07 21:00:40 +00:00
|
|
|
if (dns_tree != NULL) {
|
2001-08-29 00:51:10 +00:00
|
|
|
proto_item_append_text(trr, ", preference %u, mx %s",
|
|
|
|
preference, mx_name);
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 2, "Preference: %u", preference);
|
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset + 2, mx_name_len, "Mail exchange: %s",
|
1999-10-07 07:44:29 +00:00
|
|
|
mx_name);
|
1999-11-07 21:00:40 +00:00
|
|
|
}
|
1999-09-21 07:15:38 +00:00
|
|
|
}
|
|
|
|
break;
|
1999-11-27 07:46:44 +00:00
|
|
|
|
2000-03-21 05:15:12 +00:00
|
|
|
case T_TXT:
|
|
|
|
{
|
|
|
|
int rr_len = data_len;
|
|
|
|
int txt_offset;
|
|
|
|
int txt_len;
|
|
|
|
|
|
|
|
if (dns_tree != NULL) {
|
2000-03-21 06:21:37 +00:00
|
|
|
txt_offset = cur_offset;
|
|
|
|
while (rr_len != 0) {
|
2001-07-02 07:11:40 +00:00
|
|
|
txt_len = tvb_get_guint8(tvb, txt_offset);
|
|
|
|
proto_tree_add_text(rr_tree, tvb, txt_offset, 1 + txt_len,
|
|
|
|
"Text: %.*s", txt_len, tvb_get_ptr(tvb, txt_offset + 1, txt_len));
|
2000-03-21 06:21:37 +00:00
|
|
|
txt_offset += 1 + txt_len;
|
|
|
|
rr_len -= 1 + txt_len;
|
2000-03-21 05:15:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
1999-11-27 08:59:28 +00:00
|
|
|
case T_SIG:
|
|
|
|
{
|
|
|
|
int rr_len = data_len;
|
2001-07-02 07:11:40 +00:00
|
|
|
guint16 type_covered;
|
2001-09-14 07:10:13 +00:00
|
|
|
nstime_t nstime;
|
1999-11-27 08:59:28 +00:00
|
|
|
char signer_name[MAXDNAME];
|
|
|
|
int signer_name_len;
|
|
|
|
|
|
|
|
if (dns_tree != NULL) {
|
2001-07-02 07:11:40 +00:00
|
|
|
type_covered = tvb_get_ntohs(tvb, cur_offset);
|
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 2, "Type covered: %s (%s)",
|
|
|
|
dns_type_name(type_covered),
|
|
|
|
dns_long_type_name(type_covered));
|
1999-11-27 08:59:28 +00:00
|
|
|
cur_offset += 2;
|
|
|
|
rr_len -= 2;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Algorithm: %s",
|
|
|
|
val_to_str(tvb_get_guint8(tvb, cur_offset), algo_vals,
|
1999-11-27 08:59:28 +00:00
|
|
|
"Unknown (0x%02X)"));
|
|
|
|
cur_offset += 1;
|
|
|
|
rr_len -= 1;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Labels: %u",
|
|
|
|
tvb_get_guint8(tvb, cur_offset));
|
1999-11-27 08:59:28 +00:00
|
|
|
cur_offset += 1;
|
|
|
|
rr_len -= 1;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Original TTL: %s",
|
|
|
|
time_secs_to_str(tvb_get_ntohl(tvb, cur_offset)));
|
1999-11-27 08:59:28 +00:00
|
|
|
cur_offset += 4;
|
|
|
|
rr_len -= 4;
|
|
|
|
|
2001-09-14 07:10:13 +00:00
|
|
|
nstime.secs = tvb_get_ntohl(tvb, cur_offset);
|
|
|
|
nstime.nsecs = 0;
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Signature expiration: %s",
|
2001-09-14 07:10:13 +00:00
|
|
|
abs_time_to_str(&nstime));
|
1999-11-27 08:59:28 +00:00
|
|
|
cur_offset += 4;
|
|
|
|
rr_len -= 4;
|
|
|
|
|
2001-09-14 07:10:13 +00:00
|
|
|
nstime.secs = tvb_get_ntohl(tvb, cur_offset);
|
|
|
|
nstime.nsecs = 0;
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Time signed: %s",
|
2001-09-14 07:10:13 +00:00
|
|
|
abs_time_to_str(&nstime));
|
1999-11-27 08:59:28 +00:00
|
|
|
cur_offset += 4;
|
|
|
|
rr_len -= 4;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 2, "Key footprint: 0x%04x",
|
|
|
|
tvb_get_ntohs(tvb, cur_offset));
|
1999-11-27 08:59:28 +00:00
|
|
|
cur_offset += 2;
|
|
|
|
rr_len -= 2;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
signer_name_len = get_dns_name(tvb, cur_offset, dns_data_offset, signer_name, sizeof(signer_name));
|
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, signer_name_len,
|
1999-11-27 08:59:28 +00:00
|
|
|
"Signer's name: %s", signer_name);
|
|
|
|
cur_offset += signer_name_len;
|
|
|
|
rr_len -= signer_name_len;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, rr_len, "Signature");
|
1999-11-27 08:59:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case T_KEY:
|
|
|
|
{
|
|
|
|
int rr_len = data_len;
|
|
|
|
guint16 flags;
|
|
|
|
proto_item *tf;
|
|
|
|
proto_tree *flags_tree;
|
|
|
|
|
|
|
|
if (dns_tree != NULL) {
|
2001-07-02 07:11:40 +00:00
|
|
|
flags = tvb_get_ntohs(tvb, cur_offset);
|
|
|
|
tf = proto_tree_add_text(rr_tree, tvb, cur_offset, 2, "Flags: 0x%04X", flags);
|
1999-11-27 08:59:28 +00:00
|
|
|
flags_tree = proto_item_add_subtree(tf, ett_t_key_flags);
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(flags_tree, tvb, cur_offset, 2, "%s",
|
1999-11-27 08:59:28 +00:00
|
|
|
decode_boolean_bitfield(flags, 0x8000,
|
|
|
|
2*8, "Key prohibited for authentication",
|
|
|
|
"Key allowed for authentication"));
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(flags_tree, tvb, cur_offset, 2, "%s",
|
1999-11-27 08:59:28 +00:00
|
|
|
decode_boolean_bitfield(flags, 0x4000,
|
|
|
|
2*8, "Key prohibited for confidentiality",
|
|
|
|
"Key allowed for confidentiality"));
|
|
|
|
if ((flags & 0xC000) != 0xC000) {
|
|
|
|
/* We have a key */
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(flags_tree, tvb, cur_offset, 2, "%s",
|
1999-11-27 08:59:28 +00:00
|
|
|
decode_boolean_bitfield(flags, 0x2000,
|
|
|
|
2*8, "Key is experimental or optional",
|
|
|
|
"Key is required"));
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(flags_tree, tvb, cur_offset, 2, "%s",
|
1999-11-27 08:59:28 +00:00
|
|
|
decode_boolean_bitfield(flags, 0x0400,
|
|
|
|
2*8, "Key is associated with a user",
|
|
|
|
"Key is not associated with a user"));
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(flags_tree, tvb, cur_offset, 2, "%s",
|
1999-11-27 08:59:28 +00:00
|
|
|
decode_boolean_bitfield(flags, 0x0200,
|
|
|
|
2*8, "Key is associated with the named entity",
|
|
|
|
"Key is not associated with the named entity"));
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(flags_tree, tvb, cur_offset, 2, "%s",
|
1999-11-27 08:59:28 +00:00
|
|
|
decode_boolean_bitfield(flags, 0x0100,
|
|
|
|
2*8, "This is the zone key for the specified zone",
|
|
|
|
"This is not a zone key"));
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(flags_tree, tvb, cur_offset, 2, "%s",
|
1999-11-27 08:59:28 +00:00
|
|
|
decode_boolean_bitfield(flags, 0x0080,
|
|
|
|
2*8, "Key is valid for use with IPSEC",
|
|
|
|
"Key is not valid for use with IPSEC"));
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(flags_tree, tvb, cur_offset, 2, "%s",
|
1999-11-27 08:59:28 +00:00
|
|
|
decode_boolean_bitfield(flags, 0x0040,
|
|
|
|
2*8, "Key is valid for use with MIME security multiparts",
|
|
|
|
"Key is not valid for use with MIME security multiparts"));
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(flags_tree, tvb, cur_offset, 2, "%s",
|
1999-11-27 08:59:28 +00:00
|
|
|
decode_numeric_bitfield(flags, 0x000F,
|
|
|
|
2*8, "Signatory = %u"));
|
|
|
|
}
|
|
|
|
cur_offset += 2;
|
|
|
|
rr_len -= 2;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Protocol: %u",
|
|
|
|
tvb_get_guint8(tvb, cur_offset));
|
1999-11-27 08:59:28 +00:00
|
|
|
cur_offset += 1;
|
|
|
|
rr_len -= 1;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Algorithm: %s",
|
|
|
|
val_to_str(tvb_get_guint8(tvb, cur_offset), algo_vals,
|
1999-11-27 08:59:28 +00:00
|
|
|
"Unknown (0x%02X)"));
|
|
|
|
cur_offset += 1;
|
|
|
|
rr_len -= 1;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, rr_len, "Public key");
|
1999-11-27 08:59:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
1999-11-27 07:46:44 +00:00
|
|
|
case T_AAAA:
|
2001-07-02 07:11:40 +00:00
|
|
|
{
|
|
|
|
const guint8 *addr6;
|
|
|
|
|
|
|
|
addr6 = tvb_get_ptr(tvb, cur_offset, 16);
|
2001-12-10 00:26:21 +00:00
|
|
|
if (cinfo != NULL) {
|
|
|
|
col_append_fstr(cinfo, COL_INFO, " %s",
|
2001-07-02 07:11:40 +00:00
|
|
|
ip6_to_str((struct e_in6_addr *)addr6));
|
2000-03-21 06:21:37 +00:00
|
|
|
}
|
2001-07-02 07:11:40 +00:00
|
|
|
if (dns_tree != NULL) {
|
2001-08-29 00:51:10 +00:00
|
|
|
proto_item_append_text(trr, ", addr %s",
|
2001-07-02 07:11:40 +00:00
|
|
|
ip6_to_str((struct e_in6_addr *)addr6));
|
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 16, "Addr: %s",
|
|
|
|
ip6_to_str((struct e_in6_addr *)addr6));
|
|
|
|
}
|
1999-11-27 07:46:44 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2000-10-02 17:42:38 +00:00
|
|
|
case T_A6:
|
|
|
|
{
|
|
|
|
unsigned short pre_len;
|
|
|
|
unsigned short suf_len;
|
|
|
|
unsigned short suf_octet_count;
|
|
|
|
char pname[MAXDNAME];
|
2001-07-02 07:11:40 +00:00
|
|
|
int pname_len;
|
2000-10-02 17:42:38 +00:00
|
|
|
int a6_offset;
|
|
|
|
int suf_offset;
|
|
|
|
guint8 suffix[16];
|
|
|
|
|
|
|
|
a6_offset = cur_offset;
|
2001-07-02 07:11:40 +00:00
|
|
|
pre_len = tvb_get_guint8(tvb, cur_offset);
|
|
|
|
cur_offset++;
|
2000-10-02 17:42:38 +00:00
|
|
|
suf_len = 128 - pre_len;
|
2000-10-18 00:37:54 +00:00
|
|
|
suf_octet_count = suf_len ? (suf_len - 1) / 8 + 1 : 0;
|
2000-10-02 17:42:38 +00:00
|
|
|
/* Pad prefix */
|
|
|
|
for (suf_offset = 0; suf_offset < 16 - suf_octet_count; suf_offset++) {
|
|
|
|
suffix[suf_offset] = 0;
|
|
|
|
}
|
|
|
|
for (; suf_offset < 16; suf_offset++) {
|
2001-07-02 07:11:40 +00:00
|
|
|
suffix[suf_offset] = tvb_get_guint8(tvb, cur_offset);
|
|
|
|
cur_offset++;
|
2000-10-02 17:42:38 +00:00
|
|
|
}
|
|
|
|
|
2000-10-18 00:37:54 +00:00
|
|
|
if (pre_len > 0) {
|
2001-07-02 07:11:40 +00:00
|
|
|
pname_len = get_dns_name(tvb, cur_offset, dns_data_offset,
|
2000-10-18 00:37:54 +00:00
|
|
|
pname, sizeof(pname));
|
|
|
|
} else {
|
|
|
|
strcpy(pname, "");
|
2001-07-02 07:11:40 +00:00
|
|
|
pname_len = 0;
|
2000-10-02 17:42:38 +00:00
|
|
|
}
|
|
|
|
|
2001-12-10 00:26:21 +00:00
|
|
|
if (cinfo != NULL) {
|
|
|
|
col_append_fstr(cinfo, COL_INFO, " %d %s %s",
|
2000-10-02 17:42:38 +00:00
|
|
|
pre_len,
|
|
|
|
ip6_to_str((struct e_in6_addr *)&suffix),
|
|
|
|
pname);
|
|
|
|
}
|
|
|
|
if (dns_tree != NULL) {
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, a6_offset, 1,
|
2000-10-02 17:42:38 +00:00
|
|
|
"Prefix len: %u", pre_len);
|
|
|
|
a6_offset++;
|
2000-10-18 00:37:54 +00:00
|
|
|
if (suf_len) {
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, a6_offset, suf_octet_count,
|
2000-10-18 00:37:54 +00:00
|
|
|
"Address suffix: %s",
|
|
|
|
ip6_to_str((struct e_in6_addr *)&suffix));
|
|
|
|
a6_offset += suf_octet_count;
|
|
|
|
}
|
|
|
|
if (pre_len > 0) {
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, a6_offset, pname_len,
|
2000-10-18 00:37:54 +00:00
|
|
|
"Prefix name: %s", pname);
|
|
|
|
}
|
2001-08-29 00:51:10 +00:00
|
|
|
proto_item_append_text(trr, ", addr %d %s %s",
|
2000-10-02 17:42:38 +00:00
|
|
|
pre_len,
|
|
|
|
ip6_to_str((struct e_in6_addr *)&suffix),
|
|
|
|
pname);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case T_DNAME:
|
|
|
|
{
|
|
|
|
char dname[MAXDNAME];
|
|
|
|
int dname_len;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
dname_len = get_dns_name(tvb, cur_offset, dns_data_offset,
|
2000-10-02 17:42:38 +00:00
|
|
|
dname, sizeof(dname));
|
2001-12-10 00:26:21 +00:00
|
|
|
if (cinfo != NULL)
|
|
|
|
col_append_fstr(cinfo, COL_INFO, " %s", dname);
|
2000-10-02 17:42:38 +00:00
|
|
|
if (dns_tree != NULL) {
|
2001-08-29 00:51:10 +00:00
|
|
|
proto_item_append_text(trr, ", dname %s", dname);
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset,
|
2000-10-02 17:42:38 +00:00
|
|
|
dname_len, "Target name: %s", dname);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
1999-09-21 07:15:38 +00:00
|
|
|
case T_LOC:
|
|
|
|
{
|
2001-07-02 07:11:40 +00:00
|
|
|
guint8 version;
|
|
|
|
|
1999-11-07 21:00:40 +00:00
|
|
|
if (dns_tree != NULL) {
|
2001-07-02 07:11:40 +00:00
|
|
|
version = tvb_get_guint8(tvb, cur_offset);
|
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Version: %u", version);
|
|
|
|
if (version == 0) {
|
1999-11-07 21:00:40 +00:00
|
|
|
/* Version 0, the only version RFC 1876 discusses. */
|
|
|
|
cur_offset++;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Size: %g m",
|
|
|
|
rfc1867_size(tvb, cur_offset));
|
1999-11-07 21:00:40 +00:00
|
|
|
cur_offset++;
|
1999-10-07 07:44:29 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Horizontal precision: %g m",
|
|
|
|
rfc1867_size(tvb, cur_offset));
|
1999-11-07 21:00:40 +00:00
|
|
|
cur_offset++;
|
1999-10-07 07:44:29 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Vertical precision: %g m",
|
|
|
|
rfc1867_size(tvb, cur_offset));
|
1999-11-07 21:00:40 +00:00
|
|
|
cur_offset++;
|
1999-10-07 07:44:29 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Latitude: %s",
|
|
|
|
rfc1867_angle(tvb, cur_offset, "NS"));
|
1999-11-07 21:00:40 +00:00
|
|
|
cur_offset += 4;
|
1999-10-07 07:44:29 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Longitude: %s",
|
|
|
|
rfc1867_angle(tvb, cur_offset, "EW"));
|
1999-11-07 21:00:40 +00:00
|
|
|
cur_offset += 4;
|
1999-10-07 07:44:29 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Altitude: %g m",
|
|
|
|
(tvb_get_ntohl(tvb, cur_offset) - 10000000)/100.0);
|
1999-11-07 21:00:40 +00:00
|
|
|
} else
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "Data");
|
1999-11-07 21:00:40 +00:00
|
|
|
}
|
1999-09-21 07:15:38 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
1999-03-22 23:31:05 +00:00
|
|
|
|
1999-11-27 08:59:28 +00:00
|
|
|
case T_NXT:
|
|
|
|
{
|
|
|
|
int rr_len = data_len;
|
|
|
|
char next_domain_name[MAXDNAME];
|
|
|
|
int next_domain_name_len;
|
|
|
|
int rr_type;
|
|
|
|
guint8 bits;
|
|
|
|
int mask;
|
|
|
|
int i;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
next_domain_name_len = get_dns_name(tvb, cur_offset, dns_data_offset,
|
1999-11-27 08:59:28 +00:00
|
|
|
next_domain_name, sizeof(next_domain_name));
|
2001-12-10 00:26:21 +00:00
|
|
|
if (cinfo != NULL)
|
|
|
|
col_append_fstr(cinfo, COL_INFO, " %s", next_domain_name);
|
1999-11-27 08:59:28 +00:00
|
|
|
if (dns_tree != NULL) {
|
2001-08-29 00:51:10 +00:00
|
|
|
proto_item_append_text(trr, ", next domain name %s",
|
|
|
|
next_domain_name);
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, next_domain_name_len,
|
1999-11-27 08:59:28 +00:00
|
|
|
"Next domain name: %s", next_domain_name);
|
|
|
|
cur_offset += next_domain_name_len;
|
|
|
|
rr_len -= next_domain_name_len;
|
|
|
|
rr_type = 0;
|
|
|
|
while (rr_len != 0) {
|
2001-07-02 07:11:40 +00:00
|
|
|
bits = tvb_get_guint8(tvb, cur_offset);
|
2000-03-21 06:21:37 +00:00
|
|
|
mask = 1<<7;
|
1999-11-27 08:59:28 +00:00
|
|
|
for (i = 0; i < 8; i++) {
|
|
|
|
if (bits & mask) {
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 1,
|
1999-11-27 08:59:28 +00:00
|
|
|
"RR type in bit map: %s (%s)",
|
|
|
|
dns_type_name(rr_type),
|
|
|
|
dns_long_type_name(rr_type));
|
|
|
|
}
|
|
|
|
mask >>= 1;
|
|
|
|
rr_type++;
|
|
|
|
}
|
|
|
|
cur_offset += 1;
|
|
|
|
rr_len -= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2000-10-11 04:12:06 +00:00
|
|
|
case T_KX:
|
|
|
|
{
|
|
|
|
guint16 preference = 0;
|
|
|
|
char kx_name[MAXDNAME];
|
|
|
|
int kx_name_len;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
preference = tvb_get_ntohs(tvb, cur_offset);
|
|
|
|
kx_name_len = get_dns_name(tvb, cur_offset + 2, dns_data_offset, kx_name, sizeof(kx_name));
|
2001-12-10 00:26:21 +00:00
|
|
|
if (cinfo != NULL)
|
|
|
|
col_append_fstr(cinfo, COL_INFO, " %u %s", preference, kx_name);
|
2000-10-11 04:12:06 +00:00
|
|
|
if (dns_tree != NULL) {
|
2001-08-29 00:51:10 +00:00
|
|
|
proto_item_append_text(trr, ", preference %u, kx %s",
|
|
|
|
preference, kx_name);
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 2, "Preference: %u", preference);
|
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset + 2, kx_name_len, "Key exchange: %s",
|
2000-10-11 04:12:06 +00:00
|
|
|
kx_name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case T_CERT:
|
|
|
|
{
|
|
|
|
guint16 cert_type, cert_keytag;
|
|
|
|
guint8 cert_keyalg;
|
|
|
|
int rr_len = data_len;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
cert_type = tvb_get_ntohs(tvb, cur_offset);
|
2000-10-11 04:12:06 +00:00
|
|
|
cur_offset += 2;
|
|
|
|
rr_len -= 2;
|
2001-07-02 07:11:40 +00:00
|
|
|
cert_keytag = tvb_get_ntohs(tvb, cur_offset);
|
2000-10-11 04:12:06 +00:00
|
|
|
cur_offset += 2;
|
|
|
|
rr_len -= 2;
|
2001-07-02 07:11:40 +00:00
|
|
|
cert_keyalg = tvb_get_guint8(tvb, cur_offset);
|
2000-10-11 04:12:06 +00:00
|
|
|
cur_offset += 1;
|
|
|
|
rr_len -= 1;
|
|
|
|
|
|
|
|
if (dns_tree != NULL) {
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Type: %s",
|
2000-10-11 04:12:06 +00:00
|
|
|
val_to_str(cert_keyalg, cert_vals,
|
|
|
|
"Unknown (0x%02X)"));
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 2, "Key footprint: 0x%04x",
|
2000-10-11 04:12:06 +00:00
|
|
|
cert_keytag);
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Algorithm: %s",
|
2000-10-11 04:12:06 +00:00
|
|
|
val_to_str(cert_keyalg, algo_vals,
|
|
|
|
"Unknown (0x%02X)"));
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, rr_len, "Public key");
|
2000-10-11 04:12:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2000-03-30 01:33:10 +00:00
|
|
|
case T_OPT:
|
2001-08-29 00:51:10 +00:00
|
|
|
if (dns_tree != NULL)
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "Data");
|
2000-03-30 01:33:10 +00:00
|
|
|
break;
|
|
|
|
|
2000-10-11 04:12:06 +00:00
|
|
|
case T_TKEY:
|
|
|
|
{
|
|
|
|
char tkey_algname[MAXDNAME];
|
|
|
|
int tkey_algname_len;
|
|
|
|
guint16 tkey_mode, tkey_error, tkey_keylen, tkey_otherlen;
|
|
|
|
int rr_len = data_len;
|
2001-09-14 07:10:13 +00:00
|
|
|
nstime_t nstime;
|
2000-10-11 04:12:06 +00:00
|
|
|
static const value_string tkey_modes[] = {
|
|
|
|
{ TKEYMODE_SERVERASSIGNED, "Server assigned" },
|
|
|
|
{ TKEYMODE_DIFFIEHELLMAN, "Diffie Hellman" },
|
2001-08-29 00:51:10 +00:00
|
|
|
{ TKEYMODE_GSSAPI, "GSSAPI" },
|
2000-10-11 04:12:06 +00:00
|
|
|
{ TKEYMODE_RESOLVERASSIGNED, "Resolver assigned" },
|
|
|
|
{ TKEYMODE_DELETE, "Delete" },
|
|
|
|
{ 0, NULL } };
|
|
|
|
|
|
|
|
if (dns_tree != NULL) {
|
2001-07-02 07:11:40 +00:00
|
|
|
tkey_algname_len = get_dns_name(tvb, cur_offset, dns_data_offset, tkey_algname, sizeof(tkey_algname));
|
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, tkey_algname_len,
|
2000-10-11 04:12:06 +00:00
|
|
|
"Algorithm name: %s", tkey_algname);
|
|
|
|
cur_offset += tkey_algname_len;
|
|
|
|
rr_len -= tkey_algname_len;
|
|
|
|
|
2001-09-14 07:10:13 +00:00
|
|
|
nstime.secs = tvb_get_ntohl(tvb, cur_offset);
|
|
|
|
nstime.nsecs = 0;
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Signature inception: %s",
|
2001-09-14 07:10:13 +00:00
|
|
|
abs_time_to_str(&nstime));
|
2000-10-11 04:12:06 +00:00
|
|
|
cur_offset += 4;
|
|
|
|
rr_len -= 4;
|
|
|
|
|
2001-09-14 07:10:13 +00:00
|
|
|
nstime.secs = tvb_get_ntohl(tvb, cur_offset);
|
|
|
|
nstime.nsecs = 0;
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Signature expiration: %s",
|
2001-09-14 07:10:13 +00:00
|
|
|
abs_time_to_str(&nstime));
|
2000-10-11 04:12:06 +00:00
|
|
|
cur_offset += 4;
|
|
|
|
rr_len -= 4;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
tkey_mode = tvb_get_ntohs(tvb, cur_offset);
|
2000-10-11 04:12:06 +00:00
|
|
|
cur_offset += 2;
|
|
|
|
rr_len -= 2;
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Mode: %s",
|
2000-10-11 04:12:06 +00:00
|
|
|
val_to_str(tkey_mode, tkey_modes,
|
|
|
|
"Unknown (0x%02X)"));
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
tkey_error = tvb_get_ntohs(tvb, cur_offset);
|
2000-10-11 04:12:06 +00:00
|
|
|
cur_offset += 2;
|
|
|
|
rr_len -= 2;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Error: %s",
|
2000-10-11 04:12:06 +00:00
|
|
|
val_to_str(tkey_error, rcode_vals,
|
|
|
|
val_to_str(tkey_error, tsigerror_vals, "Unknown error (%x)")));
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
tkey_keylen = tvb_get_ntohs(tvb, cur_offset);
|
2000-10-11 04:12:06 +00:00
|
|
|
cur_offset += 2;
|
|
|
|
rr_len -= 2;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, tkey_keylen, "Key");
|
2000-10-11 04:12:06 +00:00
|
|
|
cur_offset += tkey_keylen;
|
|
|
|
rr_len -= tkey_keylen;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
tkey_otherlen = tvb_get_ntohs(tvb, cur_offset);
|
2000-10-11 04:12:06 +00:00
|
|
|
cur_offset += 2;
|
|
|
|
rr_len -= 2;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, tkey_otherlen, "Other");
|
2000-10-11 04:12:06 +00:00
|
|
|
cur_offset += tkey_otherlen;
|
|
|
|
rr_len -= tkey_otherlen;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case T_TSIG:
|
|
|
|
{
|
2001-02-20 07:17:20 +00:00
|
|
|
guint16 tsig_fudge;
|
2000-10-11 04:12:06 +00:00
|
|
|
guint16 tsig_originalid, tsig_error, tsig_timehi, tsig_siglen, tsig_otherlen;
|
|
|
|
guint32 tsig_timelo;
|
|
|
|
char tsig_algname[MAXDNAME];
|
|
|
|
int tsig_algname_len;
|
2001-09-14 07:10:13 +00:00
|
|
|
nstime_t nstime;
|
2000-10-11 04:12:06 +00:00
|
|
|
int rr_len = data_len;
|
|
|
|
|
|
|
|
if (dns_tree != NULL) {
|
2001-07-02 07:11:40 +00:00
|
|
|
tsig_algname_len = get_dns_name(tvb, cur_offset, dns_data_offset, tsig_algname, sizeof(tsig_algname));
|
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, tsig_algname_len,
|
2000-10-11 04:12:06 +00:00
|
|
|
"Algorithm name: %s", tsig_algname);
|
|
|
|
cur_offset += tsig_algname_len;
|
|
|
|
rr_len -= tsig_algname_len;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
tsig_timehi = tvb_get_ntohs(tvb, cur_offset);
|
|
|
|
tsig_timelo = tvb_get_ntohl(tvb, cur_offset + 2);
|
2001-09-14 07:10:13 +00:00
|
|
|
nstime.secs = tsig_timelo;
|
|
|
|
nstime.nsecs = 0;
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 6, "Time signed: %s%s",
|
2001-09-14 07:10:13 +00:00
|
|
|
abs_time_to_str(&nstime), tsig_timehi == 0 ? "" : "(high bits set)");
|
2001-02-20 07:17:20 +00:00
|
|
|
cur_offset += 6;
|
|
|
|
rr_len -= 6;
|
2000-10-11 04:12:06 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
tsig_fudge = tvb_get_ntohs(tvb, cur_offset);
|
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 2, "Fudge: %u",
|
2001-02-20 07:17:20 +00:00
|
|
|
tsig_fudge);
|
2000-10-11 04:12:06 +00:00
|
|
|
cur_offset += 2;
|
|
|
|
rr_len -= 2;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
tsig_siglen = tvb_get_ntohs(tvb, cur_offset);
|
2000-10-11 04:12:06 +00:00
|
|
|
cur_offset += 2;
|
|
|
|
rr_len -= 2;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, tsig_siglen, "Signature");
|
2000-10-11 04:12:06 +00:00
|
|
|
cur_offset += tsig_siglen;
|
|
|
|
rr_len -= tsig_siglen;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
tsig_originalid = tvb_get_ntohs(tvb, cur_offset);
|
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 2, "Original id: %d",
|
2001-02-20 07:17:20 +00:00
|
|
|
tsig_originalid);
|
2000-10-11 04:12:06 +00:00
|
|
|
cur_offset += 2;
|
|
|
|
rr_len -= 2;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
tsig_error = tvb_get_ntohs(tvb, cur_offset);
|
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 2, "Error: %s",
|
2000-10-11 04:12:06 +00:00
|
|
|
val_to_str(tsig_error, rcode_vals,
|
|
|
|
val_to_str(tsig_error, tsigerror_vals, "Unknown error (%x)")));
|
2001-02-20 07:17:20 +00:00
|
|
|
cur_offset += 2;
|
|
|
|
rr_len -= 2;
|
2000-10-11 04:12:06 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
tsig_otherlen = tvb_get_ntohs(tvb, cur_offset);
|
2000-10-11 04:12:06 +00:00
|
|
|
cur_offset += 2;
|
|
|
|
rr_len -= 2;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, tsig_otherlen, "Other");
|
2000-10-11 04:12:06 +00:00
|
|
|
cur_offset += tsig_otherlen;
|
|
|
|
rr_len -= tsig_otherlen;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2000-07-21 01:29:04 +00:00
|
|
|
case T_WINS:
|
|
|
|
{
|
|
|
|
int rr_len = data_len;
|
|
|
|
guint32 local_flag;
|
|
|
|
guint32 lookup_timeout;
|
|
|
|
guint32 cache_timeout;
|
|
|
|
guint32 nservers;
|
|
|
|
|
|
|
|
if (dns_tree != NULL) {
|
2001-07-02 07:11:40 +00:00
|
|
|
local_flag = tvb_get_ntohl(tvb, cur_offset);
|
2000-07-21 01:29:04 +00:00
|
|
|
if (dns_tree != NULL) {
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Local flag: %s",
|
2000-07-21 01:29:04 +00:00
|
|
|
local_flag ? "true" : "false");
|
|
|
|
}
|
|
|
|
cur_offset += 4;
|
|
|
|
rr_len -= 4;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
lookup_timeout = tvb_get_ntohl(tvb, cur_offset);
|
2000-07-21 01:29:04 +00:00
|
|
|
if (dns_tree != NULL) {
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Lookup timeout: %u seconds",
|
2000-07-21 01:29:04 +00:00
|
|
|
lookup_timeout);
|
|
|
|
}
|
|
|
|
cur_offset += 4;
|
|
|
|
rr_len -= 4;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
cache_timeout = tvb_get_ntohl(tvb, cur_offset);
|
2000-07-21 01:29:04 +00:00
|
|
|
if (dns_tree != NULL) {
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Cache timeout: %u seconds",
|
2000-07-21 01:29:04 +00:00
|
|
|
cache_timeout);
|
|
|
|
}
|
|
|
|
cur_offset += 4;
|
|
|
|
rr_len -= 4;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
nservers = tvb_get_ntohl(tvb, cur_offset);
|
2000-07-21 01:29:04 +00:00
|
|
|
if (dns_tree != NULL) {
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Number of WINS servers: %u",
|
2000-07-21 01:29:04 +00:00
|
|
|
nservers);
|
|
|
|
}
|
|
|
|
cur_offset += 4;
|
|
|
|
rr_len -= 4;
|
|
|
|
|
|
|
|
while (rr_len != 0 && nservers != 0) {
|
|
|
|
if (dns_tree != NULL) {
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "WINS server address: %s",
|
|
|
|
ip_to_str(tvb_get_ptr(tvb, cur_offset, 4)));
|
2000-07-21 01:29:04 +00:00
|
|
|
}
|
|
|
|
cur_offset += 4;
|
|
|
|
rr_len -= 4;
|
|
|
|
nservers--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case T_WINS_R:
|
|
|
|
{
|
|
|
|
int rr_len = data_len;
|
|
|
|
guint32 local_flag;
|
|
|
|
guint32 lookup_timeout;
|
|
|
|
guint32 cache_timeout;
|
|
|
|
char dname[MAXDNAME];
|
|
|
|
int dname_len;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
local_flag = tvb_get_ntohl(tvb, cur_offset);
|
2000-07-21 01:29:04 +00:00
|
|
|
if (dns_tree != NULL) {
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Local flag: %s",
|
2000-07-21 01:29:04 +00:00
|
|
|
local_flag ? "true" : "false");
|
|
|
|
}
|
|
|
|
cur_offset += 4;
|
|
|
|
rr_len -= 4;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
lookup_timeout = tvb_get_ntohl(tvb, cur_offset);
|
2000-07-21 01:29:04 +00:00
|
|
|
if (dns_tree != NULL) {
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Lookup timeout: %u seconds",
|
2000-07-21 01:29:04 +00:00
|
|
|
lookup_timeout);
|
|
|
|
}
|
|
|
|
cur_offset += 4;
|
|
|
|
rr_len -= 4;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
cache_timeout = tvb_get_ntohl(tvb, cur_offset);
|
2000-07-21 01:29:04 +00:00
|
|
|
if (dns_tree != NULL) {
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Cache timeout: %u seconds",
|
2000-07-21 01:29:04 +00:00
|
|
|
cache_timeout);
|
|
|
|
}
|
|
|
|
cur_offset += 4;
|
|
|
|
rr_len -= 4;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
dname_len = get_dns_name(tvb, cur_offset, dns_data_offset, dname, sizeof(dname));
|
2001-12-10 00:26:21 +00:00
|
|
|
if (cinfo != NULL)
|
|
|
|
col_append_fstr(cinfo, COL_INFO, " %s", dname);
|
2000-07-21 01:29:04 +00:00
|
|
|
if (dns_tree != NULL) {
|
2001-08-29 00:51:10 +00:00
|
|
|
proto_item_append_text(trr, ", name result domain %s", dname);
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, dname_len, "Name result domain: %s",
|
2000-07-21 01:29:04 +00:00
|
|
|
dname);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2001-02-20 16:25:52 +00:00
|
|
|
case T_SRV:
|
|
|
|
{
|
|
|
|
guint16 priority = 0;
|
|
|
|
guint16 weight = 0;
|
|
|
|
guint16 port = 0;
|
|
|
|
char target[MAXDNAME];
|
|
|
|
int target_len;
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
priority = tvb_get_ntohs(tvb, cur_offset);
|
|
|
|
weight = tvb_get_ntohs(tvb, cur_offset+2);
|
|
|
|
port = tvb_get_ntohs(tvb, cur_offset+4);
|
|
|
|
|
|
|
|
target_len = get_dns_name(tvb, cur_offset + 6, dns_data_offset, target, sizeof(target));
|
2001-12-10 00:26:21 +00:00
|
|
|
if (cinfo != NULL)
|
|
|
|
col_append_fstr(cinfo, COL_INFO, " %u %u %u %s", priority, weight, port, target);
|
2001-02-20 16:25:52 +00:00
|
|
|
if (dns_tree != NULL) {
|
2001-08-29 00:51:10 +00:00
|
|
|
proto_item_append_text(trr,
|
|
|
|
", priority %u, weight %u, port %u, target %s",
|
|
|
|
priority, weight, port, target);
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, 2, "Priority: %u", priority);
|
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset + 2, 2, "Weight: %u", weight);
|
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset + 4, 2, "Port: %u", port);
|
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset + 6, target_len, "Target: %s",
|
2001-02-20 16:25:52 +00:00
|
|
|
target);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
1999-03-22 23:31:05 +00:00
|
|
|
/* TODO: parse more record types */
|
|
|
|
|
1998-10-14 19:35:00 +00:00
|
|
|
default:
|
2001-08-29 00:51:10 +00:00
|
|
|
if (dns_tree != NULL)
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "Data");
|
1999-11-27 08:59:28 +00:00
|
|
|
break;
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
data_offset += data_len;
|
1998-10-14 19:35:00 +00:00
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
return data_offset - data_start;
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2001-07-02 07:11:40 +00:00
|
|
|
dissect_query_records(tvbuff_t *tvb, int cur_off, int dns_data_offset,
|
2001-12-10 00:26:21 +00:00
|
|
|
int count, column_info *cinfo, proto_tree *dns_tree, int isupdate)
|
1998-09-16 02:39:15 +00:00
|
|
|
{
|
1999-10-07 02:26:45 +00:00
|
|
|
int start_off, add_off;
|
1999-11-07 21:00:40 +00:00
|
|
|
proto_tree *qatree = NULL;
|
|
|
|
proto_item *ti = NULL;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
start_off = cur_off;
|
1999-11-07 21:00:40 +00:00
|
|
|
if (dns_tree) {
|
2000-10-11 04:12:06 +00:00
|
|
|
char *s = (isupdate ? "Zone" : "Queries");
|
Allow a length of -1 to be specified when adding FT_NONE and FT_PROTOCOL
items to the protocol tree; it's interpreted as "the rest of the data in
the tvbuff". This can be used if
1) the item covers the entire packet or the remaining payload in
the packet
or
2) the item's length won't be known until it's dissected, and
will be then set with "proto_item_set_len()" - if an
exception is thrown in the dissection, it means the item ran
*past* the end of the tvbuff, so saying it runs to the end of
the tvbuff is reasonable.
Convert a number of "proto_tree_add_XXX()" calls using
"tvb_length_remaining()", values derived from the result of
"tvb_length()", or 0 (in the case of items whose length is unknown) to
use -1 instead (using 0 means that if an exception is thrown, selecting
the item highlights nothing; using -1 means it highlights all the data
for that item that's available).
In some places where "tvb_length()" or "tvb_length_remaining()" was used
to determine how large a packet is, use "tvb_reported_length()" or
"tvb_reported_length_remaining()", instead - the first two calls
indicate how much captured data was in the packet, the latter two calls
indicate how large the packet actually was (and the fact that using the
latter could cause BoundsError exceptions to be thrown is a feature - if
such an exception is thrown, the frame really *was* short, and it should
be tagged as such).
Replace some "proto_tree_add_XXX()" calls with equivalent
"proto_tree_add_item()" calls.
Fix some indentation.
svn path=/trunk/; revision=4578
2002-01-20 22:12:39 +00:00
|
|
|
ti = proto_tree_add_text(dns_tree, tvb, start_off, -1, s);
|
1999-11-16 11:44:20 +00:00
|
|
|
qatree = proto_item_add_subtree(ti, ett_dns_qry);
|
1999-11-07 21:00:40 +00:00
|
|
|
}
|
1999-10-07 02:26:45 +00:00
|
|
|
while (count-- > 0) {
|
2001-12-10 00:26:21 +00:00
|
|
|
add_off = dissect_dns_query(tvb, cur_off, dns_data_offset, cinfo, qatree);
|
1999-10-07 02:26:45 +00:00
|
|
|
cur_off += add_off;
|
|
|
|
}
|
1999-11-07 21:00:40 +00:00
|
|
|
if (ti)
|
|
|
|
proto_item_set_len(ti, cur_off - start_off);
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
return cur_off - start_off;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2001-07-02 07:11:40 +00:00
|
|
|
dissect_answer_records(tvbuff_t *tvb, int cur_off, int dns_data_offset,
|
2001-12-10 00:26:21 +00:00
|
|
|
int count, column_info *cinfo, proto_tree *dns_tree, char *name)
|
1998-09-16 02:39:15 +00:00
|
|
|
{
|
1999-10-07 02:26:45 +00:00
|
|
|
int start_off, add_off;
|
1999-11-07 21:00:40 +00:00
|
|
|
proto_tree *qatree = NULL;
|
|
|
|
proto_item *ti = NULL;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
start_off = cur_off;
|
1999-11-07 21:00:40 +00:00
|
|
|
if (dns_tree) {
|
Allow a length of -1 to be specified when adding FT_NONE and FT_PROTOCOL
items to the protocol tree; it's interpreted as "the rest of the data in
the tvbuff". This can be used if
1) the item covers the entire packet or the remaining payload in
the packet
or
2) the item's length won't be known until it's dissected, and
will be then set with "proto_item_set_len()" - if an
exception is thrown in the dissection, it means the item ran
*past* the end of the tvbuff, so saying it runs to the end of
the tvbuff is reasonable.
Convert a number of "proto_tree_add_XXX()" calls using
"tvb_length_remaining()", values derived from the result of
"tvb_length()", or 0 (in the case of items whose length is unknown) to
use -1 instead (using 0 means that if an exception is thrown, selecting
the item highlights nothing; using -1 means it highlights all the data
for that item that's available).
In some places where "tvb_length()" or "tvb_length_remaining()" was used
to determine how large a packet is, use "tvb_reported_length()" or
"tvb_reported_length_remaining()", instead - the first two calls
indicate how much captured data was in the packet, the latter two calls
indicate how large the packet actually was (and the fact that using the
latter could cause BoundsError exceptions to be thrown is a feature - if
such an exception is thrown, the frame really *was* short, and it should
be tagged as such).
Replace some "proto_tree_add_XXX()" calls with equivalent
"proto_tree_add_item()" calls.
Fix some indentation.
svn path=/trunk/; revision=4578
2002-01-20 22:12:39 +00:00
|
|
|
ti = proto_tree_add_text(dns_tree, tvb, start_off, -1, name);
|
1999-11-16 11:44:20 +00:00
|
|
|
qatree = proto_item_add_subtree(ti, ett_dns_ans);
|
1999-11-07 21:00:40 +00:00
|
|
|
}
|
1999-10-07 02:26:45 +00:00
|
|
|
while (count-- > 0) {
|
2001-12-10 00:26:21 +00:00
|
|
|
add_off = dissect_dns_answer(tvb, cur_off, dns_data_offset, cinfo, qatree);
|
1999-10-07 02:26:45 +00:00
|
|
|
cur_off += add_off;
|
|
|
|
}
|
1999-11-07 21:00:40 +00:00
|
|
|
if (ti)
|
|
|
|
proto_item_set_len(ti, cur_off - start_off);
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
return cur_off - start_off;
|
|
|
|
}
|
|
|
|
|
2002-02-22 08:45:02 +00:00
|
|
|
static void
|
Make a "tcp_dissect_pdus()" with the standard loop for a TCP segment,
extracting PDUs from it and possibly doing reassembly. Make the COPS,
DNS, DSI, Gryphon, and SCCP dissectors use it.
Add "set_actual_length()", "tcp_dissect_pdus()",
"decode_boolean_bitfield()", "decode_numeric_bitfield()", and
"decode_enumerated_bitfield()" to the list of routines available to
dissectors on platforms where routines in the main program aren't
available to dynamically-loaded code.
Declare routines in "to_str.h" as "extern"; as I remember, that's
necessary to allow the "decode_XXX_bitfield()" routines declared therein
to be made available to plugins as per the above.
Note that new exported routines should be added to the end of the table
if that's the only change being made to the table.
Create a new "plugin_api_decls.h" header file, used to declare both the
"p_" variables and the "p_" structure members in the routine-exporting
mechanism; this reduces the number of places you have to change to
change the list of exported routines.
svn path=/trunk/; revision=5394
2002-05-05 00:16:38 +00:00
|
|
|
dissect_dns_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|
|
|
gboolean is_tcp)
|
1999-10-07 07:44:29 +00:00
|
|
|
{
|
2002-02-22 08:45:02 +00:00
|
|
|
int offset = is_tcp ? 2 : 0;
|
1999-10-07 07:44:29 +00:00
|
|
|
int dns_data_offset;
|
2001-12-10 00:26:21 +00:00
|
|
|
column_info *cinfo;
|
1999-11-07 21:00:40 +00:00
|
|
|
proto_tree *dns_tree = NULL, *field_tree;
|
1999-03-23 03:14:46 +00:00
|
|
|
proto_item *ti, *tf;
|
2002-05-15 07:24:20 +00:00
|
|
|
guint16 id, flags, opcode, rcode, quest, ans, auth, add;
|
1999-01-04 09:13:46 +00:00
|
|
|
char buf[128+1];
|
1998-09-16 02:39:15 +00:00
|
|
|
int cur_off;
|
2000-10-11 04:12:06 +00:00
|
|
|
int isupdate;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1999-10-07 07:44:29 +00:00
|
|
|
dns_data_offset = offset;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2001-12-10 00:26:21 +00:00
|
|
|
if (check_col(pinfo->cinfo, COL_PROTOCOL))
|
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "DNS");
|
|
|
|
if (check_col(pinfo->cinfo, COL_INFO))
|
|
|
|
col_clear(pinfo->cinfo, COL_INFO);
|
1999-10-07 07:44:29 +00:00
|
|
|
|
|
|
|
/* To do: check for errs, etc. */
|
2001-07-02 07:11:40 +00:00
|
|
|
id = tvb_get_ntohs(tvb, offset + DNS_ID);
|
|
|
|
flags = tvb_get_ntohs(tvb, offset + DNS_FLAGS);
|
2002-05-15 07:24:20 +00:00
|
|
|
opcode = (flags & F_OPCODE) >> OPCODE_SHIFT;
|
|
|
|
rcode = (flags & F_RCODE);
|
2001-07-02 07:11:40 +00:00
|
|
|
|
2001-12-10 00:26:21 +00:00
|
|
|
if (check_col(pinfo->cinfo, COL_INFO)) {
|
2002-05-15 07:24:20 +00:00
|
|
|
strcpy(buf, val_to_str(opcode, opcode_vals, "Unknown operation (%u)"));
|
1999-12-29 10:36:13 +00:00
|
|
|
if (flags & F_RESPONSE) {
|
|
|
|
strcat(buf, " response");
|
|
|
|
if ((flags & F_RCODE) != RCODE_NOERROR) {
|
|
|
|
strcat(buf, ", ");
|
|
|
|
strcat(buf, val_to_str(flags & F_RCODE, rcode_vals,
|
2002-05-15 07:24:20 +00:00
|
|
|
"Unknown error (%u)"));
|
1999-12-29 10:36:13 +00:00
|
|
|
}
|
|
|
|
}
|
2001-12-10 00:26:21 +00:00
|
|
|
col_add_str(pinfo->cinfo, COL_INFO, buf);
|
|
|
|
cinfo = pinfo->cinfo;
|
1999-11-07 21:00:40 +00:00
|
|
|
} else {
|
2001-12-10 00:26:21 +00:00
|
|
|
/* Set "cinfo" to NULL; we pass a NULL "cinfo" to the query and answer
|
1999-11-07 21:00:40 +00:00
|
|
|
dissectors, as a way of saying that they shouldn't add stuff
|
2001-12-10 00:26:21 +00:00
|
|
|
to the COL_INFO column (a call to "check_col(cinfo, COL_INFO)"
|
1999-11-07 21:00:40 +00:00
|
|
|
is more expensive than a check that a pointer isn't NULL). */
|
2001-12-10 00:26:21 +00:00
|
|
|
cinfo = NULL;
|
1999-01-04 09:13:46 +00:00
|
|
|
}
|
2002-05-15 07:24:20 +00:00
|
|
|
if (opcode == OPCODE_UPDATE)
|
2000-10-11 04:12:06 +00:00
|
|
|
isupdate = 1;
|
|
|
|
else
|
|
|
|
isupdate = 0;
|
2001-07-02 07:11:40 +00:00
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
if (tree) {
|
2002-02-22 08:45:02 +00:00
|
|
|
ti = proto_tree_add_protocol_format(tree, proto_dns, tvb, 0, -1,
|
1999-12-07 00:22:11 +00:00
|
|
|
"Domain Name System (%s)", (flags & F_RESPONSE) ? "response" : "query");
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1999-11-16 11:44:20 +00:00
|
|
|
dns_tree = proto_item_add_subtree(ti, ett_dns);
|
1999-10-16 15:08:11 +00:00
|
|
|
|
2001-07-02 07:29:03 +00:00
|
|
|
if (is_tcp) {
|
|
|
|
/* Put the length indication into the tree. */
|
Make a "tcp_dissect_pdus()" with the standard loop for a TCP segment,
extracting PDUs from it and possibly doing reassembly. Make the COPS,
DNS, DSI, Gryphon, and SCCP dissectors use it.
Add "set_actual_length()", "tcp_dissect_pdus()",
"decode_boolean_bitfield()", "decode_numeric_bitfield()", and
"decode_enumerated_bitfield()" to the list of routines available to
dissectors on platforms where routines in the main program aren't
available to dynamically-loaded code.
Declare routines in "to_str.h" as "extern"; as I remember, that's
necessary to allow the "decode_XXX_bitfield()" routines declared therein
to be made available to plugins as per the above.
Note that new exported routines should be added to the end of the table
if that's the only change being made to the table.
Create a new "plugin_api_decls.h" header file, used to declare both the
"p_" variables and the "p_" structure members in the routine-exporting
mechanism; this reduces the number of places you have to change to
change the list of exported routines.
svn path=/trunk/; revision=5394
2002-05-05 00:16:38 +00:00
|
|
|
proto_tree_add_item(dns_tree, hf_dns_length, tvb, offset - 2, 2, FALSE);
|
2001-07-02 07:29:03 +00:00
|
|
|
}
|
|
|
|
|
2001-07-02 07:11:40 +00:00
|
|
|
proto_tree_add_uint(dns_tree, hf_dns_transaction_id, tvb,
|
1999-10-16 15:08:11 +00:00
|
|
|
offset + DNS_ID, 2, id);
|
1999-01-04 09:13:46 +00:00
|
|
|
|
2002-05-15 07:24:20 +00:00
|
|
|
strcpy(buf, val_to_str(opcode, opcode_vals, "Unknown operation"));
|
1999-01-04 09:13:46 +00:00
|
|
|
if (flags & F_RESPONSE) {
|
|
|
|
strcat(buf, " response");
|
|
|
|
strcat(buf, ", ");
|
|
|
|
strcat(buf, val_to_str(flags & F_RCODE, rcode_vals,
|
1999-01-05 09:01:42 +00:00
|
|
|
"Unknown error"));
|
1999-01-04 09:13:46 +00:00
|
|
|
}
|
2001-07-02 07:11:40 +00:00
|
|
|
tf = proto_tree_add_uint_format(dns_tree, hf_dns_flags, tvb,
|
1999-10-16 15:08:11 +00:00
|
|
|
offset + DNS_FLAGS, 2,
|
|
|
|
flags,
|
|
|
|
"Flags: 0x%04x (%s)",
|
|
|
|
flags, buf);
|
1999-11-16 11:44:20 +00:00
|
|
|
field_tree = proto_item_add_subtree(tf, ett_dns_flags);
|
2002-05-15 07:24:20 +00:00
|
|
|
proto_tree_add_item(field_tree, hf_dns_flags_response,
|
|
|
|
tvb, offset + DNS_FLAGS, 2, FALSE);
|
|
|
|
proto_tree_add_item(field_tree, hf_dns_flags_opcode,
|
|
|
|
tvb, offset + DNS_FLAGS, 2, FALSE);
|
1999-01-04 09:13:46 +00:00
|
|
|
if (flags & F_RESPONSE) {
|
2002-05-15 07:24:20 +00:00
|
|
|
proto_tree_add_item(field_tree, hf_dns_flags_authoritative,
|
|
|
|
tvb, offset + DNS_FLAGS, 2, FALSE);
|
2000-04-26 12:01:50 +00:00
|
|
|
}
|
2002-05-15 07:24:20 +00:00
|
|
|
proto_tree_add_item(field_tree, hf_dns_flags_truncated,
|
|
|
|
tvb, offset + DNS_FLAGS, 2, FALSE);
|
|
|
|
proto_tree_add_item(field_tree, hf_dns_flags_recdesired,
|
|
|
|
tvb, offset + DNS_FLAGS, 2, FALSE);
|
2000-04-26 12:01:50 +00:00
|
|
|
if (flags & F_RESPONSE) {
|
2002-05-15 07:24:20 +00:00
|
|
|
proto_tree_add_item(field_tree, hf_dns_flags_recavail,
|
|
|
|
tvb, offset + DNS_FLAGS, 2, FALSE);
|
|
|
|
proto_tree_add_item(field_tree, hf_dns_flags_authenticated,
|
|
|
|
tvb, offset + DNS_FLAGS, 2, FALSE);
|
|
|
|
proto_tree_add_item(field_tree, hf_dns_flags_rcode,
|
|
|
|
tvb, offset + DNS_FLAGS, 2, FALSE);
|
|
|
|
} else {
|
|
|
|
proto_tree_add_item(field_tree, hf_dns_flags_checkdisable,
|
|
|
|
tvb, offset + DNS_FLAGS, 2, FALSE);
|
1999-01-04 09:13:46 +00:00
|
|
|
}
|
2001-07-02 07:11:40 +00:00
|
|
|
}
|
|
|
|
quest = tvb_get_ntohs(tvb, offset + DNS_QUEST);
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_uint(dns_tree, hf_dns_count_questions, tvb,
|
1999-10-16 15:08:11 +00:00
|
|
|
offset + DNS_QUEST, 2, quest);
|
2001-07-02 07:11:40 +00:00
|
|
|
}
|
|
|
|
ans = tvb_get_ntohs(tvb, offset + DNS_ANS);
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_uint(dns_tree, hf_dns_count_answers, tvb,
|
1999-10-16 15:08:11 +00:00
|
|
|
offset + DNS_ANS, 2, ans);
|
2001-07-02 07:11:40 +00:00
|
|
|
}
|
|
|
|
auth = tvb_get_ntohs(tvb, offset + DNS_AUTH);
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_uint(dns_tree, hf_dns_count_auth_rr, tvb,
|
1999-10-16 15:08:11 +00:00
|
|
|
offset + DNS_AUTH, 2, auth);
|
2001-07-02 07:11:40 +00:00
|
|
|
}
|
|
|
|
add = tvb_get_ntohs(tvb, offset + DNS_ADD);
|
|
|
|
if (tree) {
|
|
|
|
proto_tree_add_uint(dns_tree, hf_dns_count_add_rr, tvb,
|
1999-10-16 15:08:11 +00:00
|
|
|
offset + DNS_ADD, 2, add);
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1999-11-07 21:00:40 +00:00
|
|
|
}
|
|
|
|
cur_off = offset + DNS_HDRLEN;
|
|
|
|
|
|
|
|
if (quest > 0) {
|
|
|
|
/* If this is a response, don't add information about the queries
|
|
|
|
to the summary, just add information about the answers. */
|
2001-07-02 07:11:40 +00:00
|
|
|
cur_off += dissect_query_records(tvb, cur_off, dns_data_offset, quest,
|
2001-12-10 00:26:21 +00:00
|
|
|
(!(flags & F_RESPONSE) ? cinfo : NULL),
|
2001-09-17 00:36:04 +00:00
|
|
|
dns_tree, isupdate);
|
1999-11-07 21:00:40 +00:00
|
|
|
}
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1999-11-07 21:00:40 +00:00
|
|
|
if (ans > 0) {
|
|
|
|
/* If this is a request, don't add information about the answers
|
|
|
|
to the summary, just add information about the queries. */
|
2001-07-02 07:11:40 +00:00
|
|
|
cur_off += dissect_answer_records(tvb, cur_off, dns_data_offset, ans,
|
2001-12-10 00:26:21 +00:00
|
|
|
((flags & F_RESPONSE) ? cinfo : NULL),
|
2001-09-17 00:36:04 +00:00
|
|
|
dns_tree,
|
|
|
|
(isupdate ? "Prerequisites" : "Answers"));
|
1999-11-07 21:00:40 +00:00
|
|
|
}
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2001-09-17 00:36:04 +00:00
|
|
|
/* Don't add information about the authoritative name servers, or the
|
|
|
|
additional records, to the summary. */
|
|
|
|
if (auth > 0) {
|
|
|
|
cur_off += dissect_answer_records(tvb, cur_off, dns_data_offset, auth,
|
|
|
|
NULL, dns_tree,
|
|
|
|
(isupdate ? "Updates" :
|
|
|
|
"Authoritative nameservers"));
|
|
|
|
}
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2001-09-17 00:36:04 +00:00
|
|
|
if (add > 0) {
|
|
|
|
cur_off += dissect_answer_records(tvb, cur_off, dns_data_offset, add,
|
|
|
|
NULL, dns_tree, "Additional records");
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
}
|
1999-07-29 05:47:07 +00:00
|
|
|
|
2000-10-11 04:12:06 +00:00
|
|
|
static void
|
2001-07-02 07:11:40 +00:00
|
|
|
dissect_dns_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|
|
|
{
|
Make a "tcp_dissect_pdus()" with the standard loop for a TCP segment,
extracting PDUs from it and possibly doing reassembly. Make the COPS,
DNS, DSI, Gryphon, and SCCP dissectors use it.
Add "set_actual_length()", "tcp_dissect_pdus()",
"decode_boolean_bitfield()", "decode_numeric_bitfield()", and
"decode_enumerated_bitfield()" to the list of routines available to
dissectors on platforms where routines in the main program aren't
available to dynamically-loaded code.
Declare routines in "to_str.h" as "extern"; as I remember, that's
necessary to allow the "decode_XXX_bitfield()" routines declared therein
to be made available to plugins as per the above.
Note that new exported routines should be added to the end of the table
if that's the only change being made to the table.
Create a new "plugin_api_decls.h" header file, used to declare both the
"p_" variables and the "p_" structure members in the routine-exporting
mechanism; this reduces the number of places you have to change to
change the list of exported routines.
svn path=/trunk/; revision=5394
2002-05-05 00:16:38 +00:00
|
|
|
dissect_dns_common(tvb, pinfo, tree, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static guint
|
|
|
|
get_dns_pdu_len(tvbuff_t *tvb, int offset)
|
|
|
|
{
|
|
|
|
guint16 plen;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the length of the DNS packet.
|
|
|
|
*/
|
|
|
|
plen = tvb_get_ntohs(tvb, offset);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* That length doesn't include the length field itself; add that in.
|
|
|
|
*/
|
|
|
|
return plen + 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dissect_dns_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|
|
|
{
|
|
|
|
dissect_dns_common(tvb, pinfo, tree, TRUE);
|
2001-07-02 07:11:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dissect_dns_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
2000-10-11 04:12:06 +00:00
|
|
|
{
|
Make a "tcp_dissect_pdus()" with the standard loop for a TCP segment,
extracting PDUs from it and possibly doing reassembly. Make the COPS,
DNS, DSI, Gryphon, and SCCP dissectors use it.
Add "set_actual_length()", "tcp_dissect_pdus()",
"decode_boolean_bitfield()", "decode_numeric_bitfield()", and
"decode_enumerated_bitfield()" to the list of routines available to
dissectors on platforms where routines in the main program aren't
available to dynamically-loaded code.
Declare routines in "to_str.h" as "extern"; as I remember, that's
necessary to allow the "decode_XXX_bitfield()" routines declared therein
to be made available to plugins as per the above.
Note that new exported routines should be added to the end of the table
if that's the only change being made to the table.
Create a new "plugin_api_decls.h" header file, used to declare both the
"p_" variables and the "p_" structure members in the routine-exporting
mechanism; this reduces the number of places you have to change to
change the list of exported routines.
svn path=/trunk/; revision=5394
2002-05-05 00:16:38 +00:00
|
|
|
tcp_dissect_pdus(tvb, pinfo, tree, dns_desegment, 2, get_dns_pdu_len,
|
|
|
|
dissect_dns_tcp_pdu);
|
2000-10-11 04:12:06 +00:00
|
|
|
}
|
|
|
|
|
1999-07-29 05:47:07 +00:00
|
|
|
void
|
|
|
|
proto_register_dns(void)
|
|
|
|
{
|
1999-10-16 15:08:11 +00:00
|
|
|
static hf_register_info hf[] = {
|
2001-07-02 07:29:03 +00:00
|
|
|
{ &hf_dns_length,
|
2002-05-15 07:24:20 +00:00
|
|
|
{ "Length", "dns.length",
|
2001-07-02 07:29:03 +00:00
|
|
|
FT_UINT16, BASE_DEC, NULL, 0x0,
|
|
|
|
"Length of DNS-over-TCP request or response", HFILL }},
|
1999-10-16 15:08:11 +00:00
|
|
|
{ &hf_dns_flags,
|
2002-05-15 07:24:20 +00:00
|
|
|
{ "Flags", "dns.flags",
|
1999-10-16 15:08:11 +00:00
|
|
|
FT_UINT16, BASE_HEX, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"", HFILL }},
|
2002-05-15 07:24:20 +00:00
|
|
|
{ &hf_dns_flags_response,
|
|
|
|
{ "Response", "dns.flags.response",
|
|
|
|
FT_BOOLEAN, 16, TFS(&tfs_flags_response), F_RESPONSE,
|
|
|
|
"Is the message a response?", HFILL }},
|
|
|
|
{ &hf_dns_flags_opcode,
|
|
|
|
{ "Opcode", "dns.flags.opcode",
|
|
|
|
FT_UINT16, BASE_DEC, VALS(opcode_vals), F_OPCODE,
|
|
|
|
"Operation code", HFILL }},
|
|
|
|
{ &hf_dns_flags_authoritative,
|
|
|
|
{ "Authoritative", "dns.flags.authoritative",
|
|
|
|
FT_BOOLEAN, 16, TFS(&tfs_flags_authoritative), F_AUTHORITATIVE,
|
|
|
|
"Is the server is an authority for the domain?", HFILL }},
|
|
|
|
{ &hf_dns_flags_truncated,
|
|
|
|
{ "Truncated", "dns.flags.truncated",
|
|
|
|
FT_BOOLEAN, 16, TFS(&tfs_flags_truncated), F_TRUNCATED,
|
|
|
|
"Is the message truncated?", HFILL }},
|
|
|
|
{ &hf_dns_flags_recdesired,
|
|
|
|
{ "Recursion desired", "dns.flags.recdesired",
|
|
|
|
FT_BOOLEAN, 16, TFS(&tfs_flags_recdesired), F_RECDESIRED,
|
|
|
|
"Do query recursively?", HFILL }},
|
|
|
|
{ &hf_dns_flags_recavail,
|
|
|
|
{ "Recursion available", "dns.flags.recavail",
|
|
|
|
FT_BOOLEAN, 16, TFS(&tfs_flags_recavail), F_RECAVAIL,
|
|
|
|
"Can the server do recursive queries?", HFILL }},
|
|
|
|
{ &hf_dns_flags_authenticated,
|
|
|
|
{ "Answer authenticated", "dns.flags.authenticated",
|
|
|
|
FT_BOOLEAN, 16, TFS(&tfs_flags_authenticated), F_AUTHENTIC,
|
|
|
|
"Was the reply data authenticated by the server?", HFILL }},
|
|
|
|
{ &hf_dns_flags_checkdisable,
|
|
|
|
{ "Non-authenticated data OK", "dns.flags.checkdisable",
|
|
|
|
FT_BOOLEAN, 16, TFS(&tfs_flags_checkdisable), F_CHECKDISABLE,
|
|
|
|
"Is non-authenticated data acceptable?", HFILL }},
|
|
|
|
{ &hf_dns_flags_rcode,
|
|
|
|
{ "Reply code", "dns.flags.rcode",
|
|
|
|
FT_UINT16, BASE_DEC, VALS(rcode_vals), F_RCODE,
|
|
|
|
"Reply code", HFILL }},
|
1999-10-16 15:08:11 +00:00
|
|
|
{ &hf_dns_transaction_id,
|
|
|
|
{ "Transaction ID", "dns.id",
|
|
|
|
FT_UINT16, BASE_HEX, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Identification of transaction", HFILL }},
|
1999-10-16 15:08:11 +00:00
|
|
|
{ &hf_dns_count_questions,
|
|
|
|
{ "Questions", "dns.count.queries",
|
|
|
|
FT_UINT16, BASE_DEC, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Number of queries in packet", HFILL }},
|
1999-10-16 15:08:11 +00:00
|
|
|
{ &hf_dns_count_answers,
|
|
|
|
{ "Answer RRs", "dns.count.answers",
|
|
|
|
FT_UINT16, BASE_DEC, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Number of answers in packet", HFILL }},
|
1999-10-16 15:08:11 +00:00
|
|
|
{ &hf_dns_count_auth_rr,
|
|
|
|
{ "Authority RRs", "dns.count.auth_rr",
|
|
|
|
FT_UINT16, BASE_DEC, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Number of authoritative records in packet", HFILL }},
|
1999-10-16 15:08:11 +00:00
|
|
|
{ &hf_dns_count_add_rr,
|
|
|
|
{ "Additional RRs", "dns.count.add_rr",
|
|
|
|
FT_UINT16, BASE_DEC, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Number of additional records in packet", HFILL }}
|
1999-10-16 15:08:11 +00:00
|
|
|
};
|
1999-11-16 11:44:20 +00:00
|
|
|
static gint *ett[] = {
|
|
|
|
&ett_dns,
|
|
|
|
&ett_dns_qd,
|
|
|
|
&ett_dns_rr,
|
|
|
|
&ett_dns_qry,
|
|
|
|
&ett_dns_ans,
|
|
|
|
&ett_dns_flags,
|
1999-11-27 08:59:28 +00:00
|
|
|
&ett_t_key_flags,
|
1999-11-16 11:44:20 +00:00
|
|
|
};
|
2001-09-17 02:07:00 +00:00
|
|
|
module_t *dns_module;
|
1999-10-16 15:08:11 +00:00
|
|
|
|
2001-01-03 06:56:03 +00:00
|
|
|
proto_dns = proto_register_protocol("Domain Name Service", "DNS", "dns");
|
1999-10-16 15:08:11 +00:00
|
|
|
proto_register_field_array(proto_dns, hf, array_length(hf));
|
1999-11-16 11:44:20 +00:00
|
|
|
proto_register_subtree_array(ett, array_length(ett));
|
2001-09-17 02:07:00 +00:00
|
|
|
|
|
|
|
dns_module = prefs_register_protocol(proto_dns, NULL);
|
|
|
|
prefs_register_bool_preference(dns_module, "desegment_dns_messages",
|
|
|
|
"Desegment all DNS messages spanning multiple TCP segments",
|
|
|
|
"Whether the DNS dissector should desegment all messages spanning multiple TCP segments",
|
|
|
|
&dns_desegment);
|
1999-07-29 05:47:07 +00:00
|
|
|
}
|
2000-04-04 06:17:30 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
proto_reg_handoff_dns(void)
|
|
|
|
{
|
2001-12-03 04:00:26 +00:00
|
|
|
dissector_handle_t dns_udp_handle;
|
|
|
|
dissector_handle_t dns_tcp_handle;
|
|
|
|
|
|
|
|
dns_udp_handle = create_dissector_handle(dissect_dns_udp, proto_dns);
|
|
|
|
dns_tcp_handle = create_dissector_handle(dissect_dns_tcp, proto_dns);
|
|
|
|
dissector_add("udp.port", UDP_PORT_DNS, dns_udp_handle);
|
|
|
|
dissector_add("tcp.port", TCP_PORT_DNS, dns_tcp_handle);
|
2000-04-04 06:17:30 +00:00
|
|
|
}
|