Index: asn1/ldap/Lightweight-Directory-Access-Protocol-V3.asn
===================================================================
--- asn1/ldap/Lightweight-Directory-Access-Protocol-V3.asn	(revision 18688)
+++ asn1/ldap/Lightweight-Directory-Access-Protocol-V3.asn	(working copy)
@@ -1,7 +1,7 @@
 -- Module Lightweight-Directory-Access-Protocol-V3 (RFC 2251:12/1997)
 Lightweight-Directory-Access-Protocol-V3
 --
--- $Id:$
+-- $Id$
 -- Copyright (C) The Internet Society (1997). This version of
 -- this ASN.1 module is part of RFC 2251;
 -- see the RFC itself for full legal notices.
@@ -113,7 +113,7 @@
 
 Referral ::= SEQUENCE OF LDAPURL
 
-LDAPURL ::= LDAPString -- limited to characters permitted in URLs
+LDAPURL ::= OCTET STRING -- LDAPString - - limited to characters permitted in URLs
 
 Controls ::= SEQUENCE OF Control
 
Index: asn1/ldap/ldap.cnf
===================================================================
--- asn1/ldap/ldap.cnf	(revision 18688)
+++ asn1/ldap/ldap.cnf	(working copy)
@@ -28,6 +28,9 @@
 Mechanism  TYPE = FT_STRING  DISPLAY = BASE_NONE  STRINGS = NULL
 AssertionValue TYPE = FT_STRING  DISPLAY = BASE_NONE  STRINGS = NULL
 
+#.FN_FTR LDAPURL
+	PROTO_ITEM_SET_URL(get_ber_last_created_item());
+
 #.FN_PARS LDAPOID VAL_PTR = &parameter_tvb
 #.FN_HDR LDAPOID
 
Index: asn1/logotype-cert-extn/logotype-cert-extn.cnf
===================================================================
--- asn1/logotype-cert-extn/logotype-cert-extn.cnf	(revision 18688)
+++ asn1/logotype-cert-extn/logotype-cert-extn.cnf	(working copy)
@@ -14,6 +14,12 @@
 LogotypeExtn B "1.3.6.1.5.5.7.20.1" "id-pe-logo-loyalty"
 LogotypeExtn B "1.3.6.1.5.5.7.20.2" "id-pe-logo-background"
 
+#.FN_FTR IA5String
+	if((hf_index == hf_logotypecertextn_logotypeURI_item) ||
+	   (hf_index == hf_logotypecertextn_refStructURI_item)) 
+	   PROTO_ITEM_SET_URL(get_ber_last_created_item());
+
+
 #.NO_EMIT
 
 #.TYPE_RENAME
Index: asn1/x509ce/packet-x509ce-template.c
===================================================================
--- asn1/x509ce/packet-x509ce-template.c	(revision 18688)
+++ asn1/x509ce/packet-x509ce-template.c	(working copy)
@@ -30,6 +30,7 @@
 #include <glib.h>
 #include <epan/packet.h>
 #include <epan/conversation.h>
+#include <epan/related.h>
 
 #include <stdio.h>
 #include <string.h>
@@ -116,5 +117,8 @@
 #include "packet-x509ce-dis-tab.c"
 	register_ber_oid_dissector("2.5.29.24", dissect_x509ce_invalidityDate_callback, proto_x509ce, "id-ce-invalidityDate");
 	register_ber_oid_dissector("2.5.29.51", dissect_x509ce_baseUpdateTime_callback, proto_x509ce, "id-ce-baseUpdateTime");
+
+	register_related_hfid_callback("GeneralName URL", hf_x509ce_uniformResourceIdentifier, related_url_cb);
+
 }
 
Index: asn1/x509ce/x509ce-exp.cnf
===================================================================
--- asn1/x509ce/x509ce-exp.cnf	(revision 18688)
+++ asn1/x509ce/x509ce-exp.cnf	(working copy)
@@ -1,6 +1,6 @@
 # Do not modify this file.
 # It is created automatically by the ASN.1 to Wireshark dissector compiler
-# .\x509ce-exp.cnf
+# ./x509ce-exp.cnf
 # ../../tools/asn2wrs.py -b -e -p x509ce -c x509ce.cnf -s packet-x509ce-template CertificateExtensions.asn
 
 #.MODULE
Index: gtk/menu.c
===================================================================
--- gtk/menu.c	(revision 18688)
+++ gtk/menu.c	(working copy)
@@ -531,6 +531,8 @@
                        0, WIRESHARK_STOCK_WIKI),
     ITEM_FACTORY_STOCK_ENTRY("/Filter Field Reference", NULL, selected_ptree_ref_cb,
                        0, WIRESHARK_STOCK_INTERNET),
