Remove the (long deprecated) proto_tree_add_*_hidden() functions
[obnox/wireshark/wip.git] / wiretap / catapult_dct2000.c
index c090804c8791340350fcbefc8d44d9ce1200940c..2a436b679978f82dfb8da4374a297310eec67658 100644 (file)
 #define MAX_FIRST_LINE_LENGTH      200
 #define MAX_TIMESTAMP_LINE_LENGTH  100
 #define MAX_LINE_LENGTH            32000
+#define MAX_TIMESTAMP_LEN          32
 #define MAX_SECONDS_CHARS          16
 #define MAX_SUBSECOND_DECIMALS     4
 #define MAX_CONTEXT_NAME           64
 #define MAX_PROTOCOL_NAME          64
 #define MAX_PORT_DIGITS            2
 #define MAX_VARIANT_DIGITS         32
-#define MAX_OUTHDR_NAME            64
+#define MAX_OUTHDR_NAME            256
 #define AAL_HEADER_CHARS           12
 
 /* TODO:
@@ -60,12 +61,17 @@ typedef enum packet_direction_t
 } packet_direction_t;
 
 
+/***********************************************************************/
+/* For each line, store (in case we need to dump):                     */
+/* - String before time field                                          */
+/* - String beween time field and data (if NULL assume " l ")          */
 typedef struct
 {
     gchar *before_time;
-    gchar *after_time; /* If NULL assume " l " */
+    gchar *after_time;
 } line_prefix_info_t;
 
+
 /*******************************************************************/
 /* Information stored external to a file (wtap) needed for dumping */
 typedef struct dct2000_file_externals
@@ -79,13 +85,13 @@ typedef struct dct2000_file_externals
     gint  secondline_length;
 
     /* Hash table to store text prefix data part of displayed packets.
-       Records (file offset -> pre-data-prefix-string)
+       Records (file offset -> line_prefix_info_t)
        N.B. This is only needed for dumping
     */
     GHashTable *packet_prefix_table;
 } dct2000_file_externals_t;
 
-/* This global table maps wtap -> file_external structs */
+/* This global table maps wtap -> dct2000_file_externals_t structs */
 static GHashTable *file_externals_table = NULL;
 
 
@@ -112,7 +118,7 @@ static gchar outhdr_name[MAX_OUTHDR_NAME+1];
 
 
 /************************************************************/
-/* Functions called from wiretap                            */
+/* Functions called from wiretap core                       */
 static gboolean catapult_dct2000_read(wtap *wth, int *err, gchar **err_info,
                                       gint64 *data_offset);
 static gboolean catapult_dct2000_seek_read(wtap *wth, gint64 seek_off,
@@ -137,7 +143,7 @@ static gboolean parse_line(gint line_length, gint *seconds, gint *useconds,
                            packet_direction_t *direction,
                            int *encap);
 static int write_stub_header(guchar *frame_buffer, char *timestamp_string,
-                      packet_direction_t direction, int encap);
+                             packet_direction_t direction, int encap);
 static guchar hex_from_char(gchar c);
 static gchar char_from_hex(guchar hex);
 
@@ -164,7 +170,7 @@ static gboolean free_line_prefix_info(gpointer key, gpointer value, gpointer use
 
 
 /********************************************/
-/* Open file                                */
+/* Open file (for reading)                 */
 /********************************************/
 int catapult_dct2000_open(wtap *wth, int *err, gchar **err_info _U_)
 {
@@ -204,12 +210,12 @@ int catapult_dct2000_open(wtap *wth, int *err, gchar **err_info _U_)
         file_externals_table = g_hash_table_new(wth_hash_func, wth_equal);
     }
 
-    /* Allocate a new file_externals structure */
+    /* Allocate a new file_externals structure for this file */
     file_externals = g_malloc(sizeof(dct2000_file_externals_t));
     memset((void*)file_externals, '\0', sizeof(dct2000_file_externals_t));
 
     /* Copy this first line into buffer so could write out later */
-    strncpy(file_externals->firstline, linebuff, firstline_length);
+    g_strlcpy(file_externals->firstline, linebuff, firstline_length+1);
     file_externals->firstline_length = firstline_length;
 
 
@@ -226,12 +232,13 @@ int catapult_dct2000_open(wtap *wth, int *err, gchar **err_info _U_)
         return 0;
     }
 
