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);
/************************************************************/
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,
/********************************************/
/* 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;
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;
/* 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;
/* 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) {
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;
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;
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);
/* 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 {
/**************************************************/
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;
/***********************************************************/
/* 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 {
/***************************************************************************/
/* 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) {
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);
}
/* 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;
}
/* 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:
/* 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;
}
(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;
}
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;
}
}
/**************************************/
/* Remainder is encapsulated protocol */
- if (!do_fwrite("$", 1, 1, wdh->fh, err)) {
+ if (!wtap_dump_file_write(wdh, "$", 1, err)) {
return FALSE;
}
/* 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;
}
}
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;
}
}
-/******************************************************/
-/* 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 */
/****************************/
/* - 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 */
/* - 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,
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);
- 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 */
(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... */
atm_header_present = TRUE;
}
-
else
if (strcmp(protocol_name, "ppp") == 0) {
*encap = WTAP_ENCAP_PPP;
}
}
- /* 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') {
n++;
}
else {
- *direction = received;
+ *direction = sent;
}
/*****************************************************************/
/* 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,
/**************************************************************/
/* 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,
/*********************************************/
/* 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)
{
/* 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 =
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';
}
}
/**********************************************/
/* 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
/*********************************************/
/* 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. */
/********************************************************/
/* 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';
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'};
/***********************************************/
/* 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);
/********************************************/
/* 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);
/* 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;
/********************************************************/
/* 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 */
}
/* 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;