+    ITEM_FACTORY_STOCK_ENTRY("/Related Information", NULL, selected_ptree_related_cb,
+                       0, WIRESHARK_STOCK_INTERNET),
     ITEM_FACTORY_ENTRY("/Protocol Preferences...", NULL, properties_cb,
                        0, NULL, NULL),
     ITEM_FACTORY_ENTRY("/<separator>", NULL, NULL, 0, "<Separator>", NULL),
@@ -2160,6 +2162,8 @@
 	  TRUE);
 	set_menu_sensitivity(tree_view_menu_factory, "/Filter Field Reference",
 	  TRUE);
+	set_menu_sensitivity(tree_view_menu_factory, "/Related Information",
+			     selected_ptree_has_related());
   } else {
 	set_menu_sensitivity(main_menu_factory,
 	    "/Go/Go to Corresponding Packet", FALSE);
@@ -2177,6 +2181,8 @@
 	  FALSE);
 	set_menu_sensitivity(tree_view_menu_factory, "/Filter Field Reference",
 	  FALSE);
+	set_menu_sensitivity(tree_view_menu_factory, "/Related Information",
+	  FALSE);
   }
 
   walk_menu_tree_for_selected_tree_row(tap_menu_tree_root, cf->finfo_selected);
Index: gtk/main.c
==3D================================================================
--- gtk/main.c	(revision 18688)
+++ gtk/main.c	(working copy)
@@ -65,6 +65,7 @@
 #include <epan/emem.h>
 #include <epan/ex-opt.h>
 #include <epan/funnel.h>
+#include <epan/related.h>
 
 /* general (not GTK specific) */
 #include "file.h"
@@ -90,6 +91,7 @@
 #include "version_info.h"
 #include "merge.h"
 
+
 #ifdef HAVE_LIBPCAP
 #include "capture-pcap-util.h"
 #include "capture.h"
@@ -382,6 +384,27 @@
     }
 }
 