+    /* Allocate struct and fill in timestamp */
     wth->capture.catapult_dct2000 = g_malloc(sizeof(catapult_dct2000_t));
     wth->capture.catapult_dct2000->start_secs = timestamp;
     wth->capture.catapult_dct2000->start_usecs = usecs;
 
     /* Copy this second line into buffer so could write out later */
-    strncpy(file_externals->secondline, linebuff, file_externals->secondline_length);
+    g_strlcpy(file_externals->secondline, linebuff, file_externals->secondline_length+1);
 
 
     /************************************************************/
@@ -267,7 +274,7 @@ int catapult_dct2000_open(wtap *wth, int *err, gchar **err_info _U_)
 
 
 /**************************************************/
-/* Read function.                                 */
+/* Read packet function.                          */
 /* Look for and read the next usable packet       */
 /* - return TRUE and details if found             */
 /**************************************************/
@@ -289,7 +296,7 @@ gboolean catapult_dct2000_read(wtap *wth, int *err, gchar **err_info _U_,
         return FALSE;
     }
 
-    /* Search for a line containing a usable message */
+    /* Search for a line containing a usable packet */
     while (1)
     {
         int line_length, seconds, useconds, data_chars;
@@ -308,7 +315,7 @@ gboolean catapult_dct2000_read(wtap *wth, int *err, gchar **err_info _U_,
         /* Read a new line from file into linebuff */
         if (read_new_line(wth->fh, &offset, &line_length) == FALSE)
         {
-            /* Get out when no more lines to be read */
+            /* Get out if no more lines can be read */
             break;
         }
 
@@ -322,10 +329,10 @@ gboolean catapult_dct2000_read(wtap *wth, int *err, gchar **err_info _U_,
             int n;
             int stub_offset = 0;
             line_prefix_info_t *line_prefix_info;
-            char timestamp_string[32];
+            char timestamp_string[MAX_TIMESTAMP_LEN+1];
             gint64 *pkey = NULL;
 
-            sprintf(timestamp_string, "%d.%04d", seconds, useconds/100);
+            g_snprintf(timestamp_string, 32, "%d.%04d", seconds, useconds/100);
 
             /* All packets go to Catapult DCT2000 stub dissector */
             wth->phdr.pkt_encap = WTAP_ENCAP_CATAPULT_DCT2000;
@@ -385,7 +392,7 @@ gboolean catapult_dct2000_read(wtap *wth, int *err, gchar **err_info _U_,
 
             /* Create and use buffer for contents before time */
             line_prefix_info->before_time = g_malloc(before_time_offset+1);
-            strncpy(line_prefix_info->before_time, linebuff, before_time_offset);
+            g_strlcpy(line_prefix_info->before_time, linebuff, before_time_offset);
             line_prefix_info->before_time[before_time_offset] = '\0';
 
             /* Create and use buffer for contents before time.
@@ -398,14 +405,15 @@ gboolean catapult_dct2000_read(wtap *wth, int *err, gchar **err_info _U_,
             }
             else
             {
+                /* Allocate & write buffer for line between timestamp and data */
                 line_prefix_info->after_time = g_malloc(dollar_offset - after_time_offset);
-                strncpy(line_prefix_info->after_time, linebuff+after_time_offset,
-                        dollar_offset - after_time_offset);
+                g_strlcpy(line_prefix_info->after_time, linebuff+after_time_offset,
+                          dollar_offset - after_time_offset);
                 line_prefix_info->after_time[dollar_offset - after_time_offset-1] = '\0';
             }
 
             /* Add packet entry into table */
-            pkey = g_malloc(sizeof(pkey));
+            pkey = g_malloc(sizeof(*pkey));
             *pkey = this_offset;
             g_hash_table_insert(file_externals->packet_prefix_table, pkey, line_prefix_info);
 
@@ -448,7 +456,7 @@ catapult_dct2000_seek_read(wtap *wth, gint64 seek_off,
         return FALSE;
     }
 
-    /* Re-read whole line (this should succeed) */
+    /* Re-read whole line (this really should succeed) */
     if (read_new_line(wth->random_fh, &offset, &length) == FALSE)
     {
         return FALSE;
@@ -463,7 +471,7 @@ catapult_dct2000_seek_read(wtap *wth, gint64 seek_off,
         int n;
         int stub_offset = 0;
         char timestamp_string[32];
-        sprintf(timestamp_string, "%d.%04d", seconds, useconds/100);
+        g_snprintf(timestamp_string, 32, "%d.%04d", seconds, useconds/100);
 
         /* Make sure all packets go to catapult dct2000 dissector */
         wth->phdr.pkt_encap = WTAP_ENCAP_CATAPULT_DCT2000;
@@ -499,9 +507,9 @@ catapult_dct2000_seek_read(wtap *wth, gint64 seek_off,
 }
 
 
-/******************************************/
-/* Free dct2000-specific capture info     */
-/******************************************/
+/***************************************************************************/
+/* Free dct2000-specific capture info from file that was open for reading  */
+/***************************************************************************/
 void catapult_dct2000_close(wtap *wth)
 {
     /* Look up externals for this file */
@@ -561,7 +569,9 @@ int catapult_dct2000_dump_can_write_encap(int encap)
         case WTAP_ENCAP_CATAPULT_DCT2000:
             /* We support this */
             return 0;
+
         default:
+            /* But don't write to any other formats... */
             return WTAP_ERR_UNSUPPORTED_ENCAP;
     }
 }
@@ -570,9 +580,30 @@ int catapult_dct2000_dump_can_write_encap(int encap)
 /*****************************************/
 /* Write a single packet out to the file */
 /*****************************************/
+
+static gboolean do_fwrite(const void *data, size_t size, size_t count, FILE *stream, int *err_p)
+{
+    size_t nwritten;
+
+    nwritten = fwrite(data, size, count, stream);
+    if (nwritten != count) {
+        if (nwritten == 0 && ferror(stream))
+        {
+            *err_p = errno;
+        }
+        else
+        {
+            *err_p = WTAP_ERR_SHORT_WRITE;
+        }
+
+        return FALSE;
+    }
+    return TRUE;
+}
+
 gboolean catapult_dct2000_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
                                const union wtap_pseudo_header *pseudo_header,
-                               const guchar *pd, int *err _U_)
+                               const guchar *pd, int *err)
 {
     guint32 n;
     line_prefix_info_t *prefix = NULL;
@@ -591,14 +622,26 @@ gboolean catapult_dct2000_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
         wdh->dump.dct2000 = g_malloc(sizeof(catapult_dct2000_t));
 
         /* Write out saved first line */
-        fwrite(file_externals->firstline, 1, file_externals->firstline_length, wdh->fh);
-        fwrite("\n", 1, 1, wdh->fh);
+        if (! do_fwrite(file_externals->firstline, 1, file_externals->firstline_length, wdh->fh, err))
+        {
+            return FALSE;
+        }
+        if (! do_fwrite("\n", 1, 1, wdh->fh, err))
+        {
+            return FALSE;
+        }
 
         /* Also write out saved second line with timestamp corresponding to the
            opening time of the log.
         */
-        fwrite(file_externals->secondline, 1, file_externals->secondline_length, wdh->fh);
-        fwrite("\n", 1, 1, wdh->fh);
+        if (! do_fwrite(file_externals->secondline, 1, file_externals->secondline_length, wdh->fh, err))
+        {
+            return FALSE;
+        }
+        if (! do_fwrite("\n", 1, 1, wdh->fh, err))
+        {
+            return FALSE;
+        }
 
         /* Allocate the dct2000-specific dump structure */
         wdh->dump.dct2000 = g_malloc(sizeof(catapult_dct2000_t));
@@ -622,7 +665,10 @@ gboolean catapult_dct2000_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
                                                       (const void*)&(pseudo_header->dct2000.seek_off));
 
     /* Write out text before timestamp */
-    fwrite(prefix->before_time, 1, strlen(prefix->before_time), wdh->fh);
+    if (! do_fwrite(prefix->before_time, 1, strlen(prefix->before_time), wdh->fh, err))
+    {
+        return FALSE;
+    }
 
     /* Calculate time of this packet to write, relative to start of dump */
     if (phdr->ts.nsecs >= wdh->dump.dct2000->start_time.nsecs)
@@ -639,16 +685,25 @@ gboolean catapult_dct2000_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
     }
 
     /* Write out the calculated timestamp */
-    fwrite(time_string, 1, strlen(time_string), wdh->fh);
+    if (! do_fwrite(time_string, 1, strlen(time_string), wdh->fh, err))
+    {
+        return FALSE;
+    }
 
     /* Write out text between timestamp and start of hex data */
     if (prefix->after_time == NULL)
     {
-        fwrite(" l ", 1, strlen(" l "), wdh->fh);
+        if (! do_fwrite(" l ", 1, strlen(" l "), wdh->fh, err))
+        {
+            return FALSE;
+        }
     }
     else
     {
-        fwrite(prefix->after_time, 1, strlen(prefix->after_time), wdh->fh);
+        if (! do_fwrite(prefix->after_time, 1, strlen(prefix->after_time), wdh->fh, err))
+        {
+            return FALSE;
+        }
     }
 
 
@@ -684,7 +739,10 @@ gboolean catapult_dct2000_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
 
     /**************************************/
     /* Remainder is encapsulated protocol */
-    fwrite("$", 1, 1, wdh->fh);
+    if (! do_fwrite("$", 1, 1, wdh->fh, err))
+    {
+        return FALSE;
+    }
 
     /* Each binary byte is written out as 2 hex string chars */ 
     for (; n < phdr->len; n++)
@@ -694,11 +752,17 @@ gboolean catapult_dct2000_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
         c[1] = char_from_hex((guchar)(pd[n] & 0x0f));
 
         /* Write both hex chars of byte together */
-        fwrite(c, 1, 2, wdh->fh);
+        if (! do_fwrite(c, 1, 2, wdh->fh, err))
+        {
+            return FALSE;
+        }
     }
 
     /* End the line */
