LWRES support, from Oleg Terletsky.
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 5 Aug 2003 05:09:37 +0000 (05:09 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 5 Aug 2003 05:09:37 +0000 (05:09 +0000)
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@8133 f5534014-38df-0310-8fa8-9805f1628bb7

13 files changed:
AUTHORS
Makefile.am
configure.in
doc/ethereal.pod.template
packaging/nsis/Makefile.nmake
packaging/nsis/ethereal.nsi
plugins/Makefile.am
plugins/Makefile.nmake
plugins/lwres/AUTHORS [new file with mode: 0644]
plugins/lwres/Makefile.am [new file with mode: 0644]
plugins/lwres/Makefile.nmake [new file with mode: 0644]
plugins/lwres/moduleinfo.h [new file with mode: 0644]
plugins/lwres/packet-lwres.c [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
index dc6a168414cc6d708776233640b8cffb8da94dfe..171253b5899e891c6852febf8057a4cc64be4a62 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -1764,6 +1764,10 @@ Thierry Martin <thierry.martin [AT] accellent-group.com> {
        Support for reading files from Accellent 5Views LAN agents
 }
 
+Oleg Terletsky <oleg.terletsky [AT] comverse.com> {
+       LWRES support
+}
+
 And assorted fixes and enhancements by the people listed above and by:
 
        Pavel Roskin <proski [AT] gnu.org>
index 8d23316e1114526cdaca1268207a137c848559a1..ee820f212977e8f268e4057c2364a4663f3d3d9e 100644 (file)
@@ -1,7 +1,7 @@
 # Makefile.am
 # Automake file for Ethereal
 #
-# $Id: Makefile.am,v 1.605 2003/08/04 00:17:55 gerald Exp $
+# $Id: Makefile.am,v 1.606 2003/08/05 05:09:35 guy Exp $
 #
 # Ethereal - Network traffic analyzer
 # By Gerald Combs <gerald@ethereal.com>
@@ -441,6 +441,7 @@ plugin_libs = \
        plugins/giop/cosnaming.la \
        plugins/giop/coseventcomm.la \
        plugins/gryphon/gryphon.la \
+       plugins/lwres/lwres.la \
        plugins/megaco/megaco.la \
        plugins/mgcp/mgcp.la \
        plugins/pcli/pcli.la \
@@ -475,6 +476,7 @@ plugin_ldadd = \
        plugins/giop/packet-cosnaming-static.o \
        plugins/giop/packet-coseventcomm-static.o \
        plugins/gryphon/packet-gryphon-static.o \
+       plugins/lwres/packet-lwres-static.o \
        plugins/megaco/packet-megaco-static.o \
        plugins/mgcp/packet-mgcp-static.o \
        plugins/pcli/packet-pcli-static.o \
@@ -508,6 +510,7 @@ plugin_src = \
        plugins/giop/packet-cosnaming.c \
        plugins/giop/packet-coseventcomm.c \
        plugins/gryphon/packet-gryphon.c \
+       plugins/lwres/packet-lwres.c \
        plugins/megaco/packet-megaco.c \
        plugins/mgcp/packet-mgcp.c \
        plugins/pcli/packet-pcli.c \
@@ -521,6 +524,7 @@ plugin_ldadd = \
        "-dlopen" plugins/giop/cosnaming.la \
        "-dlopen" plugins/giop/coseventcomm.la \
        "-dlopen" plugins/gryphon/gryphon.la \
+       "-dlopen" plugins/lwres/lwres.la \
        "-dlopen" plugins/megaco/megaco.la \
        "-dlopen" plugins/mgcp/mgcp.la \
        "-dlopen" plugins/pcli/pcli.la \
index 18ab4d60b5c6afccb0ab1602e52e87aaad8bc7ea..a01fc4f101ac5aa49bf1c4d3129b4a2ed3bf7b51 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: configure.in,v 1.214 2003/07/23 20:32:35 gerald Exp $
+# $Id: configure.in,v 1.215 2003/08/05 05:09:36 guy Exp $
 dnl
 dnl Process this file with autoconf 2.13 or later to produce a
 dnl configure script; 2.12 doesn't generate a "configure" script that
@@ -786,6 +786,7 @@ AC_OUTPUT(
   plugins/docsis/Makefile
   plugins/giop/Makefile
   plugins/gryphon/Makefile
+  plugins/lwres/Makefile
   plugins/megaco/Makefile
   plugins/mgcp/Makefile
   plugins/pcli/Makefile
index 46e53438419fe43dbabcc7cf82a80159da4aeae2..5554f37c0d13c4c4def77fb268e0a22bd4aea4eb 100644 (file)
@@ -1862,6 +1862,7 @@ B<http://www.ethereal.com>.
   Christoph Wiest          <ch.wiest [AT] tesionmail.de>
   Xuan Zhang               <xz [AT] aemail4u.com>
   Thierry Martin           <thierry.martin [AT] accellent-group.com>
+  Oleg Terletsky           <oleg.terletsky [AT] comverse.com> {
   Pavel Roskin             <proski [AT] gnu.org>
   Georgi Guninski          <guninski [AT] guninski.com>
   Jason Copenhaver         <jcopenha [AT] typedef.org>
index 5c3a506d8e5d347624868b1fe1a546d1dd598ddf..6913916ce0dcf18e1572f0711e0796993acbba2d 100644 (file)
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile.nmake,v 1.19 2003/07/22 22:00:38 gerald Exp $
+# $Id: Makefile.nmake,v 1.20 2003/08/05 05:05:58 guy Exp $
 #
 # NSIS is a free packager/installer/uninstaller program for Win32.
 # It was originally written for the Winamp package, but various
@@ -27,6 +27,7 @@ PLUGINS=../../plugins/artnet/artnet.dll \
        ../../plugins/giop/coseventcomm.dll \
        ../../plugins/giop/cosnaming.dll \
        ../../plugins/gryphon/gryphon.dll \
+       ../../plugins/lwres/lwres.dll \
        ../../plugins/megaco/megaco.dll \
        ../../plugins/mgcp/mgcp.dll \
        ../../plugins/pcli/pcli.dll \
index 62489c682ddb92e8850746c0e9ad633fcacdc3b3..3dc302754ffc2a1bdd63fd3c892fda6fd775df7c 100644 (file)
@@ -1,7 +1,7 @@
 ;
 ; ethereal.nsi
 ;
-; $Id: ethereal.nsi,v 1.17 2003/07/22 22:00:38 gerald Exp $
+; $Id: ethereal.nsi,v 1.18 2003/08/05 05:05:59 guy Exp $
 
 ; ============================================================================
 ; Header configuration
@@ -179,6 +179,7 @@ File "..\..\plugins\docsis\docsis.dll"
 File "..\..\plugins\giop\coseventcomm.dll"
 File "..\..\plugins\giop\cosnaming.dll"
 File "..\..\plugins\gryphon\gryphon.dll"
+File "..\..\plugins\lwres\lwres.dll"
 File "..\..\plugins\megaco\megaco.dll"
 File "..\..\plugins\mgcp\mgcp.dll"
 File "..\..\plugins\pcli\pcli.dll"
index 95d5f84f904021471fc835023e73f38a76a2b5de..3ace2bed596d5f9171042a4e5153b9ebacd78baa 100644 (file)
@@ -1,7 +1,7 @@
 # Makefile.am
 # Automake file for Ethereal
 #
-# $Id: Makefile.am,v 1.19 2003/07/23 14:33:34 gerald Exp $
+# $Id: Makefile.am,v 1.20 2003/08/05 05:03:29 guy Exp $
 #
 # Ethereal - Network traffic analyzer
 # By Gerald Combs <gerald@ethereal.com>
@@ -21,7 +21,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-SUBDIRS = artnet docsis giop gryphon megaco mgcp pcli rtnet
+SUBDIRS = artnet docsis giop gryphon lwres megaco mgcp pcli rtnet
 
 plugindir = @plugindir@
 
index 1a99ca8f785a92d06eb2788e19809adc238c40b0..f1733deb3c39d75c5d5f6613ba386f0d8e366bf9 100644 (file)
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile.nmake,v 1.21 2003/07/18 03:01:33 guy Exp $
+# $Id: Makefile.nmake,v 1.22 2003/08/05 05:03:29 guy Exp $
 #
 
 include ..\config.nmake
@@ -11,7 +11,7 @@ CFLAGS=/DHAVE_CONFIG_H /I.. /I../wiretap /I. $(GLIB_CFLAGS) \
 
 OBJECTS=plugin_api.obj 
 
-all: $(OBJECTS) artnet docsis giop gryphon megaco mgcp pcli rtnet
+all: $(OBJECTS) artnet docsis giop gryphon lwres megaco mgcp pcli rtnet
 
 Xplugin_api.c: xyzzy plugin_gen.py plugin_api.c
        $(PYTHON) plugin_gen.py xyzzy
@@ -41,6 +41,11 @@ gryphon::
        $(MAKE) /$(MAKEFLAGS) -f Makefile.nmake
        cd ..
 
+lwres::
+       cd lwres
+       $(MAKE) /$(MAKEFLAGS) -f Makefile.nmake
+       cd ..
+
 megaco::
        cd megaco
        $(MAKE) /$(MAKEFLAGS) -f Makefile.nmake
@@ -71,6 +76,8 @@ clean:
        $(MAKE) /$(MAKEFLAGS) -f Makefile.nmake clean
        cd ../gryphon
        $(MAKE) /$(MAKEFLAGS) -f Makefile.nmake clean
+       cd ../lwres
+       $(MAKE) /$(MAKEFLAGS) -f Makefile.nmake clean
        cd ../megaco
        $(MAKE) /$(MAKEFLAGS) -f Makefile.nmake clean
        cd ../mgcp
diff --git a/plugins/lwres/AUTHORS b/plugins/lwres/AUTHORS
new file mode 100644 (file)
index 0000000..1368ca6
--- /dev/null
@@ -0,0 +1,2 @@
+Author :
+Oleg Terletsky <oleg.terletsky@comverse.com>
diff --git a/plugins/lwres/Makefile.am b/plugins/lwres/Makefile.am
new file mode 100644 (file)
index 0000000..bddeb8e
--- /dev/null
@@ -0,0 +1,48 @@
+# Makefile.am
+# Automake file for Ethereal/lwres
+#
+# $Id: Makefile.am,v 1.1 2003/08/05 05:03:30 guy Exp $
+#
+# Ethereal - Network traffic analyzer / light waight resolver (part of Bind9)
+# By Steve Oleg Terletsky <oleg.terletsky@comverse.com>
+# Copyright 20003
+# 
+# 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.
+#
+
+INCLUDES = -I$(top_srcdir)
+
+plugindir = @plugindir@
+
+plugin_LTLIBRARIES = lwres.la
+lwres_la_SOURCES = packet-lwres.c packet-lwres.h moduleinfo.h
+lwres_la_LDFLAGS = -module -avoid-version
+
+# Libs must be cleared, or else libtool won't create a shared module.
+# If your module needs to be linked against any particular libraries,
+# add them here.
+LIBS =
+
+lwres_la_DEPENDENCIES = packet-lwres-static.o
+
+packet-lwres-static.o: packet-lwres.c moduleinfo.h
+       $(LTCOMPILE) -c -o packet-lwres-static.o -D__ETHEREAL_STATIC__ $(srcdir)/packet-lwres.c 
+
+CLEANFILES = \
+       lwres \
+       *~
+
+EXTRA_DIST = \
+       Makefile.nmake
diff --git a/plugins/lwres/Makefile.nmake b/plugins/lwres/Makefile.nmake
new file mode 100644 (file)
index 0000000..479a5e2
--- /dev/null
@@ -0,0 +1,21 @@
+#
+# $Id: Makefile.nmake,v 1.1 2003/08/05 05:03:30 guy Exp $
+#
+
+include ..\..\config.nmake
+
+############### no need to modify below this line #########
+
+CFLAGS=/DHAVE_CONFIG_H /I../.. /I../../wiretap \
+       /I$(GLIB_DIR) /I$(GTK_DIR) /I$(GLIB_DIR)/gmodule \
+       /I$(GTK_DIR)\gdk /I$(GTK_DIR)\gdk\win32 \
+       /I$(PCAP_DIR)\include -D_U_="" $(LOCAL_CFLAGS)
+
+OBJECTS=packet-lwres.obj 
+
+lwres.dll lwres.exp lwres.lib : packet-lwres.obj ..\plugin_api.obj
+       link -dll /out:lwres.dll packet-lwres.obj ..\plugin_api.obj \
+       $(GLIB_DIR)\glib-$(GLIB_VERSION).lib
+
+clean:
+       rm -f $(OBJECTS) lwres.dll lwres.exp lwres.lib $(PDB_FILE)
diff --git a/plugins/lwres/moduleinfo.h b/plugins/lwres/moduleinfo.h
new file mode 100644 (file)
index 0000000..6bf1465
--- /dev/null
@@ -0,0 +1,16 @@
+/* Included *after* config.h, in order to re-define these macros */
+
+#ifdef PACKAGE
+#undef PACKAGE
+#endif
+
+/* Name of package */
+#define PACKAGE "lwres"
+
+
+#ifdef VERSION
+#undef VERSION
+#endif
+
+/* Version number of package */
+#define VERSION "0.0.1"
diff --git a/plugins/lwres/packet-lwres.c b/plugins/lwres/packet-lwres.c
new file mode 100644 (file)
index 0000000..7e76759
--- /dev/null
@@ -0,0 +1,1597 @@
+/* packet-lwres.c
+ * Routines for light weight reslover (lwres, part of BIND9) packet disassembly
+ *
+ * $Id: packet-lwres.c,v 1.1 2003/08/05 05:03:30 guy Exp $
+ *
+ * Copyright (c) 2003 by Oleg Terletsky <oleg.terletsky@comverse.com>
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1999 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
+
+#include "plugins/plugin_api.h"
+#include "moduleinfo.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <gmodule.h>
+#include <ctype.h>
+#include <time.h>
+#include <string.h>
+#include "prefs.h"
+#include "plugins/plugin_api_defs.h"
+
+#define LWRES_LWPACKET_LENGTH           (4 * 5 + 2 * 4)
+#define LWRES_LWPACKETFLAG_RESPONSE     0x0001U /* if set, pkt is a response */
+#define LWRES_LWPACKETVERSION_0         0
+
+#define LW_LENGTH_OFFSET               0 
+#define LW_VERSION_OFFSET              4 
+#define LW_PKTFLASG_OFFSET             6
+#define LW_SERIAL_OFFSET               8 
+#define LW_OPCODE_OFFSET               12 
+#define LW_RESULT_OFFSET               16 
+#define LW_RECVLEN_OFFSET              20 
+#define LW_AUTHTYPE_OFFSET             24 
+#define LW_AUTHLEN_OFFSET              26 
+
+
+#define LWRES_OPCODE_NOOP               0x00000000U
+#define LWRES_OPCODE_GETADDRSBYNAME     0x00010001U
+#define LWRES_OPCODE_GETNAMEBYADDR      0x00010002U
+#define LWRES_OPCODE_GETRDATABYNAME     0x00010003U
+
+static const value_string opcode_values[] = {
+       { LWRES_OPCODE_NOOP,                    "Noop" },
+       { LWRES_OPCODE_GETADDRSBYNAME,  "getaddrbyname" },
+       { LWRES_OPCODE_GETNAMEBYADDR,   "getnamebyaddr" },
+       { LWRES_OPCODE_GETRDATABYNAME,  "getrdatabyname" },
+       { 0, NULL },
+};
+
+
+#define LWRES_R_SUCCESS                 0
+#define LWRES_R_NOMEMORY                1
+#define LWRES_R_TIMEOUT                 2
+#define LWRES_R_NOTFOUND                3
+#define LWRES_R_UNEXPECTEDEND           4       /* unexpected end of input */
+#define LWRES_R_FAILURE                 5       /* generic failure */
+#define LWRES_R_IOERROR                 6
+#define LWRES_R_NOTIMPLEMENTED          7
+#define LWRES_R_UNEXPECTED              8
+#define LWRES_R_TRAILINGDATA            9
+#define LWRES_R_INCOMPLETE              10
+#define LWRES_R_RETRY                   11
+#define LWRES_R_TYPENOTFOUND            12
+#define LWRES_R_TOOLARGE                13
+
+#define T_A            1
+#define T_NS   2
+#define T_MX   15
+#define T_SRV  33
+
+
+static const value_string t_types[] = {
+       { T_A,          "T_A" },
+       { T_NS,         "T_NS" },
+       { T_MX,         "T_MX" },
+       { T_SRV,        "T_SRV" },
+       { 0,            NULL },
+};
+       
+
+
+
+static const value_string result_values[]  = {
+       { LWRES_R_SUCCESS,              "Success" },
+       { LWRES_R_NOMEMORY,             "No memory" },
+       { LWRES_R_TIMEOUT,                      "Timeout" },
+       { LWRES_R_NOTFOUND,                     "Not found" },
+       { LWRES_R_UNEXPECTEDEND,        "Unexpected end of input" },
+       { LWRES_R_FAILURE,                      "Generic failure" },
+       { LWRES_R_IOERROR,                      "I/O Error" },
+       { LWRES_R_UNEXPECTED,           "Unexpected" },
+       { LWRES_R_TRAILINGDATA,         "Trailing data" },
+       { LWRES_R_INCOMPLETE,           "Incompete" },
+       { LWRES_R_RETRY,                        "Retry" },
+       { LWRES_R_TYPENOTFOUND,         "Type not found" },
+       { LWRES_R_TOOLARGE,                     "Too large" },
+       { 0,                                            NULL },
+};
+
+static int hf_length = -1;
+static int hf_version = -1;
+static int hf_flags = -1;
+static int hf_serial = -1;
+static int hf_opcode = -1;
+static int hf_result = -1;
+static int hf_recvlen = -1;
+static int hf_authtype = -1;
+static int hf_authlen = -1;
+
+static int hf_rflags = -1;
+static int hf_rdclass = -1;
+static int hf_rdtype = -1;
+static int hf_namelen = -1;
+static int hf_req_name = -1;
+
+static int hf_ttl = -1;
+static int hf_nrdatas = -1;
+static int hf_nsigs = -1;
+static int hf_realnamelen = -1;
+static int hf_realname = -1;
+
+
+static int hf_a_record = -1;
+static int hf_a_rec_len = -1;
+static int hf_srv_prio = -1;
+static int hf_srv_weight = -1;
+static int hf_srv_port = -1;
+
+static int hf_adn_flags = -1;
+static int hf_adn_addrtype = -1;
+static int hf_adn_namelen = -1;
+static int hf_adn_name = -1;
+
+static int hf_adn_realname = -1;
+static int hf_adn_aliasname = -1;
+
+static int hf_adn_naddrs = -1;
+static int hf_adn_naliases = -1;
+static int hf_adn_family = -1;
+static int hf_adn_addr_len = -1;
+static int hf_adn_addr_addr = -1;
+
+
+static int ett_lwres = -1;
+static int ett_rdata_req = -1;
+static int ett_rdata_resp = -1;
+static int ett_a_rec = -1;
+static int ett_a_rec_addr = -1;
+static int ett_srv_rec = -1;
+static int ett_srv_rec_item = -1;
+static int ett_adn_request = -1;
+static int ett_adn_resp = -1;
+static int ett_adn_alias = -1;
+static int ett_adn_addr = -1;
+static int ett_nba_request = -1;
+static int ett_nba_resp = -1;
+static int ett_noop = -1;
+
+static int ett_mx_rec = -1;
+static int ett_mx_rec_item = -1;
+
+static int ett_ns_rec = -1;
+static int ett_ns_rec_item = -1;
+
+
+
+#ifndef __ETHEREAL_STATIC__
+G_MODULE_EXPORT const gchar version[] = VERSION;
+#endif
+
+
+#define LWRES_UDP_PORT 921
+
+static guint global_lwres_port = LWRES_UDP_PORT;
+static guint lwres_port = LWRES_UDP_PORT;
+
+void proto_reg_handoff_lwres(void);
+
+
+/* Define the lwres proto */
+static int proto_lwres = -1;
+
+
+/* Define many many headers for mgcp */
+
+static const value_string message_types_values[] = {
+       { 1,          "REQUEST " },
+    { 2,          "RESPONSE" },
+    { 0 ,                      NULL },
+};
+
+
+
+void
+ip_to_str_buf(const guint8 *ad, gchar *buf)
+{
+  gchar        *p;
+  int           i;
+  guint32       octet;
+  guint32       digit;
+  gboolean      saw_nonzero;
+
+  p = buf;
+  i = 0;
+  for (;;) {
+    saw_nonzero = FALSE;
+    octet = ad[i];
+    digit = octet/100;
+    if (digit != 0) {
+      *p++ = digit + '0';
+      saw_nonzero = TRUE;
+    }
+    octet %= 100;
+    digit = octet/10;
+    if (saw_nonzero || digit != 0)
+      *p++ = digit + '0';
+    digit = octet%10;
+    *p++ = digit + '0';
+    if (i == 3)
+      break;
+    *p++ = '.';
+    i++;
+  }
+  *p = '\0';
+}
+
+gchar *
+ip_to_str(const guint8 *ad) {
+  static gchar  str[4][16];
+  static gchar *cur;
+
+  if (cur == &str[0][0]) {
+    cur = &str[1][0];
+  } else if (cur == &str[1][0]) {
+    cur = &str[2][0];
+  } else if (cur == &str[2][0]) {
+    cur = &str[3][0];
+  } else {
+    cur = &str[0][0];
+  }
+  ip_to_str_buf(ad, cur);
+  return cur;
+}
+
+
+int
+get_dns_name(tvbuff_t *tvb, int offset, int dns_data_offset,
+    char *name, int maxname)
+{
+  int start_offset = offset;
+  char *np = name;
+  int len = -1;
+  int chars_processed = 0;
+  int data_size = tvb_reported_length_remaining(tvb, dns_data_offset);
+  int component_len;
+  int indir_offset;
+
+  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 */
+
+  maxname--;   /* reserve space for the trailing '\0' */
+  for (;;) {
+    component_len = tvb_get_guint8(tvb, offset);
+    offset++;
+    if (component_len == 0)
+      break;
+    chars_processed++;
+    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) {
+          *np++ = tvb_get_guint8(tvb, offset);
+          maxname--;
+        }
+       component_len--;
+       offset++;
+        chars_processed++;
+      }
+      break;
+
+    case 0x40:
+      /* Extended label (RFC 2673) */
+      switch (component_len & 0x3f) {
+
+      case 0x01:
+       /* Bitstring label */
+       {
+         int bit_count;
+         int label_len;
+         int print_len;
+
+
+         bit_count = tvb_get_guint8(tvb, offset);
+         offset++;
+         label_len = (bit_count - 1) / 8 + 1;
+
+
+         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;
+           }
+         }
+         while(label_len--) {
+           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;
+             }
+           }
+           offset++;
+         }
+         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;
+           }
+         }
+       }
+       break;
+
+      default:
+       strcpy(name, "<Unknown extended label>");
+       /* Parsing will propably fail from here on, since the */
+       /* label length is unknown... */
+       len = offset - start_offset;
+        if (len < min_len)
+          THROW(ReportedBoundsError);
+        return len;
+      }
+      break;
+
+    case 0x80:
+      THROW(ReportedBoundsError);
+
+    case 0xc0:
+      /* Pointer. */
+      indir_offset = dns_data_offset +
+          (((component_len & ~0xc0) << 8) | tvb_get_guint8(tvb, offset));
+      offset++;
+      chars_processed++;
+
+      /* 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)
+        len = offset - start_offset;
+
+      /* 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>");
+        if (len < min_len)
+          THROW(ReportedBoundsError);
+        return len;
+      }
+
+      offset = indir_offset;
+      break;   /* now continue processing from there */
+    }
+  }
+
+  *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)
+    len = offset - start_offset;
+  /* Zero-length name means "root server" */
+  if (*name == '\0')
+    strcpy(name, "<Root>");
+  if (len < min_len)
+    THROW(ReportedBoundsError);
+  return len;
+}
+
+
+static void dissect_getnamebyaddr_request(tvbuff_t* tvb, proto_tree* lwres_tree)
+{
+       guint32 flags,family;
+       guint16 addrlen, slen;
+       const gchar* addr;
+
+       proto_item* nba_request_item;
+       proto_tree* nba_request_tree;
+
+       flags = tvb_get_ntohl(tvb, LWRES_LWPACKET_LENGTH);
+       family = tvb_get_ntohl(tvb, LWRES_LWPACKET_LENGTH + 4);
+       addrlen = tvb_get_ntohs(tvb, LWRES_LWPACKET_LENGTH + 8);
+       addr = tvb_get_ptr(tvb, LWRES_LWPACKET_LENGTH + 10, 4);
+       slen = strlen((char*)ip_to_str(addr));
+
+       if(lwres_tree)
+       {
+               nba_request_item = proto_tree_add_text(lwres_tree,tvb,LWRES_LWPACKET_LENGTH,LWRES_LWPACKET_LENGTH+14,"getnamebyaddr parameters");
+               nba_request_tree = proto_item_add_subtree(nba_request_item, ett_nba_request);
+       }
+       else return;
+
+               proto_tree_add_uint(nba_request_tree,
+                                                               hf_adn_flags,
+                                                               tvb,
+                                                               LWRES_LWPACKET_LENGTH,
+                                                               4,
+                                                               flags);
+
+               proto_tree_add_uint(nba_request_tree,
+                                                               hf_adn_family,
+                                                               tvb,
+                                                               LWRES_LWPACKET_LENGTH + 4,
+                                                               4,
+                                                               family);
+
+               proto_tree_add_uint(nba_request_tree,
+                                                               hf_adn_addr_len,
+                                                               tvb,
+                                                               LWRES_LWPACKET_LENGTH + 8,
+                                                               2,
+                                                               addrlen);
+
+               proto_tree_add_string(nba_request_tree,
+                                                               hf_adn_addr_addr,
+                                                               tvb,
+                                                               LWRES_LWPACKET_LENGTH + 10,
+                                                               slen,
+                                                               ip_to_str(addr));
+
+}
+
+static void dissect_getnamebyaddr_response(tvbuff_t* tvb, proto_tree* lwres_tree)
+{
+       guint32 flags,i, offset;
+       guint16 naliases,realnamelen,aliaslen;
+       char aliasname[120];
+       char realname[120];
+       
+
+       proto_item* nba_resp_item;
+       proto_tree* nba_resp_tree;
+
+       proto_item* alias_item;
+       proto_tree* alias_tree;
+
+       if(lwres_tree)
+       {
+               nba_resp_item = proto_tree_add_text(lwres_tree, tvb, LWRES_LWPACKET_LENGTH, 10,"getnamebyaddr records");
+               nba_resp_tree = proto_item_add_subtree(nba_resp_item, ett_nba_resp);
+       }
+       else return;
+
+       flags = tvb_get_ntohl(tvb, LWRES_LWPACKET_LENGTH);
+       naliases = tvb_get_ntohs(tvb, LWRES_LWPACKET_LENGTH + 4);
+       realnamelen = tvb_get_ntohs(tvb,LWRES_LWPACKET_LENGTH + 4 + 2);
+       tvb_get_nstringz(tvb, LWRES_LWPACKET_LENGTH + 4 + 2 + 2, realnamelen, realname);
+       realname[realnamelen]='\0';
+
+       proto_tree_add_uint(nba_resp_tree,
+                                               hf_adn_flags,
+                                               tvb,
+                                               LWRES_LWPACKET_LENGTH,
+                                               4,
+                                               flags);
+       proto_tree_add_uint(nba_resp_tree,
+                                               hf_adn_naliases,
+                                               tvb,
+                                               LWRES_LWPACKET_LENGTH + 4,
+                                               2,
+                                               naliases);
+
+       proto_tree_add_uint(nba_resp_tree,
+                                               hf_adn_namelen,
+                                               tvb,
+                                               LWRES_LWPACKET_LENGTH + 6,
+                                               2, 
+                                               realnamelen);
+
+       proto_tree_add_string(nba_resp_tree,
+                                                 hf_adn_realname,
+                                                 tvb,
+                                                 LWRES_LWPACKET_LENGTH + 8,
+                                                 realnamelen,
+                                                 realname);
+
+       offset=LWRES_LWPACKET_LENGTH + 8 + realnamelen;
+
+       if(naliases)
+       {
+               for(i=0; i<naliases; i++)
+               {
+                       aliaslen = tvb_get_ntohs(tvb, offset);
+                       tvb_get_nstringz(tvb, offset + 2, aliaslen, aliasname);
+                       aliasname[aliaslen]='\0';
+
+                       alias_item = proto_tree_add_text(nba_resp_tree, tvb, offset, 2 + aliaslen, "Alias %s",aliasname);
+                       alias_tree = proto_item_add_subtree(alias_item, ett_adn_alias);
+
+                       proto_tree_add_uint(alias_tree,
+                                                               hf_adn_namelen,
+                                                               tvb,
+                                                               offset,
+                                                               2,
+                                                               aliaslen);
+
+                       proto_tree_add_string(alias_tree,
+                                                               hf_adn_aliasname,
+                                                               tvb,
+                                                               offset + 2,
+                                                               aliaslen,
+                                                               aliasname);
+
+                       offset+=(2 + aliaslen + 1);
+               }
+       }
+}
+
+static void dissect_getaddrsbyname_request(tvbuff_t* tvb, proto_tree* lwres_tree)
+{
+       guint32 flags,addrtype;
+       guint16 namelen;
+       guint8  name[120];
+
+       proto_item* adn_request_item;
+       proto_tree* adn_request_tree;
+       
+       flags = tvb_get_ntohl(tvb, LWRES_LWPACKET_LENGTH);
+       addrtype = tvb_get_ntohl(tvb, LWRES_LWPACKET_LENGTH + 4);
+       namelen  = tvb_get_ntohs(tvb, LWRES_LWPACKET_LENGTH + 8);
+       tvb_get_nstringz(tvb, LWRES_LWPACKET_LENGTH+10, namelen, name);
+        name[namelen]='\0';
+
+       if(lwres_tree)
+       {
+               adn_request_item = proto_tree_add_text(lwres_tree,tvb,
+                                               LWRES_LWPACKET_LENGTH,10+namelen+1,
+                                               "getaddrbyname parameters");
+               adn_request_tree = proto_item_add_subtree(adn_request_item, ett_adn_request);
+       }
+       else
+               return;
+
+
+       proto_tree_add_uint(adn_request_tree,
+                               hf_adn_flags,
+                               tvb,
+                               LWRES_LWPACKET_LENGTH+0,
+                               sizeof(guint32),
+                               flags);
+
+       proto_tree_add_uint(adn_request_tree,
+                               hf_adn_addrtype,
+                               tvb,
+                               LWRES_LWPACKET_LENGTH+4,
+                               sizeof(guint32),
+                               addrtype);
+
+       proto_tree_add_uint(adn_request_tree,
+                               hf_adn_namelen,
+                               tvb,
+                               LWRES_LWPACKET_LENGTH+8,
+                               sizeof(guint16),
+                               namelen);
+
+       proto_tree_add_string(adn_request_tree,
+                               hf_adn_name,
+                               tvb,
+                               LWRES_LWPACKET_LENGTH+10,
+                               namelen,
+                               name);
+       
+}
+
+
+static void dissect_getaddrsbyname_response(tvbuff_t* tvb, proto_tree* lwres_tree)
+{
+       guint32 flags, family ,i, offset;
+       guint16 naliases, naddrs, realnamelen, length, aliaslen;
+       const gchar* addr;
+       guint slen;
+       char realname[120];
+       char aliasname[120];
+
+       proto_item* adn_resp_item;
+       proto_tree* adn_resp_tree;
+       proto_item* alias_item;
+       proto_tree* alias_tree;
+       proto_item* addr_item;
+       proto_tree* addr_tree;
+
+       
+
+       if(lwres_tree)
+       {
+               adn_resp_item = proto_tree_add_text(lwres_tree, tvb, LWRES_LWPACKET_LENGTH, 10, "getaddrbyname records");
+               adn_resp_tree = proto_item_add_subtree(adn_resp_item, ett_adn_resp);
+       }
+       else return;
+
+       flags = tvb_get_ntohl(tvb, LWRES_LWPACKET_LENGTH);
+       naliases = tvb_get_ntohs(tvb, LWRES_LWPACKET_LENGTH + 4);
+       naddrs   = tvb_get_ntohs(tvb, LWRES_LWPACKET_LENGTH + 6);
+       realnamelen = tvb_get_ntohs(tvb, LWRES_LWPACKET_LENGTH + 8);
+       tvb_get_nstringz(tvb, LWRES_LWPACKET_LENGTH + 10, realnamelen, realname);
+       realname[realnamelen]='\0';
+
+       
+       proto_tree_add_uint(adn_resp_tree,
+                                               hf_adn_flags,
+                                               tvb, 
+                                               LWRES_LWPACKET_LENGTH,
+                                               4,
+                                               flags);
+
+       proto_tree_add_uint(adn_resp_tree,
+                                               hf_adn_naliases,
+                                               tvb, 
+                                               LWRES_LWPACKET_LENGTH + 4,
+                                               2,
+                                               naliases);
+
+       proto_tree_add_uint(adn_resp_tree,
+                                               hf_adn_naddrs,
+                                               tvb,
+                                               LWRES_LWPACKET_LENGTH + 6,
+                                               2,
+                                               naddrs);
+
+       proto_tree_add_uint(adn_resp_tree,
+                                               hf_adn_namelen,
+                                               tvb,
+                                               LWRES_LWPACKET_LENGTH + 8,
+                                               2, 
+                                               realnamelen);
+       
+       proto_tree_add_string(adn_resp_tree,
+                                               hf_adn_realname,
+                                               tvb,
+                                               LWRES_LWPACKET_LENGTH + 10,
+                                               realnamelen,
+                                               realname);
+
+       offset = LWRES_LWPACKET_LENGTH + 10 + realnamelen + 1;
+
+       if(naliases)
+       {
+               for(i=0; i<naliases; i++)
+               {
+                       aliaslen = tvb_get_ntohs(tvb, offset);
+                       tvb_get_nstringz(tvb, offset + 2, aliaslen, aliasname);
+                       aliasname[aliaslen]='\0';
+
+                       alias_item = proto_tree_add_text(adn_resp_tree, tvb, offset, 2 + aliaslen, "Alias %s",aliasname);
+                       alias_tree = proto_item_add_subtree(alias_item, ett_adn_alias);
+
+                       proto_tree_add_uint(alias_tree,
+                                                               hf_adn_namelen,
+                                                               tvb,
+                                                               offset,
+                                                               2,
+                                                               aliaslen);
+
+                       proto_tree_add_string(alias_tree,
+                                                               hf_adn_aliasname,
+                                                               tvb,
+                                                               offset + 2,
+                                                               aliaslen,
+                                                               aliasname);
+
+                       offset+=(2 + aliaslen + 1);
+               }
+       }
+
+       if(naddrs)
+       {
+               for(i=0; i < naddrs; i++)
+               {
+                       family = tvb_get_ntohl(tvb, offset);
+                       length = tvb_get_ntohs(tvb, offset + 4);
+                       addr = tvb_get_ptr(tvb, offset + 6, 4);
+                       slen = strlen((char*)ip_to_str(addr));
+               
+                       addr_item = proto_tree_add_text(adn_resp_tree,tvb, offset, 4+2+4, "Address %s",ip_to_str(addr));
+                       addr_tree = proto_item_add_subtree(addr_item, ett_adn_addr);
+
+                       proto_tree_add_uint(addr_tree, 
+                                                               hf_adn_family,
+                                                               tvb, 
+                                                               offset, 
+                                                               4,
+                                                               family);
+
+                       proto_tree_add_uint(addr_tree,
+                                                               hf_adn_addr_len,
+                                                               tvb,
+                                                               offset + 4,
+                                                               2,
+                                                               length);
+
+                       proto_tree_add_string(addr_tree,
+                                                               hf_adn_addr_addr,
+                                                               tvb,
+                                                               offset + 6,
+                                                               slen,
+                                                               ip_to_str(addr));
+
+                       offset+= 4 + 2 + 4;
+               }
+       }
+
+
+}
+
+static void dissect_a_records(tvbuff_t* tvb, proto_tree* tree,guint32 nrec,int offset)
+{
+       guint32 i, curr;
+       const gchar* addr;
+       guint16 len;
+       proto_item* a_rec_item;
+       proto_tree* a_rec_tree;
+       proto_item* addr_item;
+       proto_tree* addr_tree;
+
+       if(tree)
+       {
+               a_rec_item = proto_tree_add_text(tree,tvb,offset,
+                                       ((sizeof(guint32) + sizeof(guint16)) * nrec),"A records");
+
+               a_rec_tree = proto_item_add_subtree(a_rec_item, ett_a_rec);
+       }
+       else 
+               return;
+
+       for(i=0; i<nrec; i++)
+       {
+       
+               curr = offset + ((sizeof(guint32)+sizeof(guint16)) * i);
+
+               len  = tvb_get_ntohs(tvb,curr);
+               addr = tvb_get_ptr(tvb,curr+2,4);
+
+               if(a_rec_tree)
+               {
+                       addr_item = proto_tree_add_text(a_rec_tree,tvb, curr, 6,"IP Address");
+                       addr_tree = proto_item_add_subtree(addr_item, ett_a_rec_addr);
+                       proto_item_set_text(addr_item,"Address %s",ip_to_str(addr));
+               }
+               else return;
+               
+               proto_tree_add_uint(addr_tree,
+                                       hf_a_rec_len,
+                                       tvb,
+                                       curr,
+                                       sizeof(guint16),
+                                       len);
+
+               proto_tree_add_text(addr_tree, 
+                                               tvb,
+                                               curr + 2, 
+                                               4, 
+                                               "Addr: %s",
+                                               ip_to_str(addr));
+               
+       }
+
+}
+
+static void dissect_srv_records(tvbuff_t* tvb, proto_tree* tree,guint32 nrec,int offset)
+{
+       guint32 i, curr;
+       guint16 len, priority, weight, port, namelen, dlen;
+       const char *cmpname;
+       guint8 dname[120];
+
+       proto_item* srv_rec_item, *rec_item;
+       proto_item* srv_rec_tree, *rec_tree;
+
+       if(tree)
+       {
+               srv_rec_item = proto_tree_add_text(tree, tvb, offset, offset, "SRV records");
+               srv_rec_tree = proto_item_add_subtree(srv_rec_item, ett_srv_rec);
+                              proto_item_set_text(srv_rec_item, "SRV records (%d)", nrec);
+       }
+       else return;
+
+       curr = offset;
+
+       for(i=0; i < nrec; i++)
+       {
+               len =      tvb_get_ntohs(tvb, curr);
+               priority = tvb_get_ntohs(tvb, curr + 2);
+               weight   = tvb_get_ntohs(tvb, curr + 4);
+               port     = tvb_get_ntohs(tvb, curr + 6);
+               namelen = len - 8;
+               cmpname  = tvb_get_ptr(tvb, curr + 8, namelen);
+
+               dlen = get_dns_name(tvb, curr + 8, curr, dname, sizeof(dname));
+
+               if(srv_rec_tree)
+               {
+                       rec_item = proto_tree_add_text(srv_rec_tree, tvb, curr, 6,"  ");
+                       rec_tree = proto_item_add_subtree(rec_item, ett_srv_rec_item);
+                       proto_item_set_text(rec_item,
+                                               "SRV record:pri=%d,w=%d,port=%d,dname=%s",
+                                               priority,
+                                               weight,
+                                               port,
+                                               dname); 
+               }
+               else return;
+
+               proto_tree_add_uint(rec_tree,
+                                               hf_srv_prio,
+                                               tvb,
+                                               curr + 2,
+                                               2,
+                                               priority);
+
+               proto_tree_add_uint(rec_tree,
+                                               hf_srv_weight,
+                                               tvb,
+                                               curr + 4,
+                                               2,
+                                               weight);
+
+               proto_tree_add_uint(rec_tree,
+                                               hf_srv_port,
+                                               tvb,
+                                               curr + 6,
+                                               2,
+                                               port);
+
+
+               proto_tree_add_text(rec_tree,
+                                                       tvb,
+                                                       curr + 8,
+                                                       dlen,
+                                                       "DNAME: %s", dname);
+
+               curr+=((sizeof(short)*4) + dlen);
+                                                       
+       }
+
+}
+
+static void dissect_mx_records(tvbuff_t* tvb, proto_tree* tree, guint32 nrec, int offset)
+{
+       
+       guint32 i, curr;
+       guint16 len, priority, dlen, namelen;
+       const char* cname;
+       guint8 dname[120];
+
+       proto_item* mx_rec_item, *rec_item;
+       proto_tree* mx_rec_tree, *rec_tree;
+       
+
+       if(tree)
+       {
+               mx_rec_item = proto_tree_add_text(tree, tvb, offset, offset, "MX records (%d)", nrec);
+               mx_rec_tree = proto_item_add_subtree(mx_rec_item, ett_mx_rec);
+       }
+       else
+               return;
+       
+       curr = offset;
+       for(i=0; i < nrec; i++)
+       {
+               len =           tvb_get_ntohs(tvb, curr);
+               priority =  tvb_get_ntohs(tvb, curr + 2);
+               namelen  =  len - 4;
+               cname = tvb_get_ptr(tvb, curr + 4, 4);
+               dlen  = get_dns_name(tvb, curr + 4, curr, dname, sizeof(dname));
+               if(mx_rec_tree)
+               {
+                       rec_item = proto_tree_add_text(mx_rec_tree, tvb, curr,6,"MX record: pri=%d,dname=%s",
+                                               priority,dname);
+                       rec_tree = proto_item_add_subtree(rec_item, ett_mx_rec_item);
+               }
+               else 
+                       return;
+
+               
+               proto_tree_add_uint(rec_tree,
+                                                       hf_srv_prio,
+                                                       tvb,
+                                                       curr + 2,
+                                                       2,
+                                                       priority);
+       
+               proto_tree_add_text(rec_tree,
+                                                       tvb,
+                                                       curr + 4,
+                                                       dlen,
+                                                       "name: %s", dname);
+
+               curr+=((sizeof(short)*2) + dlen);
+       
+
+       }
+       
+}
+
+static void dissect_ns_records(tvbuff_t* tvb, proto_tree* tree, guint32 nrec, int offset)
+{
+       guint32 i, curr;
+       guint16 len, dlen, namelen;
+       guint8 dname[120];
+
+       proto_item* ns_rec_item, *rec_item;
+       proto_tree* ns_rec_tree, *rec_tree;
+       
+       if(tree)
+       {
+               ns_rec_item = proto_tree_add_text(tree, tvb, offset, offset, "NS record (%d)", nrec);
+               ns_rec_tree = proto_item_add_subtree(ns_rec_item, ett_ns_rec);
+       }
+       else
+               return;
+       curr=offset;
+
+       for(i=0;i<nrec;i++)
+       {
+               len = tvb_get_ntohs(tvb, curr);
+               namelen = len - 2;
+               dlen = get_dns_name(tvb, curr + 2, curr, dname, sizeof(dname));
+               if(ns_rec_tree)
+               {
+                       rec_item = proto_tree_add_text(ns_rec_tree, tvb, curr,4, "NS record: dname=%s",dname);
+                       rec_tree = proto_item_add_subtree(rec_item, ett_ns_rec_item);
+               }
+               else
+                       return;
+
+               proto_tree_add_text(rec_tree,
+                                                       tvb,
+                                                       curr + 2,
+                                                       dlen,
+                                                       "Name: %s", dname);
+               curr+=(sizeof(short) + dlen);
+                                                       
+       }
+       
+
+}
+
+static void dissect_rdata_request(tvbuff_t* tvb, proto_tree* lwres_tree)
+{
+       guint32 rflags;
+       guint16 rdclass, rdtype, namelen;
+       guint8 name[120];
+
+       proto_item* rdata_request_item;
+       proto_tree* rdata_request_tree;
+
+       rflags = tvb_get_ntohl(tvb, LWRES_LWPACKET_LENGTH+0);
+       rdclass = tvb_get_ntohs(tvb, LWRES_LWPACKET_LENGTH+4);
+       rdtype =  tvb_get_ntohs(tvb, LWRES_LWPACKET_LENGTH+6);
+       namelen = tvb_get_ntohs(tvb, LWRES_LWPACKET_LENGTH+8);
+       tvb_get_nstringz(tvb, LWRES_LWPACKET_LENGTH+10, namelen, name);
+       name[namelen]='\0';
+
+       if(lwres_tree)
+       {
+               rdata_request_item = 
+                       proto_tree_add_text(lwres_tree,tvb,LWRES_LWPACKET_LENGTH,10+namelen+1,"RDATA request parameters");
+               rdata_request_tree = proto_item_add_subtree(rdata_request_item, ett_rdata_req);
+       }
+       else 
+               return;
+
+       proto_tree_add_uint(rdata_request_tree,
+                       hf_rflags,
+                       tvb,
+                       LWRES_LWPACKET_LENGTH+0,
+                       sizeof(guint32),
+                       rflags);
+
+       proto_tree_add_uint(rdata_request_tree,
+                       hf_rdclass,
+                       tvb,
+                       LWRES_LWPACKET_LENGTH+4,
+                       sizeof(guint16),
+                       rdclass);
+
+       proto_tree_add_uint(rdata_request_tree,
+                       hf_rdtype,
+                       tvb,
+                       LWRES_LWPACKET_LENGTH+6,
+                       sizeof(guint16),
+                       rdtype);
+
+       proto_tree_add_uint(rdata_request_tree,
+                       hf_namelen,
+                       tvb,
+                       LWRES_LWPACKET_LENGTH+8,
+                       sizeof(guint16),
+                       namelen);
+
+       proto_tree_add_string(rdata_request_tree,
+                       hf_req_name,
+                       tvb,
+                       LWRES_LWPACKET_LENGTH+10,
+                       namelen,
+                       name);
+
+}
+
+static void dissect_rdata_response(tvbuff_t* tvb, proto_tree* lwres_tree)
+{
+       guint32 rflags, ttl, offset;
+       guint16 rdclass, rdtype, nrdatas, nsigs, realnamelen;
+       guint8 realname[120];
+
+       proto_item* rdata_resp_item;
+       proto_tree* rdata_resp_tree;
+
+       rflags = tvb_get_ntohl(tvb, LWRES_LWPACKET_LENGTH+0);
+       rdclass = tvb_get_ntohs(tvb, LWRES_LWPACKET_LENGTH+4);
+       rdtype =  tvb_get_ntohs(tvb, LWRES_LWPACKET_LENGTH+6);
+       ttl    =  tvb_get_ntohl(tvb, LWRES_LWPACKET_LENGTH+8);
+       nrdatas = tvb_get_ntohs(tvb, LWRES_LWPACKET_LENGTH+12);
+       nsigs   = tvb_get_ntohs(tvb, LWRES_LWPACKET_LENGTH+14);
+       realnamelen = tvb_get_ntohs(tvb,LWRES_LWPACKET_LENGTH+16);
+       tvb_get_nstringz(tvb,LWRES_LWPACKET_LENGTH+18,realnamelen, realname);
+       realname[realnamelen]='\0';
+
+       offset = LWRES_LWPACKET_LENGTH + 18 + realnamelen + 1;
+
+       if(lwres_tree)
+       {
+               rdata_resp_item = proto_tree_add_text(lwres_tree,tvb,LWRES_LWPACKET_LENGTH, 18+realnamelen+1,"RDATA response");
+               rdata_resp_tree = proto_item_add_subtree(rdata_resp_item, ett_rdata_resp);
+       }
+       else
+               return;
+
+       proto_tree_add_uint(rdata_resp_tree,
+                        hf_rflags,
+                        tvb,
+                        LWRES_LWPACKET_LENGTH+0,
+                        sizeof(guint32),
+                        rflags);
+
+       proto_tree_add_uint(rdata_resp_tree,
+                        hf_rdclass,
+                        tvb,
+                        LWRES_LWPACKET_LENGTH+4,
+                        sizeof(guint16),
+                        rdclass);
+
+       proto_tree_add_uint(rdata_resp_tree,
+                        hf_rdtype,
+                        tvb,
+                        LWRES_LWPACKET_LENGTH+6,
+                        sizeof(guint16),
+                        rdtype);
+
+       proto_tree_add_uint(rdata_resp_tree,
+                       hf_ttl,
+                       tvb,
+                       LWRES_LWPACKET_LENGTH+8,
+                       sizeof(guint32),
+                       ttl);
+
+       proto_tree_add_uint(rdata_resp_tree,
+                       hf_nrdatas,
+                       tvb,
+                       LWRES_LWPACKET_LENGTH+12,
+                       sizeof(guint16),
+                       nrdatas);
+
+       proto_tree_add_uint(rdata_resp_tree,
+                       hf_nsigs,
+                       tvb,
+                       LWRES_LWPACKET_LENGTH+14,
+                       sizeof(guint16),
+                       nsigs);
+
+       proto_tree_add_uint(rdata_resp_tree,
+                       hf_realnamelen,
+                       tvb,
+                       LWRES_LWPACKET_LENGTH+16,
+                       sizeof(guint16),
+                       realnamelen);
+
+       proto_tree_add_string(rdata_resp_tree,
+                        hf_realname,
+                        tvb,
+                        LWRES_LWPACKET_LENGTH+18,
+                        realnamelen,
+                        realname);
+
+       switch(rdtype)
+       {
+               case T_A:
+                       dissect_a_records(tvb,rdata_resp_tree,nrdatas,offset);
+               break;
+
+               case T_SRV:
+                       dissect_srv_records(tvb,rdata_resp_tree,nrdatas, offset);
+               break;
+
+               case T_MX:
+                       dissect_mx_records(tvb,rdata_resp_tree,nrdatas, offset);
+               break;
+
+               case T_NS:
+                       dissect_ns_records(tvb,rdata_resp_tree,nrdatas, offset);
+               break;
+       }
+
+}
+
+static void dissect_noop(tvbuff_t* tvb, proto_tree* lwres_tree)
+{
+       guint16 datalen;
+       const char* data;
+
+       proto_item* noop_item;
+       proto_tree* noop_tree;
+
+       datalen = tvb_get_ntohs(tvb, LWRES_LWPACKET_LENGTH);
+       data = tvb_get_ptr(tvb, LWRES_LWPACKET_LENGTH, datalen);
+       
+       if(lwres_tree)
+       {
+               noop_item = proto_tree_add_text(lwres_tree, tvb, LWRES_LWPACKET_LENGTH, 10, "Noop record");
+               noop_tree = proto_item_add_subtree(noop_item, ett_noop);
+       }
+       else
+               return;
+
+       proto_tree_add_uint(noop_tree,
+                                               hf_length,
+                                               tvb,
+                                               LWRES_LWPACKET_LENGTH,
+                                               sizeof(guint16),
+                                               datalen);
+
+}
+
+static void dissect_getaddrsbyname(tvbuff_t* tvb, proto_tree* lwres_tree, int type)
+{
+       if(type == 1)
+               dissect_getaddrsbyname_request(tvb, lwres_tree);
+       else
+               dissect_getaddrsbyname_response(tvb, lwres_tree);
+}
+
+static void dissect_getnamebyaddr(tvbuff_t* tvb, proto_tree* lwres_tree, int type)
+{
+       if(type == 1)
+               dissect_getnamebyaddr_request(tvb, lwres_tree);
+       else
+               dissect_getnamebyaddr_response(tvb, lwres_tree);
+}
+
+static void dissect_getrdatabyname(tvbuff_t* tvb, proto_tree* lwres_tree, int type)
+{
+       if(type == 1) 
+               dissect_rdata_request(tvb, lwres_tree);
+       else            
+               dissect_rdata_response(tvb, lwres_tree);
+}
+
+static void
+dissect_lwres(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+       guint16 version, flags, authtype, authlength ;
+       guint32 length, opcode, result, recvlength, serial;
+       guint32 message_type;
+
+       proto_item* lwres_item;
+       proto_tree* lwres_tree;
+
+       if (check_col(pinfo->cinfo, COL_PROTOCOL))
+               col_set_str(pinfo->cinfo, COL_PROTOCOL, "lw_res");
+       length = tvb_get_ntohl(tvb, LW_LENGTH_OFFSET);
+       version = tvb_get_ntohs(tvb, LW_VERSION_OFFSET);
+       flags = tvb_get_ntohs(tvb, LW_PKTFLASG_OFFSET);
+       serial = tvb_get_ntohl(tvb, LW_SERIAL_OFFSET);
+       opcode = tvb_get_ntohl(tvb,LW_OPCODE_OFFSET);
+       result = tvb_get_ntohl(tvb, LW_RESULT_OFFSET);
+       recvlength = tvb_get_ntohl(tvb, LW_RECVLEN_OFFSET);
+       authtype = tvb_get_ntohs(tvb, LW_AUTHTYPE_OFFSET);
+       authlength = tvb_get_ntohs(tvb, LW_AUTHLEN_OFFSET);
+
+       message_type = (flags & LWRES_LWPACKETFLAG_RESPONSE) ? 2 : 1;
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+                       col_clear(pinfo->cinfo, COL_INFO);
+
+               if(flags & LWRES_LWPACKETFLAG_RESPONSE)
+               {
+                               col_add_fstr(pinfo->cinfo, COL_INFO,
+                               "%s, opcode=%s, serial=0x%x, result=%s",
+                                       val_to_str((guint32)message_type,message_types_values,"unknown"),
+                                       val_to_str(opcode, opcode_values, "unknown"),
+                                               serial,
+                                               val_to_str(result,result_values,"unknown"));
+                       }
+               else
+               {
+                               col_add_fstr(pinfo->cinfo, COL_INFO,
+                                       "%s, opcode=%s, serial=0x%x",
+                                       val_to_str((guint32)message_type,message_types_values,"unknown"),
+                                               val_to_str(opcode, opcode_values, "unknown"),
+                               serial);
+               }
+       }
+
+       if(tree)
+       {
+               lwres_item = proto_tree_add_item(tree,proto_lwres, tvb,0, -1, FALSE);
+               lwres_tree = proto_item_add_subtree(lwres_item, ett_lwres);
+       }
+       else return;
+
+
+       proto_tree_add_uint(lwres_tree,
+                       hf_length,
+                       tvb,
+                       LW_LENGTH_OFFSET,
+                       sizeof(guint32),
+                       length);
+
+
+       proto_tree_add_uint(lwres_tree,
+                               hf_version,
+                               tvb,
+                               LW_VERSION_OFFSET,
+                               sizeof(guint16),
+                               version);
+               
+
+
+
+       proto_tree_add_uint(lwres_tree,
+                               hf_flags,
+                               tvb,
+                               LW_PKTFLASG_OFFSET,
+                               sizeof(guint16),
+                               flags);
+
+       proto_tree_add_uint(lwres_tree,
+                               hf_serial,
+                               tvb,
+                               LW_SERIAL_OFFSET,
+                               sizeof(guint32),
+                               serial);
+
+       proto_tree_add_uint(lwres_tree,
+                               hf_opcode,
+                               tvb,
+                               LW_OPCODE_OFFSET,
+                               sizeof(guint32),
+                               opcode);
+
+       proto_tree_add_uint(lwres_tree,
+                               hf_result,
+                               tvb,
+                               LW_RESULT_OFFSET,
+                               sizeof(guint32),
+                               result);
+
+       proto_tree_add_uint(lwres_tree,
+                               hf_recvlen,
+                               tvb,
+                               LW_RECVLEN_OFFSET,
+                               sizeof(guint32),
+                               recvlength);
+
+       proto_tree_add_uint(lwres_tree,
+                               hf_authtype,
+                               tvb,
+                               LW_AUTHTYPE_OFFSET,
+                               sizeof(guint16),
+                               authtype);
+
+       proto_tree_add_uint(lwres_tree,
+                               hf_authlen,
+                               tvb,
+                               LW_AUTHLEN_OFFSET,
+                               sizeof(guint16),
+                               authlength);
+
+       if(!result)
+       {
+               switch(opcode)
+               {
+                       case LWRES_OPCODE_NOOP:
+                               dissect_noop(tvb, lwres_tree);
+                       break;
+
+                       case LWRES_OPCODE_GETADDRSBYNAME:
+                               dissect_getaddrsbyname(tvb, lwres_tree, message_type);
+                       break;
+
+                       case LWRES_OPCODE_GETNAMEBYADDR:
+                               dissect_getnamebyaddr(tvb, lwres_tree, message_type);
+                       break;
+
+                       case LWRES_OPCODE_GETRDATABYNAME:
+                               dissect_getrdatabyname(tvb, lwres_tree, message_type);
+                       break;
+               }
+       }
+
+}
+
+
+void
+proto_register_lwres(void)
+{
+  static hf_register_info hf[] = {
+    { &hf_length,
+      { "Length", "lwres.length", FT_UINT32, BASE_DEC, NULL, 0x0,
+        "lwres length", HFILL }},
+
+    { &hf_version,
+      { "Version", "lwres.version", FT_UINT16, BASE_DEC, NULL, 0x0,
+        "lwres legth", HFILL }},
+
+    { &hf_flags,
+      { "Packet Flags", "lwres.flags", FT_UINT16, BASE_HEX, NULL, 0x0,
+       "lwres flags", HFILL }},
+
+    { &hf_serial,
+      { "Serial", "lwres.serial", FT_UINT32, BASE_HEX, NULL, 0x0,
+        "lwres serial", HFILL }},
+
+    { &hf_opcode,
+      { "Operation code", "lwres.opcode", FT_UINT32, BASE_DEC, VALS(opcode_values), 0x0,
+        "lwres opcode", HFILL }},
+
+    { &hf_result,
+      { "Result", "lwres.result", FT_UINT32, BASE_DEC, VALS(result_values), 0x0,
+        "lwres result", HFILL }},
+
+    { &hf_recvlen, 
+      { "Received length", "lwres.recvlen", FT_UINT32, BASE_DEC, NULL, 0x0,
+        "lwres recvlen", HFILL }},
+
+    { &hf_authtype,
+      { "Auth. type", "lwres.authtype", FT_UINT16, BASE_DEC, NULL, 0x0,
+        "lwres authtype", HFILL }},
+
+    { &hf_authlen,
+      { "Auth. length", "lwres.authlen" , FT_UINT16, BASE_DEC, NULL, 0x0,
+        "lwres authlen", HFILL }},
+
+    { &hf_rflags, 
+      { "Flags", "lwres.rflags", FT_UINT32, BASE_HEX, NULL, 0x0,
+       "lwres rflags", HFILL }},
+    { &hf_rdclass,
+      { "Class", "lwres.class", FT_UINT16, BASE_DEC, NULL, 0x0,
+       "lwres class", HFILL }},
+
+    { &hf_rdtype,
+      { "Type", "lwres.type", FT_UINT16, BASE_DEC, VALS(t_types), 0x0,
+       "lwres type" , HFILL }},
+
+    { &hf_namelen,
+      { "Name length", "lwres.namelen", FT_UINT16, BASE_DEC, NULL, 0x0,
+       "lwres namelen", HFILL }},
+
+    { &hf_req_name,
+      { "Domain name" , "lwres.reqdname" , FT_STRING, BASE_DEC, NULL, 0x0,
+       "lwres reqdname", HFILL }},
+
+    { &hf_ttl,
+      { "Time To Live", "lwres.ttl", FT_UINT32, BASE_DEC, NULL, 0x0, 
+       "lwres ttl", HFILL }},
+
+    { &hf_nrdatas,
+      { "Number of rdata records", "lwres.nrdatas", FT_UINT16, BASE_DEC, NULL, 0x0,
+       "lwres nrdatas" , HFILL }},
+   
+    { &hf_nsigs,
+      { "Number of signature records", "lwres.nsigs", FT_UINT16, BASE_DEC, NULL, 0x0,
+       "lwres nsigs" , HFILL }},
+
+    { &hf_realnamelen,
+      { "Real name length", "lwres.realnamelen", FT_UINT16, BASE_DEC, NULL, 0x0,
+       "lwres realnamelen", HFILL }},
+
+    { &hf_realname,
+      { "Real doname name", "lwres.realname", FT_STRING, BASE_DEC, NULL, 0x0,
+       "lwres realname", HFILL }},
+
+       { &hf_a_record,
+       { "IPv4 Address", "lwres.arecord", FT_UINT32, BASE_DEC, NULL, 0x0,
+         "lwres arecord", HFILL }},
+
+       { &hf_a_rec_len,
+       { "Length", "lwres.areclen", FT_UINT16, BASE_DEC, NULL, 0x0,
+       "lwres areclen", HFILL }},
+
+       { &hf_srv_prio,
+       { "Priority", "lwres.srv.priority", FT_UINT16, BASE_DEC, NULL, 0x0,
+          "lwres srv prio", HFILL }},
+
+       { &hf_srv_weight,
+       { "Weight", "lwres.srv.weight", FT_UINT16, BASE_DEC, NULL, 0x0,
+       "lwres srv weight", HFILL }},
+
+       { &hf_srv_port,
+       { "Port" , "lwres.srv.port", FT_UINT16, BASE_DEC, NULL, 0x0,
+       "lwres srv port", HFILL }},
+
+       { &hf_adn_flags,
+       { "Flags", "lwres.adn.flags", FT_UINT32, BASE_HEX, NULL, 0x0,
+         "lwres adn flags", HFILL }},
+
+       { &hf_adn_addrtype,
+       { "Address type", "lwres.adn.addrtype", FT_UINT32, BASE_DEC, NULL, 0x0,
+         "lwres adn addrtype", HFILL }},
+
+       { &hf_adn_namelen,
+        { "Name length", "lwres.adn.namelen", FT_UINT16, BASE_DEC, NULL, 0x0,
+         "lwres adn namelen", HFILL }},
+
+       { &hf_adn_name,
+        { "Name", "lwres.adn.name", FT_STRING, BASE_DEC, NULL, 0x0,
+         "lwres adn name", HFILL }}, 
+
+        { &hf_adn_naliases,
+        { "Number of aliases", "lwres.adn.naliases", FT_UINT16, BASE_DEC, NULL, 0x0,
+         "lwres adn naliases", HFILL }}, 
+
+         { &hf_adn_naddrs,
+        { "Number of addresses", "lwres.adn.naddrs", FT_UINT16, BASE_DEC, NULL, 0x0,
+         "lwres adn naddrs", HFILL }}, 
+
+               { &hf_adn_realname,
+        { "Real name", "lwres.adn.realname", FT_STRING, BASE_DEC, NULL, 0x0,
+         "lwres adn realname", HFILL }}, 
+
+               { &hf_adn_aliasname,
+        { "Alias name", "lwres.adn.aliasname", FT_STRING, BASE_DEC, NULL, 0x0,
+         "lwres adn aliasname", HFILL }}, 
+
+       { &hf_adn_family,
+       { "Address family", "lwres.adn.addr.family", FT_UINT32, BASE_DEC, NULL, 0x0,
+       "lwres adn addr family", HFILL }},
+
+       { &hf_adn_addr_len,
+       { "Address length", "lwres.adn.addr.length", FT_UINT16, BASE_DEC, NULL, 0x0,
+       "lwres adn addr lenght", HFILL }},
+
+       { &hf_adn_addr_addr,
+    { "IP Address", "lwres.adn.addr.addr", FT_STRING, BASE_DEC, NULL, 0x0,
+         "lwres adn addr addr", HFILL }},
+
+    /* Add more fields here */
+  };
+
+  static gint *ett[] = {
+    &ett_lwres,
+    &ett_rdata_req,
+    &ett_rdata_resp,
+       &ett_a_rec,
+       &ett_a_rec_addr,
+       &ett_srv_rec,
+       &ett_srv_rec_item,
+       &ett_adn_request,
+       &ett_adn_resp,
+       &ett_adn_alias,
+       &ett_adn_addr,
+       &ett_nba_request,
+       &ett_nba_resp,
+       &ett_mx_rec,
+       &ett_mx_rec_item,
+       &ett_ns_rec,
+       &ett_ns_rec_item,
+       &ett_noop,
+  };
+
+
+  module_t *lwres_module;
+
+  proto_lwres = proto_register_protocol("Light Weight DNS RESolver (BIND9)",
+                                      "LWRES", "lwres");
+
+  proto_register_field_array(proto_lwres, hf, array_length(hf));
+  proto_register_subtree_array(ett, array_length(ett));
+
+  lwres_module = prefs_register_protocol(proto_lwres, proto_reg_handoff_lwres);
+
+  prefs_register_uint_preference(lwres_module, "udp.lwres_port",
+                                "lwres listener UDP Port",
+                                "Set the UDP port for lwres daemon"
+                                "(if other than the default of 921)",
+                                10, &global_lwres_port);
+
+}
+
+/* The registration hand-off routine */
+void
+proto_reg_handoff_lwres(void)
+{
+  static int lwres_prefs_initialized = FALSE;
+  static dissector_handle_t lwres_handle;
+
+  if(!lwres_prefs_initialized) {
+                lwres_handle = create_dissector_handle(dissect_lwres, proto_lwres);
+                lwres_prefs_initialized = TRUE;
+        }
+        else {
+                dissector_delete("udp.port",global_lwres_port, lwres_handle);
+
+        }
+
+        lwres_port = global_lwres_port;
+
+  dissector_add("udp.port", lwres_port, lwres_handle);
+
+}
+
+/* Start the functions we need for the plugin stuff */
+
+#ifndef __ETHEREAL_STATIC__
+
+G_MODULE_EXPORT void
+plugin_reg_handoff(void){
+  proto_reg_handoff_lwres();
+}
+
+G_MODULE_EXPORT void
+plugin_init(plugin_address_table_t *pat
+#ifndef PLUGINS_NEED_ADDRESS_TABLE
+_U_
+#endif
+){
+  /* initialise the table of pointers needed in Win32 DLLs */
+  plugin_address_table_init(pat);
+  /* register the new protocol, protocol fields, and subtrees */
+  if (proto_lwres == -1) { /* execute protocol initialization only once */
+    proto_register_lwres();
+  }
+}
+
+#endif
+
+/* End the functions we need for plugin stuff */