From Jared Renzullo:
[obnox/wireshark/wip.git] / epan / dissectors / packet-cops.c
index 29486cfad99790abf4200d73d30c7338ad185de8..3ea72137886d21de70818f4e7548636cecc370ad 100644 (file)
@@ -1,6 +1,9 @@
 /* packet-cops.c
  * Routines for the COPS (Common Open Policy Service) protocol dissection
- * RFC2748 & COPS-PR extension RFC3084
+ *
+ * RFC 2748 The COPS (Common Open Policy Service) Protocol
+ * RFC 3084 COPS Usage for Policy Provisioning (COPS-PR)
+ * RFC 3159 Structure of Policy Provisioning Information (SPPI)
  *
  * Copyright 2000, Heikki Vatiainen <hessu@cs.tut.fi>
  *
@@ -11,7 +14,7 @@
  *    Based on PKT-SP-DQOS-I09-040402 (April 2, 2004)
  *
  *    PacketCable Multimedia Specification
- *    Based on PKT-SP-MM-I02-040930
+ *    Based on PKT-SP-MM-I04-080522
  *
  *    www.packetcable.com
  *
 #include "packet-ipv6.h"
 #include "packet-tcp.h"
 
-#ifdef HAVE_NET_SNMP
-# include <net-snmp/net-snmp-config.h>
-# include <net-snmp/mib_api.h>
-# include <net-snmp/library/default_store.h>
-# include <net-snmp/config_api.h>
-#endif /* HAVE_NET_SNMP */
-
-#include <epan/dissectors/format-oid.h>
+#include <epan/oids.h>
 #include <epan/prefs.h>
+#include <epan/expert.h>
+#include <epan/asn1.h>
 #include "packet-ber.h"
 
 /* XXX - The "plain" COPS port (3288) can be overridden in the prefs.
@@ -90,22 +88,6 @@ static guint global_cops_tcp_port = TCP_PORT_COPS;
 /* Preference: desegmentation of COPS */
 static gboolean cops_desegment = TRUE;
 
-/* Variable to allow for proper deletion of dissector registration
- * when the user changes port from the gui
- */
-
-static guint cops_tcp_port = 0;
-
-#ifdef HAVE_NET_SNMP
-static  subid_t last_decoded_prid_oid[MAX_OID_LEN]={0};
-static  subid_t last_decoded_prid_oid_length=0;
-extern struct tree *tree_head;
-
-/* Preference: COPS-PR ASN.1 type decoding based on PIB/MIB or data in packet */
-static gboolean cops_typefrommib = FALSE;
-
-#endif /* HAVE_NET_SNMP */
-
 #define COPS_OBJECT_HDR_SIZE 4
 
 /* Null string of type "guchar[]". */
@@ -113,72 +95,6 @@ static const guchar nullstring[] = "";
 
 #define        SAFE_STRING(s)  (((s) != NULL) ? (s) : nullstring)
 
