Tighten up format string used for date/time parse;
[obnox/wireshark/wip.git] / wiretap / catapult_dct2000.c
index cb7fef5785c53128179397c741ae05d07eb2d89c..865d9b9826e04ef50f45a6a9c62e6497519afb54 100644 (file)
@@ -111,14 +111,13 @@ 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,
                                            union wtap_pseudo_header *pseudo_header,
-                                           guchar *pd, int length,
+                                           guint8 *pd, int length,
                                            int *err, gchar **err_info);
 static void catapult_dct2000_close(wtap *wth);
 
 static gboolean catapult_dct2000_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
                                       const union wtap_pseudo_header *pseudo_header,
-                                      const guchar *pd, int *err);
-static gboolean catapult_dct2000_dump_close(wtap_dumper *wdh, int *err);
+                                      const guint8 *pd, int *err);
 
 
 /************************************************************/
@@ -136,13 +135,14 @@ static gboolean parse_line(char *linebuff, gint line_length,
                            gchar *context_name, guint8 *context_portp,
                            gchar *protocol_name, gchar *variant_name,
                            gchar *outhdr_name);
-static int write_stub_header(guchar *frame_buffer, char *timestamp_string,
+static int write_stub_header(guint8 *frame_buffer, char *timestamp_string,
                              packet_direction_t direction, int encap,
                              gchar *context_name, guint8 context_port,
                              gchar *protocol_name, gchar *variant_name,
                              gchar *outhdr_name);
-static guchar hex_from_char(gchar c);
-static gchar char_from_hex(guchar hex);
+static guint8 hex_from_char(gchar c);
+static guint8 hex_byte_from_chars(gchar *c);
+static gchar char_from_hex(guint8 hex);
 
 static void set_pseudo_header_info(wtap *wth,
                                    int pkt_encap,
@@ -169,14 +169,15 @@ static gboolean free_line_prefix_info(gpointer key, gpointer value, gpointer use
 /********************************************/
 /* Open file (for reading)                 */
 /********************************************/
-int catapult_dct2000_open(wtap *wth, int *err, gchar **err_info _U_)
+int
+catapult_dct2000_open(wtap *wth, int *err, gchar **err_info _U_)
 {
     gint64  offset = 0;
     time_t  timestamp;
     guint32 usecs;
     gint firstline_length = 0;
     dct2000_file_externals_t *file_externals;
-    gchar linebuff[MAX_LINE_LENGTH];
+    static gchar linebuff[MAX_LINE_LENGTH];
 
     /* Clear errno before reading from the file */
     errno = 0;
@@ -257,7 +258,7 @@ int catapult_dct2000_open(wtap *wth, int *err, gchar **err_info _U_)
         g_hash_table_new(packet_offset_hash_func, packet_offset_equal);
 
     /* Set this wtap to point to the file_externals */
-    wth->capture.generic = (void*)file_externals;
+    wth->priv = (void*)file_externals;
 
     *err = errno;
     return 1;
@@ -269,7 +270,8 @@ int catapult_dct2000_open(wtap *wth, int *err, gchar **err_info _U_)
 /* Look for and read the next usable packet       */
 /* - return TRUE and details if found             */
 /**************************************************/
-gboolean catapult_dct2000_read(wtap *wth, int *err, gchar **err_info _U_,
+static gboolean
+catapult_dct2000_read(wtap *wth, int *err, gchar **err_info _U_,
                                gint64 *data_offset)
 {
     gint64 offset = wth->data_offset;
@@ -279,7 +281,7 @@ gboolean catapult_dct2000_read(wtap *wth, int *err, gchar **err_info _U_,
 
     /* Get wtap external structure for this wtap */
     dct2000_file_externals_t *file_externals =
-        (dct2000_file_externals_t*)wth->capture.generic;
+        (dct2000_file_externals_t*)wth->priv;
 
     /* There *has* to be an entry for this wth */
     if (!file_externals) {
@@ -291,7 +293,7 @@ gboolean catapult_dct2000_read(wtap *wth, int *err, gchar **err_info _U_,
         int line_length, seconds, useconds, data_chars;
         int is_comment = FALSE;
         gint64 this_offset = offset;
-        gchar linebuff[MAX_LINE_LENGTH+1];
+        static gchar linebuff[MAX_LINE_LENGTH+1];
         gchar aal_header_chars[AAL_HEADER_CHARS];
         gchar context_name[MAX_CONTEXT_NAME];
         guint8 context_port;
@@ -323,7 +325,7 @@ gboolean catapult_dct2000_read(wtap *wth, int *err, gchar **err_info _U_,
                        aal_header_chars,
                        context_name, &context_port,
                        protocol_name, variant_name, outhdr_name)) {
-            guchar *frame_buffer;
+            guint8 *frame_buffer;
             int n;
             int stub_offset = 0;
             line_prefix_info_t *line_prefix_info;
@@ -361,7 +363,7 @@ gboolean catapult_dct2000_read(wtap *wth, int *err, gchar **err_info _U_,
                                 strlen(protocol_name)+1 +    /* Protocol name */
                                 1 +                          /* direction */
                                 1 +                          /* encap */
-                                is_comment ? data_chars : (data_chars/2));
+                                (is_comment ? data_chars : (data_chars/2)));
             frame_buffer = buffer_start_ptr(wth->frame_buffer);
 
 
@@ -383,8 +385,7 @@ gboolean catapult_dct2000_read(wtap *wth, int *err, gchar **err_info _U_,
                 /* Copy data into buffer, converting from ascii hex */
                 for (n=0; n <= data_chars; n+=2) {
                     frame_buffer[stub_offset + n/2] =
-                        (hex_from_char(linebuff[dollar_offset+n]) << 4) |
-                         hex_from_char(linebuff[dollar_offset+n+1]);
+                        hex_byte_from_chars(linebuff+dollar_offset+n);
                 }
             }
             else {
@@ -445,12 +446,12 @@ gboolean catapult_dct2000_read(wtap *wth, int *err, gchar **err_info _U_,
 /**************************************************/
 static gboolean
 catapult_dct2000_seek_read(wtap *wth, gint64 seek_off,
-                           union wtap_pseudo_header *pseudo_header, guchar *pd,
+                           union wtap_pseudo_header *pseudo_header, guint8 *pd,
                            int length, int *err, gchar **err_info)
 {
     gint64 offset = wth->data_offset;
     long dollar_offset, before_time_offset, after_time_offset;
-    gchar linebuff[MAX_LINE_LENGTH+1];
+    static gchar linebuff[MAX_LINE_LENGTH+1];
     gchar aal_header_chars[AAL_HEADER_CHARS];
     gchar context_name[MAX_CONTEXT_NAME];
     guint8 context_port;
@@ -506,8 +507,7 @@ catapult_dct2000_seek_read(wtap *wth, gint64 seek_off,
             /***********************************************************/
             /* Copy packet data into buffer, converting from ascii hex */
             for (n=0; n <= data_chars; n+=2) {
-                pd[stub_offset + n/2] = (hex_from_char(linebuff[dollar_offset+n]) << 4) |
-                                         hex_from_char(linebuff[dollar_offset+n+1]);
+                pd[stub_offset + n/2] = hex_byte_from_chars(linebuff+dollar_offset+n);
             }
         }
         else {
@@ -538,11 +538,12 @@ catapult_dct2000_seek_read(wtap *wth, gint64 seek_off,
 /***************************************************************************/
 /* Free dct2000-specific capture info from file that was open for reading  */
 /***************************************************************************/
-void catapult_dct2000_close(wtap *wth)
+static void
+catapult_dct2000_close(wtap *wth)
 {
     /* Get externals for this file */
     dct2000_file_externals_t *file_externals =
-        (dct2000_file_externals_t*)wth->capture.generic;
+        (dct2000_file_externals_t*)wth->priv;
 
     /* The entry *has* to be found */
     if (!file_externals) {
@@ -554,9 +555,6 @@ void catapult_dct2000_close(wtap *wth)
                                 free_line_prefix_info, NULL);
     /* Free up its line prefix table */
     g_hash_table_destroy(file_externals->packet_prefix_table);
-
-    /* Can now free this too */
-    g_free(file_externals);
 }
 
 
@@ -566,15 +564,20 @@ void catapult_dct2000_close(wtap *wth)
 /* Dump functions          */
 /***************************/
 
+typedef struct {
+    gboolean           first_packet_written;
+    struct wtap_nstime start_time;
+} dct2000_dump_t;
+
 /*****************************************************/
 /* The file that we are writing to has been opened.  */
 /* Set other dump callbacks.                         */
 /*****************************************************/
-gboolean catapult_dct2000_dump_open(wtap_dumper *wdh, gboolean cant_seek _U_, int *err _U_)
+gboolean
+catapult_dct2000_dump_open(wtap_dumper *wdh, int *err _U_)
 {
     /* Fill in other dump callbacks */
     wdh->subtype_write = catapult_dct2000_dump;
-    wdh->subtype_close = catapult_dct2000_dump_close;
 
     return TRUE;
 }
@@ -583,7 +586,8 @@ gboolean catapult_dct2000_dump_open(wtap_dumper *wdh, gboolean cant_seek _U_, in
 /* Respond to queries about which encap types we support */
 /* writing to.                                           */
 /*********************************************************/
-int catapult_dct2000_dump_can_write_encap(int encap)
+int
+catapult_dct2000_dump_can_write_encap(int encap)
 {
     switch (encap) {
         case WTAP_ENCAP_CATAPULT_DCT2000:
@@ -601,69 +605,57 @@ 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,
+static gboolean
+catapult_dct2000_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
                                const union wtap_pseudo_header *pseudo_header,
-                               const guchar *pd, int *err)
+                               const guint8 *pd, int *err)
 {
     guint32 n;
     line_prefix_info_t *prefix = NULL;
     gchar time_string[16];
     gboolean is_comment;
+    dct2000_dump_t *dct2000;
 
     /******************************************************/
     /* Get the file_externals structure for this file */
     /* Find wtap external structure for this wtap */
     dct2000_file_externals_t *file_externals =
-        (dct2000_file_externals_t*)pseudo_header->dct2000.wth->capture.generic;
+        (dct2000_file_externals_t*)pseudo_header->dct2000.wth->priv;
 
-    if (wdh->dump.dct2000 == NULL) {
+    dct2000 = (dct2000_dump_t *)wdh->priv;
+    if (dct2000 == NULL) {
 
         /* Write out saved first line */
-        if (!do_fwrite(file_externals->firstline, 1, file_externals->firstline_length, wdh->fh, err)) {
+        if (!wtap_dump_file_write(wdh, file_externals->firstline,
+                                  file_externals->firstline_length, err)) {
             return FALSE;
         }
-        if (!do_fwrite("\n", 1, 1, wdh->fh, err)) {
+        if (!wtap_dump_file_write(wdh, "\n", 1, err)) {
             return FALSE;
         }
 
         /* Also write out saved second line with timestamp corresponding to the
            opening time of the log.
         */
-        if (!do_fwrite(file_externals->secondline, 1, file_externals->secondline_length, wdh->fh, err)) {
+        if (!wtap_dump_file_write(wdh, file_externals->secondline,
+                                  file_externals->secondline_length, err)) {
             return FALSE;
         }
-        if (!do_fwrite("\n", 1, 1, wdh->fh, err)) {
+        if (!wtap_dump_file_write(wdh, "\n", 1, err)) {
             return FALSE;
         }
 
         /* Allocate the dct2000-specific dump structure */
-        wdh->dump.dct2000 = g_malloc(sizeof(dct2000_dump_t));
+        dct2000 = (dct2000_dump_t *)g_malloc(sizeof(dct2000_dump_t));
+        wdh->priv = (void *)dct2000;
 
         /* Copy time of beginning of file */
-        wdh->dump.dct2000->start_time.secs = file_externals->start_secs;
-        wdh->dump.dct2000->start_time.nsecs =
+        dct2000->start_time.secs = file_externals->start_secs;
+        dct2000->start_time.nsecs =
             (file_externals->start_usecs * 1000);
 
         /* Set flag do don't write header out again */
-        wdh->dump.dct2000->first_packet_written = TRUE;
+        dct2000->first_packet_written = TRUE;
     }
 
 
@@ -675,7 +667,8 @@ gboolean catapult_dct2000_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
                                                       (const void*)&(pseudo_header->dct2000.seek_off));
 
     /* Write out text before timestamp */
-    if (!do_fwrite(prefix->before_time, 1, strlen(prefix->before_time), wdh->fh, err)) {
+    if (!wtap_dump_file_write(wdh, prefix->before_time,
+                              strlen(prefix->before_time), err)) {
         return FALSE;
     }
 
@@ -683,30 +676,31 @@ gboolean catapult_dct2000_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
     is_comment = (strstr(prefix->before_time, "/////") != NULL);
 
     /* Calculate time of this packet to write, relative to start of dump */
-    if (phdr->ts.nsecs >= wdh->dump.dct2000->start_time.nsecs) {
+    if (phdr->ts.nsecs >= dct2000->start_time.nsecs) {
         g_snprintf(time_string, 16, "%ld.%04d",
-                  (long)(phdr->ts.secs - wdh->dump.dct2000->start_time.secs),
-                  (phdr->ts.nsecs - wdh->dump.dct2000->start_time.nsecs) / 100000);
+                  (long)(phdr->ts.secs - dct2000->start_time.secs),
+                  (phdr->ts.nsecs - dct2000->start_time.nsecs) / 100000);
     }
     else {
         g_snprintf(time_string, 16, "%ld.%04u",
-                  (long)(phdr->ts.secs - wdh->dump.dct2000->start_time.secs-1),
-                  ((1000000000 + (phdr->ts.nsecs / 100000)) - (wdh->dump.dct2000->start_time.nsecs / 100000)) % 10000);
+                  (long)(phdr->ts.secs - dct2000->start_time.secs-1),
+                  ((1000000000 + (phdr->ts.nsecs / 100000)) - (dct2000->start_time.nsecs / 100000)) % 10000);
     }
 
     /* Write out the calculated timestamp */
-    if (!do_fwrite(time_string, 1, strlen(time_string), wdh->fh, err)) {
+    if (!wtap_dump_file_write(wdh, time_string, strlen(time_string), err)) {
         return FALSE;
     }
 
     /* Write out text between timestamp and start of hex data */
     if (prefix->after_time == NULL) {
-        if (!do_fwrite(" l ", 1, strlen(" l "), wdh->fh, err)) {
+        if (!wtap_dump_file_write(wdh, " l ", strlen(" l "), err)) {
             return FALSE;
         }
     }
     else {
-        if (!do_fwrite(prefix->after_time, 1, strlen(prefix->after_time), wdh->fh, err)) {
+        if (!wtap_dump_file_write(wdh, prefix->after_time,
+                                  strlen(prefix->after_time), err)) {
             return FALSE;
         }
     }
@@ -744,7 +738,7 @@ gboolean catapult_dct2000_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
 
     /**************************************/
     /* Remainder is encapsulated protocol */
-    if (!do_fwrite("$", 1, 1, wdh->fh, err)) {
+    if (!wtap_dump_file_write(wdh, "$", 1, err)) {
         return FALSE;
     }
 
@@ -752,11 +746,11 @@ gboolean catapult_dct2000_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
         /* Each binary byte is written out as 2 hex string chars */ 
         for (; n < phdr->len; n++) {
             gchar c[2];
-            c[0] = char_from_hex((guchar)(pd[n] >> 4));
-            c[1] = char_from_hex((guchar)(pd[n] & 0x0f));
+            c[0] = char_from_hex((guint8)(pd[n] >> 4));
+            c[1] = char_from_hex((guint8)(pd[n] & 0x0f));
 
             /* Write both hex chars of byte together */
-            if (!do_fwrite(c, 1, 2, wdh->fh, err)) {
+            if (!wtap_dump_file_write(wdh, c, 2, err)) {
                 return FALSE;
             }
         }
@@ -767,14 +761,14 @@ gboolean catapult_dct2000_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
             c[0] = pd[n];
 
             /* Write both hex chars of byte together */
-            if (!do_fwrite(c, 1, 1, wdh->fh, err)) {
+            if (!wtap_dump_file_write(wdh, c, 1, err)) {
                 return FALSE;
             }
         }
     }
 
     /* End the line */
-    if (!do_fwrite("\n", 1, 1, wdh->fh, err)) {
+    if (!wtap_dump_file_write(wdh, "\n", 1, err)) {
         return FALSE;
     }
 
@@ -782,17 +776,6 @@ gboolean catapult_dct2000_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
 }
 
 
-/******************************************************/
-/* Close a file we've been writing to.                */
-/******************************************************/
-static gboolean catapult_dct2000_dump_close(wtap_dumper *wdh _U_, int *err _U_)
-{
-    return TRUE;
-}
-
-
-
-
 /****************************/
 /* Private helper functions */
 /****************************/
@@ -803,20 +786,20 @@ static gboolean catapult_dct2000_dump_close(wtap_dumper *wdh _U_, int *err _U_)
 /* - on return 'offset' will point to the next position to read from  */
 /* - return TRUE if this read is successful                           */
 /**********************************************************************/
-gboolean read_new_line(FILE_T fh, gint64 *offset, gint *length,
+static gboolean
+read_new_line(FILE_T fh, gint64 *offset, gint *length,
                        gchar *linebuff, size_t linebuffsize)
 {
-    char *result;
-
     /* Read in a line */
-    result = file_gets(linebuff, (int)linebuffsize - 1, fh);
+    gint64 pos_before = file_tell(fh);
+    char *result = file_gets(linebuff, (int)linebuffsize - 1, fh);
     if (result == NULL) {
         /* No characters found, or error */
         return FALSE;
     }
 
-    /* Set length and offset.. */
-    *length = (gint)strlen(linebuff);
+    /* Set length (avoiding strlen()) and offset.. */
+    *length = (gint)(file_tell(fh) - pos_before);
     *offset = *offset + *length;
 
     /* ...but don't want to include newline in line length */
@@ -836,7 +819,8 @@ gboolean read_new_line(FILE_T fh, gint64 *offset, gint *length,
 /* - data position and length                                         */
 /* Return TRUE if this packet looks valid and can be displayed        */
 /**********************************************************************/
-static gboolean parse_line(gchar *linebuff, gint line_length,
+static gboolean
+parse_line(gchar *linebuff, gint line_length,
                            gint *seconds, gint *useconds,
                            long *before_time_offset, long *after_time_offset,
                            long *data_offset, gint *data_chars,
@@ -848,7 +832,7 @@ static gboolean parse_line(gchar *linebuff, gint line_length,
                            gchar *outhdr_name)
 {
     int  n = 0;
-    int  port_digits = 0;
+    int  port_digits;
     char port_number_string[MAX_PORT_DIGITS+1];
     int  variant_digits = 0;
     int  variant = 1;
@@ -888,11 +872,10 @@ static gboolean parse_line(gchar *linebuff, gint line_length,
         return FALSE;
     }
 
-    /* Reset strings (that won't be set be comments) */
-    g_strlcpy(variant_name, "0", MAX_VARIANT_DIGITS);
-    g_strlcpy(outhdr_name, "", MAX_OUTHDR_NAME);
-    port_digits = 1;
-    g_strlcpy(port_number_string, "0", MAX_PORT_DIGITS);
+    /* Reset strings (that won't be set by comments) */
+    variant_name[0] = '\0';
+    outhdr_name[0] = '\0';
+    port_number_string[0] = '\0';
 
     if (!(*is_comment)) {
         /* '.' must follow context name */
@@ -1016,7 +999,8 @@ static gboolean parse_line(gchar *linebuff, gint line_length,
         (strcmp(protocol_name, "fp_r4") == 0) ||
         (strcmp(protocol_name, "fp_r5") == 0) ||
         (strcmp(protocol_name, "fp_r6") == 0) ||
-        (strcmp(protocol_name, "fp_r7") == 0)) {
+        (strcmp(protocol_name, "fp_r7") == 0) ||
+        (strcmp(protocol_name, "fp_r8") == 0)) {
 
         if ((variant > 256) && (variant % 256 == 3)) {
             /* FP over udp is contained in IPPrim... */
@@ -1034,7 +1018,6 @@ static gboolean parse_line(gchar *linebuff, gint line_length,
         atm_header_present = TRUE;
     }
 
-
     else
     if (strcmp(protocol_name, "ppp") == 0) {
         *encap = WTAP_ENCAP_PPP;
@@ -1113,14 +1096,28 @@ static gboolean parse_line(gchar *linebuff, gint line_length,
         }
     }
 
-    /* Scan ahead to the next space */
-    for (; (linebuff[n] != ' ') && (n+1 < line_length); n++);
-    if (n+1 >= line_length) {
-        return FALSE;
-    }
-    /* Skip it */
+    /* Skip next '/' */
     n++;
 
+    /* If there is a number, skip all info to next '/'.
+       TODO: for IP encapsulation, should store PDCP ueid, drb in pseudo info
+       and display dct2000 dissector... */
+    if (isdigit(linebuff[n])) {
+        while ((n+1 < line_length) && linebuff[n] != '/') {
+            n++;
+        }
+    }
+
+    /* Skip '/' */
+    while ((n+1 < line_length) && linebuff[n] == '/') {
+        n++;
+    }
+
+    /* Skip a space that may happen here */
+    if ((n+1 < line_length) && linebuff[n] == ' ') {
+        n++;
+    }
+
     /* Next character gives direction of message (must be 's' or 'r') */
     if (!(*is_comment)) {
         if (linebuff[n] == 's') {
@@ -1137,7 +1134,7 @@ static gboolean parse_line(gchar *linebuff, gint line_length,
         n++;
     }
     else {
-        *direction = received;
+        *direction = sent;
     }
 
 
@@ -1242,7 +1239,8 @@ static gboolean parse_line(gchar *linebuff, gint line_length,
 /*****************************************************************/
 /* Write the stub info to the data buffer while reading a packet */
 /*****************************************************************/
-static int write_stub_header(guchar *frame_buffer, char *timestamp_string,
+static int
+write_stub_header(guint8 *frame_buffer, char *timestamp_string,
                              packet_direction_t direction, int encap,
                              gchar *context_name, guint8 context_port,
                              gchar *protocol_name, gchar *variant_name,
@@ -1288,7 +1286,8 @@ static int write_stub_header(guchar *frame_buffer, char *timestamp_string,
 /**************************************************************/
 /* Set pseudo-header info depending upon packet encapsulation */
 /**************************************************************/
-static void set_pseudo_header_info(wtap *wth,
+static void
+set_pseudo_header_info(wtap *wth,
                                    int pkt_encap,
                                    gint64 file_offset,
                                    union wtap_pseudo_header *pseudo_header,
@@ -1319,7 +1318,8 @@ static void set_pseudo_header_info(wtap *wth,
 /*********************************************/
 /* Fill in atm pseudo-header with known info */
 /*********************************************/
-static void set_aal_info(union wtap_pseudo_header *pseudo_header,
+static void
+set_aal_info(union wtap_pseudo_header *pseudo_header,
                          packet_direction_t direction,
                          gchar *aal_header_chars)
 {
@@ -1346,8 +1346,7 @@ static void set_aal_info(union wtap_pseudo_header *pseudo_header,
 
     /* vpi is 8 bits (2nd & 3rd nibble) */
     pseudo_header->dct2000.inner_pseudo_header.atm.vpi =
-        ((hex_from_char(aal_header_chars[1]) << 4) |
-          hex_from_char(aal_header_chars[2]));
+        hex_byte_from_chars(aal_header_chars+1);
 
     /* vci is next 16 bits */
     pseudo_header->dct2000.inner_pseudo_header.atm.vci =
@@ -1363,12 +1362,11 @@ static void set_aal_info(union wtap_pseudo_header *pseudo_header,
        case cid is derived from last char in ascii */
     if (isalnum((guchar)aal_header_chars[11])) {
         pseudo_header->dct2000.inner_pseudo_header.atm.aal2_cid =
-            ((hex_from_char(aal_header_chars[10]) << 4) |
-              hex_from_char(aal_header_chars[11]));
+            hex_byte_from_chars(aal_header_chars+10);
     }
     else {
         pseudo_header->dct2000.inner_pseudo_header.atm.aal2_cid =
-            (int)aal_header_chars[11] - 48;
+            (int)aal_header_chars[11] - '0';
     }
 }
 
@@ -1376,7 +1374,8 @@ static void set_aal_info(union wtap_pseudo_header *pseudo_header,
 /**********************************************/
 /* Fill in isdn pseudo-header with known info */
 /**********************************************/
-void set_isdn_info(union wtap_pseudo_header *pseudo_header,
+static void
+set_isdn_info(union wtap_pseudo_header *pseudo_header,
                    packet_direction_t direction)
 {
     /* This field is used to set the 'Source' and 'Destination' columns to
@@ -1395,7 +1394,8 @@ void set_isdn_info(union wtap_pseudo_header *pseudo_header,
 /*********************************************/
 /* Fill in ppp pseudo-header with known info */
 /*********************************************/
-static void set_ppp_info(union wtap_pseudo_header *pseudo_header,
+static void
+set_ppp_info(union wtap_pseudo_header *pseudo_header,
                          packet_direction_t direction)
 {
     /* Set direction. */
@@ -1406,7 +1406,8 @@ static void set_ppp_info(union wtap_pseudo_header *pseudo_header,
 /********************************************************/
 /* Return hex nibble equivalent of hex string character */
 /********************************************************/
-guchar hex_from_char(gchar c)
+static guint8
+hex_from_char(gchar c)
 {
     if ((c >= '0') && (c <= '9')) {
         return c - '0';
@@ -1420,11 +1421,38 @@ guchar hex_from_char(gchar c)
     return 0xff;
 }
 
+/* Extract and return a byte value from 2 ascii hex chars, starting from the given pointer */
+static guint8
+hex_byte_from_chars(gchar *c)
+{
+    static guchar hex_char_array[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+                                         'a', 'b', 'c', 'd', 'e', 'f' };
+
+    /* Populate lookup table first time */
+    static guint8 tableValues[255][255];
+    static gint tableSet = FALSE;
+    if (!tableSet) {
+        gint i, j;
+        for (i=0; i < 16; i++) {
+            for (j=0; j < 16; j++) {
+                tableValues[hex_char_array[i]][hex_char_array[j]] = i*16 + j;
+            }
+        }
+
+        tableSet = TRUE;
+    }
+
+    /* Return value from quick table lookup */
+    return tableValues[(unsigned char)c[0]][(unsigned char)c[1]];
+}
+
+
 
 /********************************************************/
 /* Return character corresponding to hex nibble value   */
 /********************************************************/
-gchar char_from_hex(guchar hex)
+static gchar
+char_from_hex(guint8 hex)
 {
     static char hex_lookup[16] =
     { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
@@ -1439,7 +1467,8 @@ gchar char_from_hex(guchar hex)
 /***********************************************/
 /* Equality test for packet prefix hash tables */
 /***********************************************/
-gint packet_offset_equal(gconstpointer v, gconstpointer v2)
+static gint
+packet_offset_equal(gconstpointer v, gconstpointer v2)
 {
     /* Dereferenced pointers must have same gint64 offset value */
     return (*(const gint64*)v == *(const gint64*)v2);
@@ -1449,7 +1478,8 @@ gint packet_offset_equal(gconstpointer v, gconstpointer v2)
 /********************************************/
 /* Hash function for packet-prefix hash table */
 /********************************************/
-guint packet_offset_hash_func(gconstpointer v)
+static guint
+packet_offset_hash_func(gconstpointer v)
 {
     /* Use low-order bits of git64 offset value */
     return (guint)(*(const gint64*)v);
@@ -1461,7 +1491,8 @@ guint packet_offset_hash_func(gconstpointer v)
 /* Set secs and usecs as output                                         */
 /* Return FALSE if no valid time can be read                            */
 /************************************************************************/
-gboolean get_file_time_stamp(gchar *linebuff, time_t *secs, guint32 *usecs)
+static gboolean
+get_file_time_stamp(gchar *linebuff, time_t *secs, guint32 *usecs)
 {
     int n;
     struct tm tm;
@@ -1504,7 +1535,7 @@ gboolean get_file_time_stamp(gchar *linebuff, time_t *secs, guint32 *usecs)
 
     /********************************************************/
     /* Scan for remaining numerical fields                  */
-    scan_found = sscanf(linebuff+n, "%d, %d     %d:%d:%d.%u",
+    scan_found = sscanf(linebuff+n, "%2d, %4d     %2d:%2d:%2d.%4u",
                         &day, &year, &hour, &minute, &second, usecs);
     if (scan_found != 6) {
         /* Give up if not all found */
@@ -1530,7 +1561,8 @@ gboolean get_file_time_stamp(gchar *linebuff, time_t *secs, guint32 *usecs)
 }
 
 /* Free the data allocated inside a line_prefix_info_t */
-gboolean free_line_prefix_info(gpointer key, gpointer value,
+static gboolean
+free_line_prefix_info(gpointer key, gpointer value,
                                gpointer user_data _U_)
 {
     line_prefix_info_t *info = (line_prefix_info_t*)value;