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);
+ 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;
/* 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;
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;
g_snprintf(timestamp_string, MAX_TIMESTAMP_LEN, "%d.%04d", seconds, useconds/100);
+ wth->phdr.presence_flags = WTAP_HAS_TS;
+
/* All packets go to Catapult DCT2000 stub dissector */
wth->phdr.pkt_encap = WTAP_ENCAP_CATAPULT_DCT2000;
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 =
/* 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;
/* 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 */
/*****************************************/
-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;
/* 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 (!wtap_dump_file_write(wdh, c, 2, err)) {
/* - 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)
{
/* Read in a line */
+ 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,
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') {
/*****************************************************************/
/* 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 =
/**********************************************/
/* 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;