-/* COPS PR Tags */
-
-#define COPS_IPA    0          /* IP Address */
-#define COPS_U32    2          /* Unsigned 32*/
-#define COPS_TIT    3          /* TimeTicks */
-#define COPS_OPQ    4          /* Opaque */
-#define COPS_I64    10         /* Integer64 */
-#define COPS_U64    11         /* Uinteger64 */
-
-/* COPS PR Types */
-
-#define COPS_NULL                0
-#define COPS_INTEGER             1    /* l  */
-#define COPS_OCTETSTR            2    /* c  */
-#define COPS_OBJECTID            3    /* ul */
-#define COPS_IPADDR              4    /* uc */
-#define COPS_UNSIGNED32          5    /* ul */
-#define COPS_TIMETICKS           7    /* ul */
-#define COPS_OPAQUE              8    /* c  */
-#define COPS_INTEGER64           10   /* ll */
-#define COPS_UNSIGNED64          11   /* ull  */
-
-
-typedef struct _COPS_CNV COPS_CNV;
-
-struct _COPS_CNV
-{
-  guint class;
-  guint tag;
-  gint  syntax;
-  const gchar *name;
-};
-
-static COPS_CNV CopsCnv [] =
-{
-  {BER_CLASS_UNI, BER_UNI_TAG_NULL,                    COPS_NULL,      "NULL"},
-  {BER_CLASS_UNI, BER_UNI_TAG_INTEGER,         COPS_INTEGER,   "INTEGER"},
-  {BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING,     COPS_OCTETSTR,  "OCTET STRING"},
-  {BER_CLASS_UNI, BER_UNI_TAG_OID,                     COPS_OBJECTID,  "OBJECTID"},
-  {BER_CLASS_APP, COPS_IPA,                                    COPS_IPADDR,    "IPADDR"},
-  {BER_CLASS_APP, COPS_U32,                                    COPS_UNSIGNED32,"UNSIGNED32"},
-  {BER_CLASS_APP, COPS_TIT,                                    COPS_TIMETICKS, "TIMETICKS"},
-  {BER_CLASS_APP, COPS_OPQ,                                    COPS_OPAQUE,    "OPAQUE"},
-  {BER_CLASS_APP, COPS_I64,                                    COPS_INTEGER64, "INTEGER64"},
-  {BER_CLASS_APP, COPS_U64,                                    COPS_UNSIGNED64, "UNSIGNED64"},
-  {0,       0,         -1,                  NULL}
-};
-
-static const gchar *
-cops_tag_cls2syntax ( guint tag, guint cls, gushort *syntax)
-{
-  COPS_CNV *cnv;
-
-  cnv = CopsCnv;
-  while (cnv->syntax != -1)
-  {
-    if (cnv->tag == tag && cnv->class == cls)
-    {
-      *syntax = cnv->syntax;
-      return cnv->name;
-    }
-    cnv++;
-  }
-  return NULL;
-}
-
 static const value_string cops_flags_vals[] = {
   { 0x00,          "None" },
   { 0x01,          "Solicited Message Flag Bit" },
@@ -690,6 +606,21 @@ static gint hf_cops_accttimer = -1;
 static gint hf_cops_key_id = -1;
 static gint hf_cops_seq_num = -1;
 
+static gint hf_cops_prid_oid = -1;
+static gint hf_cops_pprid_oid = -1;
+static gint hf_cops_errprid_oid = -1;
+static gint hf_cops_epd_null = -1;
+static gint hf_cops_epd_int = -1;
+static gint hf_cops_epd_octets = -1;
+static gint hf_cops_epd_oid = -1;
+static gint hf_cops_epd_ipv4 = -1;
+static gint hf_cops_epd_u32 = -1;
+static gint hf_cops_epd_ticks = -1;
+static gint hf_cops_epd_opaque = -1;
+static gint hf_cops_epd_i64 = -1;
+static gint hf_cops_epd_u64 = -1;
+static gint hf_cops_epd_unknown = -1;
+
 /* For PacketCable D-QoS */
 static gint hf_cops_subtree = -1;
 static gint hf_cops_pc_activity_count = -1;
@@ -781,12 +712,17 @@ static gint hf_cops_pcmm_max_sustained_traffic_rate = -1;
 static gint hf_cops_pcmm_max_traffic_burst = -1;
 static gint hf_cops_pcmm_min_reserved_traffic_rate = -1;
 static gint hf_cops_pcmm_ass_min_rtr_packet_size = -1;
+static gint hf_cops_pcmm_max_concat_burst = -1;
+static gint hf_cops_pcmm_req_att_mask = -1;
+static gint hf_cops_pcmm_forbid_att_mask = -1;
 static gint hf_cops_pcmm_nominal_polling_interval = -1;
 static gint hf_cops_pcmm_tolerated_poll_jitter = -1;
 static gint hf_cops_pcmm_unsolicited_grant_size = -1;
 static gint hf_cops_pcmm_grants_per_interval = -1;
 static gint hf_cops_pcmm_nominal_grant_interval = -1;
 static gint hf_cops_pcmm_tolerated_grant_jitter = -1;
+static gint hf_cops_pcmm_down_resequencing = -1;
+static gint hf_cops_pcmm_down_peak_traffic_rate = -1;
 static gint hf_cops_pcmm_max_downstream_latency = -1;
 static gint hf_cops_pcmm_volume_based_usage_limit = -1;
 static gint hf_cops_pcmm_time_based_usage_limit = -1;
@@ -802,6 +738,7 @@ static gint hf_cops_pcmm_psid = -1;
 static gint hf_cops_pcmm_synch_options_report_type = -1;
 static gint hf_cops_pcmm_synch_options_synch_type = -1;
 static gint hf_cops_pcmm_msg_receipt_key = -1;
+static gint hf_cops_pcmm_userid = -1;
 
 
 /* Initialize the subtree pointers */
@@ -836,9 +773,11 @@ static int dissect_cops_object(tvbuff_t *tvb, packet_info *pinfo, guint8 op_code
 static void dissect_cops_object_data(tvbuff_t *tvb, packet_info *pinfo, guint32 offset, proto_tree *tree,
                                      guint8 op_code, guint16 client_type, guint8 c_num, guint8 c_type, int len);
 
-static void dissect_cops_pr_objects(tvbuff_t *tvb,packet_info *pinfo, guint32 offset, proto_tree *tree, int pr_len);
+static void dissect_cops_pr_objects(tvbuff_t *tvb, packet_info *pinfo, guint32 offset, proto_tree *tree, int pr_len,
+                                                                       oid_info_t** oid_info_p, guint32** pprid_subids_p, guint* pprid_subids_len_p);
 static int dissect_cops_pr_object_data(tvbuff_t *tvb, packet_info *pinfo, guint32 offset, proto_tree *tree,
-                                       guint8 s_num, guint8 s_type, int len);
+                                                                          guint8 s_num, guint8 s_type, int len,
+                                                                          oid_info_t** oid_info_p, guint32** pprid_subids, guint* pprid_subids_len);
 
 /* Added for PacketCable */
 static proto_tree *info_to_cops_subtree(tvbuff_t *, proto_tree *, int, int, const char *);
@@ -867,6 +806,71 @@ static gboolean cops_packetcable = TRUE;
 
 /* End of addition for PacketCable */
 
+/* COPS PR Tags */
+
+#define COPS_IPA    0          /* IP Address */
+#define COPS_U32    2          /* Unsigned 32*/
+#define COPS_TIT    3          /* TimeTicks */
+#define COPS_OPQ    4          /* Opaque */
+#define COPS_I64    10         /* Integer64 */
+#define COPS_U64    11         /* Uinteger64 */
+
+/* COPS PR Types */
+
+#define COPS_NULL                0
+#define COPS_INTEGER             1    /* l  */
+#define COPS_OCTETSTR            2    /* c  */
+#define COPS_OBJECTID            3    /* ul */
+#define COPS_IPADDR              4    /* uc */
+#define COPS_UNSIGNED32          5    /* ul */
+#define COPS_TIMETICKS           7    /* ul */
+#define COPS_OPAQUE              8    /* c  */
+#define COPS_INTEGER64           10   /* ll */
+#define COPS_UNSIGNED64          11   /* ull  */
+
+typedef struct _COPS_CNV COPS_CNV;
+
+struct _COPS_CNV
+{
+       guint class;
+       guint tag;
+       gint  syntax;
+       const gchar *name;
+       int* hfidp;
+};
+
+static COPS_CNV CopsCnv [] =
+{
+       {BER_CLASS_UNI, BER_UNI_TAG_NULL,                       COPS_NULL,      "NULL" , &hf_cops_epd_null},
+       {BER_CLASS_UNI, BER_UNI_TAG_INTEGER,            COPS_INTEGER,   "INTEGER", &hf_cops_epd_int},
+       {BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING,        COPS_OCTETSTR,  "OCTET STRING", &hf_cops_epd_octets},
+       {BER_CLASS_UNI, BER_UNI_TAG_OID,                        COPS_OBJECTID,  "OBJECTID", &hf_cops_epd_oid},
+       {BER_CLASS_APP, COPS_IPA,                                       COPS_IPADDR,    "IPADDR", &hf_cops_epd_ipv4},
+       {BER_CLASS_APP, COPS_U32,                                       COPS_UNSIGNED32,"UNSIGNED32", &hf_cops_epd_u32},
+       {BER_CLASS_APP, COPS_TIT,                                       COPS_TIMETICKS, "TIMETICKS", &hf_cops_epd_ticks},
+       {BER_CLASS_APP, COPS_OPQ,                                       COPS_OPAQUE,    "OPAQUE", &hf_cops_epd_opaque},
+       {BER_CLASS_APP, COPS_I64,                                       COPS_INTEGER64, "INTEGER64", &hf_cops_epd_i64},
+       {BER_CLASS_APP, COPS_U64,                                       COPS_UNSIGNED64, "UNSIGNED64", &hf_cops_epd_u64},
+       {BER_CLASS_ANY,       0,         -1,                  NULL, NULL}
+};
+
+static int cops_tag_cls2syntax ( guint tag, guint cls ) {
+       COPS_CNV *cnv;
+
+
+       cnv = CopsCnv;
+       while (cnv->syntax != -1)
+       {
+               if (cnv->tag == tag && cnv->class == cls)
+               {
+                       return *(cnv->hfidp);
+               }
+               cnv++;
+       }
+       return hf_cops_epd_unknown;
+}
+
+
 
 /* Code to actually dissect the packets */
 static void
@@ -892,10 +896,8 @@ dissect_cops_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
   guint16 client_type;
   int object_len;
 
-  if (check_col(pinfo->cinfo, COL_PROTOCOL))
-    col_set_str(pinfo->cinfo, COL_PROTOCOL, "COPS");
-  if (check_col(pinfo->cinfo, COL_INFO))
-    col_clear(pinfo->cinfo, COL_INFO);
+  col_set_str(pinfo->cinfo, COL_PROTOCOL, "COPS");
+  col_clear(pinfo->cinfo, COL_INFO);
 
   op_code = tvb_get_guint8(tvb, 1);
   if (check_col(pinfo->cinfo, COL_INFO))
@@ -1039,7 +1041,8 @@ static int dissect_cops_object(tvbuff_t *tvb, packet_info *pinfo, guint8 op_code
   offset++;
 
   type_str = cops_c_type_to_str(c_num, c_type);
-  proto_tree_add_text(obj_tree, tvb, offset, 1, "C-Type: %s%s%u%s",
+  proto_tree_add_uint_format_value(obj_tree, hf_cops_obj_c_type, tvb, offset, 1, c_type,
+                      "%s%s%u%s",
                       type_str,
                       strlen(type_str) ? " (" : "",
                       c_type,
@@ -1056,7 +1059,8 @@ static int dissect_cops_object(tvbuff_t *tvb, packet_info *pinfo, guint8 op_code
   return object_len;
 }
 
-static void dissect_cops_pr_objects(tvbuff_t *tvb, packet_info *pinfo, guint32 offset, proto_tree *tree, int pr_len)
+static void dissect_cops_pr_objects(tvbuff_t *tvb, packet_info *pinfo, guint32 offset, proto_tree *tree, int pr_len,
+                                                                       oid_info_t** oid_info_p, guint32** pprid_subids_p, guint* pprid_subids_len_p)
 {
   int object_len, contents_len;
   guint8 s_num, s_type;
@@ -1080,7 +1084,7 @@ static void dissect_cops_pr_objects(tvbuff_t *tvb, packet_info *pinfo, guint32 o
 
     ti = proto_tree_add_uint_format(cops_pr_tree, hf_cops_obj_s_num, tvb, offset, object_len, s_num,
                                     "%s", val_to_str(s_num, cops_s_num_vals, "Unknown"));
-    obj_tree = proto_item_add_subtree(cops_pr_tree, ett_cops_pr_obj);
+    obj_tree = proto_item_add_subtree(ti, ett_cops_pr_obj);
 
     proto_tree_add_uint(obj_tree, hf_cops_obj_len, tvb, offset, 2, object_len);
     offset += 2;
@@ -1101,7 +1105,8 @@ static void dissect_cops_pr_objects(tvbuff_t *tvb, packet_info *pinfo, guint32 o
     pr_len--;
 
     contents_len = object_len - COPS_OBJECT_HDR_SIZE;
-    ret = dissect_cops_pr_object_data(tvb, pinfo, offset, obj_tree, s_num, s_type, contents_len);
+    ret = dissect_cops_pr_object_data(tvb, pinfo, offset, obj_tree, s_num, s_type, contents_len,
+                                                                         oid_info_p, pprid_subids_p, pprid_subids_len_p);
     if (ret < 0)
       break;
 
@@ -1122,6 +1127,9 @@ static void dissect_cops_object_data(tvbuff_t *tvb, packet_info *pinfo, guint32
   guint16 r_type, m_type, reason, reason_sub, cmd_code, cmd_flags, error, error_sub, tcp_port;
   guint32 ipv4addr, ifindex;
   struct e_in6_addr ipv6addr;
+  oid_info_t* oid_info = NULL;
+  guint32* pprid_subids = NULL;
+  guint pprid_subids_len = 0;
 
   switch (c_num) {
   case COPS_OBJ_CONTEXT:
@@ -1196,7 +1204,7 @@ static void dissect_cops_object_data(tvbuff_t *tvb, packet_info *pinfo, guint32
     } else if (c_type == 5) { /*COPS-PR Data*/
       ti = proto_tree_add_text(tree, tvb, offset, 4, "Contents: %d bytes", len);
       dec_tree = proto_item_add_subtree(ti, ett_cops_decision);
-      dissect_cops_pr_objects(tvb, pinfo, offset, dec_tree, len);
+      dissect_cops_pr_objects(tvb, pinfo, offset, dec_tree, len, &oid_info, &pprid_subids, &pprid_subids_len);
     }
 
     /* PacketCable : Analyze the remaining data if available */
@@ -1243,7 +1251,7 @@ static void dissect_cops_object_data(tvbuff_t *tvb, packet_info *pinfo, guint32
     ti = proto_tree_add_text(tree, tvb, offset, 4, "Contents: %d bytes", len);
     clientsi_tree = proto_item_add_subtree(ti, ett_cops_clientsi);
 
-    dissect_cops_pr_objects(tvb, pinfo, offset, clientsi_tree, len);
+    dissect_cops_pr_objects(tvb, pinfo, offset, clientsi_tree, len, &oid_info, &pprid_subids, &pprid_subids_len);
 
     break;
   case COPS_OBJ_KATIMER:
@@ -1259,8 +1267,13 @@ static void dissect_cops_object_data(tvbuff_t *tvb, packet_info *pinfo, guint32
     if (c_type != 1)
       break;
 
-    if (tvb_strnlen(tvb, offset, len) == -1)
-      proto_tree_add_text(tree, tvb, offset, len, "<PEP Id is not a NUL terminated ASCII string>");
+    if (tvb_strnlen(tvb, offset, len) == -1) {
+      proto_item *pep_ti;
+      pep_ti = proto_tree_add_text(tree, tvb, offset, len, "PEP Id is not a NULL terminated ASCII string");
+      expert_add_info_format(pinfo, pep_ti, PI_MALFORMED, PI_NOTE,
+                             "PEP Id is not a NULL terminated ASCII string");
+      PROTO_ITEM_SET_GENERATED(pep_ti);
+    }
     else
       proto_tree_add_item(tree, hf_cops_pepid, tvb, offset,
                           tvb_strnlen(tvb, offset, len) + 1, FALSE);
@@ -1328,341 +1341,198 @@ static void dissect_cops_object_data(tvbuff_t *tvb, packet_info *pinfo, guint32
   }
 }
 
-#ifdef HAVE_NET_SNMP
-static guchar*format_asn_value (struct variable_list *variable, subid_t *variable_oid,
-                                guint variable_oid_length, u_char type_from_packet)
-{
-  struct tree *subtree=tree_head;
-
-  guchar *buf=NULL;
-  size_t buf_len=0;
-  size_t out_len=0;
-
-  /*Get the ASN.1 type etc. from the PIB-MIB. If unsuccessful use the type from packet*/
-  subtree = get_tree(variable_oid,variable_oid_length, subtree);
-
-  if (subtree->type == 0)
-    variable->type= type_from_packet;
-
-  buf_len = SPRINT_MAX_LEN; /*defined in NET-SNMP's snmp-impl.h*/
-  buf = ep_alloc(buf_len);
-  *buf = '\0';
-  out_len = 0;
-
-  /*If the ASN.1 type was found from PIB-MIB, use it for decoding*/
-  if (!variable->type)
-    variable->type=mib_to_asn_type(subtree->type);
-
-  if (!sprint_realloc_by_type(&buf, &buf_len, &out_len, FALSE, variable, subtree->enums, subtree->hint, NULL))
-    g_snprintf(buf,SPRINT_MAX_LEN,"%s","sprint_realloc_by_type failed");
-
-  return buf;
-}
-#endif /* HAVE_NET_SNMP */
-
-static int decode_cops_pr_asn1_data(tvbuff_t *tvb,packet_info *pinfo, guint32 offset,
-    proto_tree *tree, guint asnlen, guint8 cops_pr_obj
-#ifndef HAVE_NET_SNMP
-                                                 _U_
-#endif
-    )
-{
-  int start, vb_value_start;
-  guint length;
-
-  guint vb_length;
-  gushort vb_type;
-  const gchar *vb_type_name;
-
-  subid_t epd_attribute_index=0;
-
-  gint32 vb_integer_value;
-  guint32 vb_uinteger_value;
-
-  const guint8 *oid_buf;
-  guint8 *vb_octet_string;
-
-  subid_t *vb_oid;
-  guint vb_oid_length;
-  proto_item *vb_pi;
-
-  gchar *vb_display_string;
-  gchar *vb_display_string2;
-
-#ifdef HAVE_NET_SNMP
-  struct variable_list variable;
-  long value;
-#endif /* HAVE_NET_SNMP */
-
-  unsigned int i;
-  gint8 class;
-  gboolean pc, ind = 0;
-  gint32 ber_tag;
-
-  while (asnlen > 0) { /*while there is ASN stuff to be decoded*/
-
-    epd_attribute_index++;
-#ifdef HAVE_NET_SNMP
-    last_decoded_prid_oid[last_decoded_prid_oid_length-1]=epd_attribute_index;
-#endif /* HAVE_NET_SNMP */
-
-    /* parse the type of the object */
-
-    start = offset;
+static guint redecode_oid(guint32* pprid_subids, guint pprid_subids_len, guint8* encoded_subids, guint encoded_len, guint32** subids_p) {
+       guint i;
+       guint n = 0;
+       guint32 subid = 0;
+       guint32* subids;
+       guint32* subid_overflow;
 
-    offset = get_ber_identifier(tvb, offset, &class, &pc, &ber_tag);
-    offset = get_ber_length(tree, tvb, offset, &vb_length, &ind);
+       for (i=0; i<encoded_len; i++) { if (! (encoded_subids[i] & 0x80 )) n++; }
 
-    vb_value_start = offset;
+       *subids_p = subids = ep_alloc(sizeof(guint32)*(n+pprid_subids_len));
+       subid_overflow = subids+n+pprid_subids_len;
+       for (i=0;i<pprid_subids_len;i++) subids[i] = pprid_subids[i];
 
-    /* Convert the class, constructed flag, and tag to a type. */
-    vb_type_name = cops_tag_cls2syntax(ber_tag, class, &vb_type);
-    if (vb_type_name == NULL) {
-      /*
-       * Unsupported type.
-       * Dissect the value as an opaque string of octets.
-       */
-      vb_type_name = "unsupported type";
-      vb_type = COPS_OPAQUE;
-    }
+       subids += pprid_subids_len;
 
-    /* parse the value */
-
-    switch (vb_type) {
-
-    case COPS_INTEGER:
-      offset = dissect_ber_integer(FALSE, pinfo, tree, tvb, start, -1, &vb_integer_value);
-      length = offset - vb_value_start;
-      if (tree) {
-#ifdef HAVE_NET_SNMP
-        if (cops_typefrommib == TRUE)
-        {
-          variable.type = 0;
-          value = vb_integer_value;
-          variable.val.integer = &value;
-          variable.val_len = vb_length ;
-          vb_display_string=format_asn_value(&variable,
-                                             last_decoded_prid_oid,last_decoded_prid_oid_length,ASN_INTEGER);
-
-          proto_tree_add_text(tree, tvb, vb_value_start, length,
-                              "Value: %s", vb_display_string);
-        }
-        else
-#endif /* HAVE_NET_SNMP */
-          proto_tree_add_text(tree, tvb, vb_value_start, length,
-                              "Value: %s: %d (%#x)", vb_type_name,
-                              vb_integer_value, vb_integer_value);
-      }
-      break;
 
-    case COPS_UNSIGNED32:
-    case COPS_TIMETICKS:
-      offset = dissect_ber_integer(FALSE, pinfo, tree, tvb, start, -1, &vb_uinteger_value);
-      length = offset - vb_value_start;
-      if (tree) {
-#ifdef HAVE_NET_SNMP
-        if (cops_typefrommib == TRUE)
-        {
-          variable.type = 0;
-          value = vb_uinteger_value;
-          variable.val.integer = &value;
-          variable.val_len = vb_length;
-
-          vb_display_string=format_asn_value(&variable,
-                                             last_decoded_prid_oid,last_decoded_prid_oid_length,ASN_UINTEGER);
-
-          proto_tree_add_text(tree,tvb, vb_value_start, length, "Value %s: %s",vb_type_name, vb_display_string);
-
-        }
-        else
-#endif /* HAVE_NET_SNMP */
-          proto_tree_add_text(tree,tvb, vb_value_start, length,
-                              "Value: %s: %u (%#x)", vb_type_name,
-                              vb_uinteger_value, vb_uinteger_value);
-      }
-      break;
+       for (i=0; i<encoded_len; i++){
+               guint8 byte = encoded_subids[i];
 
-    case COPS_OCTETSTR:
-    case COPS_IPADDR:
-    case COPS_OPAQUE:
-    case COPS_UNSIGNED64:
-    case COPS_INTEGER64:
-      offset = dissect_ber_octet_string(FALSE, pinfo, NULL, tvb, start, -1, NULL);
-      vb_octet_string = ep_tvb_memdup(tvb, vb_value_start, vb_length);
-      length = offset - vb_value_start;
-      if (tree) {
-#ifdef HAVE_NET_SNMP
-        if (cops_typefrommib == TRUE)
-        {
-          variable.type = 0;
-          variable.val.string = vb_octet_string;
-          variable.val_len = vb_length;
-          vb_display_string = format_asn_value(&variable,
-                                               last_decoded_prid_oid,last_decoded_prid_oid_length,ASN_OCTET_STR);
-          proto_tree_add_text(tree, tvb, vb_value_start, length,
-                              "Value: %s (ASN.1 type from packet: %s)", vb_display_string, vb_type_name);
-
-        }
-        else
-        {
-#endif /* HAVE_NET_SNMP */
-          for (i = 0; i < vb_length; i++) {
-            if (!(isprint(vb_octet_string[i]) ||isspace(vb_octet_string[i])))
-              break;
-          }
-
-          /*
-           * If some characters are not printable, display the string as bytes.
-           */
-          if (i < vb_length) {
-            /*
-             * We stopped, due to a non-printable character, before we got
-             * to the end of the string.
-             */
-            vb_pi = proto_tree_add_text(tree, tvb, vb_value_start, length,
-                                "Value: %s: ", vb_type_name);
-            proto_item_append_text(vb_pi, "%03u", vb_octet_string[0]);
-            for (i = 1; i < vb_length; i++) {
-              proto_item_append_text(vb_pi, ".%03u", vb_octet_string[0]);
-            }
-          } else {
-            proto_tree_add_text(tree, tvb, vb_value_start, length,
-                                "Value: %s: %.*s", vb_type_name, (int)vb_length,
-                                SAFE_STRING(vb_octet_string));
-          }
-#ifdef HAVE_NET_SNMP
-        }
-#endif /* HAVE_NET_SNMP */
-      }
-      break;
+               subid <<= 7;
+               subid |= byte & 0x7F;
 
-    case COPS_NULL:
-      offset = dissect_ber_null(FALSE, pinfo, tree,tvb, start, -1);
-      length = offset - vb_value_start;
-      if (tree)
-        proto_tree_add_text(tree, tvb, vb_value_start, length, "Value: %s", vb_type_name);
-      break;
+               if (byte & 0x80) {
+                       continue;
+               }
 
-    case COPS_OBJECTID:
-      /* XXX Redo this using dissect_ber_object_identifier when it returns tvb
-         or some other binary form of an OID */
-      offset = start;
-      offset = dissect_ber_identifier(pinfo, tree, tvb, offset, &class, &pc, &ber_tag);
-      offset = dissect_ber_length(pinfo, tree, tvb, offset, &vb_length, &ind);
-      oid_buf = tvb_get_ptr(tvb, vb_value_start, vb_length);
-      vb_oid = g_malloc((vb_length+1) * sizeof(gulong));
-      vb_oid_length = oid_to_subid_buf(oid_buf, vb_length, vb_oid, ((vb_length+1) * sizeof(gulong)));
-
-      offset = offset + vb_length;
-      length = offset - vb_value_start;
-
-/*      ret = asn1_oid_value_decode (&asn1, vb_length, &vb_oid, &vb_oid_length);
-      if (ret != ASN1_ERR_NOERROR)
-        return ret;
-      length = asn1.offset - start;
-*/
-      if (tree) {
-       if (vb_oid_length == 0){
-         /* Empty OID */
-         proto_tree_add_text(tree, tvb, vb_value_start, length,
-                             "Value: %s: <empty>", vb_type_name);
-       }
-       else {
-         if (cops_pr_obj == COPS_OBJ_PPRID){
-           /*we're decoding Prefix PRID, that doesn't have a instance Id,
-            *Use full length of the OID when decoding it.
-            */
-           new_format_oid(vb_oid,vb_oid_length,&vb_display_string,&vb_display_string2);
-
-           if (!vb_display_string2)   /*if OID couldn't be decoded, print only numeric format*/
-             proto_tree_add_text(tree, tvb, vb_value_start, length,
-                                 "Value: %s: %s", vb_type_name, vb_display_string);
-           else
-             proto_tree_add_text(tree, tvb, vb_value_start, length,
-                                 "Value: %s: %s (%s)", vb_type_name,
-                                 vb_display_string,
-                                 vb_display_string2);
-         }
-         else { /*we're decoding PRID, Error PRID or EPD*/
-           /*strip the instance Id from the OIDs before decoding and paste it back during printing*/
-           new_format_oid(vb_oid,vb_oid_length-1,&vb_display_string,&vb_display_string2);
-
-           if (!vb_display_string2)  /*if OID couldn't be decoded, print only numeric format*/
-             proto_tree_add_text(tree, tvb, vb_value_start, length,
-                                 "Value: %s: %s.%lu", vb_type_name,
-                                 vb_display_string,
-                                 (unsigned long)vb_oid[vb_oid_length-1]);
-           else
-             proto_tree_add_text(tree, tvb, vb_value_start, length,
-                                 "Value: %s: %s.%lu (%s.%lu)", vb_type_name,
-                                 vb_display_string,
-                                 (unsigned long)vb_oid[vb_oid_length-1],
-                                 vb_display_string2,
-                                 (unsigned long)vb_oid[vb_oid_length-1]);
-         }
+               DISSECTOR_ASSERT(subids < subid_overflow);
+               *subids++ = subid;
+               subid = 0;
        }
-#ifdef HAVE_NET_SNMP
-        if (cops_pr_obj != COPS_OBJ_EPD) {
-          /* we're not decoding EPD, so let's store the OID of the PRID so that later
-             when we're decoding this PRID's EPD we can finetune the output.*/
-          memcpy(last_decoded_prid_oid,vb_oid,vb_oid_length*sizeof(subid_t));
-          last_decoded_prid_oid_length=vb_oid_length;
-        }
-#endif /* HAVE_NET_SNMP */
-      }
-      g_free(vb_oid);
-      break;
-
-    default:
-      DISSECTOR_ASSERT_NOT_REACHED();
-      return 2; /* type not right */
-    }
-
 
-    asnlen -= offset - start;
-  }
-  epd_attribute_index=0;
-  return 0;
+       return pprid_subids_len+n;
 }
 
+
 static int dissect_cops_pr_object_data(tvbuff_t *tvb, packet_info *pinfo, guint32 offset, proto_tree *tree,
-                                       guint8 s_num, guint8 s_type, int len)
-{
+                                                                          guint8 s_num, guint8 s_type, int len,
+                                                                          oid_info_t** oid_info_p, guint32** pprid_subids, guint* pprid_subids_len) {
   proto_item *ti;
-  proto_tree *asn1_object_tree, *gperror_tree, *cperror_tree;
+  proto_tree *asn_tree, *gperror_tree, *cperror_tree;
   guint16 gperror=0, gperror_sub=0, cperror=0, cperror_sub=0;
+  asn1_ctx_t actx;
 
-  switch (s_num){
-  case COPS_OBJ_PRID:
-   if (s_type != 1) /* Not Provisioning Instance Identifier (PRID) */
-      break;
-
-    ti=proto_tree_add_text(tree, tvb, offset, len, "Contents:");
-    asn1_object_tree = proto_item_add_subtree(ti, ett_cops_asn1);
+  memset(&actx,0,sizeof(actx));
+  actx.pinfo = pinfo;
 
-    decode_cops_pr_asn1_data(tvb, pinfo, offset, asn1_object_tree, len, COPS_OBJ_PRID);
+  switch (s_num){
+         case COPS_OBJ_PPRID: {
+                 tvbuff_t* oid_tvb = NULL;
 
-    break;
-  case COPS_OBJ_PPRID:
-    if (s_type != 1) /* Not Prefix Provisioning Instance Identifier (PPRID) */
-      break;
+                 if (s_type != 1) /* Not Prefix Provisioning Instance Identifier (PPRID) */
+                         break;
+                 /* Never tested this branch */
+                 ti = proto_tree_add_text(tree, tvb, offset, len, "Contents:");
+                 asn_tree = proto_item_add_subtree(ti, ett_cops_asn1);
 
-    ti = proto_tree_add_text(tree, tvb, offset, len, "Contents:");
-    asn1_object_tree = proto_item_add_subtree(ti, ett_cops_asn1);
+                 offset = dissect_ber_object_identifier(FALSE, &actx, asn_tree, tvb, offset, hf_cops_pprid_oid, &oid_tvb);
 
-    decode_cops_pr_asn1_data(tvb, pinfo, offset, asn1_object_tree, len, COPS_OBJ_PPRID);
+                 if (oid_tvb) {
+                         guint encoid_len = tvb_length_remaining(oid_tvb,0);
+                         guint8* encoid = ep_tvb_memdup(oid_tvb,0,encoid_len);
 
-    break;
-  case COPS_OBJ_EPD:
-    if (s_type != 1) /* Not  Encoded Provisioning Instance Data (EPD) */
-      break;
+                         (*pprid_subids_len) = oid_encoded2subid(encoid, encoid_len, pprid_subids);
+                 }
+                 break;
+         }
+         case COPS_OBJ_PRID: {
+                 guint32* subids;
+                 guint subids_len;
+                 guint matched;
+                 guint left;
+                 gint8 ber_class;
+                 gboolean ber_pc;
+                 gint32 ber_tag;
+                 guint encoid_len;
+                 guint8* encoid;
+                 oid_info_t* oid_info;
+
+                 if (s_type != 1) break; /* Not Provisioning Instance Identifier (PRID) */
+
+                 ti=proto_tree_add_text(tree, tvb, offset, len, "Contents:");
+                 asn_tree = proto_item_add_subtree(ti, ett_cops_asn1);
+
+                 offset = get_ber_identifier(tvb, offset, &ber_class, &ber_pc, &ber_tag);
+                 offset = get_ber_length(tvb, offset, &encoid_len, NULL);
+
+                 /* TODO: check pc, class and tag */
+
+                 encoid = ep_tvb_memdup(tvb,offset,encoid_len);
+
+                 if (*pprid_subids) {
+                         /* Never tested this branch */
+                         subids_len = redecode_oid(*pprid_subids, *pprid_subids_len, encoid, encoid_len, &subids);
+                         encoid_len = oid_subid2encoded(subids_len, subids, &encoid);
+                 } else {
+                         subids_len = oid_encoded2subid(encoid, encoid_len, &subids);
+                 }
+
+                 proto_tree_add_oid(asn_tree,hf_cops_prid_oid,tvb,offset,encoid_len,encoid);
+
+                 oid_info = oid_get(subids_len, subids, &matched, &left);
+
+                 /*
+                    TODO: from RFC 3159 find-out how the values are mapped,
+                          when instead of an oid for an xxEntry
+                          we have one decribing a scalar or something else,
+                          what's bellow works in most cases but is not complete.
+                  */
+                 if (left <= 1 && oid_info->kind == OID_KIND_ROW) {
+                         *oid_info_p = oid_info;
+                 } else {
+                         *oid_info_p = NULL;
+                 }
+
+                 break;
+         }
+         case COPS_OBJ_EPD: {
+                 oid_info_t* oid_info;
+                 guint end_offset = offset + len;
+
+                 if (s_type != 1) break;/* Not Encoded Provisioning Instance Data (EPD) */
+
+                 ti = proto_tree_add_text(tree, tvb, offset, len, "Contents:");
+                 asn_tree = proto_item_add_subtree(ti, ett_cops_asn1);
+
+                 /*
+                  * XXX: LAZYNESS WARNING:
+                  * We are assuming that for the first element in the sequence
+                  * that describes an entry subid==1, and, that the subsequent elements
+                  * use ++subid; This is true for all IETF's PIBs (and good sense
+                  * indicates it should be this way) but AFAIK there's nothing in
+                  * SMIv2 that imposes this restriction.  -- a lazy lego
+                  */
+
+                 if(*oid_info_p) {
+                         if ((*oid_info_p)->kind == OID_KIND_ROW) {
+                                 oid_info = emem_tree_lookup32((*oid_info_p)->children,1);
+                         } else {
+                                 oid_info = NULL;
+                         }
+                 } else {
+                         oid_info = NULL;
+                 }
+
+
+                 while(offset < end_offset) {
+                         gint8 ber_class;
+                         gboolean ber_pc;
+                         gint32 ber_tag;
+                         guint32 ber_length;
+                         gboolean ber_ind;
+
+                         offset = get_ber_identifier(tvb, offset, &ber_class, &ber_pc, &ber_tag);
+                         offset = get_ber_length(tvb, offset, &ber_length, &ber_ind);
+
+                         if (oid_info) {
+                                 /*
+                                  * XXX: LAZYNESS WARNING:
+                                  * We are assuming that the value of the sequenced item is of
+                                  * the right class, the right type and the right legth.
+                                  * We should check that to avoid throwing a Malformed packet and
+                                  * keep dissecting.
+                                  * We should verify the class and the tag match what we expect as well,
+                                  * but COPS and SNMP use different tags (&#@$!) so the typedata in oid_info_t
+                                  * does not work here.
+                                  * -- a lazy lego
+                                  */
+
+                                 proto_tree_add_item(asn_tree,oid_info->value_hfid,tvb,offset,ber_length,FALSE);
+
+                                 oid_info = emem_tree_lookup32((*oid_info_p)->children,oid_info->subid+1);
+                         } else {
+                                 int hfid = cops_tag_cls2syntax( ber_tag, ber_class );
+                                 proto_tree_add_item(asn_tree,hfid,tvb,offset,ber_length,FALSE);
+                         }
+
+                         offset += ber_length;
+                 }
+
+                 (*oid_info_p) = NULL;
+                 break;
+         }
+         case COPS_OBJ_ERRPRID: {
+                 if (s_type != 1) break; /*Not  Error Provisioning Instance Identifier (ErrorPRID)*/
 
-    ti = proto_tree_add_text(tree, tvb, offset, len, "Contents:");
-    asn1_object_tree = proto_item_add_subtree(ti, ett_cops_asn1);
+                 ti = proto_tree_add_text(tree, tvb, offset, len, "Contents:");
+                 asn_tree = proto_item_add_subtree(ti, ett_cops_asn1);
 
-    decode_cops_pr_asn1_data(tvb, pinfo, offset, asn1_object_tree, len, COPS_OBJ_EPD);
+                 offset = dissect_ber_object_identifier(FALSE, &actx, asn_tree, tvb, offset, hf_cops_errprid_oid, NULL);
 
-    break;
+                 break;
+         }
   case COPS_OBJ_GPERR:
     if (s_type != 1) /* Not Global Provisioning Error Object (GPERR) */
       break;
@@ -1686,8 +1556,6 @@ static int dissect_cops_pr_object_data(tvbuff_t *tvb, packet_info *pinfo, guint3
     if (s_type != 1) /*Not PRC Class Provisioning Error Object (CPERR) */
       break;
 
-    break;
-
     cperror = tvb_get_ntohs(tvb, offset);
     cperror_sub = tvb_get_ntohs(tvb, offset + 2);
     ti = proto_tree_add_text(tree, tvb, offset, 4, "Contents: Error-Code: %s, Error Sub-code: 0x%04x",
@@ -1702,16 +1570,6 @@ static int dissect_cops_pr_object_data(tvbuff_t *tvb, packet_info *pinfo, guint3
     } else
       proto_tree_add_uint(cperror_tree, hf_cops_cperror_sub, tvb, offset, 2, cperror_sub);
 
-    break;
-  case COPS_OBJ_ERRPRID:
-    if (s_type != 1) /*Not  Error Provisioning Instance Identifier (ErrorPRID)*/
-      break;
-
-    ti = proto_tree_add_text(tree, tvb, offset, len, "Contents:");
-    asn1_object_tree = proto_item_add_subtree(ti, ett_cops_asn1);
-
-    decode_cops_pr_asn1_data(tvb, pinfo, offset, asn1_object_tree, len, COPS_OBJ_ERRPRID);
-
     break;
   default:
     proto_tree_add_text(tree, tvb, offset, len, "Contents: %d bytes", len);
@@ -1796,22 +1654,22 @@ void proto_register_cops(void)
     },
     { &hf_cops_in_int_ipv4,
       { "IPv4 address",           "cops.in-int.ipv4",
-      FT_IPv4, 0, NULL, 0,
+      FT_IPv4, BASE_NONE, NULL, 0,
       "IPv4 address in COPS IN-Int object", HFILL }
     },
     { &hf_cops_in_int_ipv6,
       { "IPv6 address",           "cops.in-int.ipv6",
-      FT_IPv6, 0, NULL, 0,
+      FT_IPv6, BASE_NONE, NULL, 0,
       "IPv6 address in COPS IN-Int object", HFILL }
     },
     { &hf_cops_out_int_ipv4,
       { "IPv4 address",           "cops.out-int.ipv4",
-      FT_IPv4, 0, NULL, 0,
+      FT_IPv4, BASE_NONE, NULL, 0,
       "IPv4 address in COPS OUT-Int object", HFILL }
     },
     { &hf_cops_out_int_ipv6,
       { "IPv6 address",           "cops.out-int.ipv6",
-      FT_IPv6, 0, NULL, 0,
+      FT_IPv6, BASE_NONE, NULL, 0,
       "IPv6 address in COPS OUT-Int", HFILL }
     },
     { &hf_cops_int_ifindex,
@@ -1866,22 +1724,22 @@ void proto_register_cops(void)
     },
     { &hf_cops_pdprediraddr_ipv4,
       { "IPv4 address",           "cops.pdprediraddr.ipv4",
-      FT_IPv4, 0, NULL, 0,
+      FT_IPv4, BASE_NONE, NULL, 0,
       "IPv4 address in COPS PDPRedirAddr object", HFILL }
     },
     { &hf_cops_pdprediraddr_ipv6,
       { "IPv6 address",           "cops.pdprediraddr.ipv6",
-      FT_IPv6, 0, NULL, 0,
+      FT_IPv6, BASE_NONE, NULL, 0,
       "IPv6 address in COPS PDPRedirAddr object", HFILL }
     },
     { &hf_cops_lastpdpaddr_ipv4,
       { "IPv4 address",           "cops.lastpdpaddr.ipv4",
-      FT_IPv4, 0, NULL, 0,
+      FT_IPv4, BASE_NONE, NULL, 0,
       "IPv4 address in COPS LastPDPAddr object", HFILL }
     },
     { &hf_cops_lastpdpaddr_ipv6,
       { "IPv6 address",           "cops.lastpdpaddr.ipv6",
-      FT_IPv6, 0, NULL, 0,
+      FT_IPv6, BASE_NONE, NULL, 0,
       "IPv6 address in COPS LastPDPAddr object", HFILL }
     },
     { &hf_cops_pdp_tcp_port,
@@ -1924,248 +1782,262 @@ void proto_register_cops(void)
       FT_UINT16, BASE_HEX, NULL, 0,
       "Error Sub-code in Error object", HFILL }
     },
+  { &hf_cops_prid_oid, { "PRID Instance Identifier", "cops.prid.instance_id", FT_OID, BASE_NONE, NULL, 0, NULL, HFILL } },
+  { &hf_cops_pprid_oid, { "Prefix Identifier", "cops.pprid.prefix_id", FT_OID, BASE_NONE, NULL, 0, NULL, HFILL } },
+  { &hf_cops_errprid_oid, { "ErrorPRID Instance Identifier", "cops.errprid.instance_id", FT_OID, BASE_NONE, NULL, 0, NULL, HFILL } },
+  { &hf_cops_epd_unknown, { "EPD Unknown Data", "cops.epd.unknown", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
+  { &hf_cops_epd_null, { "EPD Null Data", "cops.epd.null", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
+  { &hf_cops_epd_int, { "EPD Integer Data", "cops.epd.int", FT_INT64, BASE_DEC, NULL, 0, NULL, HFILL } },
+  { &hf_cops_epd_octets, { "EPD Octet String Data", "cops.epd.octets", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
+  { &hf_cops_epd_oid, { "EPD OID Data", "cops.epd.oid", FT_OID, BASE_NONE, NULL, 0, NULL, HFILL } },
+  { &hf_cops_epd_ipv4, { "EPD IPAddress Data", "cops.epd.ipv4", FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL } },
+  { &hf_cops_epd_u32, { "EPD Unsigned32 Data", "cops.epd.unsigned32", FT_UINT64, BASE_DEC, NULL, 0, NULL, HFILL } },
+  { &hf_cops_epd_ticks, { "EPD TimeTicks Data", "cops.epd.timeticks", FT_UINT64, BASE_DEC, NULL, 0, NULL, HFILL } },
+  { &hf_cops_epd_opaque, { "EPD Opaque Data", "cops.epd.opaque", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
+  { &hf_cops_epd_i64, { "EPD Inetger64 Data", "cops.epd.integer64", FT_INT64, BASE_DEC, NULL, 0, NULL, HFILL } },
+  { &hf_cops_epd_u64, { "EPD Unsigned64 Data", "cops.epd.unsigned64", FT_UINT64, BASE_DEC, NULL, 0, NULL, HFILL } },
 
     /* Added for PacketCable */
 
     { &hf_cops_subtree,
       { "Object Subtree", "cops.pc_subtree",
-        FT_UINT16, BASE_HEX, NULL, 0,
-        "Object Subtree", HFILL }
+        FT_NONE, BASE_NONE, NULL, 0,
+        NULL, HFILL }
     },
     { &hf_cops_pc_ds_field,
       { "DS Field (DSCP or TOS)", "cops.pc_ds_field",
         FT_UINT8, BASE_HEX, NULL, 0x00,
-        "DS Field (DSCP or TOS)", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_direction,
       { "Direction", "cops.pc_direction",
         FT_UINT8, BASE_HEX, NULL, 0x00,
-        "Direction", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_gate_spec_flags,
       { "Flags", "cops.pc_gate_spec_flags",
         FT_UINT8, BASE_HEX, NULL, 0x00,
-        "Flags", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_protocol_id,
       { "Protocol ID", "cops.pc_protocol_id",
         FT_UINT8, BASE_HEX, NULL, 0x00,
-        "Protocol ID", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_session_class,
       { "Session Class", "cops.pc_session_class",
         FT_UINT8, BASE_HEX, NULL, 0x00,
-        "Session Class", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_algorithm,
       { "Algorithm", "cops.pc_algorithm",
         FT_UINT16, BASE_HEX, NULL, 0x00,
-        "Algorithm", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_cmts_ip_port,
       { "CMTS IP Port", "cops.pc_cmts_ip_port",
         FT_UINT16, BASE_HEX, NULL, 0x00,
-        "CMTS IP Port", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_prks_ip_port,
       { "PRKS IP Port", "cops.pc_prks_ip_port",
         FT_UINT16, BASE_HEX, NULL, 0x00,
-        "PRKS IP Port", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_srks_ip_port,
       { "SRKS IP Port", "cops.pc_srks_ip_port",
         FT_UINT16, BASE_HEX, NULL, 0x00,
-        "SRKS IP Port", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_dest_port,
       { "Destination IP Port", "cops.pc_dest_port",
         FT_UINT16, BASE_HEX, NULL, 0x00,
-        "Destination IP Port", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_packetcable_err_code,
       { "Error Code", "cops.pc_packetcable_err_code",
         FT_UINT16, BASE_HEX, NULL, 0x00,
-        "Error Code", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_packetcable_sub_code,
       { "Error Sub Code", "cops.pc_packetcable_sub_code",
         FT_UINT16, BASE_HEX, NULL, 0x00,
-        "Error Sub Code", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_remote_flags,
       { "Flags", "cops.pc_remote_flags",
         FT_UINT16, BASE_HEX, NULL, 0x00,
-        "Flags", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_close_subcode,
       { "Reason Sub Code", "cops.pc_close_subcode",
         FT_UINT16, BASE_HEX, NULL, 0x00,
-        "Reason Sub Code", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_gate_command_type,
       { "Gate Command Type", "cops.pc_gate_command_type",
         FT_UINT16, BASE_HEX, NULL, 0x00,
-        "Gate Command Type", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_reason_code,
       { "Reason Code", "cops.pc_reason_code",
         FT_UINT16, BASE_HEX, NULL, 0x00,
-        "Reason Code", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_delete_subcode,
       { "Reason Sub Code", "cops.pc_delete_subcode",
         FT_UINT16, BASE_HEX, NULL, 0x00,
-        "Reason Sub Code", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_src_port,
       { "Source IP Port", "cops.pc_src_port",
         FT_UINT16, BASE_HEX, NULL, 0x00,
-        "Source IP Port", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_t1_value,
       { "Timer T1 Value (sec)", "cops.pc_t1_value",
         FT_UINT16, BASE_HEX, NULL, 0x00,
-        "Timer T1 Value (sec)", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_t7_value,
       { "Timer T7 Value (sec)", "cops.pc_t7_value",
         FT_UINT16, BASE_HEX, NULL, 0x00,
-        "Timer T7 Value (sec)", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_t8_value,
       { "Timer T8 Value (sec)", "cops.pc_t8_value",
         FT_UINT16, BASE_HEX, NULL, 0x00,
-        "Timer T8 Value (sec)", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_transaction_id,
       { "Transaction Identifier", "cops.pc_transaction_id",
         FT_UINT16, BASE_HEX, NULL, 0x00,
-        "Transaction Identifier", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_cmts_ip,
       { "CMTS IP Address", "cops.pc_cmts_ip",
-        FT_IPv4, BASE_HEX, NULL, 0x00,
-        "CMTS IP Address", HFILL }
+        FT_IPv4, BASE_NONE, NULL, 0x00,
+        NULL, HFILL }
     },
     { &hf_cops_pc_prks_ip,
       { "PRKS IP Address", "cops.pc_prks_ip",
-        FT_IPv4, BASE_HEX, NULL, 0x00,
-        "PRKS IP Address", HFILL }
+        FT_IPv4, BASE_NONE, NULL, 0x00,
+        NULL, HFILL }
     },
     { &hf_cops_pc_srks_ip,
       { "SRKS IP Address", "cops.pc_srks_ip",
-        FT_IPv4, BASE_HEX, NULL, 0x00,
-        "SRKS IP Address", HFILL }
+        FT_IPv4, BASE_NONE, NULL, 0x00,
+        NULL, HFILL }
     },
     { &hf_cops_pc_dfcdc_ip,
       { "DF IP Address CDC", "cops.pc_dfcdc_ip",
-        FT_IPv4, BASE_HEX, NULL, 0x00,
-        "DF IP Address CDC", HFILL }
+        FT_IPv4, BASE_NONE, NULL, 0x00,
+        NULL, HFILL }
     },
     { &hf_cops_pc_dfccc_ip,
       { "DF IP Address CCC", "cops.pc_dfccc_ip",
-        FT_IPv4, BASE_HEX, NULL, 0x00,
-        "DF IP Address CCC", HFILL }
+        FT_IPv4, BASE_NONE, NULL, 0x00,
+        NULL, HFILL }
     },
     { &hf_cops_pc_dfcdc_ip_port,
       { "DF IP Port CDC", "cops.pc_dfcdc_ip_port",
         FT_UINT16, BASE_HEX, NULL, 0x00,
-        "DF IP Port CDC", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_dfccc_ip_port,
       { "DF IP Port CCC", "cops.pc_dfccc_ip_port",
         FT_UINT16, BASE_HEX, NULL, 0x00,
-        "DF IP Port CCC", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_dfccc_id,
       { "CCC ID", "cops.pc_dfccc_id",
         FT_UINT32, BASE_DEC, NULL, 0x00,
-        "CCC ID", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_activity_count,
       { "Count", "cops.pc_activity_count",
         FT_UINT32, BASE_HEX, NULL, 0x00,
-        "Count", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_dest_ip,
       { "Destination IP Address", "cops.pc_dest_ip",
-        FT_IPv4, BASE_HEX, NULL, 0x00,
-        "Destination IP Address", HFILL }
+        FT_IPv4, BASE_NONE, NULL, 0x00,
+        NULL, HFILL }
     },
     { &hf_cops_pc_gate_id,
       { "Gate Identifier", "cops.pc_gate_id",
         FT_UINT32, BASE_HEX, NULL, 0x00,
-        "Gate Identifier", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_max_packet_size,
       { "Maximum Packet Size", "cops.pc_max_packet_size",
         FT_UINT32, BASE_HEX, NULL, 0x00,
-        "Maximum Packet Size", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_min_policed_unit,
       { "Minimum Policed Unit", "cops.pc_min_policed_unit",
         FT_UINT32, BASE_HEX, NULL, 0x00,
-        "Minimum Policed Unit", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_peak_data_rate,
       { "Peak Data Rate", "cops.pc_peak_data_rate",
         FT_FLOAT, BASE_NONE, NULL, 0x00,
-        "Peak Data Rate", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_spec_rate,
       { "Rate", "cops.pc_spec_rate",
         FT_FLOAT, BASE_NONE, NULL, 0x00,
-        "Rate", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_remote_gate_id,
       { "Remote Gate ID", "cops.pc_remote_gate_id",
         FT_UINT32, BASE_HEX, NULL, 0x00,
-        "Remote Gate ID", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_reserved,
       { "Reserved", "cops.pc_reserved",
         FT_UINT32, BASE_HEX, NULL, 0x00,
-        "Reserved", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_key,
       { "Security Key", "cops.pc_key",
         FT_UINT32, BASE_HEX, NULL, 0x00,
-        "Security Key", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_slack_term,
       { "Slack Term", "cops.pc_slack_term",
         FT_UINT32, BASE_HEX, NULL, 0x00,
-        "Slack Term", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_src_ip,
       { "Source IP Address", "cops.pc_src_ip",
-        FT_IPv4, BASE_HEX, NULL, 0x00,
-        "Source IP Address", HFILL }
+        FT_IPv4, BASE_NONE, NULL, 0x00,
+        NULL, HFILL }
     },
     { &hf_cops_pc_subscriber_id_ipv4,
       { "Subscriber Identifier (IPv4)", "cops.pc_subscriber_id4",
-        FT_IPv4, BASE_HEX, NULL, 0x00,
-        "Subscriber Identifier (IPv4)", HFILL }
+        FT_IPv4, BASE_NONE, NULL, 0x00,
+        NULL, HFILL }
     },
     { &hf_cops_pc_subscriber_id_ipv6,
       { "Subscriber Identifier (IPv6)", "cops.pc_subscriber_id6",
-        FT_IPv6, BASE_HEX, NULL, 0x00,
-        "Subscriber Identifier (IPv6)", HFILL }
+        FT_IPv6, BASE_NONE, NULL, 0x00,
+        NULL, HFILL }
     },
     { &hf_cops_pc_token_bucket_rate,
       { "Token Bucket Rate", "cops.pc_token_bucket_rate",
         FT_FLOAT, BASE_NONE, NULL, 0x00,
-        "Token Bucket Rate", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_token_bucket_size,
       { "Token Bucket Size", "cops.pc_token_bucket_size",
         FT_FLOAT, BASE_NONE, NULL, 0x00,
-        "Token Bucket Size", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_bcid,
       { "Billing Correlation ID", "cops.pc_bcid",
         FT_UINT32, BASE_HEX, NULL, 0x00,
-        "Billing Correlation ID", HFILL }
+        NULL, HFILL }
     },
     { &hf_cops_pc_bcid_ts,
       { "BDID Timestamp", "cops.pc_bcid_ts",
@@ -2258,26 +2130,26 @@ void proto_register_cops(void)
     { &hf_cops_pcmm_classifier_dscp_tos_mask,
            { "DSCP/TOS Mask", "cops.pc_mm_classifier_dscp_mask",
            FT_UINT8, BASE_HEX, NULL, 0,
-           "PacketCable Multimedia Classifer DSCP/TOS Mask", HFILL }
+           "PacketCable Multimedia Classifier DSCP/TOS Mask", HFILL }
     },
     { &hf_cops_pcmm_classifier_src_addr,
            { "Source address", "cops.pc_mm_classifier_src_addr",
-           FT_IPv4, 0, NULL, 0,
+           FT_IPv4, BASE_NONE, NULL, 0,
            "PacketCable Multimedia Classifier Source IP Address", HFILL }
     },
     { &hf_cops_pcmm_classifier_src_mask,
            { "Source mask", "cops.pc_mm_classifier_src_mask",
-           FT_IPv4, 0, NULL, 0,
+           FT_IPv4, BASE_NONE, NULL, 0,
            "PacketCable Multimedia Classifier Source Mask", HFILL }
     },
     { &hf_cops_pcmm_classifier_dst_addr,
            { "Destination address", "cops.pc_mm_classifier_dst_addr",
-           FT_IPv4, 0, NULL, 0,
+           FT_IPv4, BASE_NONE, NULL, 0,
            "PacketCable Multimedia Classifier Destination IP Address", HFILL }
     },
     { &hf_cops_pcmm_classifier_dst_mask,
            { "Destination address", "cops.pc_mm_classifier_dst_mask",
-           FT_IPv4, 0, NULL, 0,
+           FT_IPv4, BASE_NONE, NULL, 0,
            "PacketCable Multimedia Classifier Destination Mask", HFILL }
     },
     { &hf_cops_pcmm_classifier_src_port,
@@ -2334,7 +2206,7 @@ void proto_register_cops(void)
 
     { &hf_cops_pcmm_docsis_scn,
            { "Service Class Name", "cops.pc_mm_docsis_scn",
-           FT_STRINGZ, BASE_DEC, NULL, 0,
+           FT_STRINGZ, BASE_NONE, NULL, 0,
            "PacketCable Multimedia DOCSIS Service Class Name", HFILL }
     },
 
@@ -2374,6 +2246,21 @@ void proto_register_cops(void)
            FT_UINT16, BASE_DEC, NULL, 0,
            "PacketCable Multimedia Committed Envelope Assumed Minimum Reserved Traffic Rate Packet Size", HFILL }
     },
+    { &hf_cops_pcmm_max_concat_burst,
+               { "Maximum Concatenated Burst", "cops.pc_mm_mcburst",
+               FT_UINT16, BASE_DEC, NULL, 0,
+               "PacketCable Multimedia Committed Envelope Maximum Concatenated Burst", HFILL }
+    },
+    { &hf_cops_pcmm_req_att_mask,
+               { "Required Attribute Mask", "cops.pc_mm_ramask",
+               FT_UINT16, BASE_DEC, NULL, 0,
+               "PacketCable Multimedia Committed Envelope Required Attribute Mask", HFILL }
+       },
+       { &hf_cops_pcmm_forbid_att_mask,
+               { "Forbidden Attribute Mask", "cops.pc_mm_famask",
+               FT_UINT16, BASE_DEC, NULL, 0,
+               "PacketCable Multimedia Committed Envelope Forbidden Attribute Mask", HFILL }
+       },
 
     { &hf_cops_pcmm_nominal_polling_interval,
            { "Nominal Polling Interval", "cops.pc_mm_npi",
@@ -2408,6 +2295,18 @@ void proto_register_cops(void)
            "PacketCable Multimedia Tolerated Grant Jitter", HFILL }
     },
 
+    { &hf_cops_pcmm_down_resequencing,
+               { "Downstream Resequencing", "cops.pc_mm_downres",
+               FT_UINT32, BASE_DEC, NULL, 0,
+               "PacketCable Multimedia Downstream Resequencing", HFILL }
+       },
+
+       { &hf_cops_pcmm_down_peak_traffic_rate,
+               { "Downstream Peak Traffic Rate", "cops.pc_mm_downpeak",
+               FT_UINT32, BASE_DEC, NULL, 0,
+               "PacketCable Multimedia Downstream Peak Traffic Rate", HFILL }
+       },
+
     { &hf_cops_pcmm_max_downstream_latency,
            { "Maximum Downstream Latency", "cops.pc_mm_mdl",
            FT_UINT32, BASE_DEC, NULL, 0,
@@ -2434,7 +2333,7 @@ void proto_register_cops(void)
 
     { &hf_cops_pcmm_gate_usage_info,
            { "Gate Usage Info", "cops.pc_mm_gui",
-           FT_UINT32, BASE_DEC, NULL, 0,
+           FT_UINT64, BASE_DEC, NULL, 0,
            "PacketCable Multimedia Gate Usage Info", HFILL }
     },
 
@@ -2492,6 +2391,13 @@ void proto_register_cops(void)
            FT_UINT32, BASE_HEX, NULL, 0,
            "PacketCable Multimedia Msg Receipt Key", HFILL }
     },
+
+    { &hf_cops_pcmm_userid,
+       { "UserID", "cops.pc_mm_userid",
+       FT_STRING, BASE_NONE, NULL, 0,
+       "PacketCable Multimedia UserID", HFILL }
+    },
+
     /* End of addition for PacketCable */
 
   };
@@ -2527,6 +2433,9 @@ void proto_register_cops(void)
   proto_register_field_array(proto_cops, hf, array_length(hf));
   proto_register_subtree_array(ett, array_length(ett));
 
+  /* Make dissector findable by name */
+  register_dissector("cops", dissect_cops, proto_cops);
+
   /* Register our configuration options for cops */
   cops_module = prefs_register_protocol(proto_cops, proto_reg_handoff_cops);
   prefs_register_uint_preference(cops_module,"tcp.cops_port",
@@ -2545,31 +2454,30 @@ void proto_register_cops(void)
                                  "Decode the COPS messages using PacketCable clients. (Select port 2126)",
                                  &cops_packetcable);
 
-#ifdef HAVE_NET_SNMP /*enable preference only if compiled with NET-SNMP*/
-  prefs_register_bool_preference(cops_module, "typefrommib",
-                                 "Decode COPS-PR ASN.1 types by reading them\nfrom PIBs (converted to MIBs)",
-                                 "Whether the COPS dissector should decode COPS-PR ASN.1 types based on data types read from packet or PIBs (converted to MIBs)",
-                                 &cops_typefrommib);
-#endif /*HAVE_NET_SNMP*/
+  prefs_register_static_text_preference(cops_module, "info_pibs",
+      "PIB settings can be changed in the Name Resolution preferences",
+      "PIB settings can be changed in the Name Resolution preferences");
+
+  prefs_register_obsolete_preference(cops_module, "typefrommib");
 }
 
 void proto_reg_handoff_cops(void)
 {
-  static int cops_prefs_initialized = FALSE;
+  static gboolean cops_prefs_initialized = FALSE;
   static dissector_handle_t cops_handle;
+  static guint cops_tcp_port;
 
   if (!cops_prefs_initialized) {
-    cops_handle = create_dissector_handle(dissect_cops, proto_cops);
+    cops_handle = find_dissector("cops");
+    dissector_add("tcp.port", TCP_PORT_PKTCABLE_COPS, cops_handle);
+    dissector_add("tcp.port", TCP_PORT_PKTCABLE_MM_COPS, cops_handle);
     cops_prefs_initialized = TRUE;
-  } else
+  } else {
     dissector_delete("tcp.port",cops_tcp_port,cops_handle);
-
-  /* Set our port numbers for future use */
+  }
   cops_tcp_port = global_cops_tcp_port;
 
   dissector_add("tcp.port", cops_tcp_port, cops_handle);
-  dissector_add("tcp.port", TCP_PORT_PKTCABLE_COPS, cops_handle);
-  dissector_add("tcp.port", TCP_PORT_PKTCABLE_MM_COPS, cops_handle);
 }
 
 
@@ -2582,6 +2490,7 @@ void proto_reg_handoff_cops(void)
 #define   FMT_IPv4  2
 #define   FMT_IPv6  3
 #define   FMT_FLT   4
+#define   FMT_STR   5
 
 /* Print the translated information in the display gui in a formatted way
  *
@@ -2594,6 +2503,7 @@ void proto_reg_handoff_cops(void)
  *          2 -> print value as an IPv4 address
  *          3 -> print value as an IPv6 address
  *          4 -> print value as an IEEE float
+ *          5 -> print value as a string
  *
  * This function in combination with the separate function info_to_cops_subtree() for subtrees.
  *
@@ -2603,11 +2513,21 @@ static proto_item *
 info_to_display(tvbuff_t *tvb, proto_item *stt, int offset, int octets, const char *str, const value_string *vsp, int mode,gint *hf_proto_parameter)
 {
      proto_item *pi = NULL;
+     guint8   *codestr;
      guint8   code8  = 0;
      guint16  code16 = 0;
      guint32  codeipv4 = 0;
      guint32  code32 = 0;
-     float    codefl = 0.0;
+     guint64  code64 = 0;
+     float    codefl = 0.0f;
+
+     /* Special section for printing strings */
+        if (mode==FMT_STR) {
+                codestr = tvb_get_ephemeral_string(tvb, offset, octets);
+                pi = proto_tree_add_string_format(stt, *hf_proto_parameter, tvb,
+                offset, octets, codestr, "%-28s : %s", str, codestr);
+                return pi;
+        }
 
      /* Print information elements in the specified way */
      switch (octets) {
@@ -2710,19 +2630,23 @@ info_to_display(tvbuff_t *tvb, proto_item *stt, int offset, int octets, const ch
              break;
 
         /* In case of more than 4 octets.... */
-        default: {
+        default:
+
              if (mode==FMT_HEX) {
                 pi = proto_tree_add_bytes(stt, *hf_proto_parameter,
                    tvb, offset, octets, tvb_get_ptr(tvb, offset,octets));
-            } else if (mode==FMT_IPv6 && octets==16) {
-               pi = proto_tree_add_ipv6(stt, *hf_proto_parameter, tvb, offset, octets,
-                  tvb_get_ptr(tvb, offset, octets));
+             } else if (mode==FMT_IPv6 && octets==16) {
+                pi = proto_tree_add_ipv6(stt, *hf_proto_parameter, tvb, offset, octets,
+                   tvb_get_ptr(tvb, offset, octets));
+             } else if (mode==FMT_DEC && octets==8) {
+                code64 = tvb_get_ntoh64(tvb, offset);
+                pi = proto_tree_add_uint64_format(stt, *hf_proto_parameter, tvb, offset, octets,
+                   code64, "%-28s : %" G_GINT64_MODIFIER "u", str, code64);
              } else {
                 pi = proto_tree_add_uint_format(stt, *hf_proto_parameter,
                    tvb, offset, octets, code32,"%s",str);
-            }
+             }
              break;
-        }
 
      }
      return pi;
@@ -2733,7 +2657,7 @@ static proto_tree *
 info_to_cops_subtree(tvbuff_t *tvb, proto_tree *st, int n, int offset, const char *str) {
      proto_item *tv;
 
-     tv  = proto_tree_add_uint_format( st, hf_cops_subtree, tvb, offset, n, (guint)NULL, str);
+     tv  = proto_tree_add_none_format( st, hf_cops_subtree, tvb, offset, n, "%s", str);
      return( proto_item_add_subtree( tv, ett_cops_subtree ) );
 }
 
@@ -2760,8 +2684,8 @@ cops_transaction_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *st, guint8 op
             val_to_str(code16,table_cops_dqos_transaction_id, "Unknown (0x%04x)"),code16);
 
      /* Write the right data into the 'info field' on the Gui */
-     g_snprintf(info,sizeof(info),"COPS %-20s - ",val_to_str(op_code,cops_op_code_vals, "Unknown"));
-     strcat(info,val_to_str(code16,table_cops_dqos_transaction_id, "Unknown"));
+     g_snprintf(info,sizeof(info),"COPS %-20s - %s",val_to_str(op_code,cops_op_code_vals, "Unknown"),
+               val_to_str(code16,table_cops_dqos_transaction_id, "Unknown"));
 
      if (check_col(pinfo->cinfo, COL_INFO)) {
           col_clear(pinfo->cinfo, COL_INFO);
@@ -2963,12 +2887,12 @@ cops_surveillance_parameters(tvbuff_t *tvb, proto_tree *st, guint n, guint32 off
      offset += 4;
 
      /* BCID Element ID */
-     bcid_str = tvb_format_text(tvb, offset, 8);
+     bcid_str = (guchar*)tvb_format_text(tvb, offset, 8);
      proto_tree_add_text(stt, tvb, offset, 8,"%-28s : '%s'","BCID - Element ID",bcid_str);
      offset += 8;
 
      /* BCID Time Zone */
-     bcid_str = tvb_format_text(tvb, offset, 8);
+     bcid_str = (guchar*)tvb_format_text(tvb, offset, 8);
      proto_tree_add_text(stt, tvb, offset, 8,"%-28s : '%s'","BCID - Time Zone",bcid_str);
      offset += 8;
 
@@ -3024,12 +2948,12 @@ cops_event_generation_info(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offse
      offset += 4;
 
      /* BCID Element ID */
-     bcid_str = tvb_format_text(tvb, offset, 8);
+     bcid_str = (guchar*)tvb_format_text(tvb, offset, 8);
      proto_tree_add_text(stt, tvb, offset, 8,"%-28s : '%s'","BCID - Element ID",bcid_str);
      offset += 8;
 
      /* BCID Time Zone */
-     bcid_str = tvb_format_text(tvb, offset, 8);
+     bcid_str = (guchar*)tvb_format_text(tvb, offset, 8);
      proto_tree_add_text(stt, tvb, offset, 8,"%-28s : '%s'","BCID - Time Zone",bcid_str);
      offset += 8;
 
@@ -3156,8 +3080,8 @@ cops_mm_transaction_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *st, guint8
             val_to_str(code16,table_cops_mm_transaction_id, "Unknown (0x%04x)"),code16);
 
      /* Write the right data into the 'info field' on the Gui */
-     g_snprintf(info,sizeof(info),"COPS %-20s - ",val_to_str(op_code,cops_op_code_vals, "Unknown"));
-     strcat(info,val_to_str(code16,table_cops_mm_transaction_id, "Unknown"));
+     g_snprintf(info,sizeof(info),"COPS %-20s - %s",val_to_str(op_code,cops_op_code_vals, "Unknown"),
+               val_to_str(code16,table_cops_mm_transaction_id, "Unknown"));
 
      if (check_col(pinfo->cinfo, COL_INFO)) {
           col_clear(pinfo->cinfo, COL_INFO);
@@ -3304,15 +3228,17 @@ cops_classifier(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset, gboolean
        offset += 2;
     }
 
-    /* Priority */
-    info_to_display(tvb,stt,offset,1,"Priority",NULL,FMT_HEX,&hf_cops_pcmm_classifier_priority);
-    offset += 1;
-
     if (extended) {
        /* ClassifierID */
        info_to_display(tvb,stt,offset,2,"ClassifierID",NULL,FMT_HEX,&hf_cops_pcmm_classifier_classifier_id);
        offset += 2;
+    }
+
+    /* Priority */
+    info_to_display(tvb,stt,offset,1,"Priority",NULL,FMT_HEX,&hf_cops_pcmm_classifier_priority);
+    offset += 1;
 
+    if (extended) {
        /* Activation State */
        info_to_display(tvb,stt,offset,1,"Activation State",NULL,FMT_HEX,&hf_cops_pcmm_classifier_activation_state);
        offset += 1;
@@ -3473,9 +3399,15 @@ cops_docsis_service_class_name(tvbuff_t *tvb, proto_tree *st, guint object_len,
      }
 }
 
+/* New functions were made with the i04 suffix to maintain backward compatibility with I03
+*
+*  BEGIN PCMM I04
+*
+*/
+
 /* Cops - Section : Best Effort Service */
 static void
-cops_best_effort_service(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
+cops_best_effort_service_i04(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
      proto_item *ti;
      proto_tree *stt, *object_tree;
 
@@ -3521,10 +3453,18 @@ cops_best_effort_service(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset)
      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
      offset += 2;
 
-     /* Reserved */
-     info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
+     /* Maximum Concatenated Burst */
+     info_to_display(tvb,object_tree,offset,2,"Maximum Concatenated Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_concat_burst);
      offset += 2;
 
+     /* Required Attribute Mask */
+     info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
+     offset += 4;
+
+     /* Forbidden Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
+        offset += 4;
+
      if (n < 56) return;
 
      /* Reserved Envelope */
@@ -3558,9 +3498,17 @@ cops_best_effort_service(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset)
      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
      offset += 2;
 
-     /* Reserved */
-     info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
-     offset += 2;
+     /* Maximum Concatenated Burst */
+        info_to_display(tvb,object_tree,offset,2,"Maximum Concatenated Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_concat_burst);
+        offset += 2;
+
+        /* Required Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
+        offset += 4;
+
+        /* Forbidden Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
+        offset += 4;
 
      if (n < 80) return;
 
@@ -3595,14 +3543,22 @@ cops_best_effort_service(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset)
      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
      offset += 2;
 
-     /* Reserved */
-     info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
+     /* Maximum Concatenated Burst */
+     info_to_display(tvb,object_tree,offset,2,"Maximum Concatenated Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_concat_burst);
      offset += 2;
+
+     /* Required Attribute Mask */
+     info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
+        offset += 4;
+
+        /* Forbidden Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
+        offset += 4;
 }
 
 /* Cops - Section : Non-Real-Time Polling Service */
 static void
-cops_non_real_time_polling_service(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
+cops_non_real_time_polling_service_i04(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
      proto_item *ti;
      proto_tree *stt, *object_tree;
 
@@ -3648,14 +3604,22 @@ cops_non_real_time_polling_service(tvbuff_t *tvb, proto_tree *st, guint n, guint
      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
      offset += 2;
 
-     /* Reserved */
-     info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
+     /* Maximum Concatenated Burst */
+     info_to_display(tvb,object_tree,offset,2,"Maximum Concatenated Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_concat_burst);
      offset += 2;
 
      /* Nominal Polling Interval */
      info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
      offset += 4;
 
+     /* Required Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
+        offset += 4;
+
+        /* Forbidden Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
+        offset += 4;
+
      if (n < 64) return;
 
      /* Reserved Envelope */
@@ -3689,13 +3653,21 @@ cops_non_real_time_polling_service(tvbuff_t *tvb, proto_tree *st, guint n, guint
      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
      offset += 2;
 
-     /* Reserved */
-     info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
-     offset += 2;
+     /* Maximum Concatenated Burst */
+        info_to_display(tvb,object_tree,offset,2,"Maximum Concatenated Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_concat_burst);
+        offset += 2;
 
-     /* Nominal Polling Interval */
-     info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
-     offset += 4;
+        /* Nominal Polling Interval */
+        info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
+        offset += 4;
+
+        /* Required Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
+        offset += 4;
+
+        /* Forbidden Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
+        offset += 4;
 
      if (n < 92) return;
 
@@ -3730,18 +3702,26 @@ cops_non_real_time_polling_service(tvbuff_t *tvb, proto_tree *st, guint n, guint
      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
      offset += 2;
 
-     /* Reserved */
-     info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
-     offset += 2;
+     /* Maximum Concatenated Burst */
+        info_to_display(tvb,object_tree,offset,2,"Maximum Concatenated Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_concat_burst);
+        offset += 2;
 
-     /* Nominal Polling Interval */
-     info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
-     offset += 4;
+        /* Nominal Polling Interval */
+        info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
+        offset += 4;
+
+        /* Required Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
+        offset += 4;
+
+        /* Forbidden Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
+        offset += 4;
 }
 
 /* Cops - Section : Real-Time Polling Service */
 static void
-cops_real_time_polling_service(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
+cops_real_time_polling_service_i04(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
      proto_item *ti;
      proto_tree *stt, *object_tree;
 
@@ -3780,8 +3760,8 @@ cops_real_time_polling_service(tvbuff_t *tvb, proto_tree *st, guint n, guint32 o
      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
      offset += 2;
 
-     /* Reserved */
-     info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
+     /* Maximum Concatenated Burst */
+     info_to_display(tvb,object_tree,offset,2,"Maximum Concatenated Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_concat_burst);
      offset += 2;
 
      /* Nominal Polling Interval */
@@ -3792,6 +3772,14 @@ cops_real_time_polling_service(tvbuff_t *tvb, proto_tree *st, guint n, guint32 o
      info_to_display(tvb,object_tree,offset,4,"Tolerated Poll Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_poll_jitter);
      offset += 4;
 
+     /* Required Attribute Mask */
+     info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
+     offset += 4;
+
+     /* Forbidden Attribute Mask */
+     info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
+     offset += 4;
+
      if (n < 64) return;
 
      /* Reserved Envelope */
@@ -3818,17 +3806,25 @@ cops_real_time_polling_service(tvbuff_t *tvb, proto_tree *st, guint n, guint32 o
      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
      offset += 2;
 
-     /* Reserved */
-     info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
-     offset += 2;
+     /* Maximum Concatenated Burst */
+        info_to_display(tvb,object_tree,offset,2,"Maximum Concatenated Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_concat_burst);
+        offset += 2;
 
-     /* Nominal Polling Interval */
-     info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
-     offset += 4;
+        /* Nominal Polling Interval */
+        info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
+        offset += 4;
 
-     /* Tolerated Poll Jitter */
-     info_to_display(tvb,object_tree,offset,4,"Tolerated Poll Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_poll_jitter);
-     offset += 4;
+        /* Tolerated Poll Jitter */
+        info_to_display(tvb,object_tree,offset,4,"Tolerated Poll Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_poll_jitter);
+        offset += 4;
+
+        /* Required Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
+        offset += 4;
+
+        /* Forbidden Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
+        offset += 4;
 
      if (n < 92) return;
 
@@ -3856,22 +3852,30 @@ cops_real_time_polling_service(tvbuff_t *tvb, proto_tree *st, guint n, guint32 o
      info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
      offset += 2;
 
-     /* Reserved */
-     info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
-     offset += 2;
+     /* Maximum Concatenated Burst */
+        info_to_display(tvb,object_tree,offset,2,"Maximum Concatenated Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_concat_burst);
+        offset += 2;
 
-     /* Nominal Polling Interval */
-     info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
-     offset += 4;
+        /* Nominal Polling Interval */
+        info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
+        offset += 4;
 
-     /* Tolerated Poll Jitter */
-     info_to_display(tvb,object_tree,offset,4,"Tolerated Poll Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_poll_jitter);
-     offset += 4;
+        /* Tolerated Poll Jitter */
+        info_to_display(tvb,object_tree,offset,4,"Tolerated Poll Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_poll_jitter);
+        offset += 4;
+
+        /* Required Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
+        offset += 4;
+
+        /* Forbidden Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
+        offset += 4;
 }
 
 /* Cops - Section : Unsolicited Grant Service */
 static void
-cops_unsolicited_grant_service(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
+cops_unsolicited_grant_service_i04(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
      proto_item *ti;
      proto_tree *stt, *object_tree;
 
@@ -3913,6 +3917,14 @@ cops_unsolicited_grant_service(tvbuff_t *tvb, proto_tree *st, guint n, guint32 o
      info_to_display(tvb,object_tree,offset,4,"Tolerated Grant Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_grant_jitter);
      offset += 4;
 
+     /* Required Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
+        offset += 4;
+
+        /* Forbidden Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
+        offset += 4;
+
      if (n < 40) return;
 
      /* Reserved Envelope */
@@ -3942,6 +3954,14 @@ cops_unsolicited_grant_service(tvbuff_t *tvb, proto_tree *st, guint n, guint32 o
      info_to_display(tvb,object_tree,offset,4,"Tolerated Grant Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_grant_jitter);
      offset += 4;
 
+     /* Required Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
+        offset += 4;
+
+        /* Forbidden Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
+        offset += 4;
+
      if (n < 56) return;
 
      /* Committed Envelope */
@@ -3970,11 +3990,863 @@ cops_unsolicited_grant_service(tvbuff_t *tvb, proto_tree *st, guint n, guint32 o
      /* Tolerated Grant Jitter */
      info_to_display(tvb,object_tree,offset,4,"Tolerated Grant Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_grant_jitter);
      offset += 4;
+
+     /* Required Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
+        offset += 4;
+
+        /* Forbidden Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
+        offset += 4;
 }
 
 /* Cops - Section : Unsolicited Grant Service with Activity Detection */
 static void
-cops_ugs_with_activity_detection(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
+cops_ugs_with_activity_detection_i04(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
+     proto_item *ti;
+     proto_tree *stt, *object_tree;
+
+     /* Create a subtree */
+     stt = info_to_cops_subtree(tvb,st,n,offset,"Unsolicited Grant Service with Activity Detection");
+     offset += 4;
+
+     /* Envelope */
+     info_to_display(tvb,stt,offset,1,"Envelope",NULL,FMT_DEC,&hf_cops_pcmm_envelope);
+     offset += 1;
+
+     proto_tree_add_text(stt, tvb, offset, 3, "Reserved");
+     offset += 3;
+
+     /* Authorized Envelope */
+     ti = proto_tree_add_text(stt, tvb, offset, 24, "Authorized Envelope");
+     object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
+
+     /* Request Transmission Policy */
+     decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
+     offset += 4;
+
+     /* Unsolicited Grant Size */
+     info_to_display(tvb,object_tree,offset,2,"Unsolicited Grant Size",NULL,FMT_DEC,&hf_cops_pcmm_unsolicited_grant_size);
+     offset += 2;
+
+     /* Grants Per Interval */
+     info_to_display(tvb,object_tree,offset,1,"Grants Per Interval",NULL,FMT_DEC,&hf_cops_pcmm_grants_per_interval);
+     offset += 1;
+
+     proto_tree_add_text(object_tree, tvb, offset, 1, "Reserved");
+     offset += 1;
+
+     /* Nominal Grant Interval */
+     info_to_display(tvb,object_tree,offset,4,"Nominal Grant Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_grant_interval);
+     offset += 4;
+
+     /* Tolerated Grant Jitter */
+     info_to_display(tvb,object_tree,offset,4,"Tolerated Grant Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_grant_jitter);
+     offset += 4;
+
+     /* Nominal Polling Interval */
+     info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
+     offset += 4;
+
+     /* Tolerated Poll Jitter */
+     info_to_display(tvb,object_tree,offset,4,"Tolerated Poll Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_poll_jitter);
+     offset += 4;
+
+     /* Required Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
+        offset += 4;
+
+        /* Forbidden Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
+        offset += 4;
+
+     if (n < 56) return;
+
+     /* Reserved Envelope */
+     ti = proto_tree_add_text(stt, tvb, offset, 24, "Reserved Envelope");
+     object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
+
+     /* Request Transmission Policy */
+     decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
+     offset += 4;
+
+     /* Unsolicited Grant Size */
+     info_to_display(tvb,object_tree,offset,2,"Unsolicited Grant Size",NULL,FMT_DEC,&hf_cops_pcmm_unsolicited_grant_size);
+     offset += 2;
+
+     /* Grants Per Interval */
+     info_to_display(tvb,object_tree,offset,1,"Grants Per Interval",NULL,FMT_DEC,&hf_cops_pcmm_grants_per_interval);
+     offset += 1;
+
+     proto_tree_add_text(object_tree, tvb, offset, 1, "Reserved");
+     offset += 1;
+
+     /* Nominal Grant Interval */
+     info_to_display(tvb,object_tree,offset,4,"Nominal Grant Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_grant_interval);
+     offset += 4;
+
+     /* Tolerated Grant Jitter */
+     info_to_display(tvb,object_tree,offset,4,"Tolerated Grant Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_grant_jitter);
+     offset += 4;
+
+     /* Nominal Polling Interval */
+     info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
+     offset += 4;
+
+     /* Tolerated Poll Jitter */
+     info_to_display(tvb,object_tree,offset,4,"Tolerated Poll Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_poll_jitter);
+     offset += 4;
+
+     /* Required Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
+        offset += 4;
+
+        /* Forbidden Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
+        offset += 4;
+
+     if (n < 80) return;
+
+     /* Committed Envelope */
+     ti = proto_tree_add_text(stt, tvb, offset, 24, "Committed Envelope");
+     object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
+
+     /* Request Transmission Policy */
+     decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
+     offset += 4;
+
+     /* Unsolicited Grant Size */
+     info_to_display(tvb,object_tree,offset,2,"Unsolicited Grant Size",NULL,FMT_DEC,&hf_cops_pcmm_unsolicited_grant_size);
+     offset += 2;
+
+     /* Grants Per Interval */
+     info_to_display(tvb,object_tree,offset,1,"Grants Per Interval",NULL,FMT_DEC,&hf_cops_pcmm_grants_per_interval);
+     offset += 1;
+
+     proto_tree_add_text(object_tree, tvb, offset, 1, "Reserved");
+     offset += 1;
+
+     /* Nominal Grant Interval */
+     info_to_display(tvb,object_tree,offset,4,"Nominal Grant Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_grant_interval);
+     offset += 4;
+
+     /* Tolerated Grant Jitter */
+     info_to_display(tvb,object_tree,offset,4,"Tolerated Grant Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_grant_jitter);
+     offset += 4;
+
+     /* Nominal Polling Interval */
+     info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
+     offset += 4;
+
+     /* Tolerated Poll Jitter */
+     info_to_display(tvb,object_tree,offset,4,"Tolerated Poll Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_poll_jitter);
+     offset += 4;
+
+     /* Required Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
+        offset += 4;
+
+        /* Forbidden Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
+        offset += 4;
+}
+
+/* Cops - Section : Downstream Service */
+static void
+cops_downstream_service_i04(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
+     proto_item *ti;
+     proto_tree *stt, *object_tree;
+
+     /* Create a subtree */
+     stt = info_to_cops_subtree(tvb,st,n,offset,"Downstream Service");
+     offset += 4;
+
+     /* Envelope */
+     info_to_display(tvb,stt,offset,1,"Envelope",NULL,FMT_DEC,&hf_cops_pcmm_envelope);
+     offset += 1;
+
+     proto_tree_add_text(stt, tvb, offset, 3, "Reserved");
+     offset += 3;
+
+     /* Authorized Envelope */
+     ti = proto_tree_add_text(stt, tvb, offset, 24, "Authorized Envelope");
+     object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
+
+     /* Traffic Priority */
+     info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
+     offset += 1;
+
+     /* Downstream Resequencing */
+        info_to_display(tvb,object_tree,offset,1,"Downstream Resequencing",NULL,FMT_HEX,&hf_cops_pcmm_down_resequencing);
+        offset += 1;
+
+     proto_tree_add_text(object_tree, tvb, offset, 2, "Reserved");
+     offset += 2;
+
+     /* Maximum Sustained Traffic Rate */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
+     offset += 4;
+
+     /* Maximum Traffic Burst */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
+     offset += 4;
+
+     /* Minimum Reserved Traffic Rate */
+     info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
+     offset += 4;
+
+     /* Assumed Minimum Reserved Traffic Rate Packet Size */
+     info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
+     offset += 2;
+
+     /* Reserved */
+     info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
+     offset += 2;
+
+     /* Maximum Downstream Latency */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Downstream Latency",NULL,FMT_DEC,&hf_cops_pcmm_max_downstream_latency);
+     offset += 4;
+
+     /* Downstream Peak Traffic Rate */
+        info_to_display(tvb,object_tree,offset,4,"Downstream Peak Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_down_peak_traffic_rate);
+        offset += 4;
+
+        /* Required Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
+        offset += 4;
+
+        /* Forbidden Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
+        offset += 4;
+
+     if (n < 56) return;
+
+     /* Reserved Envelope */
+     ti = proto_tree_add_text(stt, tvb, offset, 24, "Reserved Envelope");
+     object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
+
+     /* Traffic Priority */
+     info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
+     offset += 1;
+
+     /* Downstream Resequencing */
+        info_to_display(tvb,object_tree,offset,1,"Downstream Resequencing",NULL,FMT_HEX,&hf_cops_pcmm_down_resequencing);
+        offset += 1;
+
+     proto_tree_add_text(object_tree, tvb, offset, 2, "Reserved");
+     offset += 2;
+
+     /* Maximum Sustained Traffic Rate */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
+     offset += 4;
+
+     /* Maximum Traffic Burst */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
+     offset += 4;
+
+     /* Minimum Reserved Traffic Rate */
+     info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
+     offset += 4;
+
+     /* Assumed Minimum Reserved Traffic Rate Packet Size */
+     info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
+     offset += 2;
+
+     /* Reserved */
+     info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
+     offset += 2;
+
+     /* Maximum Downstream Latency */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Downstream Latency",NULL,FMT_DEC,&hf_cops_pcmm_max_downstream_latency);
+     offset += 4;
+
+     /* Downstream Peak Traffic Rate */
+        info_to_display(tvb,object_tree,offset,4,"Downstream Peak Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_down_peak_traffic_rate);
+        offset += 4;
+
+        /* Required Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
+        offset += 4;
+
+        /* Forbidden Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
+        offset += 4;
+
+     if (n < 80) return;
+
+     /* Committed Envelope */
+     ti = proto_tree_add_text(stt, tvb, offset, 24, "Committed Envelope");
+     object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
+
+     /* Traffic Priority */
+     info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
+     offset += 1;
+
+     /* Downstream Resequencing */
+        info_to_display(tvb,object_tree,offset,1,"Downstream Resequencing",NULL,FMT_HEX,&hf_cops_pcmm_down_resequencing);
+        offset += 1;
+
+     proto_tree_add_text(object_tree, tvb, offset, 2, "Reserved");
+     offset += 2;
+
+     /* Maximum Sustained Traffic Rate */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
+     offset += 4;
+
+     /* Maximum Traffic Burst */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
+     offset += 4;
+
+     /* Minimum Reserved Traffic Rate */
+     info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
+     offset += 4;
+
+     /* Assumed Minimum Reserved Traffic Rate Packet Size */
+     info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
+     offset += 2;
+
+     /* Reserved */
+     info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
+     offset += 2;
+
+     /* Maximum Downstream Latency */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Downstream Latency",NULL,FMT_DEC,&hf_cops_pcmm_max_downstream_latency);
+     offset += 4;
+
+     /* Downstream Peak Traffic Rate */
+        info_to_display(tvb,object_tree,offset,4,"Downstream Peak Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_down_peak_traffic_rate);
+        offset += 4;
+
+        /* Required Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Required Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_req_att_mask);
+        offset += 4;
+
+        /* Forbidden Attribute Mask */
+        info_to_display(tvb,object_tree,offset,4,"Forbidden Attribute Mask",NULL,FMT_DEC,&hf_cops_pcmm_forbid_att_mask);
+        offset += 4;
+}
+
+/* Cops - Section : Upstream Drop */
+static void
+cops_upstream_drop_i04(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
+     proto_tree *stt;
+
+     /* Create a subtree */
+     stt = info_to_cops_subtree(tvb,st,n,offset,"Upstream Drop");
+     offset += 4;
+
+     /* Envelope */
+     info_to_display(tvb,stt,offset,1,"Envelope",NULL,FMT_DEC,&hf_cops_pcmm_envelope);
+     offset += 1;
+
+     proto_tree_add_text(stt, tvb, offset, 3, "Reserved");
+     offset += 3;
+}
+
+/* END PCMM I04 */
+
+/* Cops - Section : Best Effort Service */
+static void
+cops_best_effort_service(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
+     proto_item *ti;
+     proto_tree *stt, *object_tree;
+
+     /* Create a subtree */
+     stt = info_to_cops_subtree(tvb,st,n,offset,"Best Effort Service");
+     offset += 4;
+
+     /* Envelope */
+     info_to_display(tvb,stt,offset,1,"Envelope",NULL,FMT_DEC,&hf_cops_pcmm_envelope);
+     offset += 1;
+
+     proto_tree_add_text(stt, tvb, offset, 3, "Reserved");
+     offset += 3;
+
+     /* Authorized Envelope */
+     ti = proto_tree_add_text(stt, tvb, offset, 24, "Authorized Envelope");
+     object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
+
+     /* Traffic Priority */
+     info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
+     offset += 1;
+
+     proto_tree_add_text(object_tree, tvb, offset, 3, "Reserved");
+     offset += 3;
+
+     /* Request Transmission Policy */
+     decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
+     offset += 4;
+
+     /* Maximum Sustained Traffic Rate */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
+     offset += 4;
+
+     /* Maximum Traffic Burst */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
+     offset += 4;
+
+     /* Minimum Reserved Traffic Rate */
+     info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
+     offset += 4;
+
+     /* Assumed Minimum Reserved Traffic Rate Packet Size */
+     info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
+     offset += 2;
+
+     /* Reserved */
+     info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
+     offset += 2;
+
+     if (n < 56) return;
+
+     /* Reserved Envelope */
+     ti = proto_tree_add_text(stt, tvb, offset, 24, "Reserved Envelope");
+     object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
+
+     /* Traffic Priority */
+     info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
+     offset += 1;
+
+     proto_tree_add_text(object_tree, tvb, offset, 3, "Reserved");
+     offset += 3;
+
+     /* Request Transmission Policy */
+     decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
+     offset += 4;
+
+     /* Maximum Sustained Traffic Rate */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
+     offset += 4;
+
+     /* Maximum Traffic Burst */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
+     offset += 4;
+
+     /* Minimum Reserved Traffic Rate */
+     info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
+     offset += 4;
+
+     /* Assumed Minimum Reserved Traffic Rate Packet Size */
+     info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
+     offset += 2;
+
+     /* Reserved */
+     info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
+     offset += 2;
+
+     if (n < 80) return;
+
+     /* Committed Envelope */
+     ti = proto_tree_add_text(stt, tvb, offset, 24, "Committed Envelope");
+     object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
+
+     /* Traffic Priority */
+     info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
+     offset += 1;
+
+     proto_tree_add_text(object_tree, tvb, offset, 3, "Reserved");
+     offset += 3;
+
+     /* Request Transmission Policy */
+     decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
+     offset += 4;
+
+     /* Maximum Sustained Traffic Rate */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
+     offset += 4;
+
+     /* Maximum Traffic Burst */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
+     offset += 4;
+
+     /* Minimum Reserved Traffic Rate */
+     info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
+     offset += 4;
+
+     /* Assumed Minimum Reserved Traffic Rate Packet Size */
+     info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
+     offset += 2;
+
+     /* Reserved */
+     info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
+     offset += 2;
+}
+
+/* Cops - Section : Non-Real-Time Polling Service */
+static void
+cops_non_real_time_polling_service(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
+     proto_item *ti;
+     proto_tree *stt, *object_tree;
+
+     /* Create a subtree */
+     stt = info_to_cops_subtree(tvb,st,n,offset,"Non-Real-Time Polling Service");
+     offset += 4;
+
+     /* Envelope */
+     info_to_display(tvb,stt,offset,1,"Envelope",NULL,FMT_DEC,&hf_cops_pcmm_envelope);
+     offset += 1;
+
+     proto_tree_add_text(stt, tvb, offset, 3, "Reserved");
+     offset += 3;
+
+     /* Authorized Envelope */
+     ti = proto_tree_add_text(stt, tvb, offset, 28, "Authorized Envelope");
+     object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
+
+     /* Traffic Priority */
+     info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
+     offset += 1;
+
+     proto_tree_add_text(object_tree, tvb, offset, 3, "Reserved");
+     offset += 3;
+
+     /* Request Transmission Policy */
+     decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
+     offset += 4;
+
+     /* Maximum Sustained Traffic Rate */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
+     offset += 4;
+
+     /* Maximum Traffic Burst */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
+     offset += 4;
+
+     /* Minimum Reserved Traffic Rate */
+     info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
+     offset += 4;
+
+     /* Assumed Minimum Reserved Traffic Rate Packet Size */
+     info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
+     offset += 2;
+
+     /* Reserved */
+     info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
+     offset += 2;
+
+     /* Nominal Polling Interval */
+     info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
+     offset += 4;
+
+     if (n < 64) return;
+
+     /* Reserved Envelope */
+     ti = proto_tree_add_text(stt, tvb, offset, 24, "Reserved Envelope");
+     object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
+
+     /* Traffic Priority */
+     info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
+     offset += 1;
+
+     proto_tree_add_text(object_tree, tvb, offset, 3, "Reserved");
+     offset += 3;
+
+     /* Request Transmission Policy */
+     decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
+     offset += 4;
+
+     /* Maximum Sustained Traffic Rate */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
+     offset += 4;
+
+     /* Maximum Traffic Burst */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
+     offset += 4;
+
+     /* Minimum Reserved Traffic Rate */
+     info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
+     offset += 4;
+
+     /* Assumed Minimum Reserved Traffic Rate Packet Size */
+     info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
+     offset += 2;
+
+     /* Reserved */
+     info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
+     offset += 2;
+
+     /* Nominal Polling Interval */
+     info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
+     offset += 4;
+
+     if (n < 92) return;
+
+     /* Committed Envelope */
+     ti = proto_tree_add_text(stt, tvb, offset, 24, "Committed Envelope");
+     object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
+
+     /* Traffic Priority */
+     info_to_display(tvb,object_tree,offset,1,"Traffic Priority",NULL,FMT_HEX,&hf_cops_pcmm_traffic_priority);
+     offset += 1;
+
+     proto_tree_add_text(object_tree, tvb, offset, 3, "Reserved");
+     offset += 3;
+
+     /* Request Transmission Policy */
+     decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
+     offset += 4;
+
+     /* Maximum Sustained Traffic Rate */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
+     offset += 4;
+
+     /* Maximum Traffic Burst */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
+     offset += 4;
+
+     /* Minimum Reserved Traffic Rate */
+     info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
+     offset += 4;
+
+     /* Assumed Minimum Reserved Traffic Rate Packet Size */
+     info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
+     offset += 2;
+
+     /* Reserved */
+     info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
+     offset += 2;
+
+     /* Nominal Polling Interval */
+     info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
+     offset += 4;
+}
+
+/* Cops - Section : Real-Time Polling Service */
+static void
+cops_real_time_polling_service(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
+     proto_item *ti;
+     proto_tree *stt, *object_tree;
+
+     /* Create a subtree */
+     stt = info_to_cops_subtree(tvb,st,n,offset,"Real-Time Polling Service");
+     offset += 4;
+
+     /* Envelope */
+     info_to_display(tvb,stt,offset,1,"Envelope",NULL,FMT_DEC,&hf_cops_pcmm_envelope);
+     offset += 1;
+
+     proto_tree_add_text(stt, tvb, offset, 3, "Reserved");
+     offset += 3;
+
+     /* Authorized Envelope */
+     ti = proto_tree_add_text(stt, tvb, offset, 28, "Authorized Envelope");
+     object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
+
+     /* Request Transmission Policy */
+     decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
+     offset += 4;
+
+     /* Maximum Sustained Traffic Rate */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
+     offset += 4;
+
+     /* Maximum Traffic Burst */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
+     offset += 4;
+
+     /* Minimum Reserved Traffic Rate */
+     info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
+     offset += 4;
+
+     /* Assumed Minimum Reserved Traffic Rate Packet Size */
+     info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
+     offset += 2;
+
+     /* Reserved */
+     info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
+     offset += 2;
+
+     /* Nominal Polling Interval */
+     info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
+     offset += 4;
+
+     /* Tolerated Poll Jitter */
+     info_to_display(tvb,object_tree,offset,4,"Tolerated Poll Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_poll_jitter);
+     offset += 4;
+
+     if (n < 64) return;
+
+     /* Reserved Envelope */
+     ti = proto_tree_add_text(stt, tvb, offset, 24, "Reserved Envelope");
+     object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
+
+     /* Request Transmission Policy */
+     decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
+     offset += 4;
+
+     /* Maximum Sustained Traffic Rate */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
+     offset += 4;
+
+     /* Maximum Traffic Burst */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
+     offset += 4;
+
+     /* Minimum Reserved Traffic Rate */
+     info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
+     offset += 4;
+
+     /* Assumed Minimum Reserved Traffic Rate Packet Size */
+     info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
+     offset += 2;
+
+     /* Reserved */
+     info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
+     offset += 2;
+
+     /* Nominal Polling Interval */
+     info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
+     offset += 4;
+
+     /* Tolerated Poll Jitter */
+     info_to_display(tvb,object_tree,offset,4,"Tolerated Poll Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_poll_jitter);
+     offset += 4;
+
+     if (n < 92) return;
+
+     /* Committed Envelope */
+     ti = proto_tree_add_text(stt, tvb, offset, 24, "Committed Envelope");
+     object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
+
+     /* Request Transmission Policy */
+     decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
+     offset += 4;
+
+     /* Maximum Sustained Traffic Rate */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Sustained Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_max_sustained_traffic_rate);
+     offset += 4;
+
+     /* Maximum Traffic Burst */
+     info_to_display(tvb,object_tree,offset,4,"Maximum Traffic Burst",NULL,FMT_DEC,&hf_cops_pcmm_max_traffic_burst);
+     offset += 4;
+
+     /* Minimum Reserved Traffic Rate */
+     info_to_display(tvb,object_tree,offset,4,"Minimum Reserved Traffic Rate",NULL,FMT_DEC,&hf_cops_pcmm_min_reserved_traffic_rate);
+     offset += 4;
+
+     /* Assumed Minimum Reserved Traffic Rate Packet Size */
+     info_to_display(tvb,object_tree,offset,2,"Assumed Minimum Reserved Traffic Rate Packet Size",NULL,FMT_DEC,&hf_cops_pcmm_ass_min_rtr_packet_size);
+     offset += 2;
+
+     /* Reserved */
+     info_to_display(tvb,object_tree,offset,2,"Reserved",NULL,FMT_HEX,&hf_cops_pc_reserved);
+     offset += 2;
+
+     /* Nominal Polling Interval */
+     info_to_display(tvb,object_tree,offset,4,"Nominal Polling Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_polling_interval);
+     offset += 4;
+
+     /* Tolerated Poll Jitter */
+     info_to_display(tvb,object_tree,offset,4,"Tolerated Poll Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_poll_jitter);
+     offset += 4;
+}
+
+/* Cops - Section : Unsolicited Grant Service */
+static void
+cops_unsolicited_grant_service(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
+     proto_item *ti;
+     proto_tree *stt, *object_tree;
+
+     /* Create a subtree */
+     stt = info_to_cops_subtree(tvb,st,n,offset,"Unsolicited Grant Service");
+     offset += 4;
+
+     /* Envelope */
+     info_to_display(tvb,stt,offset,1,"Envelope",NULL,FMT_DEC,&hf_cops_pcmm_envelope);
+     offset += 1;
+
+     proto_tree_add_text(stt, tvb, offset, 3, "Reserved");
+     offset += 3;
+
+     /* Authorized Envelope */
+     ti = proto_tree_add_text(stt, tvb, offset, 16, "Authorized Envelope");
+     object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
+
+     /* Request Transmission Policy */
+     decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
+     offset += 4;
+
+     /* Unsolicited Grant Size */
+     info_to_display(tvb,object_tree,offset,2,"Unsolicited Grant Size",NULL,FMT_DEC,&hf_cops_pcmm_unsolicited_grant_size);
+     offset += 2;
+
+     /* Grants Per Interval */
+     info_to_display(tvb,object_tree,offset,1,"Grants Per Interval",NULL,FMT_DEC,&hf_cops_pcmm_grants_per_interval);
+     offset += 1;
+
+     proto_tree_add_text(object_tree, tvb, offset, 1, "Reserved");
+     offset += 1;
+
+     /* Nominal Grant Interval */
+     info_to_display(tvb,object_tree,offset,4,"Nominal Grant Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_grant_interval);
+     offset += 4;
+
+     /* Tolerated Grant Jitter */
+     info_to_display(tvb,object_tree,offset,4,"Tolerated Grant Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_grant_jitter);
+     offset += 4;
+
+     if (n < 40) return;
+
+     /* Reserved Envelope */
+     ti = proto_tree_add_text(stt, tvb, offset, 16, "Reserved Envelope");
+     object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
+
+     /* Request Transmission Policy */
+     decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
+     offset += 4;
+
+     /* Unsolicited Grant Size */
+     info_to_display(tvb,object_tree,offset,2,"Unsolicited Grant Size",NULL,FMT_DEC,&hf_cops_pcmm_unsolicited_grant_size);
+     offset += 2;
+
+     /* Grants Per Interval */
+     info_to_display(tvb,object_tree,offset,1,"Grants Per Interval",NULL,FMT_DEC,&hf_cops_pcmm_grants_per_interval);
+     offset += 1;
+
+     proto_tree_add_text(object_tree, tvb, offset, 1, "Reserved");
+     offset += 1;
+
+     /* Nominal Grant Interval */
+     info_to_display(tvb,object_tree,offset,4,"Nominal Grant Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_grant_interval);
+     offset += 4;
+
+     /* Tolerated Grant Jitter */
+     info_to_display(tvb,object_tree,offset,4,"Tolerated Grant Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_grant_jitter);
+     offset += 4;
+
+     if (n < 56) return;
+
+     /* Committed Envelope */
+     ti = proto_tree_add_text(stt, tvb, offset, 16, "Committed Envelope");
+     object_tree = proto_item_add_subtree(ti, ett_cops_subtree);
+
+     /* Request Transmission Policy */
+     decode_docsis_request_transmission_policy(tvb, offset, object_tree, hf_cops_pcmm_request_transmission_policy);
+     offset += 4;
+
+     /* Unsolicited Grant Size */
+     info_to_display(tvb,object_tree,offset,2,"Unsolicited Grant Size",NULL,FMT_DEC,&hf_cops_pcmm_unsolicited_grant_size);
+     offset += 2;
+
+     /* Grants Per Interval */
+     info_to_display(tvb,object_tree,offset,1,"Grants Per Interval",NULL,FMT_DEC,&hf_cops_pcmm_grants_per_interval);
+     offset += 1;
+
+     proto_tree_add_text(object_tree, tvb, offset, 1, "Reserved");
+     offset += 1;
+
+     /* Nominal Grant Interval */
+     info_to_display(tvb,object_tree,offset,4,"Nominal Grant Interval",NULL,FMT_DEC,&hf_cops_pcmm_nominal_grant_interval);
+     offset += 4;
+
+     /* Tolerated Grant Jitter */
+     info_to_display(tvb,object_tree,offset,4,"Tolerated Grant Jitter",NULL,FMT_DEC,&hf_cops_pcmm_tolerated_grant_jitter);
+     offset += 4;
+}
+
+/* Cops - Section : Unsolicited Grant Service with Activity Detection */
+static void
+cops_ugs_with_activity_detection(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
      proto_item *ti;
      proto_tree *stt, *object_tree;
 
@@ -4266,12 +5138,12 @@ cops_mm_event_generation_info(tvbuff_t *tvb, proto_tree *st, guint n, guint32 of
      offset += 4;
 
      /* BCID Element ID */
-     bcid_str = tvb_format_text(tvb, offset, 8);
+     bcid_str = (guchar*)tvb_format_text(tvb, offset, 8);
      proto_tree_add_text(stt, tvb, offset, 8,"%-28s : '%s'","BCID - Element ID",bcid_str);
      offset += 8;
 
      /* BCID Time Zone */
-     bcid_str = tvb_format_text(tvb, offset, 8);
+     bcid_str = (guchar*)tvb_format_text(tvb, offset, 8);
      proto_tree_add_text(stt, tvb, offset, 8,"%-28s : '%s'","BCID - Time Zone",bcid_str);
      offset += 8;
 
@@ -4348,9 +5220,8 @@ cops_gate_usage_info(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
      stt = info_to_cops_subtree(tvb,st,n,offset,"Gate Usage Info");
      offset += 4;
 
-     /* Gate Time Info */
-     info_to_display(tvb,stt,offset,4,"Octet Count", NULL,FMT_DEC,&hf_cops_pcmm_gate_usage_info);
-     offset += 4;
+     /* Gate Usage Info */
+     info_to_display(tvb,stt,offset,8,"Octet Count", NULL,FMT_DEC,&hf_cops_pcmm_gate_usage_info);
 }
 
 /* Cops - Section : PacketCable error */
@@ -4469,6 +5340,19 @@ cops_msg_receipt_key(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
      info_to_display(tvb,stt,offset,4,"Msg Receipt Key", NULL,FMT_HEX,&hf_cops_pcmm_msg_receipt_key);
 }
 
+/* Cops - Section : UserID */
+static void
+cops_userid(tvbuff_t *tvb, proto_tree *st, guint n, guint32 offset) {
+
+     proto_tree *stt;
+
+     /* Create a subtree */
+     stt = info_to_cops_subtree(tvb, st, n, offset, "UserID");
+     offset += 4;
+
+     /* UserID */
+     info_to_display(tvb, stt, offset, n-4, "UserID", NULL, FMT_STR, &hf_cops_pcmm_userid);
+}
 
 /* PacketCable D-QoS S-Num/S-Type globs */
 #define PCDQ_TRANSACTION_ID              0x0101
@@ -4598,6 +5482,7 @@ decode_docsis_request_transmission_policy(tvbuff_t *tvb, guint32 offset, proto_t
 #define PCMM_TRANSACTION_ID                0x0101
 #define PCMM_AMID                          0x0201
 #define PCMM_SUBSCRIBER_ID                 0x0301
+#define PCMM_SUBSCRIBER_ID_V6              0x0302
 #define PCMM_GATE_ID                       0x0401
 #define PCMM_GATE_SPEC                     0x0501
 #define PCMM_CLASSIFIER                    0x0601
@@ -4610,6 +5495,7 @@ decode_docsis_request_transmission_policy(tvbuff_t *tvb, guint32 offset, proto_t
 #define PCMM_UNSOLICITED_GRANT_SERVICE     0x0706
 #define PCMM_UGS_WITH_ACTIVITY_DETECTION   0x0707
 #define PCMM_DOWNSTREAM_SERVICE            0x0708
+#define PCMM_UPSTREAM_DROP                 0x0709
 #define PCMM_EVENT_GENERATION_INFO         0x0801
 #define PCMM_VOLUME_BASED_USAGE_LIMIT      0x0901
 #define PCMM_TIME_BASED_USAGE_LIMIT        0x0a01
@@ -4622,6 +5508,7 @@ decode_docsis_request_transmission_policy(tvbuff_t *tvb, guint32 offset, proto_t
 #define PCMM_PSID                          0x1101
 #define PCMM_SYNCH_OPTIONS                 0x1201
 #define PCMM_MSG_RECEIPT_KEY               0x1301
+#define PCMM_USERID                        0x1501
 
 
 static void
@@ -4664,6 +5551,9 @@ cops_analyze_packetcable_mm_obj(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
         case PCMM_SUBSCRIBER_ID:
                cops_subscriber_id_v4(tvb, tree, object_len, offset);
                break;
+        case PCMM_SUBSCRIBER_ID_V6:
+               cops_subscriber_id_v6(tvb, tree, object_len, offset);
+               break;
         case PCMM_GATE_ID:
                cops_gate_id(tvb, tree, object_len, offset);
                break;
@@ -4683,23 +5573,44 @@ cops_analyze_packetcable_mm_obj(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
                cops_docsis_service_class_name(tvb, tree, object_len, offset);
                break;
         case PCMM_BEST_EFFORT_SERVICE:
-               cops_best_effort_service(tvb, tree, object_len, offset);
-               break;
+                      if (object_len == 40 || object_len == 72 || object_len == 104)
+                          cops_best_effort_service_i04(tvb, tree, object_len, offset);
+                      else
+                          cops_best_effort_service(tvb, tree, object_len, offset);
+                      break;
         case PCMM_NON_REAL_TIME_POLLING_SERVICE:
-               cops_non_real_time_polling_service(tvb, tree, object_len, offset);
+                  if (object_len == 44 || object_len == 80 || object_len == 116)
+                   cops_non_real_time_polling_service_i04(tvb, tree, object_len, offset);
+                  else
+                          cops_non_real_time_polling_service(tvb, tree, object_len, offset);
                break;
         case PCMM_REAL_TIME_POLLING_SERVICE:
-               cops_real_time_polling_service(tvb, tree, object_len, offset);
+                  if (object_len == 44 || object_len == 80 || object_len == 116)
+                   cops_real_time_polling_service_i04(tvb, tree, object_len, offset);
+                  else
+                          cops_real_time_polling_service(tvb, tree, object_len, offset);
                break;
         case PCMM_UNSOLICITED_GRANT_SERVICE:
-               cops_unsolicited_grant_service(tvb, tree, object_len, offset);
-               break;
+                  if (object_len == 32 || object_len == 56 || object_len == 80)
+                   cops_unsolicited_grant_service_i04(tvb, tree, object_len, offset);
+                  else
+                          cops_unsolicited_grant_service(tvb, tree, object_len, offset);
+                  break;
         case PCMM_UGS_WITH_ACTIVITY_DETECTION:
-               cops_ugs_with_activity_detection(tvb, tree, object_len, offset);
-               break;
+                  if (object_len == 40 || object_len == 72 || object_len == 104)
+                   cops_ugs_with_activity_detection_i04(tvb, tree, object_len, offset);
+                  else
+                          cops_ugs_with_activity_detection(tvb, tree, object_len, offset);
+                  break;
         case PCMM_DOWNSTREAM_SERVICE:
-               cops_downstream_service(tvb, tree, object_len, offset);
-               break;
+                  if (object_len == 40 || object_len == 72 || object_len == 104)
+                   cops_downstream_service_i04(tvb, tree, object_len, offset);
+                  else
+                          cops_downstream_service(tvb, tree, object_len, offset);
+                  break;
+        case PCMM_UPSTREAM_DROP:
+                  cops_upstream_drop_i04(tvb, tree, object_len, offset);
+                  break;
         case PCMM_EVENT_GENERATION_INFO:
                cops_mm_event_generation_info(tvb, tree, object_len, offset);
                break;
@@ -4736,6 +5647,10 @@ cops_analyze_packetcable_mm_obj(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
         case PCMM_MSG_RECEIPT_KEY:
                cops_msg_receipt_key(tvb, tree, object_len, offset);
                break;
+        case PCMM_USERID:
+                          cops_userid(tvb, tree, object_len, offset);
+                          break;
+
        }
 
        /* Tune offset */