Ethereal-dev: [Ethereal-dev] lots of new DNS stuff
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Brian Wellington <bwelling@xxxxxxxxx>
Date: Tue, 10 Oct 2000 13:10:15 -0700 (PDT)
Hi. I added support for some new DNS record types (CERT, KX, TSIG, TKEY), recognition of additional opcodes (NOTIFY, UPDATE), rcodes (YXDOMAIN, YXRRSET, NXRRSET, NOTAUTH, NOTZONE, and the TSIG/TKEY errors), and partial (but not very good) support for decoding of TCP messages. The patch is included below. I'm going to try and get full TCP decoding working, if I can figure out conversations... Brian ----- Index: packet-dns.c =================================================================== RCS file: /cvsroot/ethereal/packet-dns.c,v retrieving revision 1.54 diff -u -r1.54 packet-dns.c --- packet-dns.c 2000/10/02 17:42:29 1.54 +++ packet-dns.c 2000/10/10 19:56:43 @@ -61,8 +61,9 @@ /* DNS structs and definitions */ -/* Port used for DNS. */ +/* Ports used for DNS. */ #define UDP_PORT_DNS 53 +#define TCP_PORT_DNS 53 /* Offsets of fields in the DNS header. */ #define DNS_ID 0 @@ -99,21 +100,25 @@ #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) */ -#define T_SIG 24 /* digital signature (RFC 2065) */ -#define T_KEY 25 /* public key (RFC 2065) */ +#define T_SIG 24 /* digital signature (RFC 2535) */ +#define T_KEY 25 /* public key (RFC 2535) */ #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) */ -#define T_NXT 30 /* "next" name (RFC 2065) */ +#define T_NXT 30 /* "next" name (RFC 2535) */ #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) */ +#define T_KX 36 /* Key Exchange (RFC 2230) */ +#define T_CERT 37 /* Certificate (RFC 2538) */ #define T_A6 38 /* IPv6 address with indirection (RFC 2874) */ #define T_DNAME 39 /* Non-terminal DNS name redirection (RFC 2672) */ #define T_OPT 41 /* OPT pseudo-RR (RFC 2671) */ +#define T_TKEY 249 /* Transaction Key (RFC 2930) */ +#define T_TSIG 250 /* Transaction Signature (RFC 2845) */ #define T_WINS 65281 /* Microsoft's WINS RR */ #define T_WINS_R 65282 /* Microsoft's WINS-R RR */ @@ -122,6 +127,8 @@ #define C_CS 2 /* CSNET (obsolete) */ #define C_CH 3 /* CHAOS */ #define C_HS 4 /* Hesiod */ +#define C_NONE 254 /* none */ +#define C_ANY 255 /* any */ /* Bit fields in the flags */ #define F_RESPONSE (1<<15) /* packet is response */ @@ -138,14 +145,58 @@ #define OPCODE_QUERY (0<<11) /* standard query */ #define OPCODE_IQUERY (1<<11) /* inverse query */ #define OPCODE_STATUS (2<<11) /* server status request */ +#define OPCODE_NOTIFY (4<<11) /* zone change notification */ +#define OPCODE_UPDATE (5<<11) /* dynamic update */ /* Reply codes */ #define RCODE_NOERROR (0<<0) -#define RCODE_FMTERROR (1<<0) +#define RCODE_FORMERR (1<<0) #define RCODE_SERVFAIL (2<<0) -#define RCODE_NAMEERROR (3<<0) +#define RCODE_NXDOMAIN (3<<0) #define RCODE_NOTIMPL (4<<0) #define RCODE_REFUSED (5<<0) +#define RCODE_YXDOMAIN (6<<0) +#define RCODE_YXRRSET (7<<0) +#define RCODE_NXRRSET (8<<0) +#define RCODE_NOTAUTH (9<<0) +#define RCODE_NOTZONE (10<<0) + +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) /* 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 @@ -186,20 +237,20 @@ "RT", /* RFC 1183 */ "NSAP", /* RFC 1706 */ "NSAP-PTR", /* RFC 1348 */ - "SIG", /* RFC 2065 */ - "KEY", /* RFC 2065 */ + "SIG", /* RFC 2535 */ + "KEY", /* RFC 2535 */ "PX", /* RFC 1664 */ "GPOS", /* RFC 1712 */ "AAAA", /* RFC 1886 */ "LOC", /* RFC 1876 */ - "NXT", /* RFC 2065 */ + "NXT", /* RFC 2535 */ "EID", "NIMLOC", "SRV", /* RFC 2052 */ "ATMA", "NAPTR", /* RFC 2168 */ - NULL, - NULL, + "KX", /* RFC 2230 */ + "CERT", /* RFC 2538 */ "A6", /* RFC 2874 */ "DNAME", /* RFC 2672 */ NULL, @@ -226,6 +277,12 @@ case T_WINS_R: return "WINS-R"; + /* meta */ + case T_TKEY: + return "TKEY"; + case T_TSIG: + return "TSIG"; + /* queries */ case 251: return "IXFR"; /* RFC 1995 */ @@ -272,20 +329,20 @@ "Route through", /* RFC 1183 */ "OSI NSAP", /* RFC 1706 */ "OSI NSAP name pointer", /* RFC 1348 */ - "Signature", /* RFC 2065 */ - "Public key", /* RFC 2065 */ + "Signature", /* RFC 2535 */ + "Public key", /* RFC 2535 */ "Pointer to X.400/RFC822 mapping info", /* RFC 1664 */ "Geographical position", /* RFC 1712 */ "IPv6 address", /* RFC 1886 */ "Location", /* RFC 1876 */ - "Next", /* RFC 2065 */ + "Next", /* RFC 2535 */ "EID", "NIMLOC", "Service location", /* RFC 2052 */ "ATMA", "Naming authority pointer", /* RFC 2168 */ - NULL, - NULL, + "Key Exchange", /* RFC 2230 */ + "Certificate", /* RFC 2538 */ "IPv6 address with indirection", /* RFC 2874 */ "Non-terminal DNS name redirection", /* RFC 2672 */ NULL, @@ -313,6 +370,12 @@ case T_WINS_R: return "WINS-R"; + /* meta */ + case T_TKEY: + return "Transaction Key"; + case T_TSIG: + return "Transaction Signature"; + /* queries */ case 251: return "Request for incremental zone transfer"; /* RFC 1995 */ @@ -349,6 +412,12 @@ case C_HS: class_name = "hesiod"; break; + case C_NONE: + class_name = "none"; + break; + case C_ANY: + class_name = "any"; + break; default: class_name = "unknown"; } @@ -667,7 +736,7 @@ } /* - * SIG and KEY RR algorithms. + * SIG, KEY, and CERT RR algorithms. */ #define DNS_ALGO_RSAMD5 1 /* RSA/MD5 */ #define DNS_ALGO_DH 2 /* Diffie-Hellman */ @@ -688,6 +757,21 @@ { 0, NULL } }; +#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 } +}; + static int dissect_dns_answer(const u_char *pd, int offset, int dns_data_offset, frame_data *fd, proto_tree *dns_tree) @@ -1592,6 +1676,103 @@ } break; + case T_KX: + { + guint16 preference = 0; + char kx_name[MAXDNAME]; + int kx_name_len; + + if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { + /* We ran past the end of the captured data in the packet. */ + if (dns_tree != NULL) { + proto_item_set_text(trr, + "%s: type %s, class %s, <preference goes past end of captured data in packet>", + name, type_name, class_name); + } + return 0; + } + preference = pntohs(&pd[cur_offset]); + kx_name_len = get_dns_name(pd, cur_offset + 2, dns_data_offset, kx_name, sizeof(kx_name)); + if (kx_name_len < 0) { + /* We ran past the end of the captured data in the packet. */ + if (dns_tree != NULL) { + proto_item_set_text(trr, + "%s: type %s, class %s, preference %u, <kx goes past end of captured data in packet>", + name, type_name, class_name, preference); + } + return 0; + } + if (fd != NULL) + col_append_fstr(fd, COL_INFO, " %u %s", preference, kx_name); + if (dns_tree != NULL) { + proto_item_set_text(trr, + "%s: type %s, class %s, preference %u, kx %s", + name, type_name, class_name, preference, kx_name); + proto_tree_add_text(rr_tree, NullTVB, cur_offset, 2, "Preference: %u", preference); + proto_tree_add_text(rr_tree, NullTVB, cur_offset + 2, kx_name_len, "Key exchange: %s", + kx_name); + } + } + break; + + case T_CERT: + { + guint16 cert_type, cert_keytag; + guint8 cert_keyalg; + int rr_len = data_len; + + if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { + /* We ran past the end of the captured data in the packet. */ + if (dns_tree != NULL) { + proto_item_set_text(trr, + "%s: type %s, class %s, <preference goes past end of captured data in packet>", + name, type_name, class_name); + } + return 0; + } + cert_type = pntohs(&pd[cur_offset]); + cur_offset += 2; + rr_len -= 2; + if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { + /* We ran past the end of the captured data in the packet. */ + if (dns_tree != NULL) { + proto_item_set_text(trr, + "%s: type %s, class %s, <preference goes past end of captured data in packet>", + name, type_name, class_name); + } + return 0; + } + cert_keytag = pntohs(&pd[cur_offset]); + cur_offset += 2; + rr_len -= 2; + if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { + /* We ran past the end of the captured data in the packet. */ + if (dns_tree != NULL) { + proto_item_set_text(trr, + "%s: type %s, class %s, <preference goes past end of captured data in packet>", + name, type_name, class_name); + } + return 0; + } + cert_keyalg = pd[cur_offset]; + cur_offset += 1; + rr_len -= 1; + + if (dns_tree != NULL) { + proto_tree_add_text(rr_tree, NullTVB, cur_offset, 1, "Type: %s", + val_to_str(cert_keyalg, cert_vals, + "Unknown (0x%02X)")); + proto_tree_add_text(rr_tree, NullTVB, cur_offset, 2, "Key footprint: 0x%04x", + cert_keytag); + proto_tree_add_text(rr_tree, NullTVB, cur_offset, 1, "Algorithm: %s", + val_to_str(cert_keyalg, algo_vals, + "Unknown (0x%02X)")); + proto_tree_add_text(rr_tree, NullTVB, cur_offset, rr_len, "Public key"); + } + + } + break; + case T_OPT: if (dns_tree != NULL) { proto_item_set_text(trr, "%s: type %s", name, type_name); @@ -1599,6 +1780,221 @@ } break; + 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; + struct timeval unixtime; + static const value_string tkey_modes[] = { + { TKEYMODE_SERVERASSIGNED, "Server assigned" }, + { TKEYMODE_DIFFIEHELLMAN, "Diffie Hellman" }, + { TKEYMODE_GSSAPI, "GSSAPI " }, + { TKEYMODE_RESOLVERASSIGNED, "Resolver assigned" }, + { TKEYMODE_DELETE, "Delete" }, + { 0, NULL } }; + + if (dns_tree != NULL) { + proto_item_set_text(trr, + "%s: type %s, class %s", name, type_name, class_name); + tkey_algname_len = get_dns_name(pd, cur_offset, dns_data_offset, tkey_algname, sizeof(tkey_algname)); + if (tkey_algname_len < 0) { + /* We ran past the end of the captured data in the packet. */ + return 0; + } + proto_tree_add_text(rr_tree, NullTVB, cur_offset, tkey_algname_len, + "Algorithm name: %s", tkey_algname); + cur_offset += tkey_algname_len; + rr_len -= tkey_algname_len; + + if (!BYTES_ARE_IN_FRAME(cur_offset, 4)) { + /* We ran past the end of the captured data in the packet. */ + return 0; + } + unixtime.tv_sec = pntohl(&pd[cur_offset]); + unixtime.tv_usec = 0; + proto_tree_add_text(rr_tree, NullTVB, cur_offset, 4, "Signature inception: %s", + abs_time_to_str(&unixtime)); + cur_offset += 4; + rr_len -= 4; + + if (!BYTES_ARE_IN_FRAME(cur_offset, 4)) { + /* We ran past the end of the captured data in the packet. */ + return 0; + } + unixtime.tv_sec = pntohl(&pd[cur_offset]); + unixtime.tv_usec = 0; + proto_tree_add_text(rr_tree, NullTVB, cur_offset, 4, "Signature expiration: %s", + abs_time_to_str(&unixtime)); + cur_offset += 4; + rr_len -= 4; + + if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { + /* We ran past the end of the captured data in the packet. */ + return 0; + } + tkey_mode = pntohs(&pd[cur_offset]); + cur_offset += 2; + rr_len -= 2; + proto_tree_add_text(rr_tree, NullTVB, cur_offset, 1, "Mode: %s", + val_to_str(tkey_mode, tkey_modes, + "Unknown (0x%02X)")); + + tkey_error = pntohs(&pd[cur_offset]); + cur_offset += 2; + rr_len -= 2; + + proto_tree_add_text(rr_tree, NullTVB, cur_offset, 4, "Error: %s", + val_to_str(tkey_error, rcode_vals, + val_to_str(tkey_error, tsigerror_vals, "Unknown error (%x)"))); + + tkey_keylen = pntohs(&pd[cur_offset]); + cur_offset += 2; + rr_len -= 2; + + if (!BYTES_ARE_IN_FRAME(cur_offset, tkey_keylen)) { + /* We ran past the end of the captured data in the packet. */ + return 0; + } + + proto_tree_add_text(rr_tree, NullTVB, cur_offset, tkey_keylen, "Key"); + cur_offset += tkey_keylen; + rr_len -= tkey_keylen; + + tkey_otherlen = pntohs(&pd[cur_offset]); + cur_offset += 2; + rr_len -= 2; + + if (!BYTES_ARE_IN_FRAME(cur_offset, tkey_otherlen)) { + /* We ran past the end of the captured data in the packet. */ + return 0; + } + + proto_tree_add_text(rr_tree, NullTVB, cur_offset, tkey_otherlen, "Other"); + cur_offset += tkey_otherlen; + rr_len -= tkey_otherlen; + } + } + break; + + case T_TSIG: + { + guint8 tsig_fudge; + guint16 tsig_originalid, tsig_error, tsig_timehi, tsig_siglen, tsig_otherlen; + guint32 tsig_timelo; + char tsig_algname[MAXDNAME]; + int tsig_algname_len; + struct timeval unixtime; + int rr_len = data_len; + + if (dns_tree != NULL) { + proto_item_set_text(trr, + "%s: type %s, class %s", name, type_name, class_name); + tsig_algname_len = get_dns_name(pd, cur_offset, dns_data_offset, tsig_algname, sizeof(tsig_algname)); + if (tsig_algname_len < 0) { + /* We ran past the end of the captured data in the packet. */ + return 0; + } + proto_tree_add_text(rr_tree, NullTVB, cur_offset, tsig_algname_len, + "Algorithm name: %s", tsig_algname); + cur_offset += tsig_algname_len; + rr_len -= tsig_algname_len; + + if (!BYTES_ARE_IN_FRAME(cur_offset, 6)) { + /* We ran past the end of the captured data in the packet. */ + return 0; + } + + tsig_timehi = pntohs(&pd[cur_offset]); + cur_offset += 2; + rr_len -= 2; + + tsig_timelo = pntohl(&pd[cur_offset]); + cur_offset += 4; + rr_len -= 4; + + unixtime.tv_sec = tsig_timelo; + unixtime.tv_usec = 0; + proto_tree_add_text(rr_tree, NullTVB, cur_offset, 6, "Time signed: %s%s", + abs_time_to_str(&unixtime), tsig_timehi == 0 ? "" : "(high bits set)"); + + if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { + /* We ran past the end of the captured data in the packet. */ + return 0; + } + + tsig_fudge = pntohs(&pd[cur_offset]); + cur_offset += 2; + rr_len -= 2; + + proto_tree_add_text(rr_tree, NullTVB, cur_offset, 2, "Fudge: %d", + tsig_fudge); + + if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { + /* We ran past the end of the captured data in the packet. */ + return 0; + } + + tsig_siglen = pntohs(&pd[cur_offset]); + cur_offset += 2; + rr_len -= 2; + + if (!BYTES_ARE_IN_FRAME(cur_offset, tsig_siglen)) { + /* We ran past the end of the captured data in the packet. */ + return 0; + } + + proto_tree_add_text(rr_tree, NullTVB, cur_offset, tsig_siglen, "Signature"); + cur_offset += tsig_siglen; + rr_len -= tsig_siglen; + + if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { + /* We ran past the end of the captured data in the packet. */ + return 0; + } + + tsig_originalid = pntohs(&pd[cur_offset]); + cur_offset += 2; + rr_len -= 2; + + proto_tree_add_text(rr_tree, NullTVB, cur_offset, 4, "Original id: %d", + tsig_originalid); + + if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { + /* We ran past the end of the captured data in the packet. */ + return 0; + } + + tsig_error = pntohs(&pd[cur_offset]); + cur_offset += 2; + rr_len -= 2; + + proto_tree_add_text(rr_tree, NullTVB, cur_offset, 4, "Error: %s", + val_to_str(tsig_error, rcode_vals, + val_to_str(tsig_error, tsigerror_vals, "Unknown error (%x)"))); + + if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { + /* We ran past the end of the captured data in the packet. */ + return 0; + } + + tsig_otherlen = pntohs(&pd[cur_offset]); + cur_offset += 2; + rr_len -= 2; + + if (!BYTES_ARE_IN_FRAME(cur_offset, tsig_otherlen)) { + /* We ran past the end of the captured data in the packet. */ + return 0; + } + + proto_tree_add_text(rr_tree, NullTVB, cur_offset, tsig_otherlen, "Other"); + cur_offset += tsig_otherlen; + rr_len -= tsig_otherlen; + } + } + break; + case T_WINS: { int rr_len = data_len; @@ -1774,7 +2170,7 @@ static int dissect_query_records(const u_char *pd, int cur_off, int dns_data_offset, - int count, frame_data *fd, proto_tree *dns_tree) + int count, frame_data *fd, proto_tree *dns_tree, int isupdate) { int start_off, add_off; proto_tree *qatree = NULL; @@ -1782,7 +2178,8 @@ start_off = cur_off; if (dns_tree) { - ti = proto_tree_add_text(dns_tree, NullTVB, start_off, 0, "Queries"); + char *s = (isupdate ? "Zone" : "Queries"); + ti = proto_tree_add_text(dns_tree, NullTVB, start_off, 0, s); qatree = proto_item_add_subtree(ti, ett_dns_qry); } while (count-- > 0) { @@ -1835,19 +2232,14 @@ guint16 id, flags, quest, ans, auth, add; char buf[128+1]; int cur_off; + int isupdate; static const value_string opcode_vals[] = { - { OPCODE_QUERY, "Standard query" }, - { OPCODE_IQUERY, "Inverse query" }, - { OPCODE_STATUS, "Server status request" }, - { 0, NULL } }; - static const value_string rcode_vals[] = { - { RCODE_NOERROR, "No error" }, - { RCODE_FMTERROR, "Format error" }, - { RCODE_SERVFAIL, "Server failure" }, - { RCODE_NAMEERROR, "Name error" }, - { RCODE_NOTIMPL, "Not implemented" }, - { RCODE_REFUSED, "Refused" }, - { 0, NULL } }; + { OPCODE_QUERY, "Standard query" }, + { OPCODE_IQUERY, "Inverse query" }, + { OPCODE_STATUS, "Server status request" }, + { OPCODE_NOTIFY, "Zone change notification" }, + { OPCODE_UPDATE, "Dynamic update" }, + { 0, NULL } }; OLD_CHECK_DISPLAY_AS_DATA(proto_dns, pd, offset, fd, tree); @@ -1856,7 +2248,7 @@ if (check_col(fd, COL_PROTOCOL)) col_add_str(fd, COL_PROTOCOL, "DNS"); - if (pi.captured_len < DNS_HDRLEN) { + if (!BYTES_ARE_IN_FRAME(offset, DNS_HDRLEN)) { col_add_str(fd, COL_INFO, "Short DNS packet"); old_dissect_data(pd, offset, fd, tree); return; @@ -1888,6 +2280,10 @@ is more expensive than a check that a pointer isn't NULL). */ fd = NULL; } + if ((flags & F_OPCODE) == OPCODE_UPDATE) + isupdate = 1; + else + isupdate = 0; if (tree) { ti = proto_tree_add_protocol_format(tree, proto_dns, NullTVB, offset, 4, @@ -1980,23 +2376,26 @@ to the summary, just add information about the answers. */ cur_off += dissect_query_records(pd, cur_off, dns_data_offset, quest, (!(flags & F_RESPONSE) ? fd : NULL), - dns_tree); + dns_tree, isupdate); } if (ans > 0) { /* If this is a request, don't add information about the answers to the summary, just add information about the queries. */ + char *s = (isupdate ? "Prerequisites" : "Answers"); cur_off += dissect_answer_records(pd, cur_off, dns_data_offset, ans, ((flags & F_RESPONSE) ? fd : NULL), - dns_tree, "Answers"); + dns_tree, s); } if (tree) { /* Don't add information about the authoritative name servers, or the additional records, to the summary. */ - if (auth > 0) + if (auth > 0) { + char *s = (isupdate ? "Updates" : "Authoritative nameservers"); cur_off += dissect_answer_records(pd, cur_off, dns_data_offset, auth, - NULL, dns_tree, "Authoritative nameservers"); + NULL, dns_tree, s); + } if (add > 0) cur_off += dissect_answer_records(pd, cur_off, dns_data_offset, add, @@ -2004,6 +2403,20 @@ } } +static void +dissect_dns_tcp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) +{ + guint16 plen; + + if (pi.captured_len < 2) + return; + plen = pntohs(&pd[offset]); + offset += 2; + if (END_OF_FRAME != plen) + return; + dissect_dns(pd, offset, fd, tree); +} + void proto_register_dns(void) { @@ -2060,4 +2473,5 @@ proto_reg_handoff_dns(void) { old_dissector_add("udp.port", UDP_PORT_DNS, dissect_dns); + old_dissector_add("tcp.port", TCP_PORT_DNS, dissect_dns_tcp); }
- Follow-Ups:
- Re: [Ethereal-dev] lots of new DNS stuff
- From: Guy Harris
- Re: [Ethereal-dev] lots of new DNS stuff
- Prev by Date: Re: [Ethereal-dev] proto_tree_add_bytes_hidden has a const char * type argument
- Next by Date: [Ethereal-dev] add "/Capture/Stop" menu item
- Previous by thread: Re: [Ethereal-dev] Ethereal bug
- Next by thread: Re: [Ethereal-dev] lots of new DNS stuff
- Index(es):