For proto_tree_add_item(..., proto_xxx, ...)use ENC_NA as the encoding arg.
[obnox/wireshark/wip.git] / epan / dissectors / packet-dcp-etsi.c
index 26516caa499b014929271254bf846c064da6fca2..1e36601a5d27b56ad97c854b8a4889d1f0e11e91 100644 (file)
 # include "config.h"
 #endif
 
-#include <gmodule.h>
 #include <epan/packet.h>
 #include <epan/reassemble.h>
-#include <epan/crcdrm.h>
+#include <wsutil/crcdrm.h>
 #include <epan/reedsolomon.h>
 #include <epan/emem.h>
 #include <string.h>
@@ -91,7 +90,9 @@ static int hf_edcp_fragment_overlap_conflicts = -1;
 static int hf_edcp_fragment_multiple_tails = -1;
 static int hf_edcp_fragment_too_long_fragment = -1;
 static int hf_edcp_fragment_error = -1;
+static int hf_edcp_fragment_count = -1;
 static int hf_edcp_reassembled_in = -1;
+static int hf_edcp_reassembled_length = -1;
 
 /* Initialize the subtree pointers */
 static gint ett_edcp = -1;
@@ -116,8 +117,11 @@ static const fragment_items dcp_frag_items = {
   &hf_edcp_fragment_multiple_tails,
   &hf_edcp_fragment_too_long_fragment,
   &hf_edcp_fragment_error,
+  &hf_edcp_fragment_count,
 /* Reassembled in field */
   &hf_edcp_reassembled_in,
+/* Reassembled length field */
+  &hf_edcp_reassembled_length,
 /* Tag */
   "Message fragments"
 };
