#define MAX_PROTOCOL_NAME 64
#define MAX_PORT_DIGITS 2
#define MAX_VARIANT_DIGITS 32
+#define MAX_OUTHDR_NAME 64
#define AAL_HEADER_CHARS 12
/* TODO:
+ - support for FP over AAL0
+ - support for IuR interface FP
- support for x.25?
*/
typedef struct
{
gchar *before_time;
- gchar *after_time;
+ gchar *after_time; /* If NULL assume " l " */
} line_prefix_info_t;
/*******************************************************************/
Records (file offset -> pre-data-prefix-string)
N.B. This is only needed for dumping
*/
- GHashTable *line_header_prefixes_table;
+ GHashTable *packet_prefix_table;
} dct2000_file_externals_t;
/* This global table maps wtap -> file_external structs */
/* The DCT2000 protocol name of the packet, plus variant number */
static gchar protocol_name[MAX_PROTOCOL_NAME+1];
static gchar variant_name[MAX_VARIANT_DIGITS+1];
+static gchar outhdr_name[MAX_OUTHDR_NAME+1];
-/*************************************************/
-/* Preference state (shared with stub protocol). */
-/* Set to FALSE to get better use out of other */
-/* wiretap applications (mergecap, editcap) */
-gboolean catapult_dct2000_board_ports_only = FALSE;
-
/************************************************************/
/* Functions called from wiretap */
static gboolean catapult_dct2000_read(wtap *wth, int *err, gchar **err_info,
- long *data_offset);
-static gboolean catapult_dct2000_seek_read(wtap *wth, long seek_off,
+ gint64 *data_offset);
+static gboolean catapult_dct2000_seek_read(wtap *wth, gint64 seek_off,
union wtap_pseudo_header *pseudo_header,
guchar *pd, int length,
int *err, gchar **err_info);
/************************************************************/
/* Private helper functions */
-static gboolean read_new_line(FILE_T fh, long *offset, gint *length);
+static gboolean read_new_line(FILE_T fh, gint64 *offset, gint *length);
static gboolean parse_line(gint line_length, gint *seconds, gint *useconds,
long *before_time_offset, long *after_time_offset,
long *data_offset,
gint *data_chars,
packet_direction_t *direction,
- int *encap,
- gboolean seek_read);
+ int *encap);
static int write_stub_header(guchar *frame_buffer, char *timestamp_string,
packet_direction_t direction, int encap);
static guchar hex_from_char(gchar c);
static void set_pseudo_header_info(wtap *wth,
int pkt_encap,
- long file_offset,
+ gint64 file_offset,
union wtap_pseudo_header *pseudo_header,
- gint length,
packet_direction_t direction);
-static void set_aal_info(union wtap_pseudo_header *pseudo_header, gint length,
+static void set_aal_info(union wtap_pseudo_header *pseudo_header,
packet_direction_t direction);
static void set_isdn_info(union wtap_pseudo_header *pseudo_header,
packet_direction_t direction);
static void set_ppp_info(union wtap_pseudo_header *pseudo_header,
packet_direction_t direction);
+static gint wth_equal(gconstpointer v, gconstpointer v2);
+static guint wth_hash_func(gconstpointer v);
+static gint packet_offset_equal(gconstpointer v, gconstpointer v2);
+static guint packet_offset_hash_func(gconstpointer v);
-static gint prefix_equal(gconstpointer v, gconstpointer v2);
-static guint prefix_hash_func(gconstpointer v);
static gboolean get_file_time_stamp(time_t *secs, guint32 *usecs);
static gboolean free_line_prefix_info(gpointer key, gpointer value, gpointer user_data);
/********************************************/
int catapult_dct2000_open(wtap *wth, int *err, gchar **err_info _U_)
{
- long offset = 0;
+ gint64 offset = 0;
time_t timestamp;
guint32 usecs;
- gint firstline_length;
+ gint firstline_length = 0;
dct2000_file_externals_t *file_externals;
/* Clear errno before reading from the file */
errno = 0;
- /*********************************************************************/
- /* Need entry in file_externals table */
-
- /* Create file externals table if it doesn't yet exist */
- if (file_externals_table == NULL)
- {
- file_externals_table = g_hash_table_new(prefix_hash_func, prefix_equal);
- }
-
-
/********************************************************************/
/* First line needs to contain at least as many characters as magic */
}
+ /*********************************************************************/
+ /* Need entry in file_externals table */
+
+ /* Create file externals table if it doesn't yet exist */
+ if (file_externals_table == NULL)
+ {
+ file_externals_table = g_hash_table_new(wth_hash_func, wth_equal);
+ }
+
/* Allocate a new file_externals structure */
file_externals = g_malloc(sizeof(dct2000_file_externals_t));
memset((void*)file_externals, '\0', sizeof(dct2000_file_externals_t));
wth->tsprecision = WTAP_FILE_TSPREC_USEC;
- /**********************************************/
- /* Initialise line_header_prefixes_table */
- file_externals->line_header_prefixes_table =
- g_hash_table_new(prefix_hash_func, prefix_equal);
+ /***************************************************************/
+ /* Initialise packet_prefix_table (index is offset into file) */
+ file_externals->packet_prefix_table =
+ g_hash_table_new(packet_offset_hash_func, packet_offset_equal);
/* Add file_externals for this wtap into the global table */
g_hash_table_insert(file_externals_table,
/* - return TRUE and details if found */
/**************************************************/
gboolean catapult_dct2000_read(wtap *wth, int *err, gchar **err_info _U_,
- long *data_offset)
+ gint64 *data_offset)
{
- long offset = wth->data_offset;
+ gint64 offset = wth->data_offset;
long dollar_offset, before_time_offset, after_time_offset;
packet_direction_t direction;
int encap;
while (1)
{
int line_length, seconds, useconds, data_chars;
- long this_offset = offset;
+ gint64 this_offset = offset;
/* Are looking for first packet after 2nd line */
if (wth->data_offset == 0)
break;
}
- /* Try to parse the line as a message */
+ /* Try to parse the line as a frame record */
if (parse_line(line_length, &seconds, &useconds,
&before_time_offset, &after_time_offset,
&dollar_offset,
- &data_chars, &direction, &encap, FALSE))
+ &data_chars, &direction, &encap))
{
guchar *frame_buffer;
int n;
int stub_offset = 0;
line_prefix_info_t *line_prefix_info;
char timestamp_string[32];
+ gint64 *pkey = NULL;
+
sprintf(timestamp_string, "%d.%04d", seconds, useconds/100);
/* All packets go to Catapult DCT2000 stub dissector */
/* Get buffer pointer ready */
buffer_assure_space(wth->frame_buffer,
- strlen(context_name)+1 + /* Context name */
- 1 + /* port */
- strlen(protocol_name)+1 + /* Protocol name */
- 1 + /* direction */
- 1 + /* encap */
+ strlen(context_name)+1 + /* Context name */
+ 1 + /* port */
+ strlen(timestamp_string)+1 + /* timestamp */
+ strlen(variant_name)+1 + /* variant */
+ strlen(outhdr_name)+1 + /* outhdr */
+ strlen(protocol_name)+1 + /* Protocol name */
+ 1 + /* direction */
+ 1 + /* encap */
(data_chars/2));
frame_buffer = buffer_start_ptr(wth->frame_buffer);
/* Store the packet prefix in the hash table */
line_prefix_info = g_malloc(sizeof(line_prefix_info_t));
+ /* 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);
line_prefix_info->before_time[before_time_offset] = '\0';
- 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);
- line_prefix_info->after_time[dollar_offset - after_time_offset-1] = '\0';
+ /* Create and use buffer for contents before time.
+ Do this only if it doesn't correspond to " l ", which is by far the most
+ common case. */
+ if (((size_t)(dollar_offset - after_time_offset -1) == strlen(" l ")) &&
+ (strncmp(linebuff+after_time_offset, " l ", strlen(" l ")) == 0))
+ {
+ line_prefix_info->after_time = NULL;
+ }
+ else
+ {
+ 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);
+ line_prefix_info->after_time[dollar_offset - after_time_offset-1] = '\0';
+ }
/* Add packet entry into table */
- g_hash_table_insert(file_externals->line_header_prefixes_table,
- (void*)this_offset, line_prefix_info);
-
+ pkey = g_malloc(sizeof(pkey));
+ *pkey = this_offset;
+ g_hash_table_insert(file_externals->packet_prefix_table, pkey, line_prefix_info);
/* Set pseudo-header if necessary */
set_pseudo_header_info(wth, encap, this_offset, &wth->pseudo_header,
- data_chars/2, direction);
+ direction);
/* OK, we have packet details to return */
*err = errno;
/* Read & seek function. */
/**************************************************/
static gboolean
-catapult_dct2000_seek_read(wtap *wth, long seek_off,
+catapult_dct2000_seek_read(wtap *wth, gint64 seek_off,
union wtap_pseudo_header *pseudo_header, guchar *pd,
int length, int *err, gchar **err_info)
{
- long offset = wth->data_offset;
+ gint64 offset = wth->data_offset;
long dollar_offset, before_time_offset, after_time_offset;
packet_direction_t direction;
int encap;
if (parse_line(length, &seconds, &useconds,
&before_time_offset, &after_time_offset,
&dollar_offset,
- &data_chars, &direction, &encap, TRUE))
+ &data_chars, &direction, &encap))
{
int n;
int stub_offset = 0;
/*********************/
/* Write stub header */
- stub_offset = write_stub_header((char*)pd, timestamp_string,
+ stub_offset = write_stub_header((guchar*)pd, timestamp_string,
direction, encap);
}
/* Set packet pseudo-header if necessary */
- set_pseudo_header_info(wth, encap, seek_off, pseudo_header, data_chars/2, direction);
+ set_pseudo_header_info(wth, encap, seek_off, pseudo_header, direction);
*err = errno = 0;
return TRUE;
/* If get here, must have failed */
*err = errno;
*err_info = g_strdup_printf("catapult dct2000: seek_read failed to read/parse "
- "line at position %ld", seek_off);
+ "line at position %" G_GINT64_MODIFIER "d",
+ seek_off);
return FALSE;
}
}
/* Free up its line prefix values */
- g_hash_table_foreach_remove(file_externals->line_header_prefixes_table,
+ g_hash_table_foreach_remove(file_externals->packet_prefix_table,
free_line_prefix_info, NULL);
/* Free up its line prefix table */
- g_hash_table_destroy(file_externals->line_header_prefixes_table);
+ g_hash_table_destroy(file_externals->packet_prefix_table);
/* And remove the externals entry from the global table */
g_hash_table_remove(file_externals_table, (void*)wth);
gboolean catapult_dct2000_dump_open(wtap_dumper *wdh, gboolean cant_seek _U_, int *err _U_)
{
/* Fill in other dump callbacks */
- wdh->subtype_write = catapult_dct2000_dump;
- wdh->subtype_close = catapult_dct2000_dump_close;
+ wdh->subtype_write = catapult_dct2000_dump;
+ wdh->subtype_close = catapult_dct2000_dump_close;
return TRUE;
}
/* Write out this packet's prefix, including calculated timestamp */
/* Look up line data prefix using stored offset */
- prefix = (line_prefix_info_t*)g_hash_table_lookup(file_externals->line_header_prefixes_table,
- (void*)pseudo_header->dct2000.seek_off);
+ prefix = (line_prefix_info_t*)g_hash_table_lookup(file_externals->packet_prefix_table,
+ (const void*)&(pseudo_header->dct2000.seek_off));
/* Write out text before timestamp */
fwrite(prefix->before_time, 1, strlen(prefix->before_time), wdh->fh);
fwrite(time_string, 1, strlen(time_string), wdh->fh);
/* Write out text between timestamp and start of hex data */
- fwrite(prefix->after_time, 1, strlen(prefix->after_time), wdh->fh);
+ if (prefix->after_time == NULL)
+ {
+ fwrite(" l ", 1, strlen(" l "), wdh->fh);
+ }
+ else
+ {
+ fwrite(prefix->after_time, 1, strlen(prefix->after_time), wdh->fh);
+ }
/****************************************************************/
for (; pd[n] != '\0'; n++);
n++;
+ /* Variant number (as string) */
+ for (; pd[n] != '\0'; n++);
+ n++;
+
+ /* Outhdr (as string) */
+ for (; pd[n] != '\0'; n++);
+ n++;
+
/* Direction & encap */
n += 2;
/* - 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, long *offset, gint *length)
+gboolean read_new_line(FILE_T fh, gint64 *offset, gint *length)
{
char *result;
long *before_time_offset, long *after_time_offset,
long *data_offset, gint *data_chars,
packet_direction_t *direction,
- int *encap,
- gboolean seek_read)
+ int *encap)
{
int n = 0;
int port_digits = 0;
char port_number_string[MAX_PORT_DIGITS+1];
int variant_digits = 0;
+ int variant = 1;
int protocol_chars = 0;
+ int outhdr_chars = 0;
char seconds_buff[MAX_SECONDS_CHARS+1];
int seconds_chars;
char subsecond_decimals_buff[MAX_SUBSECOND_DECIMALS+1];
int subsecond_decimals_chars;
+ int skip_first_byte = FALSE;
gboolean atm_header_present = FALSE;
/* Read context name until find '.' */
for (n=0; linebuff[n] != '.' && (n < MAX_CONTEXT_NAME) && (n+1 < line_length); n++)
{
- if (!isalnum(linebuff[n]) && (linebuff[n] != '_'))
+ if (!isalnum((int)linebuff[n]) && (linebuff[n] != '_'))
{
return FALSE;
}
(linebuff[n] != '/') && (port_digits <= MAX_PORT_DIGITS) && (n+1 < line_length);
n++, port_digits++)
{
- if (!isdigit(linebuff[n]))
+ if (!isdigit((int)linebuff[n]))
{
return FALSE;
}
(linebuff[n] != '/') && (protocol_chars < MAX_PROTOCOL_NAME) && (n < line_length);
n++, protocol_chars++)
{
- if (!isalnum(linebuff[n]) && linebuff[n] != '_')
+ if (!isalnum((int)linebuff[n]) && linebuff[n] != '_')
{
return FALSE;
}
n++;
+ /* 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);
+ n++, variant_digits++)
+ {
+ if (!isdigit((int)linebuff[n]))
+ {
+ return FALSE;
+ }
+ variant_name[variant_digits] = linebuff[n];
+ }
+ if (variant_digits > MAX_VARIANT_DIGITS || (n+1 >= line_length))
+ {
+ return FALSE;
+ }
+ if (variant_digits > 0)
+ {
+ variant_name[variant_digits] = '\0';
+ variant = atoi(variant_name);
+ }
+ else
+ {
+ strcpy(variant_name, "1");
+ }
+
+
+ /* Outheader values may follow */
+ outhdr_name[0] = '\0';
+ if (linebuff[n] == ',')
+ {
+ /* Skip , */
+ n++;
+
+ for (outhdr_chars = 0;
+ (isdigit((int)linebuff[n]) || linebuff[n] == ',') &&
+ (outhdr_chars <= MAX_OUTHDR_NAME) && (n+1 < line_length);
+ n++, outhdr_chars++)
+ {
+ if (!isdigit((int)linebuff[n]) && (linebuff[n] != ','))
+ {
+ return FALSE;
+ }
+ outhdr_name[outhdr_chars] = linebuff[n];
+ }
+ if (outhdr_chars > MAX_OUTHDR_NAME || (n+1 >= line_length))
+ {
+ return FALSE;
+ }
+ /* Terminate (possibly empty) string */
+ outhdr_name[outhdr_chars] = '\0';
+ }
+
+
+
+
/******************************************************************/
/* Now check whether we know how to use a packet of this protocol */
- if ((strcmp(protocol_name, "ip") == 0) || (strcmp(protocol_name, "sctp") == 0))
+ if ((strcmp(protocol_name, "ip") == 0) ||
+ (strcmp(protocol_name, "sctp") == 0) ||
+ (strcmp(protocol_name, "gre") == 0) ||
+ (strcmp(protocol_name, "mipv6") == 0))
{
*encap = WTAP_ENCAP_RAW_IP;
}
else
- /* For ATM protocols, we need to read the separate atm headerparse */
+ /* FP may be carried over ATM, which has separate atm header to parse */
if ((strcmp(protocol_name, "fp") == 0) ||
(strcmp(protocol_name, "fp_r4") == 0) ||
(strcmp(protocol_name, "fp_r5") == 0) ||
(strcmp(protocol_name, "fp_r6") == 0))
{
+ if ((variant > 256) && (variant % 256 == 3))
+ {
+ /* FP over udp is contained in IPPrim... */
+ *encap = 0;
+ }
+ else
+ {
+ /* FP over AAL0 or AAL2 */
+ *encap = WTAP_ENCAP_ATM_PDUS_UNTRUNCATED;
+ atm_header_present = TRUE;
+ }
+ }
+ else if (strcmp(protocol_name, "fpiur_r5") == 0)
+ {
+ /* FP (IuR) over AAL2 */
*encap = WTAP_ENCAP_ATM_PDUS_UNTRUNCATED;
atm_header_present = TRUE;
}
+
else
if (strcmp(protocol_name, "ppp") == 0)
{
else
if (strcmp(protocol_name, "isdn_l3") == 0)
{
- /* Despite the name, this does seem to correspond to L2... */
+ /* TODO: find out what this byte means... */
+ skip_first_byte = TRUE;
+ *encap = WTAP_ENCAP_ISDN;
+ }
+ else
+ if (strcmp(protocol_name, "isdn_l2") == 0)
+ {
*encap = WTAP_ENCAP_ISDN;
}
else
*encap = DCT2000_ENCAP_MTP2;
}
else
+ if ((strcmp(protocol_name, "nbap") == 0) ||
+ (strcmp(protocol_name, "nbap_r4") == 0) ||
+ (strncmp(protocol_name, "nbap_sscfuni", strlen("nbap_sscfuni")) == 0))
{
- /* Only reject protocol if reading for the first time and preference
- setting says board ports only. This should not fail to read a
- non board-port protocol on re-reading because the preference setting
- has since changed...
- */
- if (catapult_dct2000_board_ports_only && !seek_read)
- {
- return FALSE;
- }
- else
- {
- /* Not a supported protocol/encap, but should show as raw data anyway */
- *encap = DCT2000_ENCAP_UNHANDLED;
- }
- }
-
-
- /* Following the / is the variant number. No digits indicate 1 */
- for (variant_digits = 0;
- (isdigit(linebuff[n])) && (variant_digits <= MAX_VARIANT_DIGITS) && (n+1 < line_length);
- n++, variant_digits++)
- {
- if (!isdigit(linebuff[n]))
- {
- return FALSE;
- }
- variant_name[variant_digits] = linebuff[n];
- }
- if (variant_digits > MAX_VARIANT_DIGITS || (n+1 >= line_length))
- {
- return FALSE;
- }
- if (variant_digits > 0)
- {
- variant_name[variant_digits] = '\0';
+ /* The entire message in these cases is nbap, so use an encap value. */
+ *encap = DCT2000_ENCAP_NBAP;
}
else
{
- strcpy(variant_name, "1");
+ /* Not a supported board port protocol/encap, but can show as raw data or
+ in some cases find protocol embedded inside primitive */
+ *encap = DCT2000_ENCAP_UNHANDLED;
}
/* Read consecutive hex chars into atm header buffer */
for (;
- (isalnum(linebuff[n]) &&
+ (isalnum((int)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++;
+ }
+
if (header_chars_seen != AAL_HEADER_CHARS || n >= line_length)
{
return FALSE;
/* Find and read the timestamp */
/* Now scan to the next digit, which should be the start of the timestamp */
- for (; !isdigit(linebuff[n]) && (n < line_length); n++);
+ for (; !isdigit((int)linebuff[n]) && (n < line_length); n++);
if (n >= line_length)
{
return FALSE;
(n < line_length);
n++, seconds_chars++)
{
- if (!isdigit(linebuff[n]))
+ if (!isdigit((int)linebuff[n]))
{
/* Found a non-digit before decimal point. Fail */
return FALSE;
/* Didn't fit in buffer. Fail rather than use truncated */
return FALSE;
}
-
+
/* Convert found value into number */
seconds_buff[seconds_chars] = '\0';
*seconds = atoi(seconds_buff);
(n < line_length);
n++, subsecond_decimals_chars++)
{
- if (!isdigit(linebuff[n]))
+ if (!isdigit((int)linebuff[n]))
{
return FALSE;
}
/* Set number of chars that comprise the hex string protocol data */
*data_chars = line_length - n;
- /* Need to skip first byte (2 hex string chars) from ISDN messages.
- TODO: find out what this byte means...
- */
- if (*encap == WTAP_ENCAP_ISDN)
+ /* May need to skip first byte (2 hex string chars) */
+ if (skip_first_byte)
{
*data_offset += 2;
*data_chars -= 2;
}
+
return TRUE;
}
strcpy((char*)&frame_buffer[stub_offset], protocol_name);
stub_offset += (strlen(protocol_name) + 1);
- /* Protocol variant number */
+ /* Protocol variant number (as string) */
strcpy((void*)&frame_buffer[stub_offset], variant_name);
stub_offset += (strlen(variant_name) + 1);
+ /* Outhdr */
+ strcpy((char*)&frame_buffer[stub_offset], outhdr_name);
+ stub_offset += (strlen(outhdr_name) + 1);
+
/* Direction */
frame_buffer[stub_offset] = direction;
stub_offset++;
/* Encap */
frame_buffer[stub_offset] = (guint8)encap;
stub_offset++;
-
+
return stub_offset;
}
/**************************************************************/
void set_pseudo_header_info(wtap *wth,
int pkt_encap,
- long file_offset,
+ gint64 file_offset,
union wtap_pseudo_header *pseudo_header,
- gint length,
packet_direction_t direction)
{
pseudo_header->dct2000.seek_off = file_offset;
switch (pkt_encap)
{
case WTAP_ENCAP_ATM_PDUS_UNTRUNCATED:
- set_aal_info(pseudo_header, length, direction);
+ set_aal_info(pseudo_header, direction);
break;
case WTAP_ENCAP_ISDN:
set_isdn_info(pseudo_header, direction);
/*********************************************/
/* Fill in atm pseudo-header with known info */
/*********************************************/
-void set_aal_info(union wtap_pseudo_header *pseudo_header, gint length,
- packet_direction_t direction)
+void set_aal_info(union wtap_pseudo_header *pseudo_header, packet_direction_t direction)
{
/* 'aal_head_chars' has this format (for AAL2 at least):
Global Flow Control (4 bits) | VPI (8 bits) | VCI (16 bits) |
/* Assume always AAL2 for FP */
pseudo_header->dct2000.inner_pseudo_header.atm.aal = AAL_2;
- pseudo_header->dct2000.inner_pseudo_header.atm.type = TRAF_UNKNOWN;
+ pseudo_header->dct2000.inner_pseudo_header.atm.type = TRAF_UMTS_FP;
pseudo_header->dct2000.inner_pseudo_header.atm.subtype = TRAF_ST_UNKNOWN;
/* vpi is 8 bits (2nd & 3rd nibble) */
/* 0 means we don't know how many cells the frame comprises. */
pseudo_header->dct2000.inner_pseudo_header.atm.cells = 0;
- pseudo_header->dct2000.inner_pseudo_header.atm.aal5t_u2u = 0;
- pseudo_header->dct2000.inner_pseudo_header.atm.aal5t_len = length;
- pseudo_header->dct2000.inner_pseudo_header.atm.aal5t_chksum = 0;
+ /* 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]))
+ {
+ pseudo_header->dct2000.inner_pseudo_header.atm.aal2_cid =
+ ((hex_from_char(aal_header_chars[10]) << 4) |
+ hex_from_char(aal_header_chars[11]));
+ }
+ else
+ {
+ pseudo_header->dct2000.inner_pseudo_header.atm.aal2_cid =
+ (int)aal_header_chars[11] - 48;
+ }
+
}
return hex_lookup[hex];
}
-
-/********************************************/
-/* Equality test for line-prefix hash table */
-/********************************************/
-gint prefix_equal(gconstpointer v, gconstpointer v2)
+/***************************************************/
+/* Equality function for file_externals hash table */
+/***************************************************/
+gint wth_equal(gconstpointer v, gconstpointer v2)
{
return (v == v2);
}
+/***********************************************/
+/* Hash function for file_externals hash table */
+/***********************************************/
+guint wth_hash_func(gconstpointer v)
+{
+ return (guint)(unsigned long)v;
+}
+
+
+/***********************************************/
+/* Equality test for packet prefix hash tables */
+/***********************************************/
+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 line-prefix hash table */
+/* Hash function for packet-prefix hash table */
/********************************************/
-guint prefix_hash_func(gconstpointer v)
+guint packet_offset_hash_func(gconstpointer v)
{
- /* Just use pointer itself (is actually byte offset of line in file) */
- return (guint)v;
+ /* Use low-order bits of git64 offset value */
+ return (guint)(*(const gint64*)v);
}
}
/* Free the data allocated inside a line_prefix_info_t */
-gboolean free_line_prefix_info(gpointer key _U_, gpointer value,
+gboolean free_line_prefix_info(gpointer key, gpointer value,
gpointer user_data _U_)
{
line_prefix_info_t *info = (line_prefix_info_t*)value;
+ /* Free the 64-bit key value */
+ g_free(key);
+
/* Free the strings inside */
g_free(info->before_time);
- g_free(info->after_time);
+ if (info->after_time)
+ {
+ g_free(info->after_time);
+ }
/* And the structure itself */
g_free(info);