+void
+selected_ptree_related_cb(GtkWidget *widget _U_, gpointer data _U_)
+{
+
+  gchar *ret_url = NULL;
+
+  if(do_related(cfile.finfo_selected, &ret_url) && *ret_url) {
+    browser_open_url(ret_url);
+    g_free(ret_url);
+  }
+
+
+}
+
+gboolean selected_ptree_has_related()
+{
+
+  return have_related(cfile.finfo_selected);
+
+}
+
 static gchar *
 get_text_from_packet_list(gpointer data)
 {
Index: gtk/main.h
===================================================================
--- gtk/main.h	(revision 18688)
+++ gtk/main.h	(working copy)
@@ -105,6 +105,18 @@
  */
 extern void selected_ptree_ref_cb(GtkWidget *widget, gpointer data);
 
+/** User requested "Related Information" by ptree context menu.
+ *
+ * @param widget parent widget (unused)
+ * @param data unused
+ */
+extern void selected_ptree_related_cb(GtkWidget *widget, gpointer data);
+
+/** Determine if "Related Information" should be enabled in ptree context menu.
+ *
+ */
+extern gboolean selected_ptree_has_related();
+
 /** "Apply as Filter" / "Prepare a Filter" action type. */
 typedef enum {
     MATCH_SELECTED_REPLACE, /**< "Selected" */
Index: epan/related.c
===================================================================
--- epan/related.c	(revision 0)
+++ epan/related.c	(revision 0)
@@ -0,0 +1,177 @@
+/* related.c
+ * related field information   2006 Graeme Lunt
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#include <string.h>
+#include "epan/packet_info.h"
+#include <epan/related.h>
+
+typedef struct _related_callback_t {
+  struct _related_callback_t *next;
+  gchar *name;
+  int  hf_lb;
+  int hf_ub;
+  enum ftenum type;
+  related_cb related;
+} related_t;
+
+
+static related_t *related_list=NULL;
+
+static gboolean check_related(field_info *finfo, gboolean doit, const gchar **ret_url);
+
+static gboolean related_url_string_cb(field_info *finfo, gboolean doit, const gchar**  ret_url)
+{
+
+  if(finfo && IS_FT_STRING(finfo->hfinfo->type) && FI_GET_FLAG(finfo, FI_URL)) {
+    
+    if(doit && ret_url) {
+      /* the URL will be freed */
+      *ret_url = g_strndup(tvb_get_ptr(finfo->ds_tvb, finfo->start, finfo->length), finfo->length);
+
+      return TRUE;
+    } else {
+	return TRUE;
+    }
+  }
+
+  return FALSE;
+
+}
+
+void related_init()
+{
+
+  /* register a callback for strings that have been marked as URLs with
+     PROTO_ITEM_SET_URL */
+
+  register_related_type_callback("View URL", FT_STRING, related_url_string_cb);
+
+}
+
+int register_related_callback(const char *name, int hf_lb, int hf_ub, enum ftenum type, related_cb related)
+{
+  related_t *r, *rl;
+  int i;
+
+  /* sanity check */
+  if(!related)
+    return 0;
+
+  r = g_malloc(sizeof(related_t));
+  r->next = NULL;
+  
+  r->name = g_strdup(name);
+  r->hf_lb = hf_lb;
+  r->hf_ub = hf_ub;
+  r->type = type;
+  r->related = related;
+
+  if(!related_list){
+    related_list=r;
+    i=1;
+  } else {
+    for(i=2,rl=related_list; rl->next; i++,rl=rl->next)
+      ;
+    rl->next=r;
+  }
+  
+  return i;
+
+}
+
+gboolean have_related(field_info *finfo)
+{
+
+  return check_related(finfo, FALSE, NULL);
+
+}
+
+gboolean do_related(field_info *finfo, const gchar **ret_url)
+{
+
+  return check_related(finfo, TRUE, ret_url);
+
+}
+
+static gboolean check_related(field_info *finfo, gboolean doit, const gchar **ret_url)
+{
+  related_t *r;
+  int pass;
+  
+  for(pass = 1; pass < 3; pass++) {
+    for(r = related_list; r; r = r->next) {
+    
+      if(/* first pass does specific ranges and hfid fields */ 
+	 ((pass == 1) && (r->hf_ub != G_MAXINT)) || 
+	 /* second pass does generic type field */
+	 ((pass == 2) && (r->hf_ub == G_MAXINT))) {
+    
+	if(((finfo->hfinfo->id >= r->hf_lb) && (finfo->hfinfo->id <= r->hf_ub)) &&
+	   ((finfo->hfinfo->type == r->type) || (r->type == FT_NONE))) {
+
+	  if(r->related(finfo, doit, ret_url))
+	    /* we have found some related information */
+	    return TRUE;
+	}
+      }
+    }
+  }
+  
+  return FALSE;
+
+}
+
+/* a common utility function for fields that are URLs */
+
+gboolean related_url_cb(field_info *finfo, gboolean doit, const gchar**  ret_url)
+{
+  
+  if(finfo && IS_FT_STRING(finfo->hfinfo->type)) {
+
+    if(doit && ret_url) {
+      /* the URL will be freed */
+      *ret_url = g_strndup(tvb_get_ptr(finfo->ds_tvb, finfo->start, finfo->length), finfo->length);
+
+      return TRUE;
+    } else {
+	return TRUE;
+    }
+  }
+
+  return FALSE;
+
+}
+
+
+

Property changes on: epan/related.c
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Index: epan/related.h
===================================================================
--- epan/related.h	(revision 0)
+++ epan/related.h	(revision 0)
@@ -0,0 +1,57 @@
+/* related.h
+ * related field information   2006  Graeme Lunt
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef _RELATED_H_
+#define _RELATED_H_
+
+#include <epan/proto.h>
+
+/* The callback function indicates if it can provide related information for
+   the given field by its return value. As much info is likely to be a URL
+   the callback can return a url which will be opened by the caller
+*/
+
+typedef gboolean (*related_cb)(field_info *finfo, gboolean doit, const gchar**  ret_url);
+
+void related_init();
+
+/* Register a related function for a given range of fields, or a specific 
+   field type */
+int register_related_callback(const char *name, int hf_lb, int hf_ub, enum ftenum type, related_cb related);
+
+#define register_related_range_callback(n, lb, ub, cb) register_related_callback(n, lb, ub, FT_NONE, cb)
+#define register_related_type_callback(n, t, cb) register_related_callback(n, 0, G_MAXINT, t, cb)
+#define register_related_hfid_callback(n, h, cb) register_related_callback(n, h, h, FT_NONE, cb)
+
+
+/* Determine if there is related information for this field */
+gboolean have_related(field_info *finfo);
+
+/* Show the related information for this field */
+gboolean do_related(field_info *finfo, const gchar **ret_url);
+
+/* A common function for fields that are URIs */
+gboolean related_url_cb(field_info *finfo, gboolean doit, const gchar**  ret_url);
+
+#endif

Property changes on: epan/related.h
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Index: epan/Makefile.common
==========================================D========================
--- epan/Makefile.common	(revision 18688)
+++ epan/Makefile.common	(working copy)
@@ -71,6 +71,7 @@
 	radius_dict.c		\
 	range.c			\
 	reassemble.c		\