@@ -145,6 +149,37 @@ dissect_dcp_etsi (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
 {
   guint8 *sync;
   proto_tree *dcp_tree = NULL;
+
+  /* 6.1 AF packet structure
+   *
+   * AF Header
+   * SYNC               LEN             SEQ             AR              PT
+   * 2 bytes    4 bytes 2 bytes 1 byte  1 byte
+   *
+   * SYNC: two-byte ASCII representation of "AF".
+   * LEN: length of the payload, in bytes.
+   * SEQ: sequence number
+   * AR: AF protocol Revision - a field combining the CF, MAJ and MIN fields
+   * CF: CRC Flag, 0 if the CRC field is not used
+   * MAJ: major revision of the AF protocol in use, see clause 6.2.
+   * MIN: minor revision of the AF protocol in use, see clause 6.2.
+   * Protocol Type (PT): single byte encoding the protocol of the data carried in the payload. For TAG Packets, the value
+   * shall be the ASCII representation of "T".
+   *
+   * 7.1 PFT fragment structure
+   * PFT Header
+   * 14, 16, 18 or 20 bytes (depending on options)                                                                              Optional present if FEC=1 Optional present if Addr = 1
+   * Psync              Pseq            Findex          Fcount          FEC             HCRC            Addr    Plen    | RSk           RSz                     | Source        Dest
+   * 16 bits    16 bits         24 bits         24 bits         1 bit   16 bits         1 bit   14 bits | 8 bits        8 bits          | 16 bits       16 bits
+   *
+   * Psync: the ASCII string "PF" is used as the synchronization word for the PFT Layer
+   *
+   * Don't accept this packet unless at least a full AF header present(10 bytes).
+   * It should be possible to strengthen the heuristic further if need be.
+   */
+  if(tvb_length(tvb) < 11)
+    return FALSE;
+
   sync = tvb_get_ephemeral_string (tvb, 0, 2);
   if((sync[0]!='A' && sync[0]!='P') || sync[1]!='F')
     return FALSE;
@@ -152,17 +187,13 @@ dissect_dcp_etsi (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
   pinfo->current_proto = "DCP (ETSI)";
 
   /* Clear out stuff in the info column */
-  if (check_col (pinfo->cinfo, COL_INFO)) {
-    col_clear (pinfo->cinfo, COL_INFO);
-  }
-  if (check_col (pinfo->cinfo, COL_PROTOCOL)) {
-    col_set_str (pinfo->cinfo, COL_PROTOCOL, "DCP (ETSI)");
+  col_clear(pinfo->cinfo, COL_INFO);
+  col_set_str (pinfo->cinfo, COL_PROTOCOL, "DCP (ETSI)");
     /*col_append_fstr (pinfo->cinfo, COL_INFO, " tvb %d", tvb_length(tvb));*/
-  }
 
   if(tree) {
     proto_item *ti = NULL;
-    ti = proto_tree_add_item (tree, proto_dcp_etsi, tvb, 0, -1, FALSE);
+    ti = proto_tree_add_item (tree, proto_dcp_etsi, tvb, 0, -1, ENC_NA);
     dcp_tree = proto_item_add_subtree (ti, ett_edcp);
   }
 
@@ -215,7 +246,7 @@ gboolean rs_correct_data(guint8 *deinterleaved, guint8 *output,
 
 static tvbuff_t *
 dissect_pft_fec_detailed(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
-  guint32 findex,
+  guint32 findex _U_,
   guint32 fcount,
   guint16 seq,
   gint offset,
@@ -229,7 +260,6 @@ dissect_pft_fec_detailed(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
   guint16 decoded_size;
   guint32 c_max;
   guint32 rx_min;
-  gboolean first, last;
   tvbuff_t *new_tvb=NULL;
 
   if (fcount > MAX_FRAGMENTS) {
@@ -238,8 +268,6 @@ dissect_pft_fec_detailed(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
     return NULL;
   }
 
-  first = findex == 0;
-  last = fcount == (findex+1);
   decoded_size = fcount*plen;
   c_max = fcount*plen/(rsk+PFT_RS_P);  /* rounded down */
   rx_min = c_max*rsk/plen;
@@ -247,32 +275,32 @@ dissect_pft_fec_detailed(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
     rx_min++;
   if (fdx)
     new_tvb = process_reassembled_data (tvb, offset, pinfo,
-                                           "Reassembled Message",
-                                           fdx, &dcp_frag_items,
-                                           NULL, tree);
+                                        "Reassembled DCP (ETSI)",
+                                        fdx, &dcp_frag_items,
+                                        NULL, tree);
   else {
     guint fragments=0;
     guint32 *got;
     fragment_data *fd;
     fragment_data *fd_head;
 
-      if(tree)
-        proto_tree_add_text (tree, tvb, 0, -1, "want %d, got %d need %d",
-        fcount, fragments, rx_min
+    if(tree)
+      proto_tree_add_text (tree, tvb, 0, -1, "want %d, got %d need %d",
+                           fcount, fragments, rx_min
         );
     got = ep_alloc(fcount*sizeof(guint32));
 
-       /* make a list of the findex (offset) numbers of the fragments we have */
+    /* make a list of the findex (offset) numbers of the fragments we have */
     fd = fragment_get(pinfo, seq, dcp_fragment_table);
-       for (fd_head = fd; fd_head != NULL; fd_head = fd_head->next) {
+    for (fd_head = fd; fd_head != NULL; fd_head = fd_head->next) {
       if(fd_head->data) {
         got[fragments++] = fd_head->offset; /* this is the findex of the fragment */
       }
-       }
-       /* put a sentinel at the end */
+    }
+    /* put a sentinel at the end */
     got[fragments++] = fcount;
-       /* have we got enough for Reed Solomon to try to correct ? */
-       if(fragments>=rx_min) { /* yes, in theory */
+    /* have we got enough for Reed Solomon to try to correct ? */
+    if(fragments>=rx_min) { /* yes, in theory */
       guint i,current_findex;
       fragment_data *frag=NULL;
       guint8 *dummy_data = (guint8*) ep_alloc0 (plen);
@@ -280,28 +308,29 @@ dissect_pft_fec_detailed(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
       /* try and decode with missing fragments */
       if(tree)
           proto_tree_add_text (tree, tvb, 0, -1, "want %d, got %d need %d",
-          fcount, fragments, rx_min
-          );
-         /* fill the fragment table with empty fragments */
-         current_findex = 0;
+                               fcount, fragments, rx_min
+            );
+      /* fill the fragment table with empty fragments */
+      current_findex = 0;
       for(i=0; i<fragments; i++) {
-           guint next_fragment_we_have = got[i];
-            if (next_fragment_we_have > MAX_FRAGMENTS) {
-              if (tree)
-                proto_tree_add_text(tree, tvb , 0, -1, "[Reassembly of %d fragments not attempted]", next_fragment_we_have);
-                return NULL;
-            }
+        guint next_fragment_we_have = got[i];
+        if (next_fragment_we_have > MAX_FRAGMENTS) {
+          if (tree)
+            proto_tree_add_text(tree, tvb , 0, -1, "[Reassembly of %d fragments not attempted]", next_fragment_we_have);
+          return NULL;
+        }
         for(; current_findex<next_fragment_we_have; current_findex++) {
           frag = fragment_add_seq_check (dummytvb, 0, pinfo, seq,
-            dcp_fragment_table, dcp_reassembled_table, current_findex, plen, (current_findex+1!=fcount));
+                                         dcp_fragment_table, dcp_reassembled_table,
+                                         current_findex, plen, (current_findex+1!=fcount));
         }
-               current_findex++; /* skip over the fragment we have */
+        current_findex++; /* skip over the fragment we have */
       }
       if(frag)
         new_tvb = process_reassembled_data (tvb, offset, pinfo,
-                                           "Reassembled Message",
-                                           frag, &dcp_frag_items,
-                                           NULL, tree);
+                                            "Reassembled DCP (ETSI)",
+                                            frag, &dcp_frag_items,
+                                            NULL, tree);
     }
   }
   if(new_tvb) {
@@ -313,17 +342,15 @@ dissect_pft_fec_detailed(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
     guint8 *output = (guint8*) g_malloc (decoded_size);
     rs_deinterleave(input, deinterleaved, plen, fcount);
 
-    dtvb = tvb_new_real_data(deinterleaved, reassembled_size, reassembled_size);
-    tvb_set_child_real_data_tvbuff(tvb, dtvb);
+    dtvb = tvb_new_child_real_data(tvb, deinterleaved, reassembled_size, reassembled_size);
     add_new_data_source(pinfo, dtvb, "Deinterleaved");
     tvb_set_free_cb(dtvb, g_free);
 
     decoded = rs_correct_data(deinterleaved, output, c_max, rsk, rsz);
     if(tree)
-        proto_tree_add_boolean (tree, hf_edcp_rs_ok, tvb, offset, 2, decoded);
+      proto_tree_add_boolean (tree, hf_edcp_rs_ok, tvb, offset, 2, decoded);
 
-    new_tvb = tvb_new_real_data(output, decoded_size, decoded_size);
-    tvb_set_child_real_data_tvbuff(dtvb, new_tvb);
+    new_tvb = tvb_new_child_real_data(dtvb, output, decoded_size, decoded_size);
     add_new_data_source(pinfo, new_tvb, "RS Error Corrected Data");
     tvb_set_free_cb(new_tvb, g_free);
   }
@@ -366,39 +393,37 @@ dissect_pft_fragmented(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
   first = findex == 0;
   last = fcount == (findex+1);
   frag_edcp = fragment_add_seq_check (
-     tvb, offset, pinfo,
-     seq,
-        dcp_fragment_table, dcp_reassembled_table,
-        findex,
-     plen,
-        !last);
+    tvb, offset, pinfo,
+    seq,
+    dcp_fragment_table, dcp_reassembled_table,
+    findex,
+    plen,
+    !last);
   if(fec) {
     new_tvb = dissect_pft_fec_detailed(
-          tvb, pinfo, tree, findex, fcount, seq, offset, plen, fec, rsk, rsz, frag_edcp
-        );
+      tvb, pinfo, tree, findex, fcount, seq, offset, plen, fec, rsk, rsz, frag_edcp
+      );
   } else {
     new_tvb = process_reassembled_data (tvb, offset, pinfo,
-                                           "Reassembled Message",
-                                           frag_edcp, &dcp_frag_items,
-                                           NULL, tree);
+                                        "Reassembled DCP (ETSI)",
+                                        frag_edcp, &dcp_frag_items,
+                                        NULL, tree);
   }
-  if (check_col (pinfo->cinfo, COL_INFO)) {
-    if(new_tvb) {
-      col_append_str (pinfo->cinfo, COL_INFO, " (Message Reassembled)");
+  if(new_tvb) {
+    col_append_str (pinfo->cinfo, COL_INFO, " (Message Reassembled)");
+  } else {
+    if(last) {
+      col_append_str (pinfo->cinfo, COL_INFO, " (Message Reassembly failure)");
     } else {
-      if(last) {
-        col_append_str (pinfo->cinfo, COL_INFO, " (Message Reassembly failure)");
-      } else {
-        col_append_fstr (pinfo->cinfo, COL_INFO, " (Message fragment %u)", findex);
-      }
+      col_append_fstr (pinfo->cinfo, COL_INFO, " (Message fragment %u)", findex);
     }
-    if(first)
-      col_append_str (pinfo->cinfo, COL_INFO, " (first)");
-    if(last)
-      col_append_str (pinfo->cinfo, COL_INFO, " (last)");
   }
+  if(first)
+    col_append_str (pinfo->cinfo, COL_INFO, " (first)");
+  if(last)
+   col_append_str (pinfo->cinfo, COL_INFO, " (last)");
   return new_tvb;
-}
+  }
 
 /** Dissect a PFT packet. Details follow
  *  here.
@@ -411,7 +436,7 @@ dissect_pft(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
 {
   guint16 plen;
   gint offset = 0;
-  guint16 seq, payload_len, hcrc;
+  guint16 seq, payload_len;
   guint32 findex, fcount;
   proto_tree *pft_tree = NULL;
   proto_item *ti = NULL, *li = NULL;
@@ -420,56 +445,54 @@ dissect_pft(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
   guint16 rsk=0, rsz=0;
 
   pinfo->current_proto = "DCP-PFT";
-  if (check_col (pinfo->cinfo, COL_PROTOCOL)) {
-    col_set_str (pinfo->cinfo, COL_PROTOCOL, "DCP-PFT");
-  }
+  col_set_str(pinfo->cinfo, COL_PROTOCOL, "DCP-PFT");
 
-  if (tree) {                  /* we are being asked for details */
-    ti = proto_tree_add_item (tree, proto_pft, tvb, 0, -1, FALSE);
+  if (tree) {                   /* we are being asked for details */
+    ti = proto_tree_add_item (tree, proto_pft, tvb, 0, -1, ENC_NA);
     pft_tree = proto_item_add_subtree (ti, ett_pft);
-    proto_tree_add_item (pft_tree, hf_edcp_sync, tvb, offset, 2, FALSE);
+    proto_tree_add_item (pft_tree, hf_edcp_sync, tvb, offset, 2, ENC_ASCII|ENC_NA);
   }
   offset += 2;
   seq = tvb_get_ntohs (tvb, offset);
   if (tree) {
-    proto_tree_add_item (pft_tree, hf_edcp_pseq, tvb, offset, 2, FALSE);
+    proto_tree_add_item (pft_tree, hf_edcp_pseq, tvb, offset, 2, ENC_BIG_ENDIAN);
   }
   offset += 2;
   findex = tvb_get_ntoh24 (tvb, offset);
   if (tree) {
-    proto_tree_add_item (pft_tree, hf_edcp_findex, tvb, offset, 3, FALSE);
+    proto_tree_add_item (pft_tree, hf_edcp_findex, tvb, offset, 3, ENC_BIG_ENDIAN);
   }
   offset += 3;
   fcount = tvb_get_ntoh24 (tvb, offset);
   if (tree) {
-    proto_tree_add_item (pft_tree, hf_edcp_fcount, tvb, offset, 3, FALSE);
+    proto_tree_add_item (pft_tree, hf_edcp_fcount, tvb, offset, 3, ENC_BIG_ENDIAN);
   }
   offset += 3;
   plen = tvb_get_ntohs (tvb, offset);
   payload_len = plen & 0x3fff;
   if (tree) {
-    proto_tree_add_item (pft_tree, hf_edcp_fecflag, tvb, offset, 2, FALSE);
-    proto_tree_add_item (pft_tree, hf_edcp_addrflag, tvb, offset, 2, FALSE);
-    li = proto_tree_add_item (pft_tree, hf_edcp_plen, tvb, offset, 2, FALSE);
+    proto_tree_add_item (pft_tree, hf_edcp_fecflag, tvb, offset, 2, ENC_BIG_ENDIAN);
+    proto_tree_add_item (pft_tree, hf_edcp_addrflag, tvb, offset, 2, ENC_BIG_ENDIAN);
+    li = proto_tree_add_item (pft_tree, hf_edcp_plen, tvb, offset, 2, ENC_BIG_ENDIAN);
   }
   offset += 2;
   if (plen & 0x8000) {
     fec = TRUE;
     rsk = tvb_get_guint8 (tvb, offset);
     if (tree)
-         proto_tree_add_item (pft_tree, hf_edcp_rsk, tvb, offset, 1, FALSE);
+          proto_tree_add_item (pft_tree, hf_edcp_rsk, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset += 1;
     rsz = tvb_get_guint8 (tvb, offset);
     if (tree)
-         proto_tree_add_item (pft_tree, hf_edcp_rsz, tvb, offset, 1, FALSE);
+          proto_tree_add_item (pft_tree, hf_edcp_rsz, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset += 1;
   }
   if (plen & 0x4000) {
     if (tree)
-      proto_tree_add_item (pft_tree, hf_edcp_source, tvb, offset, 2, FALSE);
+      proto_tree_add_item (pft_tree, hf_edcp_source, tvb, offset, 2, ENC_BIG_ENDIAN);
     offset += 2;
     if (tree)
-         proto_tree_add_item (pft_tree, hf_edcp_dest, tvb, offset, 2, FALSE);
+          proto_tree_add_item (pft_tree, hf_edcp_dest, tvb, offset, 2, ENC_BIG_ENDIAN);
     offset += 2;
   }
   if (tree) {
@@ -477,16 +500,15 @@ dissect_pft(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
     guint header_len = offset+2;
     const char *crc_buf = (const char *) tvb_get_ptr(tvb, 0, header_len);
     unsigned long c = crc_drm(crc_buf, header_len, 16, 0x11021, 1);
-    ci = proto_tree_add_item (pft_tree, hf_edcp_hcrc, tvb, offset, 2, FALSE);
+    ci = proto_tree_add_item (pft_tree, hf_edcp_hcrc, tvb, offset, 2, ENC_BIG_ENDIAN);
     proto_item_append_text(ci, " (%s)", (c==0xe2f0)?"Ok":"bad");
     proto_tree_add_boolean(pft_tree, hf_edcp_hcrc_ok, tvb, offset, 2, c==0xe2f0);
   }
-  hcrc = tvb_get_ntohs (tvb, offset);
   offset += 2;
-  if (fcount > 1) {            /* fragmented*/
+  if (fcount > 1) {             /* fragmented*/
     gboolean save_fragmented = pinfo->fragmented;
     guint16 real_len = tvb_length(tvb)-offset;
-    proto_tree_add_item (pft_tree, hf_edcp_pft_payload, tvb, offset, real_len, FALSE);
+    proto_tree_add_item (pft_tree, hf_edcp_pft_payload, tvb, offset, real_len, ENC_NA);
     if(real_len != payload_len) {
       if(li)
         proto_item_append_text(li, " (length error (%d))", real_len);
@@ -497,7 +519,7 @@ dissect_pft(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
                                       );
     pinfo->fragmented = save_fragmented;
   } else {
-    next_tvb = tvb_new_subset (tvb, offset, -1, -1);
+    next_tvb = tvb_new_subset_remaining (tvb, offset);
   }
   if(next_tvb) {
     dissect_af(next_tvb, pinfo, tree);
@@ -525,20 +547,18 @@ dissect_af (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
   tvbuff_t *next_tvb = NULL;
 
   pinfo->current_proto = "DCP-AF";
-  if (check_col (pinfo->cinfo, COL_PROTOCOL)) {
-    col_set_str (pinfo->cinfo, COL_PROTOCOL, "DCP-AF");
-  }
+  col_set_str(pinfo->cinfo, COL_PROTOCOL, "DCP-AF");
 
-  if (tree) {                  /* we are being asked for details */
-    ti = proto_tree_add_item (tree, proto_af, tvb, 0, -1, FALSE);
+  if (tree) {                   /* we are being asked for details */
+    ti = proto_tree_add_item (tree, proto_af, tvb, 0, -1, ENC_NA);
     af_tree = proto_item_add_subtree (ti, ett_af);
-    proto_tree_add_item (af_tree, hf_edcp_sync, tvb, offset, 2, FALSE);
+    proto_tree_add_item (af_tree, hf_edcp_sync, tvb, offset, 2, ENC_ASCII|ENC_NA);
   }
   offset += 2;
   payload_len = tvb_get_ntohl(tvb, offset);
   if (tree) {
     guint32 real_payload_len = tvb_length(tvb)-12;
-    li = proto_tree_add_item (af_tree, hf_edcp_len, tvb, offset, 4, FALSE);
+    li = proto_tree_add_item (af_tree, hf_edcp_len, tvb, offset, 4, ENC_BIG_ENDIAN);
     if(real_payload_len < payload_len) {
       proto_item_append_text (li, " (wrong len claims %d is %d)",
       payload_len, real_payload_len
@@ -551,34 +571,34 @@ dissect_af (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
   }
   offset += 4;
   if (tree)
-    proto_tree_add_item (af_tree, hf_edcp_seq, tvb, offset, 2, FALSE);
+    proto_tree_add_item (af_tree, hf_edcp_seq, tvb, offset, 2, ENC_BIG_ENDIAN);
   offset += 2;
   ver = tvb_get_guint8 (tvb, offset);
   if (tree) {
-    proto_tree_add_item (af_tree, hf_edcp_crcflag, tvb, offset, 1, FALSE);
-    proto_tree_add_item (af_tree, hf_edcp_maj, tvb, offset, 1, FALSE);
-    proto_tree_add_item (af_tree, hf_edcp_min, tvb, offset, 1, FALSE);
+    proto_tree_add_item (af_tree, hf_edcp_crcflag, tvb, offset, 1, ENC_BIG_ENDIAN);
+    proto_tree_add_item (af_tree, hf_edcp_maj, tvb, offset, 1, ENC_BIG_ENDIAN);
+    proto_tree_add_item (af_tree, hf_edcp_min, tvb, offset, 1, ENC_BIG_ENDIAN);
   }
   offset += 1;
   pt = tvb_get_guint8 (tvb, offset);
   if (tree)
-    proto_tree_add_item (af_tree, hf_edcp_pt, tvb, offset, 1, FALSE);
+    proto_tree_add_item (af_tree, hf_edcp_pt, tvb, offset, 1, ENC_ASCII|ENC_NA);
   offset += 1;
   next_tvb = tvb_new_subset (tvb, offset, payload_len, -1);
   offset += payload_len;
   if (tree)
-    ci = proto_tree_add_item (af_tree, hf_edcp_crc, tvb, offset, 2, FALSE);
+    ci = proto_tree_add_item (af_tree, hf_edcp_crc, tvb, offset, 2, ENC_BIG_ENDIAN);
   if (ver & 0x80) { /* crc valid */
     guint len = offset+2;
     const char *crc_buf = (const char *) tvb_get_ptr(tvb, 0, len);
     unsigned long c = crc_drm(crc_buf, len, 16, 0x11021, 1);
     if (tree) {
-         proto_item_append_text(ci, " (%s)", (c==0xe2f0)?"Ok":"bad");
+          proto_item_append_text(ci, " (%s)", (c==0xe2f0)?"Ok":"bad");
       proto_tree_add_boolean(af_tree, hf_edcp_crc_ok, tvb, offset, 2, c==0xe2f0);
     }
   }
   offset += 2;
-  dissector_try_port(af_dissector_table, pt, next_tvb, pinfo, tree);
+  dissector_try_uint(af_dissector_table, pt, next_tvb, pinfo, tree);
 }
 
 /** Dissect the Tag Packet Layer.
@@ -600,13 +620,11 @@ dissect_tpl(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
   guint16 maj, min;
 
   pinfo->current_proto = "DCP-TPL";
-  if (check_col (pinfo->cinfo, COL_PROTOCOL)) {
-    col_set_str (pinfo->cinfo, COL_PROTOCOL, "DCP-TPL");
-  }
+  col_set_str(pinfo->cinfo, COL_PROTOCOL, "DCP-TPL");
 
   if(tree) {
     proto_item *ti = NULL;
-    ti = proto_tree_add_item (tree, proto_tpl, tvb, 0, -1, FALSE);
+    ti = proto_tree_add_item (tree, proto_tpl, tvb, 0, -1, ENC_NA);
     tpl_tree = proto_item_add_subtree (ti, ett_tpl);
   }
   while(offset<tvb_length(tvb)) {
@@ -618,17 +636,17 @@ dissect_tpl(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
     if(bits % 8)
       bytes++;
     if(tree) {
-      proto_item *i = NULL;
-      const guint8 *p = tvb_get_ptr(tvb, offset, bytes);
       if(strcmp(tag, "*ptr")==0) {
         prot = (char*)tvb_get_ephemeral_string (tvb, offset, 4);
         maj = tvb_get_ntohs(tvb, offset+4);
         min = tvb_get_ntohs(tvb, offset+6);
-        i = proto_tree_add_bytes_format(tpl_tree, hf_tpl_tlv, tvb,
-              offset-8, bytes+8, p, "%s %s rev %d.%d", tag, prot, maj, min);
+        proto_tree_add_bytes_format(tpl_tree, hf_tpl_tlv, tvb,
+              offset-8, bytes+8, tvb_get_ptr(tvb, offset, bytes),
+              "%s %s rev %d.%d", tag, prot, maj, min);
       } else {
-        i = proto_tree_add_bytes_format(tpl_tree, hf_tpl_tlv, tvb,
-              offset-8, bytes+8, p, "%s (%u bits)", tag, bits);
+        proto_tree_add_bytes_format(tpl_tree, hf_tpl_tlv, tvb,
+              offset-8, bytes+8, tvb_get_ptr(tvb, offset, bytes),
+              "%s (%u bits)", tag, bits);
       }
     }
     offset += bytes;
@@ -652,7 +670,7 @@ proto_reg_handoff_dcp_etsi (void)
   dissector_add_string("dcp-etsi.sync", "AF", af_handle);
   dissector_add_string("dcp-etsi.sync", "PF", pft_handle);
   /* if there are ever other payload types ...*/
-  dissector_add("dcp-af.pt", 'T', tpl_handle);
+  dissector_add_uint("dcp-af.pt", 'T', tpl_handle);
 }
 
 void
@@ -678,7 +696,7 @@ proto_register_dcp_etsi (void)
      },
     {&hf_edcp_crcflag,
      {"crc flag", "dcp-af.crcflag",
-      FT_BOOLEAN, BASE_NONE, NULL, 0x80,
+      FT_BOOLEAN, 8, NULL, 0x80,
       "Frame is protected by CRC", HFILL}
      },
     {&hf_edcp_maj,
@@ -699,11 +717,11 @@ proto_register_dcp_etsi (void)
     {&hf_edcp_crc,
      {"CRC", "dcp-af.crc",
       FT_UINT16, BASE_HEX, NULL, 0,
-      "CRC", HFILL}
+      NULL, HFILL}
      },
     {&hf_edcp_crc_ok,
      {"CRC OK", "dcp-af.crc_ok",
-      FT_BOOLEAN, BASE_NONE, NULL, 0,
+      FT_BOOLEAN, BASE_NONE, NULL, 0x0,
       "AF CRC OK", HFILL}
      }
     };
@@ -731,12 +749,12 @@ proto_register_dcp_etsi (void)
      },
     {&hf_edcp_fecflag,
      {"FEC", "dcp-pft.fec",
-      FT_BOOLEAN, BASE_NONE, NULL, 0x8000,
+      FT_BOOLEAN, 16, NULL, 0x8000,
       "When set the optional RS header is present", HFILL}
      },
     {&hf_edcp_addrflag,
      {"Addr", "dcp-pft.addr",
-      FT_BOOLEAN, BASE_NONE, NULL, 0x4000,
+      FT_BOOLEAN, 16, NULL, 0x4000,
       "When set the optional transport header is present", HFILL}
      },
     {&hf_edcp_plen,
@@ -771,7 +789,7 @@ proto_register_dcp_etsi (void)
      },
     {&hf_edcp_hcrc_ok,
      {"PFT CRC OK", "dcp-pft.crc_ok",
-      FT_BOOLEAN, BASE_NONE, NULL, 0,
+      FT_BOOLEAN, BASE_NONE, NULL, 0x0,
       "PFT Header CRC OK", HFILL}
      },
     {&hf_edcp_fragments,
@@ -782,24 +800,30 @@ proto_register_dcp_etsi (void)
       FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL}},
     {&hf_edcp_fragment_overlap,
      {"Message fragment overlap", "dcp-pft.fragment.overlap",
-      FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL}},
+      FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL}},
     {&hf_edcp_fragment_overlap_conflicts,
      {"Message fragment overlapping with conflicting data",
       "dcp-pft.fragment.overlap.conflicts",
-      FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL}},
+      FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL}},
     {&hf_edcp_fragment_multiple_tails,
      {"Message has multiple tail fragments",
       "dcp-pft.fragment.multiple_tails",
-      FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL}},
+      FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL}},
     {&hf_edcp_fragment_too_long_fragment,
      {"Message fragment too long", "dcp-pft.fragment.too_long_fragment",
-      FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL}},
+      FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL}},
     {&hf_edcp_fragment_error,
      {"Message defragmentation error", "dcp-pft.fragment.error",
       FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL}},
+    {&hf_edcp_fragment_count,
+     {"Message fragment count", "dcp-pft.fragment.count",
+      FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL}},
     {&hf_edcp_reassembled_in,
      {"Reassembled in", "dcp-pft.reassembled.in",
-      FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL}},
+      FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL}},
+    {&hf_edcp_reassembled_length,
+     {"Reassembled DCP (ETSI) length", "dcp-pft.reassembled.length",
+      FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL}},
     {&hf_edcp_c_max,
      {"C max", "dcp-pft.cmax",
       FT_UINT16, BASE_DEC, NULL, 0,
@@ -817,12 +841,12 @@ proto_register_dcp_etsi (void)
      },
     {&hf_edcp_rs_ok,
      {"RS decode OK", "dcp-pft.rs_ok",
-      FT_BOOLEAN, BASE_NONE, NULL, 0,
+      FT_BOOLEAN, BASE_NONE, NULL, 0x0,
       "successfully decoded RS blocks", HFILL}
      },
     {&hf_edcp_pft_payload,
      {"payload", "dcp-pft.payload",
-      FT_BYTES, BASE_HEX, NULL, 0,
+      FT_BYTES, BASE_NONE, NULL, 0,
       "PFT Payload", HFILL}
     }
   };
@@ -830,7 +854,7 @@ proto_register_dcp_etsi (void)
   static hf_register_info hf_tpl[] = {
     {&hf_tpl_tlv,
      {"tag", "dcp-tpl.tlv",
-      FT_BYTES, BASE_HEX, NULL, 0,
+      FT_BYTES, BASE_NONE, NULL, 0,
       "Tag Packet", HFILL}
      },
     {&hf_tpl_ptr,
@@ -850,17 +874,14 @@ proto_register_dcp_etsi (void)
     &ett_edcp_fragments
   };
 
-  if (proto_dcp_etsi == -1) {
-    proto_dcp_etsi = proto_register_protocol ("ETSI Distribution & Communication Protocol (for DRM)",  /* name */
-                                        "DCP (ETSI)",  /* short name */
-                                        "dcp-etsi"     /* abbrev */
-      );
-    proto_af = proto_register_protocol ("DCP Application Framing Layer", "DCP-AF", "dcp-af");
-    proto_pft = proto_register_protocol ("DCP Protection, Fragmentation & Transport Layer", "DCP-PFT", "dcp-pft");
-    proto_tpl = proto_register_protocol ("DCP Tag Packet Layer", "DCP-TPL", "dcp-tpl");
-
+  proto_dcp_etsi = proto_register_protocol ("ETSI Distribution & Communication Protocol (for DRM)",     /* name */
+                                            "DCP (ETSI)",       /* short name */
+                                            "dcp-etsi"  /* abbrev */
+    );
+  proto_af = proto_register_protocol ("DCP Application Framing Layer", "DCP-AF", "dcp-af");
+  proto_pft = proto_register_protocol ("DCP Protection, Fragmentation & Transport Layer", "DCP-PFT", "dcp-pft");
+  proto_tpl = proto_register_protocol ("DCP Tag Packet Layer", "DCP-TPL", "dcp-tpl");
 
-  }
   proto_register_field_array (proto_dcp_etsi, hf_edcp, array_length (hf_edcp));
   proto_register_field_array (proto_af, hf_af, array_length (hf_af));
   proto_register_field_array (proto_pft, hf_pft, array_length (hf_pft));
@@ -869,12 +890,12 @@ proto_register_dcp_etsi (void)
 
   /* subdissector code */
   dcp_dissector_table = register_dissector_table("dcp-etsi.sync",
-           "DCP Sync", FT_STRING, BASE_NONE);
+            "DCP Sync", FT_STRING, BASE_NONE);
   af_dissector_table = register_dissector_table("dcp-af.pt",
-           "AF Payload Type", FT_UINT8, BASE_DEC);
+            "AF Payload Type", FT_UINT8, BASE_DEC);
 
   tpl_dissector_table = register_dissector_table("dcp-tpl.ptr",
-           "AF Payload Type", FT_STRING, BASE_NONE);
+            "AF Payload Type", FT_STRING, BASE_NONE);
 
   register_init_routine(dcp_init_protocol);