-    fwrite("\n", 1, 1, wdh->fh);
+    if (! do_fwrite("\n", 1, 1, wdh->fh, err))
+    {
+        return FALSE;
+    }
 
     return TRUE;
 }
@@ -784,7 +848,7 @@ gboolean parse_line(gint line_length, gint *seconds, gint *useconds,
     /* Read context name until find '.' */
     for (n=0; linebuff[n] != '.' && (n < MAX_CONTEXT_NAME) && (n+1 < line_length); n++)
     {
-        if (!isalnum((int)linebuff[n]) && (linebuff[n] != '_'))
+        if (!isalnum((guchar)linebuff[n]) && (linebuff[n] != '_'))
         {
             return FALSE;
         }
@@ -810,7 +874,7 @@ gboolean parse_line(gint line_length, gint *seconds, gint *useconds,
          (linebuff[n] != '/') && (port_digits <= MAX_PORT_DIGITS) && (n+1 < line_length);
          n++, port_digits++)
     {
-        if (!isdigit((int)linebuff[n]))
+        if (!isdigit((guchar)linebuff[n]))
         {
             return FALSE;
         }
@@ -837,7 +901,7 @@ gboolean parse_line(gint line_length, gint *seconds, gint *useconds,
          (linebuff[n] != '/') && (protocol_chars < MAX_PROTOCOL_NAME) && (n < line_length);
          n++, protocol_chars++)
     {
-        if (!isalnum((int)linebuff[n]) && linebuff[n] != '_')
+        if (!isalnum((guchar)linebuff[n]) && linebuff[n] != '_')
         {
             return FALSE;
         }
@@ -861,10 +925,10 @@ gboolean parse_line(gint line_length, gint *seconds, gint *useconds,
 
     /* Following the / is the variant number.  No digits indicate 1 */
     for (variant_digits = 0;
-         (isdigit((int)linebuff[n])) && (variant_digits <= MAX_VARIANT_DIGITS) && (n+1 < line_length);
+         (isdigit((guchar)linebuff[n])) && (variant_digits <= MAX_VARIANT_DIGITS) && (n+1 < line_length);
          n++, variant_digits++)
     {
-        if (!isdigit((int)linebuff[n]))
+        if (!isdigit((guchar)linebuff[n]))
         {
             return FALSE;
         }
@@ -881,7 +945,7 @@ gboolean parse_line(gint line_length, gint *seconds, gint *useconds,
     }
     else
     {
-        strcpy(variant_name, "1");
+        g_strlcpy(variant_name, "1", MAX_VARIANT_DIGITS+1);
     }
 
 
@@ -893,11 +957,11 @@ gboolean parse_line(gint line_length, gint *seconds, gint *useconds,
         n++;
 
         for (outhdr_chars = 0;
-             (isdigit((int)linebuff[n]) || linebuff[n] == ',') &&
+             (isdigit((guchar)linebuff[n]) || linebuff[n] == ',') &&
              (outhdr_chars <= MAX_OUTHDR_NAME) && (n+1 < line_length);
              n++, outhdr_chars++)
         {
-            if (!isdigit((int)linebuff[n]) && (linebuff[n] != ','))
+            if (!isdigit((guchar)linebuff[n]) && (linebuff[n] != ','))
             {
                 return FALSE;
             }
@@ -920,7 +984,8 @@ gboolean parse_line(gint line_length, gint *seconds, gint *useconds,
     if ((strcmp(protocol_name, "ip") == 0) ||
         (strcmp(protocol_name, "sctp") == 0) ||
         (strcmp(protocol_name, "gre") == 0) ||
-        (strcmp(protocol_name, "mipv6") == 0))
+        (strcmp(protocol_name, "mipv6") == 0) ||
+        (strcmp(protocol_name, "igmp") == 0))
     {
         *encap = WTAP_ENCAP_RAW_IP;
     }
@@ -930,7 +995,8 @@ gboolean parse_line(gint line_length, gint *seconds, gint *useconds,
     if ((strcmp(protocol_name, "fp") == 0) ||
         (strcmp(protocol_name, "fp_r4") == 0) ||
         (strcmp(protocol_name, "fp_r5") == 0) ||
-        (strcmp(protocol_name, "fp_r6") == 0))
+        (strcmp(protocol_name, "fp_r6") == 0) ||
+        (strcmp(protocol_name, "fp_r7") == 0))
     {
         if ((variant > 256) && (variant % 256 == 3))
         {
@@ -1022,19 +1088,17 @@ gboolean parse_line(gint line_length, gint *seconds, gint *useconds,
 
         /* Read consecutive hex chars into atm header buffer */
         for (;
-             (isalnum((int)linebuff[n]) &&
+             ((linebuff[n] >= '0') && (linebuff[n] <= '?') &&
               (n < line_length) &&
               (header_chars_seen < AAL_HEADER_CHARS));
              n++, header_chars_seen++)
         {
             aal_header_chars[header_chars_seen] = linebuff[n];
-        }
-
-        /* Sometimes see strange encoding of cid in last (non-digit) character */
-        if (header_chars_seen == (AAL_HEADER_CHARS-1))
-        {
-            aal_header_chars[AAL_HEADER_CHARS-1] = linebuff[n];
-            header_chars_seen++;
+            /* Next 6 characters after '9' are mapped to a->f */
+            if (!isdigit((guchar)linebuff[n]))
+            {
+                aal_header_chars[header_chars_seen] = 'a' + (linebuff[n] - '9') -1;
+            }
         }
 
         if (header_chars_seen != AAL_HEADER_CHARS || n >= line_length)
@@ -1073,7 +1137,7 @@ gboolean parse_line(gint line_length, gint *seconds, gint *useconds,
     /* Find and read the timestamp                                       */
 
     /* Now scan to the next digit, which should be the start of the timestamp */
-    for (; !isdigit((int)linebuff[n]) && (n < line_length); n++);
+    for (; !isdigit((guchar)linebuff[n]) && (n < line_length); n++);
     if (n >= line_length)
     {
         return FALSE;
@@ -1088,7 +1152,7 @@ gboolean parse_line(gint line_length, gint *seconds, gint *useconds,
          (n < line_length);
          n++, seconds_chars++)
     {
-        if (!isdigit((int)linebuff[n]))
+        if (!isdigit((guchar)linebuff[n]))
         {
             /* Found a non-digit before decimal point. Fail */
             return FALSE;
@@ -1120,7 +1184,7 @@ gboolean parse_line(gint line_length, gint *seconds, gint *useconds,
          (n < line_length);
          n++, subsecond_decimals_chars++)
     {
-        if (!isdigit((int)linebuff[n]))
+        if (!isdigit((guchar)linebuff[n]))
         {
             return FALSE;
         }
@@ -1176,8 +1240,8 @@ int write_stub_header(guchar *frame_buffer, char *timestamp_string,
                       packet_direction_t direction, int encap)
 {
     int stub_offset = 0;
-    
-    strcpy((char*)frame_buffer, context_name);
+
+    g_strlcpy((char*)frame_buffer, context_name, MAX_CONTEXT_NAME+1);
     stub_offset += (strlen(context_name) + 1);
 
     /* Context port number */
@@ -1185,19 +1249,19 @@ int write_stub_header(guchar *frame_buffer, char *timestamp_string,
     stub_offset++;
 
     /* Timestamp within file */
-    strcpy((char*)&frame_buffer[stub_offset], timestamp_string);
+    g_strlcpy((char*)&frame_buffer[stub_offset], timestamp_string, MAX_TIMESTAMP_LEN+1);
     stub_offset += (strlen(timestamp_string) + 1);
 
     /* Protocol name */
-    strcpy((char*)&frame_buffer[stub_offset], protocol_name);
+    g_strlcpy((char*)&frame_buffer[stub_offset], protocol_name, MAX_PROTOCOL_NAME+1);
     stub_offset += (strlen(protocol_name) + 1);
 
     /* Protocol variant number (as string) */
-    strcpy((void*)&frame_buffer[stub_offset], variant_name);
+    g_strlcpy((void*)&frame_buffer[stub_offset], variant_name, MAX_VARIANT_DIGITS+1);
     stub_offset += (strlen(variant_name) + 1);
 
     /* Outhdr */
-    strcpy((char*)&frame_buffer[stub_offset], outhdr_name);
+    g_strlcpy((char*)&frame_buffer[stub_offset], outhdr_name, MAX_OUTHDR_NAME+1);
     stub_offset += (strlen(outhdr_name) + 1);
 
     /* Direction */
@@ -1286,7 +1350,7 @@ void set_aal_info(union wtap_pseudo_header *pseudo_header, packet_direction_t di
 
     /* cid is usually last byte.  Unless last char is not hex digit, in which
        case cid is derived from last char in ascii */
-    if (isalnum((int)aal_header_chars[11]))
+    if (isalnum((guchar)aal_header_chars[11]))
     {
         pseudo_header->dct2000.inner_pseudo_header.atm.aal2_cid =
             ((hex_from_char(aal_header_chars[10]) << 4) |