#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:
} 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
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;
/************************************************************/
-/* 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,
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);
/********************************************/
-/* Open file */
+/* Open file (for reading) */
/********************************************/
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;
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);
/************************************************************/
/**************************************************/
-/* Read function. */
+/* Read packet function. */
/* Look for and read the next usable packet */
/* - return TRUE and details if found */
/**************************************************/
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;
/* 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;
}
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;
/* 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.
}
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);
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;
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;
}
-/******************************************/
-/* 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 */
case WTAP_ENCAP_CATAPULT_DCT2000:
/* We support this */
return 0;
+
default:
+ /* But don't write to any other formats... */
return WTAP_ERR_UNSUPPORTED_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;
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));
(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)
}
/* 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;
+ }
}
/**************************************/
/* 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++)
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;
}
/* 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;
}
(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;
}
(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;
}
/* 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;
}
}
else
{
- strcpy(variant_name, "1");
+ g_strlcpy(variant_name, "1", MAX_VARIANT_DIGITS+1);
}
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;
}
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;
}
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))
{
/* 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)
/* 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;
(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;
(n < line_length);
n++, subsecond_decimals_chars++)
{
- if (!isdigit((int)linebuff[n]))
+ if (!isdigit((guchar)linebuff[n]))
{
return FALSE;
}
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 */
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 */
/* 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) |