+	related.c 		\
 	req_resp_hdrs.c		\
 	sha1.c			\
 	sigcomp_state_hdlr.c	\
@@ -163,6 +164,7 @@
 	ptvcursor.h		\
 	range.h			\
 	reassemble.h		\
+	related.h 		\
 	report_err.h		\
 	req_resp_hdrs.h		\
 	rtp_pt.h		\
Index: epan/proto.h
===================================================================
--- epan/proto.h	(revision 18688)
+++ epan/proto.h	(working copy)
@@ -212,6 +212,8 @@
  * used in field_info.flags. */
 #define FI_GENERATED		0x0002
 
+/* The protocol field is actually a URL */
+#define FI_URL                  0x0004
 
 /** convenience macro to get field_info.flags */
 #define FI_GET_FLAG(fi, flag) (fi->flags & flag)
@@ -289,6 +291,12 @@
 /** mark this protocol field as generated by Wireshark (and not read from the packet data) */
 #define PROTO_ITEM_SET_GENERATED(proto_item)	\
 	((proto_item) ? FI_SET_FLAG((proto_item)->finfo, FI_GENERATED) : 0)
+/* is this protocol field actually a URL */
+#define PROTO_ITEM_IS_URL(proto_item)	\
+	((proto_item) ? FI_GET_FLAG((proto_item)->finfo, FI_URL) : 0)
+/* mark this protocol field as a URL */
+#define PROTO_ITEM_SET_URL(proto_item)	\
+	((proto_item) ? FI_SET_FLAG((proto_item)->finfo, FI_URL) : 0)
 
 typedef void (*proto_tree_foreach_func)(proto_node *, gpointer);
 
