some compilers dont like unnamed unions and structs
[obnox/wireshark/wip.git] / epan / dissectors / packet-clnp.c
index 5f8f6945f0cd08709295632103a7bde64e32364f..bd0ff637969506dd1a7c6590781c339027a263b8 100644 (file)
@@ -5,8 +5,8 @@
  * Laurent Deniel <laurent.deniel@free.fr>
  * Ralf Schneider <Ralf.Schneider@t-online.de>
  *
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  *
  * This program is free software; you can redistribute it and/or
@@ -35,6 +35,7 @@
 #include <epan/packet.h>
 #include <epan/reassemble.h>
 #include <epan/emem.h>
+#include "packet-frame.h"
 #include "packet-osi.h"
 #include "packet-osi-options.h"
 #include "packet-isis.h"
@@ -367,6 +368,7 @@ static GHashTable *clnp_reassembled_table = NULL;
  */
 static GHashTable *cotp_segment_table = NULL;
 static GHashTable *cotp_reassembled_table = NULL;
+static guint16    cotp_dst_ref = 0;
 
 #define TSAP_DISPLAY_AUTO      0
 #define TSAP_DISPLAY_STRING    1
@@ -391,6 +393,12 @@ const enum_val_t tsap_display_options[] = {
 /* function definitions */
 
 #define MAX_TSAP_LEN   32
+
+static void cotp_frame_end(void)
+{
+  cotp_dst_ref = 0;
+}
+
 static gboolean is_all_printable(const guchar *stringtocheck, int length)
 {
   gboolean allprintable;
@@ -411,8 +419,8 @@ static gchar *print_tsap(const guchar *tsap, int length)
 {
 
   gchar *cur;
-  gchar tmp[3];
   gboolean allprintable;
+  size_t index = 0, returned_length;
 
   cur=ep_alloc(MAX_TSAP_LEN * 2 + 3);
   cur[0] = '\0';
@@ -420,14 +428,18 @@ static gchar *print_tsap(const guchar *tsap, int length)
     g_snprintf(cur, MAX_TSAP_LEN * 2 + 3, "<unsupported TSAP length>");
   else {
     allprintable = is_all_printable(tsap,length);
-    if (!allprintable)
-      strcat(cur,"0x");
+    if (!allprintable) {
+      returned_length = g_snprintf(cur, MAX_TSAP_LEN * 2 + 3, "0x");
+      index += MIN(returned_length, MAX_TSAP_LEN * 2 + 3 - 1);
+    }
     while (length != 0) {
-      if (allprintable)
-       g_snprintf(tmp, sizeof(tmp), "%c", *tsap ++);
-      else
-       g_snprintf(tmp, sizeof(tmp), "%02x", *tsap ++);
-      strcat(cur, tmp);
+      if (allprintable) {
+        returned_length = g_snprintf(&cur[index], MAX_TSAP_LEN * 2 + 3 - index, "%c", *tsap ++);
+        index += MIN(returned_length, MAX_TSAP_LEN * 2 + 3 - index - 1 );
+      } else {
+        returned_length = g_snprintf(&cur[index], MAX_TSAP_LEN * 2 + 3 - index, "%02x", *tsap ++);
+        index += MIN(returned_length, MAX_TSAP_LEN * 2 + 3 - index - 1);
+      }
       length --;
     }
   }
@@ -918,7 +930,7 @@ static int ositp_decode_DT(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
        fragment = TRUE;
       is_extended = FALSE;
       is_class_234 = FALSE;
-      dst_ref = 0;
+      dst_ref = cotp_dst_ref;
       break;
 
     default : /* bad TPDU */
@@ -935,11 +947,11 @@ static int ositp_decode_DT(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
       col_append_fstr(pinfo->cinfo, COL_INFO, "DT TPDU (%u) dst-ref: 0x%04x %s",
                 tpdu_nr,
                 dst_ref,
-                (fragment)? "(fragment)" : "EOT");
+                (fragment)? "[COTP Fragment]" : "EOT");
     } else {
       col_append_fstr(pinfo->cinfo, COL_INFO, "DT TPDU (%u) %s",
                 tpdu_nr,
-                (fragment)? "(fragment)" : "EOT");
+                (fragment)? "[COTP Fragment]" : "EOT");
     }
   }
 
@@ -1024,6 +1036,9 @@ static int ositp_decode_DT(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
                               pinfo, reassembled_tvb, &ti);
        pinfo->fragmented = fragment;
        next_tvb = reassembled_tvb;
+
+       cotp_dst_ref++;
+       register_frame_end_routine(cotp_frame_end);
       }
     }
     if (fragment && reassembled_tvb == NULL) {
@@ -1253,8 +1268,8 @@ static int ositp_decode_CC(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
 
   src_ref = tvb_get_ntohs(tvb, offset + P_SRC_REF);
 
-  class_option = (tvb_get_guint8(tvb, offset + P_CLASS_OPTION) >> 4 ) & 0x0F;
-  if (class_option > 4)
+  class_option = tvb_get_guint8(tvb, offset + P_CLASS_OPTION);
+  if (((class_option & 0xF0) >> 4) > 4) /* class 0..4 allowed */
     return -1;
 
   dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF);
@@ -1300,7 +1315,9 @@ static int ositp_decode_CC(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
 
   if (tree) {
     proto_tree_add_text(cotp_tree, tvb, offset, 1,
-                       "Class option: 0x%02x", class_option);
+                       "Class: %1u", (class_option & 0xF0) >> 4);
+    proto_tree_add_text(cotp_tree, tvb, offset, 1,
+                       "Option: %1u", (class_option & 0x0F));
   }
   offset += 1;
   li -= 1;
@@ -2164,6 +2181,7 @@ clnp_reassemble_init(void)
 {
   fragment_table_init(&clnp_segment_table);
   reassembled_table_init(&clnp_reassembled_table);
+  cotp_dst_ref = 0;
 }
 
 static void