2 * Routines for light weight reslover (lwres, part of BIND9) packet disassembly
4 * Copyright (c) 2003 by Oleg Terletsky <oleg.terletsky@comverse.com>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1999 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
16 #include <epan/packet.h>
17 #include <epan/to_str.h>
18 #include <epan/strutil.h>
20 #include "packet-dns.h"
22 void proto_register_lwres(void);
23 void proto_reg_handoff_lwres(void);
25 static dissector_handle_t lwres_handle
;
27 #define LWRES_LWPACKET_LENGTH (4 * 5 + 2 * 4)
28 #define LWRES_LWPACKETFLAG_RESPONSE 0x0001U /* if set, pkt is a response */
29 #define LWRES_LWPACKETVERSION_0 0
31 #define LW_LENGTH_OFFSET 0
32 #define LW_VERSION_OFFSET 4
33 #define LW_PKTFLASG_OFFSET 6
34 #define LW_SERIAL_OFFSET 8
35 #define LW_OPCODE_OFFSET 12
36 #define LW_RESULT_OFFSET 16
37 #define LW_RECVLEN_OFFSET 20
38 #define LW_AUTHTYPE_OFFSET 24
39 #define LW_AUTHLEN_OFFSET 26
41 #define LWRES_OPCODE_NOOP 0x00000000U
42 #define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U
43 #define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U
44 #define LWRES_OPCODE_GETRDATABYNAME 0x00010003U
46 static const value_string opcode_values
[] = {
47 { LWRES_OPCODE_NOOP
, "Noop" },
48 { LWRES_OPCODE_GETADDRSBYNAME
, "getaddrbyname" },
49 { LWRES_OPCODE_GETNAMEBYADDR
, "getnamebyaddr" },
50 { LWRES_OPCODE_GETRDATABYNAME
, "getrdatabyname" },
55 #define LWRES_R_SUCCESS 0
56 #define LWRES_R_NOMEMORY 1
57 #define LWRES_R_TIMEOUT 2
58 #define LWRES_R_NOTFOUND 3
59 #define LWRES_R_UNEXPECTEDEND 4 /* unexpected end of input */
60 #define LWRES_R_FAILURE 5 /* generic failure */
61 #define LWRES_R_IOERROR 6
62 #define LWRES_R_NOTIMPLEMENTED 7
63 #define LWRES_R_UNEXPECTED 8
64 #define LWRES_R_TRAILINGDATA 9
65 #define LWRES_R_INCOMPLETE 10
66 #define LWRES_R_RETRY 11
67 #define LWRES_R_TYPENOTFOUND 12
68 #define LWRES_R_TOOLARGE 13
76 static const value_string t_types
[] = {
87 static const value_string result_values
[] = {
88 { LWRES_R_SUCCESS
, "Success" },
89 { LWRES_R_NOMEMORY
, "No memory" },
90 { LWRES_R_TIMEOUT
, "Timeout" },
91 { LWRES_R_NOTFOUND
, "Not found" },
92 { LWRES_R_UNEXPECTEDEND
, "Unexpected end of input" },
93 { LWRES_R_FAILURE
, "Generic failure" },
94 { LWRES_R_IOERROR
, "I/O Error" },
95 { LWRES_R_NOTIMPLEMENTED
, "Not Implemented"},
96 { LWRES_R_UNEXPECTED
, "Unexpected" },
97 { LWRES_R_TRAILINGDATA
, "Trailing data" },
98 { LWRES_R_INCOMPLETE
, "Incomplete" },
99 { LWRES_R_RETRY
, "Retry" },
100 { LWRES_R_TYPENOTFOUND
, "Type not found" },
101 { LWRES_R_TOOLARGE
, "Too large" },
105 static int hf_length
;
106 static int hf_version
;
108 static int hf_serial
;
109 static int hf_opcode
;
110 static int hf_result
;
111 static int hf_recvlen
;
112 static int hf_authtype
;
113 static int hf_authlen
;
115 static int hf_rflags
;
116 static int hf_rdclass
;
117 static int hf_rdtype
;
118 static int hf_namelen
;
119 static int hf_req_name
;
122 static int hf_nrdatas
;
124 static int hf_realnamelen
;
125 static int hf_realname
;
128 static int hf_a_record
;
129 static int hf_a_rec_len
;
130 static int hf_srv_prio
;
131 static int hf_srv_weight
;
132 static int hf_srv_port
;
133 static int hf_srv_dname
;
135 static int hf_adn_flags
;
136 static int hf_adn_addrtype
;
137 static int hf_adn_namelen
;
138 static int hf_adn_name
;
140 static int hf_adn_realname
;
141 static int hf_adn_aliasname
;
143 static int hf_adn_naddrs
;
144 static int hf_adn_naliases
;
145 static int hf_adn_family
;
146 static int hf_adn_addr_len
;
147 static int hf_adn_addr_addr
;
149 static int hf_ns_dname
;
151 static int ett_lwres
;
152 static int ett_rdata_req
;
153 static int ett_rdata_resp
;
154 static int ett_a_rec
;
155 static int ett_a_rec_addr
;
156 static int ett_srv_rec
;
157 static int ett_srv_rec_item
;
158 static int ett_adn_request
;
159 static int ett_adn_resp
;
160 static int ett_adn_alias
;
161 static int ett_adn_addr
;
162 static int ett_nba_request
;
163 static int ett_nba_resp
;
166 static int ett_mx_rec
;
167 static int ett_mx_rec_item
;
169 static int ett_ns_rec
;
170 static int ett_ns_rec_item
;
174 #define LWRES_UDP_PORT 921 /* Not IANA registered */
176 /* Define the lwres proto */
177 static int proto_lwres
;
180 /* Define many many headers for mgcp */
182 static const value_string message_types_values
[] = {
188 static void dissect_getnamebyaddr_request(tvbuff_t
* tvb
, packet_info
*pinfo
, proto_tree
* lwres_tree
)
190 uint32_t flags
,family
;
191 unsigned addrlen
, slen
;
194 proto_tree
* nba_request_tree
;
196 flags
= tvb_get_ntohl(tvb
, LWRES_LWPACKET_LENGTH
);
197 family
= tvb_get_ntohl(tvb
, LWRES_LWPACKET_LENGTH
+ 4);
198 addrlen
= tvb_get_ntohs(tvb
, LWRES_LWPACKET_LENGTH
+ 8);
199 addrs
= tvb_ip_to_str(pinfo
->pool
, tvb
, LWRES_LWPACKET_LENGTH
+ 10);
200 slen
= (int)strlen(addrs
);
202 if (lwres_tree
== NULL
)
205 nba_request_tree
= proto_tree_add_subtree(lwres_tree
,tvb
,LWRES_LWPACKET_LENGTH
,LWRES_LWPACKET_LENGTH
+14,
206 ett_nba_request
,NULL
,"getnamebyaddr parameters");
208 proto_tree_add_uint(nba_request_tree
, hf_adn_flags
, tvb
,
209 LWRES_LWPACKET_LENGTH
, 4, flags
);
211 proto_tree_add_uint(nba_request_tree
, hf_adn_family
, tvb
,
212 LWRES_LWPACKET_LENGTH
+ 4, 4, family
);
214 proto_tree_add_uint(nba_request_tree
, hf_adn_addr_len
, tvb
,
215 LWRES_LWPACKET_LENGTH
+ 8, 2, addrlen
);
217 proto_tree_add_string(nba_request_tree
, hf_adn_addr_addr
, tvb
,
218 LWRES_LWPACKET_LENGTH
+ 10, slen
, addrs
);
222 static void dissect_getnamebyaddr_response(tvbuff_t
* tvb
, packet_info
*pinfo
, proto_tree
* lwres_tree
)
225 uint16_t naliases
,realnamelen
,aliaslen
;
228 proto_tree
* nba_resp_tree
;
229 proto_tree
* alias_tree
;
231 if(lwres_tree
== NULL
)
234 nba_resp_tree
= proto_tree_add_subtree(lwres_tree
, tvb
, LWRES_LWPACKET_LENGTH
, 10, ett_nba_resp
, NULL
, "getnamebyaddr records");
236 naliases
= tvb_get_ntohs(tvb
, LWRES_LWPACKET_LENGTH
+ 4);
237 realnamelen
= tvb_get_ntohs(tvb
,LWRES_LWPACKET_LENGTH
+ 4 + 2);
239 proto_tree_add_item(nba_resp_tree
,
242 LWRES_LWPACKET_LENGTH
,
245 proto_tree_add_item(nba_resp_tree
,
248 LWRES_LWPACKET_LENGTH
+ 4,
252 proto_tree_add_item(nba_resp_tree
,
255 LWRES_LWPACKET_LENGTH
+ 6,
259 proto_tree_add_item(nba_resp_tree
,
262 LWRES_LWPACKET_LENGTH
+ 8,
266 offset
=LWRES_LWPACKET_LENGTH
+ 8 + realnamelen
;
270 for(i
=0; i
<naliases
; i
++)
272 aliaslen
= tvb_get_ntohs(tvb
, offset
);
273 aliasname
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
+ 2, aliaslen
, ENC_ASCII
);
275 alias_tree
= proto_tree_add_subtree_format(nba_resp_tree
, tvb
, offset
, 2 + aliaslen
,
276 ett_adn_alias
, NULL
, "Alias %s",aliasname
);
278 proto_tree_add_item(alias_tree
,
285 proto_tree_add_item(alias_tree
,
292 offset
+=(2 + aliaslen
+ 1);
297 static void dissect_getaddrsbyname_request(tvbuff_t
* tvb
, proto_tree
* lwres_tree
)
301 proto_tree
* adn_request_tree
;
303 namelen
= tvb_get_ntohs(tvb
, LWRES_LWPACKET_LENGTH
+ 8);
305 if(lwres_tree
== NULL
)
308 adn_request_tree
= proto_tree_add_subtree(lwres_tree
,tvb
,
309 LWRES_LWPACKET_LENGTH
,10+namelen
+1,
310 ett_adn_request
, NULL
,
311 "getaddrbyname parameters");
313 proto_tree_add_item(adn_request_tree
,
316 LWRES_LWPACKET_LENGTH
+0,
320 proto_tree_add_item(adn_request_tree
,
323 LWRES_LWPACKET_LENGTH
+4,
327 proto_tree_add_item(adn_request_tree
,
330 LWRES_LWPACKET_LENGTH
+8,
334 proto_tree_add_item(adn_request_tree
,
337 LWRES_LWPACKET_LENGTH
+10,
344 static void dissect_getaddrsbyname_response(tvbuff_t
* tvb
, packet_info
*pinfo
, proto_tree
* lwres_tree
)
346 uint32_t family
,i
, offset
;
347 uint16_t naliases
, naddrs
, realnamelen
, length
, aliaslen
;
352 proto_tree
*adn_resp_tree
;
353 proto_tree
*alias_tree
;
354 proto_tree
*addr_tree
;
358 if(lwres_tree
== NULL
)
361 adn_resp_tree
= proto_tree_add_subtree(lwres_tree
, tvb
, LWRES_LWPACKET_LENGTH
, 10,
362 ett_adn_resp
, NULL
, "getaddrbyname records");
364 naliases
= tvb_get_ntohs(tvb
, LWRES_LWPACKET_LENGTH
+ 4);
365 naddrs
= tvb_get_ntohs(tvb
, LWRES_LWPACKET_LENGTH
+ 6);
366 realnamelen
= tvb_get_ntohs(tvb
, LWRES_LWPACKET_LENGTH
+ 8);
369 proto_tree_add_item(adn_resp_tree
, hf_adn_flags
, tvb
,
370 LWRES_LWPACKET_LENGTH
, 4, ENC_BIG_ENDIAN
);
372 proto_tree_add_item(adn_resp_tree
, hf_adn_naliases
, tvb
,
373 LWRES_LWPACKET_LENGTH
+ 4, 2, ENC_BIG_ENDIAN
);
375 proto_tree_add_item(adn_resp_tree
, hf_adn_naddrs
, tvb
,
376 LWRES_LWPACKET_LENGTH
+ 6, 2, ENC_BIG_ENDIAN
);
378 proto_tree_add_item(adn_resp_tree
, hf_adn_namelen
, tvb
,
379 LWRES_LWPACKET_LENGTH
+ 8, 2, ENC_BIG_ENDIAN
);
381 proto_tree_add_item(adn_resp_tree
, hf_adn_realname
, tvb
,
382 LWRES_LWPACKET_LENGTH
+ 10, realnamelen
, ENC_ASCII
);
384 offset
= LWRES_LWPACKET_LENGTH
+ 10 + realnamelen
+ 1;
388 for(i
=0; i
<naliases
; i
++)
390 aliaslen
= tvb_get_ntohs(tvb
, offset
);
391 aliasname
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
+ 2, aliaslen
, ENC_ASCII
);
393 alias_tree
= proto_tree_add_subtree_format(adn_resp_tree
, tvb
, offset
, 2 + aliaslen
,
394 ett_adn_alias
, NULL
, "Alias %s",aliasname
);
396 proto_tree_add_uint(alias_tree
, hf_adn_namelen
, tvb
,
397 offset
, 2, aliaslen
);
399 proto_tree_add_item(alias_tree
, hf_adn_aliasname
, tvb
,
400 offset
+ 2, aliaslen
, ENC_ASCII
);
402 offset
+=(2 + aliaslen
+ 1);
408 for(i
=0; i
< naddrs
; i
++)
410 family
= tvb_get_ntohl(tvb
, offset
);
411 length
= tvb_get_ntohs(tvb
, offset
+ 4);
412 addrs
= tvb_ip_to_str(pinfo
->pool
, tvb
, offset
+ 6);
413 slen
= (int)strlen(addrs
);
415 addr_tree
= proto_tree_add_subtree_format(adn_resp_tree
,tvb
, offset
, 4+2+4, ett_adn_addr
, NULL
, "Address %s", addrs
);
417 proto_tree_add_uint(addr_tree
, hf_adn_family
, tvb
,
420 proto_tree_add_uint(addr_tree
, hf_adn_addr_len
, tvb
,
421 offset
+ 4, 2, length
);
423 proto_tree_add_string(addr_tree
, hf_adn_addr_addr
, tvb
,
424 offset
+ 6, slen
, addrs
);
433 static void dissect_a_records(tvbuff_t
* tvb
, packet_info
*pinfo
, proto_tree
* tree
,uint32_t nrec
,int offset
)
437 proto_tree
* a_rec_tree
;
438 proto_tree
* addr_tree
;
443 a_rec_tree
= proto_tree_add_subtree(tree
,tvb
,offset
,
444 (int)((sizeof(uint32_t) + sizeof(uint16_t)) * nrec
),
445 ett_a_rec
, NULL
, "A records");
447 for(i
=0; i
<nrec
; i
++)
450 curr
= offset
+ (int)((sizeof(uint32_t)+sizeof(uint16_t)) * i
);
452 addrs
= tvb_ip_to_str(pinfo
->pool
, tvb
, curr
+2);
454 addr_tree
= proto_tree_add_subtree_format(a_rec_tree
, tvb
, curr
,
455 6, ett_a_rec_addr
, NULL
, "Address %s", addrs
);
457 proto_tree_add_item(addr_tree
, hf_a_rec_len
, tvb
, curr
,
458 sizeof(uint16_t), ENC_BIG_ENDIAN
);
460 proto_tree_add_item(addr_tree
, hf_a_record
, tvb
, curr
+ 2, 4, ENC_BIG_ENDIAN
);
465 static void dissect_srv_records(tvbuff_t
* tvb
, packet_info
*pinfo
, proto_tree
* tree
,uint32_t nrec
,int offset
)
468 uint16_t /*len, namelen,*/ priority
, weight
, port
;
473 proto_item
* srv_rec_tree
, *rec_tree
;
478 srv_rec_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
, offset
, ett_srv_rec
, NULL
, "SRV records (%d)", nrec
);
482 for(i
=0; i
< nrec
; i
++)
484 /*len = tvb_get_ntohs(tvb, curr);*/
485 priority
= tvb_get_ntohs(tvb
, curr
+ 2);
486 weight
= tvb_get_ntohs(tvb
, curr
+ 4);
487 port
= tvb_get_ntohs(tvb
, curr
+ 6);
488 /*namelen = len - 8;*/
490 used_bytes
= get_dns_name(tvb
, curr
+ 8, 0, curr
+ 8, &dname
, &dlen
);
492 rec_tree
= proto_tree_add_subtree_format(srv_rec_tree
, tvb
, curr
, 6,
493 ett_srv_rec_item
, NULL
,
494 "SRV record:pri=%d,w=%d,port=%d,dname=%s",
495 priority
, weight
, port
, format_text(pinfo
->pool
, dname
, dlen
));
497 proto_tree_add_uint(rec_tree
,
504 proto_tree_add_uint(rec_tree
,
511 proto_tree_add_uint(rec_tree
,
519 proto_tree_add_string(rec_tree
,
524 format_text(pinfo
->pool
, dname
, dlen
));
526 curr
+=(int)((sizeof(short)*4) + used_bytes
);
532 static void dissect_mx_records(tvbuff_t
* tvb
, packet_info
*pinfo
, proto_tree
* tree
, uint32_t nrec
, int offset
)
541 proto_tree
* mx_rec_tree
, *rec_tree
;
547 mx_rec_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
, offset
, ett_mx_rec
, NULL
, "MX records (%d)", nrec
);
550 for(i
=0; i
< nrec
; i
++)
552 /*len = tvb_get_ntohs(tvb, curr);*/
553 priority
= tvb_get_ntohs(tvb
, curr
+ 2);
554 /*namelen = len - 4;*/
556 used_bytes
= get_dns_name(tvb
, curr
+ 4, 0, curr
+ 4, &dname
, &dlen
);
558 rec_tree
= proto_tree_add_subtree_format(mx_rec_tree
, tvb
, curr
,6,ett_mx_rec_item
,NULL
,
559 "MX record: pri=%d,dname=%s", priority
,
560 format_text(pinfo
->pool
, dname
, dlen
));
563 proto_tree_add_item(rec_tree
,
570 proto_tree_add_string(rec_tree
,
575 format_text(pinfo
->pool
, dname
, dlen
));
577 curr
+=(int)((sizeof(short)*2) + used_bytes
);
584 static void dissect_ns_records(tvbuff_t
* tvb
, packet_info
*pinfo
, proto_tree
* tree
, uint32_t nrec
, int offset
)
591 proto_tree
* ns_rec_tree
, *rec_tree
;
596 ns_rec_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
, offset
, ett_ns_rec
, NULL
, "NS record (%d)", nrec
);
602 /*len = tvb_get_ntohs(tvb, curr);*/
603 /*namelen = len - 2;*/
605 used_bytes
= get_dns_name(tvb
, curr
+ 2, 0, curr
+ 2, &dname
, &dlen
);
607 rec_tree
= proto_tree_add_subtree_format(ns_rec_tree
, tvb
, curr
,4, ett_ns_rec_item
, NULL
, "NS record: dname=%s",
608 format_text(pinfo
->pool
, dname
, dlen
));
610 proto_tree_add_string(rec_tree
,
615 format_text(pinfo
->pool
, dname
, dlen
));
616 curr
+=(int)(sizeof(short) + used_bytes
);
623 static void dissect_rdata_request(tvbuff_t
* tvb
, proto_tree
* lwres_tree
)
627 proto_tree
* rdata_request_tree
;
629 namelen
= tvb_get_ntohs(tvb
, LWRES_LWPACKET_LENGTH
+8);
631 if(lwres_tree
== NULL
)
635 proto_tree_add_subtree(lwres_tree
,tvb
,LWRES_LWPACKET_LENGTH
,10+namelen
+1,ett_rdata_req
,NULL
,"RDATA request parameters");
637 proto_tree_add_item(rdata_request_tree
,
640 LWRES_LWPACKET_LENGTH
+0,
644 proto_tree_add_item(rdata_request_tree
,
647 LWRES_LWPACKET_LENGTH
+4,
651 proto_tree_add_item(rdata_request_tree
,
654 LWRES_LWPACKET_LENGTH
+6,
658 proto_tree_add_item(rdata_request_tree
,
661 LWRES_LWPACKET_LENGTH
+8,
665 proto_tree_add_item(rdata_request_tree
,
668 LWRES_LWPACKET_LENGTH
+10,
674 static void dissect_rdata_response(tvbuff_t
* tvb
, packet_info
*pinfo
, proto_tree
* lwres_tree
)
677 unsigned rdtype
, nrdatas
, realnamelen
;
679 proto_tree
* rdata_resp_tree
;
681 rdtype
= tvb_get_ntohs(tvb
, LWRES_LWPACKET_LENGTH
+6);
682 nrdatas
= tvb_get_ntohs(tvb
, LWRES_LWPACKET_LENGTH
+12);
683 realnamelen
= tvb_get_ntohs(tvb
,LWRES_LWPACKET_LENGTH
+16);
685 offset
= LWRES_LWPACKET_LENGTH
+ 18 + realnamelen
+ 1;
687 if(lwres_tree
== NULL
)
690 rdata_resp_tree
= proto_tree_add_subtree(lwres_tree
,tvb
,LWRES_LWPACKET_LENGTH
, 18+realnamelen
+1,ett_rdata_resp
,NULL
,"RDATA response");
692 proto_tree_add_item(rdata_resp_tree
,
695 LWRES_LWPACKET_LENGTH
+0,
699 proto_tree_add_item(rdata_resp_tree
,
702 LWRES_LWPACKET_LENGTH
+4,
706 proto_tree_add_item(rdata_resp_tree
,
709 LWRES_LWPACKET_LENGTH
+6,
713 proto_tree_add_item(rdata_resp_tree
,
716 LWRES_LWPACKET_LENGTH
+8,
720 proto_tree_add_item(rdata_resp_tree
,
723 LWRES_LWPACKET_LENGTH
+12,
727 proto_tree_add_item(rdata_resp_tree
,
730 LWRES_LWPACKET_LENGTH
+14,
734 proto_tree_add_item(rdata_resp_tree
,
737 LWRES_LWPACKET_LENGTH
+16,
741 proto_tree_add_item(rdata_resp_tree
,
744 LWRES_LWPACKET_LENGTH
+18,
751 dissect_a_records(tvb
,pinfo
,rdata_resp_tree
,nrdatas
,offset
);
755 dissect_srv_records(tvb
,pinfo
,rdata_resp_tree
,nrdatas
, offset
);
759 dissect_mx_records(tvb
,pinfo
,rdata_resp_tree
,nrdatas
, offset
);
763 dissect_ns_records(tvb
,pinfo
,rdata_resp_tree
,nrdatas
, offset
);
769 static void dissect_noop(tvbuff_t
* tvb
, proto_tree
* lwres_tree
)
773 proto_tree
* noop_tree
;
775 datalen
= tvb_get_ntohs(tvb
, LWRES_LWPACKET_LENGTH
);
777 if(lwres_tree
== NULL
)
780 noop_tree
= proto_tree_add_subtree(lwres_tree
, tvb
, LWRES_LWPACKET_LENGTH
, 10, ett_noop
, NULL
, "Noop record");
782 proto_tree_add_uint(noop_tree
, hf_length
, tvb
,
783 LWRES_LWPACKET_LENGTH
, sizeof(uint16_t), datalen
);
785 tvb_ensure_bytes_exist(tvb
, LWRES_LWPACKET_LENGTH
, datalen
);
789 static void dissect_getaddrsbyname(tvbuff_t
* tvb
, packet_info
*pinfo
, proto_tree
* lwres_tree
, int type
)
792 dissect_getaddrsbyname_request(tvb
, lwres_tree
);
794 dissect_getaddrsbyname_response(tvb
, pinfo
, lwres_tree
);
797 static void dissect_getnamebyaddr(tvbuff_t
* tvb
, packet_info
*pinfo
, proto_tree
* lwres_tree
, int type
)
800 dissect_getnamebyaddr_request(tvb
, pinfo
, lwres_tree
);
802 dissect_getnamebyaddr_response(tvb
, pinfo
, lwres_tree
);
805 static void dissect_getrdatabyname(tvbuff_t
* tvb
, packet_info
*pinfo _U_
, proto_tree
* lwres_tree
, int type
)
808 dissect_rdata_request(tvb
, lwres_tree
);
810 dissect_rdata_response(tvb
, pinfo
, lwres_tree
);
814 dissect_lwres(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
816 uint16_t version
, flags
, authtype
, authlength
;
817 uint32_t length
, opcode
, result
, recvlength
, serial
;
818 uint32_t message_type
;
820 proto_item
* lwres_item
;
821 proto_tree
* lwres_tree
;
823 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "lw_res");
824 length
= tvb_get_ntohl(tvb
, LW_LENGTH_OFFSET
);
825 version
= tvb_get_ntohs(tvb
, LW_VERSION_OFFSET
);
826 flags
= tvb_get_ntohs(tvb
, LW_PKTFLASG_OFFSET
);
827 serial
= tvb_get_ntohl(tvb
, LW_SERIAL_OFFSET
);
828 opcode
= tvb_get_ntohl(tvb
,LW_OPCODE_OFFSET
);
829 result
= tvb_get_ntohl(tvb
, LW_RESULT_OFFSET
);
830 recvlength
= tvb_get_ntohl(tvb
, LW_RECVLEN_OFFSET
);
831 authtype
= tvb_get_ntohs(tvb
, LW_AUTHTYPE_OFFSET
);
832 authlength
= tvb_get_ntohs(tvb
, LW_AUTHLEN_OFFSET
);
834 message_type
= (flags
& LWRES_LWPACKETFLAG_RESPONSE
) ? 2 : 1;
836 if(flags
& LWRES_LWPACKETFLAG_RESPONSE
)
838 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
839 "%s, opcode=%s, serial=0x%x, result=%s",
840 val_to_str_const((uint32_t)message_type
,message_types_values
,"unknown"),
841 val_to_str_const(opcode
, opcode_values
, "unknown"),
843 val_to_str_const(result
,result_values
,"unknown"));
847 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
848 "%s, opcode=%s, serial=0x%x",
849 val_to_str_const((uint32_t)message_type
,message_types_values
,"unknown"),
850 val_to_str_const(opcode
, opcode_values
, "unknown"),
855 return tvb_captured_length(tvb
);
857 lwres_item
= proto_tree_add_item(tree
,proto_lwres
, tvb
,0, -1, ENC_NA
);
858 lwres_tree
= proto_item_add_subtree(lwres_item
, ett_lwres
);
860 proto_tree_add_uint(lwres_tree
,
868 proto_tree_add_uint(lwres_tree
,
878 proto_tree_add_uint(lwres_tree
,
885 proto_tree_add_uint(lwres_tree
,
892 proto_tree_add_uint(lwres_tree
,
899 proto_tree_add_uint(lwres_tree
,
906 proto_tree_add_uint(lwres_tree
,
913 proto_tree_add_uint(lwres_tree
,
920 proto_tree_add_uint(lwres_tree
,
931 case LWRES_OPCODE_NOOP
:
932 dissect_noop(tvb
, lwres_tree
);
935 case LWRES_OPCODE_GETADDRSBYNAME
:
936 dissect_getaddrsbyname(tvb
, pinfo
, lwres_tree
, message_type
);
939 case LWRES_OPCODE_GETNAMEBYADDR
:
940 dissect_getnamebyaddr(tvb
, pinfo
, lwres_tree
, message_type
);
943 case LWRES_OPCODE_GETRDATABYNAME
:
944 dissect_getrdatabyname(tvb
, pinfo
, lwres_tree
, message_type
);
948 return tvb_captured_length(tvb
);
953 proto_register_lwres(void)
955 static hf_register_info hf
[] = {
957 { "Length", "lwres.length", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
958 "lwres length", HFILL
}},
961 { "Version", "lwres.version", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
962 "lwres version", HFILL
}},
965 { "Packet Flags", "lwres.flags", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
966 "lwres flags", HFILL
}},
969 { "Serial", "lwres.serial", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
970 "lwres serial", HFILL
}},
973 { "Operation code", "lwres.opcode", FT_UINT32
, BASE_DEC
, VALS(opcode_values
), 0x0,
974 "lwres opcode", HFILL
}},
977 { "Result", "lwres.result", FT_UINT32
, BASE_DEC
, VALS(result_values
), 0x0,
978 "lwres result", HFILL
}},
981 { "Received length", "lwres.recvlen", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
982 "lwres recvlen", HFILL
}},
985 { "Auth. type", "lwres.authtype", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
986 "lwres authtype", HFILL
}},
989 { "Auth. length", "lwres.authlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
990 "lwres authlen", HFILL
}},
993 { "Flags", "lwres.rflags", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
994 "lwres rflags", HFILL
}},
996 { "Class", "lwres.class", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
997 "lwres class", HFILL
}},
1000 { "Type", "lwres.type", FT_UINT16
, BASE_DEC
, VALS(t_types
), 0x0,
1001 "lwres type", HFILL
}},
1004 { "Name length", "lwres.namelen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1005 "lwres namelen", HFILL
}},
1008 { "Domain name", "lwres.reqdname", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1009 "lwres reqdname", HFILL
}},
1012 { "Time To Live", "lwres.ttl", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1013 "lwres ttl", HFILL
}},
1016 { "Number of rdata records", "lwres.nrdatas", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1017 "lwres nrdatas", HFILL
}},
1020 { "Number of signature records", "lwres.nsigs", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1021 "lwres nsigs", HFILL
}},
1024 { "Real name length", "lwres.realnamelen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1025 "lwres realnamelen", HFILL
}},
1028 { "Real doname name", "lwres.realname", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1029 "lwres realname", HFILL
}},
1032 { "IPv4 Address", "lwres.arecord", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1033 "lwres arecord", HFILL
}},
1036 { "Length", "lwres.areclen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1037 "lwres areclen", HFILL
}},
1040 { "Priority", "lwres.srv.priority", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1041 "lwres srv prio", HFILL
}},
1044 { "Weight", "lwres.srv.weight", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1045 "lwres srv weight", HFILL
}},
1048 { "Port", "lwres.srv.port", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1049 "lwres srv port", HFILL
}},
1052 { "DNAME", "lwres.srv.dname", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1056 { "Flags", "lwres.adn.flags", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1057 "lwres adn flags", HFILL
}},
1060 { "Address type", "lwres.adn.addrtype", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1061 "lwres adn addrtype", HFILL
}},
1064 { "Name length", "lwres.adn.namelen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1065 "lwres adn namelen", HFILL
}},
1068 { "Name", "lwres.adn.name", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1069 "lwres adn name", HFILL
}},
1072 { "Number of aliases", "lwres.adn.naliases", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1073 "lwres adn naliases", HFILL
}},
1076 { "Number of addresses", "lwres.adn.naddrs", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1077 "lwres adn naddrs", HFILL
}},
1080 { "Real name", "lwres.adn.realname", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1081 "lwres adn realname", HFILL
}},
1083 { &hf_adn_aliasname
,
1084 { "Alias name", "lwres.adn.aliasname", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1085 "lwres adn aliasname", HFILL
}},
1088 { "Address family", "lwres.adn.addr.family", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1089 "lwres adn addr family", HFILL
}},
1092 { "Address length", "lwres.adn.addr.length", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1093 "lwres adn addr length", HFILL
}},
1095 { &hf_adn_addr_addr
,
1096 { "IP Address", "lwres.adn.addr.addr", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1097 "lwres adn addr addr", HFILL
}},
1100 { "Name", "lwres.ns.dname", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1103 /* Add more fields here */
1106 static int *ett
[] = {
1127 proto_lwres
= proto_register_protocol("Light Weight DNS RESolver (BIND9)", "LWRES", "lwres");
1129 proto_register_field_array(proto_lwres
, hf
, array_length(hf
));
1130 proto_register_subtree_array(ett
, array_length(ett
));
1132 lwres_handle
= register_dissector("lwres", dissect_lwres
, proto_lwres
);
1135 /* The registration hand-off routine */
1137 proto_reg_handoff_lwres(void)
1139 dissector_add_uint_with_preference("udp.port", LWRES_UDP_PORT
, lwres_handle
);
1143 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1148 * indent-tabs-mode: nil
1151 * vi: set shiftwidth=4 tabstop=8 expandtab:
1152 * :indentSize=4:tabSize=8:noTabs=true: