2 * Routines for light weight reslover (lwres, part of BIND9) packet disassembly
6 * Copyright (c) 2003 by Oleg Terletsky <oleg.terletsky@comverse.com>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1999 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 #include <epan/packet.h>
34 #include <epan/prefs.h>
35 #include "packet-dns.h"
37 #define LWRES_LWPACKET_LENGTH (4 * 5 + 2 * 4)
38 #define LWRES_LWPACKETFLAG_RESPONSE 0x0001U /* if set, pkt is a response */
39 #define LWRES_LWPACKETVERSION_0 0
41 #define LW_LENGTH_OFFSET 0
42 #define LW_VERSION_OFFSET 4
43 #define LW_PKTFLASG_OFFSET 6
44 #define LW_SERIAL_OFFSET 8
45 #define LW_OPCODE_OFFSET 12
46 #define LW_RESULT_OFFSET 16
47 #define LW_RECVLEN_OFFSET 20
48 #define LW_AUTHTYPE_OFFSET 24
49 #define LW_AUTHLEN_OFFSET 26
51 #define LWRES_OPCODE_NOOP 0x00000000U
52 #define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U
53 #define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U
54 #define LWRES_OPCODE_GETRDATABYNAME 0x00010003U
56 static const value_string opcode_values
[] = {
57 { LWRES_OPCODE_NOOP
, "Noop" },
58 { LWRES_OPCODE_GETADDRSBYNAME
, "getaddrbyname" },
59 { LWRES_OPCODE_GETNAMEBYADDR
, "getnamebyaddr" },
60 { LWRES_OPCODE_GETRDATABYNAME
, "getrdatabyname" },
65 #define LWRES_R_SUCCESS 0
66 #define LWRES_R_NOMEMORY 1
67 #define LWRES_R_TIMEOUT 2
68 #define LWRES_R_NOTFOUND 3
69 #define LWRES_R_UNEXPECTEDEND 4 /* unexpected end of input */
70 #define LWRES_R_FAILURE 5 /* generic failure */
71 #define LWRES_R_IOERROR 6
72 #define LWRES_R_NOTIMPLEMENTED 7
73 #define LWRES_R_UNEXPECTED 8
74 #define LWRES_R_TRAILINGDATA 9
75 #define LWRES_R_INCOMPLETE 10
76 #define LWRES_R_RETRY 11
77 #define LWRES_R_TYPENOTFOUND 12
78 #define LWRES_R_TOOLARGE 13
86 static const value_string t_types
[] = {
97 static const value_string result_values
[] = {
98 { LWRES_R_SUCCESS
, "Success" },
99 { LWRES_R_NOMEMORY
, "No memory" },
100 { LWRES_R_TIMEOUT
, "Timeout" },
101 { LWRES_R_NOTFOUND
, "Not found" },
102 { LWRES_R_UNEXPECTEDEND
, "Unexpected end of input" },
103 { LWRES_R_FAILURE
, "Generic failure" },
104 { LWRES_R_IOERROR
, "I/O Error" },
105 { LWRES_R_UNEXPECTED
, "Unexpected" },
106 { LWRES_R_TRAILINGDATA
, "Trailing data" },
107 { LWRES_R_INCOMPLETE
, "Incomplete" },
108 { LWRES_R_RETRY
, "Retry" },
109 { LWRES_R_TYPENOTFOUND
, "Type not found" },
110 { LWRES_R_TOOLARGE
, "Too large" },
114 static int hf_length
= -1;
115 static int hf_version
= -1;
116 static int hf_flags
= -1;
117 static int hf_serial
= -1;
118 static int hf_opcode
= -1;
119 static int hf_result
= -1;
120 static int hf_recvlen
= -1;
121 static int hf_authtype
= -1;
122 static int hf_authlen
= -1;
124 static int hf_rflags
= -1;
125 static int hf_rdclass
= -1;
126 static int hf_rdtype
= -1;
127 static int hf_namelen
= -1;
128 static int hf_req_name
= -1;
130 static int hf_ttl
= -1;
131 static int hf_nrdatas
= -1;
132 static int hf_nsigs
= -1;
133 static int hf_realnamelen
= -1;
134 static int hf_realname
= -1;
137 /* static int hf_a_record = -1; */
138 static int hf_a_rec_len
= -1;
139 static int hf_srv_prio
= -1;
140 static int hf_srv_weight
= -1;
141 static int hf_srv_port
= -1;
143 static int hf_adn_flags
= -1;
144 static int hf_adn_addrtype
= -1;
145 static int hf_adn_namelen
= -1;
146 static int hf_adn_name
= -1;
148 static int hf_adn_realname
= -1;
149 static int hf_adn_aliasname
= -1;
151 static int hf_adn_naddrs
= -1;
152 static int hf_adn_naliases
= -1;
153 static int hf_adn_family
= -1;
154 static int hf_adn_addr_len
= -1;
155 static int hf_adn_addr_addr
= -1;
158 static int ett_lwres
= -1;
159 static int ett_rdata_req
= -1;
160 static int ett_rdata_resp
= -1;
161 static int ett_a_rec
= -1;
162 static int ett_a_rec_addr
= -1;
163 static int ett_srv_rec
= -1;
164 static int ett_srv_rec_item
= -1;
165 static int ett_adn_request
= -1;
166 static int ett_adn_resp
= -1;
167 static int ett_adn_alias
= -1;
168 static int ett_adn_addr
= -1;
169 static int ett_nba_request
= -1;
170 static int ett_nba_resp
= -1;
171 static int ett_noop
= -1;
173 static int ett_mx_rec
= -1;
174 static int ett_mx_rec_item
= -1;
176 static int ett_ns_rec
= -1;
177 static int ett_ns_rec_item
= -1;
181 #define LWRES_UDP_PORT 921
183 static guint global_lwres_port
= LWRES_UDP_PORT
;
185 void proto_reg_handoff_lwres(void);
188 /* Define the lwres proto */
189 static int proto_lwres
= -1;
192 /* Define many many headers for mgcp */
194 static const value_string message_types_values
[] = {
200 static void dissect_getnamebyaddr_request(tvbuff_t
* tvb
, proto_tree
* lwres_tree
)
202 guint32 flags
,family
;
203 guint16 addrlen
, slen
;
206 proto_item
* nba_request_item
;
207 proto_tree
* nba_request_tree
;
209 flags
= tvb_get_ntohl(tvb
, LWRES_LWPACKET_LENGTH
);
210 family
= tvb_get_ntohl(tvb
, LWRES_LWPACKET_LENGTH
+ 4);
211 addrlen
= tvb_get_ntohs(tvb
, LWRES_LWPACKET_LENGTH
+ 8);
212 addrs
= tvb_ip_to_str(tvb
, LWRES_LWPACKET_LENGTH
+ 10);
213 slen
= (int)strlen(addrs
);
217 nba_request_item
= proto_tree_add_text(lwres_tree
,tvb
,LWRES_LWPACKET_LENGTH
,LWRES_LWPACKET_LENGTH
+14,"getnamebyaddr parameters");
218 nba_request_tree
= proto_item_add_subtree(nba_request_item
, ett_nba_request
);
222 proto_tree_add_uint(nba_request_tree
, hf_adn_flags
, tvb
,
223 LWRES_LWPACKET_LENGTH
, 4, flags
);
225 proto_tree_add_uint(nba_request_tree
, hf_adn_family
, tvb
,
226 LWRES_LWPACKET_LENGTH
+ 4, 4, family
);
228 proto_tree_add_uint(nba_request_tree
, hf_adn_addr_len
, tvb
,
229 LWRES_LWPACKET_LENGTH
+ 8, 2, addrlen
);
231 proto_tree_add_string(nba_request_tree
, hf_adn_addr_addr
, tvb
,
232 LWRES_LWPACKET_LENGTH
+ 10, slen
, addrs
);
236 static void dissect_getnamebyaddr_response(tvbuff_t
* tvb
, proto_tree
* lwres_tree
)
239 guint16 naliases
,realnamelen
,aliaslen
;
243 proto_item
* nba_resp_item
;
244 proto_tree
* nba_resp_tree
;
246 proto_item
* alias_item
;
247 proto_tree
* alias_tree
;
251 nba_resp_item
= proto_tree_add_text(lwres_tree
, tvb
, LWRES_LWPACKET_LENGTH
, 10,"getnamebyaddr records");
252 nba_resp_tree
= proto_item_add_subtree(nba_resp_item
, ett_nba_resp
);
256 naliases
= tvb_get_ntohs(tvb
, LWRES_LWPACKET_LENGTH
+ 4);
257 realnamelen
= tvb_get_ntohs(tvb
,LWRES_LWPACKET_LENGTH
+ 4 + 2);
259 proto_tree_add_item(nba_resp_tree
,
262 LWRES_LWPACKET_LENGTH
,
265 proto_tree_add_item(nba_resp_tree
,
268 LWRES_LWPACKET_LENGTH
+ 4,
272 proto_tree_add_item(nba_resp_tree
,
275 LWRES_LWPACKET_LENGTH
+ 6,
279 proto_tree_add_item(nba_resp_tree
,
282 LWRES_LWPACKET_LENGTH
+ 8,
286 offset
=LWRES_LWPACKET_LENGTH
+ 8 + realnamelen
;
290 for(i
=0; i
<naliases
; i
++)
292 aliaslen
= tvb_get_ntohs(tvb
, offset
);
293 aliasname
= tvb_get_string(wmem_packet_scope(), tvb
, offset
+ 2, aliaslen
);
295 alias_item
= proto_tree_add_text(nba_resp_tree
, tvb
, offset
, 2 + aliaslen
, "Alias %s",aliasname
);
296 alias_tree
= proto_item_add_subtree(alias_item
, ett_adn_alias
);
298 proto_tree_add_item(alias_tree
,
305 proto_tree_add_item(alias_tree
,
312 offset
+=(2 + aliaslen
+ 1);
317 static void dissect_getaddrsbyname_request(tvbuff_t
* tvb
, proto_tree
* lwres_tree
)
321 proto_item
* adn_request_item
;
322 proto_tree
* adn_request_tree
;
324 namelen
= tvb_get_ntohs(tvb
, LWRES_LWPACKET_LENGTH
+ 8);
328 adn_request_item
= proto_tree_add_text(lwres_tree
,tvb
,
329 LWRES_LWPACKET_LENGTH
,10+namelen
+1,
330 "getaddrbyname parameters");
331 adn_request_tree
= proto_item_add_subtree(adn_request_item
, ett_adn_request
);
337 proto_tree_add_item(adn_request_tree
,
340 LWRES_LWPACKET_LENGTH
+0,
344 proto_tree_add_item(adn_request_tree
,
347 LWRES_LWPACKET_LENGTH
+4,
351 proto_tree_add_item(adn_request_tree
,
354 LWRES_LWPACKET_LENGTH
+8,
358 proto_tree_add_item(adn_request_tree
,
361 LWRES_LWPACKET_LENGTH
+10,
368 static void dissect_getaddrsbyname_response(tvbuff_t
* tvb
, proto_tree
* lwres_tree
)
370 guint32 family
,i
, offset
;
371 guint16 naliases
, naddrs
, realnamelen
, length
, aliaslen
;
376 proto_item
*adn_resp_item
;
377 proto_tree
*adn_resp_tree
;
378 proto_item
*alias_item
;
379 proto_tree
*alias_tree
;
380 proto_item
*addr_item
;
381 proto_tree
*addr_tree
;
387 adn_resp_item
= proto_tree_add_text(lwres_tree
, tvb
, LWRES_LWPACKET_LENGTH
, 10, "getaddrbyname records");
388 adn_resp_tree
= proto_item_add_subtree(adn_resp_item
, ett_adn_resp
);
392 naliases
= tvb_get_ntohs(tvb
, LWRES_LWPACKET_LENGTH
+ 4);
393 naddrs
= tvb_get_ntohs(tvb
, LWRES_LWPACKET_LENGTH
+ 6);
394 realnamelen
= tvb_get_ntohs(tvb
, LWRES_LWPACKET_LENGTH
+ 8);
397 proto_tree_add_item(adn_resp_tree
, hf_adn_flags
, tvb
,
398 LWRES_LWPACKET_LENGTH
, 4, ENC_BIG_ENDIAN
);
400 proto_tree_add_item(adn_resp_tree
, hf_adn_naliases
, tvb
,
401 LWRES_LWPACKET_LENGTH
+ 4, 2, ENC_BIG_ENDIAN
);
403 proto_tree_add_item(adn_resp_tree
, hf_adn_naddrs
, tvb
,
404 LWRES_LWPACKET_LENGTH
+ 6, 2, ENC_BIG_ENDIAN
);
406 proto_tree_add_item(adn_resp_tree
, hf_adn_namelen
, tvb
,
407 LWRES_LWPACKET_LENGTH
+ 8, 2, ENC_BIG_ENDIAN
);
409 proto_tree_add_item(adn_resp_tree
, hf_adn_realname
, tvb
,
410 LWRES_LWPACKET_LENGTH
+ 10, realnamelen
, ENC_ASCII
|ENC_NA
);
412 offset
= LWRES_LWPACKET_LENGTH
+ 10 + realnamelen
+ 1;
416 for(i
=0; i
<naliases
; i
++)
418 aliaslen
= tvb_get_ntohs(tvb
, offset
);
419 aliasname
= tvb_get_string(wmem_packet_scope(), tvb
, offset
+ 2, aliaslen
);
421 alias_item
= proto_tree_add_text(adn_resp_tree
, tvb
, offset
, 2 + aliaslen
, "Alias %s",aliasname
);
422 alias_tree
= proto_item_add_subtree(alias_item
, ett_adn_alias
);
424 proto_tree_add_uint(alias_tree
, hf_adn_namelen
, tvb
,
425 offset
, 2, aliaslen
);
427 proto_tree_add_item(alias_tree
, hf_adn_aliasname
, tvb
,
428 offset
+ 2, aliaslen
, ENC_ASCII
|ENC_NA
);
430 offset
+=(2 + aliaslen
+ 1);
436 for(i
=0; i
< naddrs
; i
++)
438 family
= tvb_get_ntohl(tvb
, offset
);
439 length
= tvb_get_ntohs(tvb
, offset
+ 4);
440 addrs
= tvb_ip_to_str(tvb
, offset
+ 6);
441 slen
= (int)strlen(addrs
);
443 addr_item
= proto_tree_add_text(adn_resp_tree
,tvb
, offset
, 4+2+4, "Address %s", addrs
);
444 addr_tree
= proto_item_add_subtree(addr_item
, ett_adn_addr
);
446 proto_tree_add_uint(addr_tree
, hf_adn_family
, tvb
,
449 proto_tree_add_uint(addr_tree
, hf_adn_addr_len
, tvb
,
450 offset
+ 4, 2, length
);
452 proto_tree_add_string(addr_tree
, hf_adn_addr_addr
, tvb
,
453 offset
+ 6, slen
, addrs
);
462 static void dissect_a_records(tvbuff_t
* tvb
, proto_tree
* tree
,guint32 nrec
,int offset
)
467 proto_item
* a_rec_item
;
468 proto_tree
* a_rec_tree
;
469 proto_item
* addr_item
;
470 proto_tree
* addr_tree
;
474 a_rec_item
= proto_tree_add_text(tree
,tvb
,offset
,
475 (int)((sizeof(guint32
) + sizeof(guint16
)) * nrec
),"A records");
477 a_rec_tree
= proto_item_add_subtree(a_rec_item
, ett_a_rec
);
482 for(i
=0; i
<nrec
; i
++)
485 curr
= offset
+ (int)((sizeof(guint32
)+sizeof(guint16
)) * i
);
487 len
= tvb_get_ntohs(tvb
,curr
);
489 addrs
= tvb_ip_to_str(tvb
, curr
+2);
492 addr_item
= proto_tree_add_text(a_rec_tree
, tvb
, curr
,
493 6, "Address %s", addrs
);
494 addr_tree
= proto_item_add_subtree(addr_item
, ett_a_rec_addr
);
498 proto_tree_add_uint(addr_tree
, hf_a_rec_len
, tvb
, curr
,
499 sizeof(guint16
), len
);
501 proto_tree_add_text(addr_tree
, tvb
, curr
+ 2, 4, "Addr: %s",
508 static void dissect_srv_records(tvbuff_t
* tvb
, proto_tree
* tree
,guint32 nrec
,int offset
)
511 guint16
/*len, namelen,*/ priority
, weight
, port
, dlen
;
514 proto_item
* srv_rec_item
, *rec_item
;
515 proto_item
* srv_rec_tree
, *rec_tree
;
519 srv_rec_item
= proto_tree_add_text(tree
, tvb
, offset
, offset
, "SRV records");
520 srv_rec_tree
= proto_item_add_subtree(srv_rec_item
, ett_srv_rec
);
521 proto_item_set_text(srv_rec_item
, "SRV records (%d)", nrec
);
527 for(i
=0; i
< nrec
; i
++)
529 /*len = tvb_get_ntohs(tvb, curr);*/
530 priority
= tvb_get_ntohs(tvb
, curr
+ 2);
531 weight
= tvb_get_ntohs(tvb
, curr
+ 4);
532 port
= tvb_get_ntohs(tvb
, curr
+ 6);
533 /*namelen = len - 8;*/
535 dlen
= get_dns_name(tvb
, curr
+ 8, 0, curr
+ 8, &dname
);
539 rec_item
= proto_tree_add_text(srv_rec_tree
, tvb
, curr
, 6," ");
540 rec_tree
= proto_item_add_subtree(rec_item
, ett_srv_rec_item
);
541 proto_item_set_text(rec_item
,
542 "SRV record:pri=%d,w=%d,port=%d,dname=%s",
550 proto_tree_add_uint(rec_tree
,
557 proto_tree_add_uint(rec_tree
,
564 proto_tree_add_uint(rec_tree
,
572 proto_tree_add_text(rec_tree
,
578 curr
+=(int)((sizeof(short)*4) + dlen
);
584 static void dissect_mx_records(tvbuff_t
* tvb
, proto_tree
* tree
, guint32 nrec
, int offset
)
588 guint
/*len, namelen,*/ priority
, dlen
;
591 proto_item
* mx_rec_item
, *rec_item
;
592 proto_tree
* mx_rec_tree
, *rec_tree
;
597 mx_rec_item
= proto_tree_add_text(tree
, tvb
, offset
, offset
, "MX records (%d)", nrec
);
598 mx_rec_tree
= proto_item_add_subtree(mx_rec_item
, ett_mx_rec
);
604 for(i
=0; i
< nrec
; i
++)
606 /*len = tvb_get_ntohs(tvb, curr);*/
607 priority
= tvb_get_ntohs(tvb
, curr
+ 2);
608 /*namelen = len - 4;*/
610 dlen
= get_dns_name(tvb
, curr
+ 4, 0, curr
+ 4, &dname
);
613 rec_item
= proto_tree_add_text(mx_rec_tree
, tvb
, curr
,6,"MX record: pri=%d,dname=%s",
615 rec_tree
= proto_item_add_subtree(rec_item
, ett_mx_rec_item
);
621 proto_tree_add_uint(rec_tree
,
628 proto_tree_add_text(rec_tree
,
634 curr
+=(int)((sizeof(short)*2) + dlen
);
641 static void dissect_ns_records(tvbuff_t
* tvb
, proto_tree
* tree
, guint32 nrec
, int offset
)
644 guint
/*len, namelen,*/ dlen
;
647 proto_item
* ns_rec_item
, *rec_item
;
648 proto_tree
* ns_rec_tree
, *rec_tree
;
652 ns_rec_item
= proto_tree_add_text(tree
, tvb
, offset
, offset
, "NS record (%d)", nrec
);
653 ns_rec_tree
= proto_item_add_subtree(ns_rec_item
, ett_ns_rec
);
661 /*len = tvb_get_ntohs(tvb, curr);*/
662 /*namelen = len - 2;*/
664 dlen
= get_dns_name(tvb
, curr
+ 2, 0, curr
+ 2, &dname
);
667 rec_item
= proto_tree_add_text(ns_rec_tree
, tvb
, curr
,4, "NS record: dname=%s",dname
);
668 rec_tree
= proto_item_add_subtree(rec_item
, ett_ns_rec_item
);
673 proto_tree_add_text(rec_tree
,
678 curr
+=(int)(sizeof(short) + dlen
);
685 static void dissect_rdata_request(tvbuff_t
* tvb
, proto_tree
* lwres_tree
)
689 proto_item
* rdata_request_item
;
690 proto_tree
* rdata_request_tree
;
692 namelen
= tvb_get_ntohs(tvb
, LWRES_LWPACKET_LENGTH
+8);
697 proto_tree_add_text(lwres_tree
,tvb
,LWRES_LWPACKET_LENGTH
,10+namelen
+1,"RDATA request parameters");
698 rdata_request_tree
= proto_item_add_subtree(rdata_request_item
, ett_rdata_req
);
703 proto_tree_add_item(rdata_request_tree
,
706 LWRES_LWPACKET_LENGTH
+0,
710 proto_tree_add_item(rdata_request_tree
,
713 LWRES_LWPACKET_LENGTH
+4,
717 proto_tree_add_item(rdata_request_tree
,
720 LWRES_LWPACKET_LENGTH
+6,
724 proto_tree_add_item(rdata_request_tree
,
727 LWRES_LWPACKET_LENGTH
+8,
731 proto_tree_add_item(rdata_request_tree
,
734 LWRES_LWPACKET_LENGTH
+10,
740 static void dissect_rdata_response(tvbuff_t
* tvb
, proto_tree
* lwres_tree
)
743 guint rdtype
, nrdatas
, realnamelen
;
745 proto_item
* rdata_resp_item
;
746 proto_tree
* rdata_resp_tree
;
748 rdtype
= tvb_get_ntohs(tvb
, LWRES_LWPACKET_LENGTH
+6);
749 nrdatas
= tvb_get_ntohs(tvb
, LWRES_LWPACKET_LENGTH
+12);
750 realnamelen
= tvb_get_ntohs(tvb
,LWRES_LWPACKET_LENGTH
+16);
752 offset
= LWRES_LWPACKET_LENGTH
+ 18 + realnamelen
+ 1;
756 rdata_resp_item
= proto_tree_add_text(lwres_tree
,tvb
,LWRES_LWPACKET_LENGTH
, 18+realnamelen
+1,"RDATA response");
757 rdata_resp_tree
= proto_item_add_subtree(rdata_resp_item
, ett_rdata_resp
);
762 proto_tree_add_item(rdata_resp_tree
,
765 LWRES_LWPACKET_LENGTH
+0,
769 proto_tree_add_item(rdata_resp_tree
,
772 LWRES_LWPACKET_LENGTH
+4,
776 proto_tree_add_item(rdata_resp_tree
,
779 LWRES_LWPACKET_LENGTH
+6,
783 proto_tree_add_item(rdata_resp_tree
,
786 LWRES_LWPACKET_LENGTH
+8,
790 proto_tree_add_item(rdata_resp_tree
,
793 LWRES_LWPACKET_LENGTH
+12,
797 proto_tree_add_item(rdata_resp_tree
,
800 LWRES_LWPACKET_LENGTH
+14,
804 proto_tree_add_item(rdata_resp_tree
,
807 LWRES_LWPACKET_LENGTH
+16,
811 proto_tree_add_item(rdata_resp_tree
,
814 LWRES_LWPACKET_LENGTH
+18,
821 dissect_a_records(tvb
,rdata_resp_tree
,nrdatas
,offset
);
825 dissect_srv_records(tvb
,rdata_resp_tree
,nrdatas
, offset
);
829 dissect_mx_records(tvb
,rdata_resp_tree
,nrdatas
, offset
);
833 dissect_ns_records(tvb
,rdata_resp_tree
,nrdatas
, offset
);
839 static void dissect_noop(tvbuff_t
* tvb
, proto_tree
* lwres_tree
)
843 proto_item
* noop_item
;
844 proto_tree
* noop_tree
;
846 datalen
= tvb_get_ntohs(tvb
, LWRES_LWPACKET_LENGTH
);
850 noop_item
= proto_tree_add_text(lwres_tree
, tvb
, LWRES_LWPACKET_LENGTH
, 10, "Noop record");
851 noop_tree
= proto_item_add_subtree(noop_item
, ett_noop
);
856 proto_tree_add_uint(noop_tree
, hf_length
, tvb
,
857 LWRES_LWPACKET_LENGTH
, sizeof(guint16
), datalen
);
859 tvb_ensure_bytes_exist(tvb
, LWRES_LWPACKET_LENGTH
, datalen
);
863 static void dissect_getaddrsbyname(tvbuff_t
* tvb
, proto_tree
* lwres_tree
, int type
)
866 dissect_getaddrsbyname_request(tvb
, lwres_tree
);
868 dissect_getaddrsbyname_response(tvb
, lwres_tree
);
871 static void dissect_getnamebyaddr(tvbuff_t
* tvb
, proto_tree
* lwres_tree
, int type
)
874 dissect_getnamebyaddr_request(tvb
, lwres_tree
);
876 dissect_getnamebyaddr_response(tvb
, lwres_tree
);
879 static void dissect_getrdatabyname(tvbuff_t
* tvb
, proto_tree
* lwres_tree
, int type
)
882 dissect_rdata_request(tvb
, lwres_tree
);
884 dissect_rdata_response(tvb
, lwres_tree
);
888 dissect_lwres(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
890 guint16 version
, flags
, authtype
, authlength
;
891 guint32 length
, opcode
, result
, recvlength
, serial
;
892 guint32 message_type
;
894 proto_item
* lwres_item
;
895 proto_tree
* lwres_tree
;
897 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "lw_res");
898 length
= tvb_get_ntohl(tvb
, LW_LENGTH_OFFSET
);
899 version
= tvb_get_ntohs(tvb
, LW_VERSION_OFFSET
);
900 flags
= tvb_get_ntohs(tvb
, LW_PKTFLASG_OFFSET
);
901 serial
= tvb_get_ntohl(tvb
, LW_SERIAL_OFFSET
);
902 opcode
= tvb_get_ntohl(tvb
,LW_OPCODE_OFFSET
);
903 result
= tvb_get_ntohl(tvb
, LW_RESULT_OFFSET
);
904 recvlength
= tvb_get_ntohl(tvb
, LW_RECVLEN_OFFSET
);
905 authtype
= tvb_get_ntohs(tvb
, LW_AUTHTYPE_OFFSET
);
906 authlength
= tvb_get_ntohs(tvb
, LW_AUTHLEN_OFFSET
);
908 message_type
= (flags
& LWRES_LWPACKETFLAG_RESPONSE
) ? 2 : 1;
910 if(flags
& LWRES_LWPACKETFLAG_RESPONSE
)
912 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
913 "%s, opcode=%s, serial=0x%x, result=%s",
914 val_to_str_const((guint32
)message_type
,message_types_values
,"unknown"),
915 val_to_str_const(opcode
, opcode_values
, "unknown"),
917 val_to_str_const(result
,result_values
,"unknown"));
921 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
922 "%s, opcode=%s, serial=0x%x",
923 val_to_str_const((guint32
)message_type
,message_types_values
,"unknown"),
924 val_to_str_const(opcode
, opcode_values
, "unknown"),
930 lwres_item
= proto_tree_add_item(tree
,proto_lwres
, tvb
,0, -1, ENC_NA
);
931 lwres_tree
= proto_item_add_subtree(lwres_item
, ett_lwres
);
936 proto_tree_add_uint(lwres_tree
,
944 proto_tree_add_uint(lwres_tree
,
954 proto_tree_add_uint(lwres_tree
,
961 proto_tree_add_uint(lwres_tree
,
968 proto_tree_add_uint(lwres_tree
,
975 proto_tree_add_uint(lwres_tree
,
982 proto_tree_add_uint(lwres_tree
,
989 proto_tree_add_uint(lwres_tree
,
996 proto_tree_add_uint(lwres_tree
,
1007 case LWRES_OPCODE_NOOP
:
1008 dissect_noop(tvb
, lwres_tree
);
1011 case LWRES_OPCODE_GETADDRSBYNAME
:
1012 dissect_getaddrsbyname(tvb
, lwres_tree
, message_type
);
1015 case LWRES_OPCODE_GETNAMEBYADDR
:
1016 dissect_getnamebyaddr(tvb
, lwres_tree
, message_type
);
1019 case LWRES_OPCODE_GETRDATABYNAME
:
1020 dissect_getrdatabyname(tvb
, lwres_tree
, message_type
);
1028 proto_register_lwres(void)
1030 static hf_register_info hf
[] = {
1032 { "Length", "lwres.length", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1033 "lwres length", HFILL
}},
1036 { "Version", "lwres.version", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1037 "lwres version", HFILL
}},
1040 { "Packet Flags", "lwres.flags", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1041 "lwres flags", HFILL
}},
1044 { "Serial", "lwres.serial", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1045 "lwres serial", HFILL
}},
1048 { "Operation code", "lwres.opcode", FT_UINT32
, BASE_DEC
, VALS(opcode_values
), 0x0,
1049 "lwres opcode", HFILL
}},
1052 { "Result", "lwres.result", FT_UINT32
, BASE_DEC
, VALS(result_values
), 0x0,
1053 "lwres result", HFILL
}},
1056 { "Received length", "lwres.recvlen", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1057 "lwres recvlen", HFILL
}},
1060 { "Auth. type", "lwres.authtype", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1061 "lwres authtype", HFILL
}},
1064 { "Auth. length", "lwres.authlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1065 "lwres authlen", HFILL
}},
1068 { "Flags", "lwres.rflags", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1069 "lwres rflags", HFILL
}},
1071 { "Class", "lwres.class", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1072 "lwres class", HFILL
}},
1075 { "Type", "lwres.type", FT_UINT16
, BASE_DEC
, VALS(t_types
), 0x0,
1076 "lwres type", HFILL
}},
1079 { "Name length", "lwres.namelen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1080 "lwres namelen", HFILL
}},
1083 { "Domain name", "lwres.reqdname", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1084 "lwres reqdname", HFILL
}},
1087 { "Time To Live", "lwres.ttl", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1088 "lwres ttl", HFILL
}},
1091 { "Number of rdata records", "lwres.nrdatas", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1092 "lwres nrdatas", HFILL
}},
1095 { "Number of signature records", "lwres.nsigs", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1096 "lwres nsigs", HFILL
}},
1099 { "Real name length", "lwres.realnamelen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1100 "lwres realnamelen", HFILL
}},
1103 { "Real doname name", "lwres.realname", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1104 "lwres realname", HFILL
}},
1108 { "IPv4 Address", "lwres.arecord", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1109 "lwres arecord", HFILL
}},
1113 { "Length", "lwres.areclen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1114 "lwres areclen", HFILL
}},
1117 { "Priority", "lwres.srv.priority", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1118 "lwres srv prio", HFILL
}},
1121 { "Weight", "lwres.srv.weight", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1122 "lwres srv weight", HFILL
}},
1125 { "Port" , "lwres.srv.port", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1126 "lwres srv port", HFILL
}},
1129 { "Flags", "lwres.adn.flags", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1130 "lwres adn flags", HFILL
}},
1133 { "Address type", "lwres.adn.addrtype", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1134 "lwres adn addrtype", HFILL
}},
1137 { "Name length", "lwres.adn.namelen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1138 "lwres adn namelen", HFILL
}},
1141 { "Name", "lwres.adn.name", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1142 "lwres adn name", HFILL
}},
1145 { "Number of aliases", "lwres.adn.naliases", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1146 "lwres adn naliases", HFILL
}},
1149 { "Number of addresses", "lwres.adn.naddrs", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1150 "lwres adn naddrs", HFILL
}},
1153 { "Real name", "lwres.adn.realname", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1154 "lwres adn realname", HFILL
}},
1156 { &hf_adn_aliasname
,
1157 { "Alias name", "lwres.adn.aliasname", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1158 "lwres adn aliasname", HFILL
}},
1161 { "Address family", "lwres.adn.addr.family", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1162 "lwres adn addr family", HFILL
}},
1165 { "Address length", "lwres.adn.addr.length", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1166 "lwres adn addr length", HFILL
}},
1168 { &hf_adn_addr_addr
,
1169 { "IP Address", "lwres.adn.addr.addr", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1170 "lwres adn addr addr", HFILL
}},
1172 /* Add more fields here */
1175 static gint
*ett
[] = {
1197 module_t
*lwres_module
;
1199 proto_lwres
= proto_register_protocol("Light Weight DNS RESolver (BIND9)",
1202 proto_register_field_array(proto_lwres
, hf
, array_length(hf
));
1203 proto_register_subtree_array(ett
, array_length(ett
));
1205 lwres_module
= prefs_register_protocol(proto_lwres
, proto_reg_handoff_lwres
);
1207 prefs_register_uint_preference(lwres_module
, "udp.lwres_port",
1208 "lwres listener UDP Port",
1209 "Set the UDP port for lwres daemon"
1210 "(if other than the default of 921)",
1211 10, &global_lwres_port
);
1215 /* The registration hand-off routine */
1217 proto_reg_handoff_lwres(void)
1219 static gboolean lwres_prefs_initialized
= FALSE
;
1220 static dissector_handle_t lwres_handle
;
1221 static guint lwres_port
;
1223 if(!lwres_prefs_initialized
) {
1224 lwres_handle
= create_dissector_handle(dissect_lwres
, proto_lwres
);
1225 lwres_prefs_initialized
= TRUE
;
1228 dissector_delete_uint("udp.port", lwres_port
, lwres_handle
);
1231 dissector_add_uint("udp.port", global_lwres_port
, lwres_handle
);
1232 lwres_port
= global_lwres_port
;