Index: epan/dissectors/packet-ldap.c
===================================================================
--- epan/dissectors/packet-ldap.c	(revision 18688)
+++ epan/dissectors/packet-ldap.c	(working copy)
@@ -642,7 +642,7 @@
 
 static int
 dissect_ldap_MessageID(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
-#line 53 "ldap.cnf"
+#line 56 "ldap.cnf"
 
     offset = dissect_ber_integer(implicit_tag, pinfo, tree, tvb, offset, hf_index,
                                   &MessageID);
@@ -675,7 +675,7 @@
 
 static int
 dissect_ldap_LDAPString(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
-#line 240 "ldap.cnf"
+#line 243 "ldap.cnf"
   tvbuff_t	*parameter_tvb = NULL;
   char          *ldapstring;
   gchar		*sc = NULL; /* semi-colon pointer */
@@ -799,7 +799,7 @@
 
 static int
 dissect_ldap_Simple(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
-#line 103 "ldap.cnf"
+#line 106 "ldap.cnf"
 ldap_conv_info_t *ldap_info;
 
   offset = dissect_ber_octet_string(implicit_tag, pinfo, tree, tvb, offset, hf_index,
@@ -823,7 +823,7 @@
 
 static int
 dissect_ldap_Mechanism(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
-#line 114 "ldap.cnf"
+#line 117 "ldap.cnf"
 
 ldap_conv_info_t *ldap_info;
 tvbuff_t	*parameter_tvb;
@@ -875,7 +875,7 @@
 
 static int
 dissect_ldap_Credentials(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
-#line 153 "ldap.cnf"
+#line 156 "ldap.cnf"
 
 tvbuff_t	*parameter_tvb;
 ldap_conv_info_t *ldap_info;
@@ -943,7 +943,7 @@
 
 static int
 dissect_ldap_AuthenticationChoice(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
-#line 415 "ldap.cnf"
+#line 418 "ldap.cnf"
   gint branch = -1;
   gint auth = -1;
   const gchar *valstr;
@@ -1041,7 +1041,7 @@
 
 static int
 dissect_ldap_BindResponse_resultCode(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
-#line 357 "ldap.cnf"
+#line 360 "ldap.cnf"
 
   const gchar *valstr;
 
@@ -1088,8 +1088,13 @@
 
 static int
 dissect_ldap_LDAPURL(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
-  offset = dissect_ldap_LDAPString(implicit_tag, tvb, offset, pinfo, tree, hf_index);
+  offset = dissect_ber_octet_string(implicit_tag, pinfo, tree, tvb, offset, hf_index,
+                                       NULL);
 
+#line 32 "ldap.cnf"
+	PROTO_ITEM_SET_URL(get_ber_last_created_item());
+
+
   return offset;
 }
 static int dissect_Referral_item(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
@@ -1119,7 +1124,7 @@
 
 static int
 dissect_ldap_ServerSaslCreds(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
-#line 179 "ldap.cnf"
+#line 182 "ldap.cnf"
 
 tvbuff_t	*parameter_tvb;
 ldap_conv_info_t *ldap_info;
@@ -1213,7 +1218,7 @@
 
 static int
 dissect_ldap_UnbindRequest(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
-#line 436 "ldap.cnf"
+#line 439 "ldap.cnf"
 
  implicit_tag = TRUE; /* correct problem with asn2wrs */
 
@@ -1245,7 +1250,7 @@
 
 static int
 dissect_ldap_T_scope(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
-#line 316 "ldap.cnf"
+#line 319 "ldap.cnf"
 
   gint 	scope;
   const gchar *valstr;
@@ -1313,7 +1318,7 @@
 
 static int
 dissect_ldap_BOOLEAN(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
-#line 529 "ldap.cnf"
+#line 532 "ldap.cnf"
 	gboolean val;
 
 	offset = dissect_ber_boolean_value(implicit_tag, pinfo, tree, tvb, offset, hf_index, &val);
@@ -1345,7 +1350,7 @@
 dissect_ldap_T_and_item(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
   offset = dissect_ldap_Filter(implicit_tag, tvb, offset, pinfo, tree, hf_index);
 
-#line 470 "ldap.cnf"
+#line 473 "ldap.cnf"
 	if(and_filter_string){
 		and_filter_string=ep_strdup_printf("(&%s%s)",and_filter_string,Filter_string);
 	} else {
@@ -1366,7 +1371,7 @@
 
 static int
 dissect_ldap_T_and(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
-#line 477 "ldap.cnf"
+#line 480 "ldap.cnf"
 	const ber_sequence_t and_set_of[1] = {  { BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_and_item },
 };
 	proto_tree *tr=NULL;
@@ -1399,7 +1404,7 @@
 dissect_ldap_T_or_item(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
   offset = dissect_ldap_Filter(implicit_tag, tvb, offset, pinfo, tree, hf_index);
 
-#line 496 "ldap.cnf"
+#line 499 "ldap.cnf"
 	if(or_filter_string){
 		or_filter_string=ep_strdup_printf("(|%s%s)",or_filter_string,Filter_string);
 	} else {
@@ -1421,7 +1426,7 @@
 
 static int
 dissect_ldap_T_or(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
-#line 504 "ldap.cnf"
+#line 507 "ldap.cnf"
 	const ber_sequence_t or_set_of[1] = {  { BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_or_item },
 };
 	proto_tree *tr=NULL;
@@ -1454,7 +1459,7 @@
 dissect_ldap_T_not(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
   offset = dissect_ldap_Filter(implicit_tag, tvb, offset, pinfo, tree, hf_index);
 
-#line 526 "ldap.cnf"
+#line 529 "ldap.cnf"
 	Filter_string=ep_strdup_printf("(!%s)",Filter_string);
 
 
@@ -1516,7 +1521,7 @@
 dissect_ldap_T_equalityMatch(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
   offset = dissect_ldap_AttributeValueAssertion(implicit_tag, tvb, offset, pinfo, tree, hf_index);
 
-#line 455 "ldap.cnf"
+#line 458 "ldap.cnf"
 	Filter_string=ep_strdup_printf("(%s=%s)",attributedesc_string,assertionvalue_string);
 
 
@@ -1548,7 +1553,7 @@
                                  T_substringFilter_substrings_item_choice, hf_index, ett_ldap_T_substringFilter_substrings_item,
                                  NULL);
 
-#line 552 "ldap.cnf"
+#line 555 "ldap.cnf"
 	if (substring_item_final) {
 		substring_value=ep_strdup_printf("%s%s",
 						 (substring_value?substring_value:"*"),
@@ -1594,7 +1599,7 @@
 
 static int
 dissect_ldap_SubstringFilter(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
-#line 566 "ldap.cnf"
+#line 569 "ldap.cnf"
 	proto_tree *tr=NULL;
 	proto_item *it=NULL;
 	char *old_substring_value=substring_value;
@@ -1629,7 +1634,7 @@
 dissect_ldap_T_greaterOrEqual(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
   offset = dissect_ldap_AttributeValueAssertion(implicit_tag, tvb, offset, pinfo, tree, hf_index);
 
-#line 459 "ldap.cnf"
+#line 462 "ldap.cnf"
 	Filter_string=ep_strdup_printf("(%s>=%s)",attributedesc_string,assertionvalue_string);
 
 
@@ -1646,7 +1651,7 @@
 dissect_ldap_T_lessOrEqual(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
   offset = dissect_ldap_AttributeValueAssertion(implicit_tag, tvb, offset, pinfo, tree, hf_index);
 
-#line 463 "ldap.cnf"
+#line 466 "ldap.cnf"
 	Filter_string=ep_strdup_printf("(%s<=%s)",attributedesc_string,assertionvalue_string);
 
 
@@ -1663,7 +1668,7 @@
 dissect_ldap_T_present(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
   offset = dissect_ldap_AttributeDescription(implicit_tag, tvb, offset, pinfo, tree, hf_index);
 
-#line 523 "ldap.cnf"
+#line 526 "ldap.cnf"
 	Filter_string=ep_strdup_printf("(%s=*)",Filter_string);
 
 
@@ -1679,7 +1684,7 @@
 dissect_ldap_T_approxMatch(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
   offset = dissect_ldap_AttributeValueAssertion(implicit_tag, tvb, offset, pinfo, tree, hf_index);
 
-#line 467 "ldap.cnf"
+#line 470 "ldap.cnf"
 	Filter_string=ep_strdup_printf("(%s~=%s)",attributedesc_string,assertionvalue_string);
 
 
@@ -1722,7 +1727,7 @@
 
 static int
 dissect_ldap_T_extensibleMatch(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
-#line 538 "ldap.cnf"
+#line 541 "ldap.cnf"
 	attr_type=NULL;
 	matching_rule_string=NULL;
 	assertionvalue_string=NULL;
@@ -1731,7 +1736,7 @@
 
   offset = dissect_ldap_MatchingRuleAssertion(implicit_tag, tvb, offset, pinfo, tree, hf_index);
 
-#line 544 "ldap.cnf"
+#line 547 "ldap.cnf"
 	Filter_string=ep_strdup_printf("(%s:%s%s%s=%s)",
 					(attr_type?attr_type:""),
 					(matching_rule_dnattr?"dn:":""),
@@ -1777,7 +1782,7 @@
 
 static int
 dissect_ldap_Filter(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
-#line 587 "ldap.cnf"
+#line 590 "ldap.cnf"
 	proto_tree *tr=NULL;
 	proto_item *it=NULL;
 
@@ -1800,13 +1805,13 @@
 
 static int
 dissect_ldap_T_filter(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
-#line 448 "ldap.cnf"
+#line 451 "ldap.cnf"
 	Filter_string=NULL;
 
 
   offset = dissect_ldap_Filter(implicit_tag, tvb, offset, pinfo, tree, hf_index);
 
-#line 451 "ldap.cnf"
+#line 454 "ldap.cnf"
 	Filter_string=NULL;
 	and_filter_string=NULL;
 
@@ -1861,7 +1866,7 @@
 
 static int
 dissect_ldap_AttributeValue(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
-#line 378 "ldap.cnf"
+#line 381 "ldap.cnf"
 
   tvbuff_t	*next_tvb;
   gchar		*string;
@@ -2021,7 +2026,7 @@
 
 static int
 dissect_ldap_T_resultCode(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
-#line 335 "ldap.cnf"
+#line 338 "ldap.cnf"
 
   const gchar *valstr;
 
@@ -2376,7 +2381,7 @@
 
 static int
 dissect_ldap_LDAPOID(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
-#line 33 "ldap.cnf"
+#line 36 "ldap.cnf"
 
 	tvbuff_t	*parameter_tvb;
 	const gchar *name;
@@ -2387,7 +2392,7 @@
   offset = dissect_ber_octet_string(implicit_tag, pinfo, tree, tvb, offset, hf_index,
                                        &parameter_tvb);
 
-#line 40 "ldap.cnf"
+#line 43 "ldap.cnf"
 	if (!parameter_tvb)
 		return offset;
 	item = get_ber_last_created_item();
@@ -2583,7 +2588,7 @@
 
 static int
 dissect_ldap_ProtocolOp(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
-#line 61 "ldap.cnf"
+#line 64 "ldap.cnf"
 
   ldap_call_response_t *lcrp;
   ldap_conv_info_t *ldap_info = (ldap_conv_info_t *)pinfo->private_data;
@@ -2594,7 +2599,7 @@
                                  ProtocolOp_choice, hf_index, ett_ldap_ProtocolOp,
                                  &ProtocolOp);
 
-#line 67 "ldap.cnf"
+#line 70 "ldap.cnf"
 
   lcrp=ldap_match_call_response(tvb, pinfo, tree, MessageID, ProtocolOp);
   if(lcrp){
Index: epan/dissectors/packet-x509ce.c
===================================================================
--- epan/dissectors/packet-x509ce.c	(revision 18688)
+++ epan/dissectors/packet-x509ce.c	(working copy)
@@ -1,6 +1,6 @@
 /* Do not modify this file.                                                   */
 /* It is created automatically by the ASN.1 to Wireshark dissector compiler   */
-/* .\packet-x509ce.c                                                          */
+/* ./packet-x509ce.c                                                          */
 /* ../../tools/asn2wrs.py -b -e -p x509ce -c x509ce.cnf -s packet-x509ce-template CertificateExtensions.asn */
 
 /* Input file: packet-x509ce-template.c */
@@ -38,6 +38,7 @@
 #include <glib.h>
 #include <epan/packet.h>
 #include <epan/conversation.h>
+#include <epan/related.h>
 
 #include <stdio.h>
 #include <string.h>
@@ -213,7 +214,7 @@
 static int hf_x509ce_ReasonFlags_aACompromise = -1;
 
 /*--- End of included file: packet-x509ce-hf.c ---*/
-#line 55 "packet-x509ce-template.c"
+#line 56 "packet-x509ce-template.c"
 
 /* Initialize the subtree pointers */
 
@@ -265,7 +266,7 @@
 static gint ett_x509ce_PkiPathMatchSyntax = -1;
 
 /*--- End of included file: packet-x509ce-ett.c ---*/
-#line 58 "packet-x509ce-template.c"
+#line 59 "packet-x509ce-template.c"
 
 static const char *object_identifier_id;
 
@@ -1657,7 +1658,7 @@
 
 
 /*--- End of included file: packet-x509ce-fn.c ---*/
-#line 62 "packet-x509ce-template.c"
+#line 63 "packet-x509ce-template.c"
 
 
 static void
@@ -2289,7 +2290,7 @@
         "", HFILL }},
 
 /*--- End of included file: packet-x509ce-hfarr.c ---*/
-#line 97 "packet-x509ce-template.c"
+#line 98 "packet-x509ce-template.c"
   };
 
   /* List of subtrees */
@@ -2343,7 +2344,7 @@
     &ett_x509ce_PkiPathMatchSyntax,
 
 /*--- End of included file: packet-x509ce-ettarr.c ---*/
-#line 102 "packet-x509ce-template.c"
+#line 103 "packet-x509ce-template.c"
   };
 
   /* Register protocol */
@@ -2391,8 +2392,11 @@
 
 
 /*--- End of included file: packet-x509ce-dis-tab.c ---*/
-#line 117 "packet-x509ce-template.c"
+#line 118 "packet-x509ce-template.c"
 	register_ber_oid_dissector("2.5.29.24", dissect_x509ce_invalidityDate_callback, proto_x509ce, "id-ce-invalidityDate");
 	register_ber_oid_dissector("2.5.29.51", dissect_x509ce_baseUpdateTime_callback, proto_x509ce, "id-ce-baseUpdateTime");
+
+	register_related_hfid_callback("GeneralName URL", hf_x509ce_uniformResourceIdentifier, related_url_cb);
+
 }
 
Index: epan/dissectors/packet-logotypecertextn.c
===================================================================
--- epan/dissectors/packet-logotypecertextn.c	(revision 18688)
+++ epan/dissectors/packet-logotypecertextn.c	(working copy)
@@ -1,6 +1,6 @@
 /* Do not modify this file.                                                   */
 /* It is created automatically by the ASN.1 to Wireshark dissector compiler   */
-/* .\packet-logotypecertextn.c                                                */
+/* ./packet-logotypecertextn.c                                                */
 /* ../../tools/asn2wrs.py -b -e -p logotypecertextn -c logotype-cert-extn.cnf -s packet-logotype-cert-extn-template LogotypeCertExtn.asn */
 
 /* Input file: packet-logotype-cert-extn-template.c */
@@ -144,6 +144,13 @@
                                             pinfo, tree, tvb, offset, hf_index,
                                             NULL);
 
+#line 18 "logotype-cert-extn.cnf"
+	if((hf_index == hf_logotypecertextn_logotypeURI_item) ||
+	   (hf_index == hf_logotypecertextn_refStructURI_item)) 
+	   PROTO_ITEM_SET_URL(get_ber_last_created_item());
+
+
+
   return offset;
 }
 static int dissect_mediaType(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
@@ -311,8 +318,8 @@
 };
 
 static const ber_choice_t LogotypeImageResolution_choice[] = {
-  {   1, BER_CLASS_CON, 1, 0, dissect_numBits_impl },
-  {   2, BER_CLASS_CON, 2, 0, dissect_tableSize_impl },
+  {   1, BER_CLASS_CON, 1, BER_FLAGS_IMPLTAG, dissect_numBits_impl },
+  {   2, BER_CLASS_CON, 2, BER_FLAGS_IMPLTAG, dissect_tableSize_impl },
   { 0, 0, 0, 0, NULL }
 };
 
@@ -499,8 +506,8 @@
 };
 
 static const ber_choice_t LogotypeInfo_choice[] = {
-  {   0, BER_CLASS_CON, 0, 0, dissect_direct_impl },
-  {   1, BER_CLASS_CON, 1, 0, dissect_indirect_impl },
+  {   0, BER_CLASS_CON, 0, BER_FLAGS_IMPLTAG, dissect_direct_impl },
+  {   1, BER_CLASS_CON, 1, BER_FLAGS_IMPLTAG, dissect_indirect_impl },
   { 0, 0, 0, 0, NULL }
 };
 
Index: epan/dissectors/packet-x509ce.h
===================================================================
--- epan/dissectors/packet-x509ce.h	(revision 18688)
+++ epan/dissectors/packet-x509ce.h	(working copy)
@@ -1,6 +1,6 @@
 /* Do not modify this file.                                                   */
 /* It is created automatically by the ASN.1 to Wireshark dissector compiler   */
-/* .\packet-x509ce.h                                                          */
+/* ./packet-x509ce.h                                                          */
 /* ../../tools/asn2wrs.py -b -e -p x509ce -c x509ce.cnf -s packet-x509ce-template CertificateExtensions.asn */
 
 /* Input file: packet-x509ce-template.h */
Index: epan/dissectors/packet-logotypecertextn.h
===================================================================
--- epan/dissectors/packet-logotypecertextn.h	(revision 18688)
+++ epan/dissectors/packet-logotypecertextn.h	(working copy)
@@ -1,6 +1,6 @@
 /* Do not modify this file.                                                   */
 /* It is created automatically by the ASN.1 to Wireshark dissector compiler   */
-/* .\packet-logotypecertextn.h                                                */
+/* ./packet-logotypecertextn.h                                                */
 /* ../../tools/asn2wrs.py -b -e -p logotypecertextn -c logotype-cert-extn.cnf -s packet-logotype-cert-extn-template LogotypeCertExtn.asn */
 
 /* Input file: packet-logotype-cert-extn-template.h */
Index: epan/oid_resolv.c
===================================================================
--- epan/oid_resolv.c	(revision 18688)
+++ epan/oid_resolv.c	(working copy)
@@ -32,11 +32,44 @@
 #include "to_str.h"
 #include "strutil.h"
 #include "epan/dissectors/format-oid.h"
+#include "related.h"
 
 static GHashTable *oid_table = NULL;
 
+/* this should be configurable - but where ? */
+static const gchar *oid_url_template = "http://www.alvestrand.no/objectid/%s.html";
+
+static gboolean oid_related_cb(field_info *finfo, gboolean doit, const gchar **ret_url)
+{
+  const char *oid;
+  
+  if(finfo && (finfo->hfinfo->type == FT_OID) && 
+     (oid_url_template != NULL) && (*oid_url_template != '\0')) {
+    if(doit && ret_url) {
+      /* return the URL */
+      oid = oid_to_str(tvb_get_ptr(finfo->ds_tvb, finfo->start, finfo->length),
+		       finfo->length);
+
+      /* the URL will be freed */
+      *ret_url = g_strdup_printf(oid_url_template, oid);
+      return TRUE;
+    } else {
+      /* return TRUE if we are configured to return URLs */
+
+      if((oid_url_template != NULL) && (*oid_url_template != '\0')) 
+	return TRUE;
+      
+    }
+  }
+
+  return FALSE;
+}
+
 void oid_resolv_init(void) {
   oid_table = g_hash_table_new(g_str_hash, g_str_equal);
+  
+  register_related_type_callback("OID Ref", FT_OID, oid_related_cb);
+
 }
 
 static void free_oid_str(gpointer key, gpointer value _U_,
Index: epan/epan.c
===================================================================
--- epan/epan.c	(revision 18688)
+++ epan/epan.c	(working copy)
@@ -24,6 +24,7 @@
 #include "oid_resolv.h"
 #include "emem.h"
 #include "expert.h"
+#include "related.h"
 
 static void (*report_failure_func)(const char *, va_list);
 static void (*report_open_failure_func)(const char *, int, gboolean);
@@ -75,6 +76,7 @@
 	final_registration_all_protocols();
 	host_name_lookup_init();
 	expert_init();
+	related_init();
 }
 
 void

