* Routines for reading signalling traces generated by Gammu (www.gammu.org)
* from Nokia DCT3 phones in Netmonitor mode.
*
- * gammu --nokiadebug nhm5_587.txt v20-25,v18-19
+ * gammu --nokiadebug nhm5_587.txt v18-19
*
* Duncan Salerno <duncan.salerno@googlemail.com>
*
static const char dct3trace_magic_l2_end[] = "</l2>";
static const char dct3trace_magic_end[] = "</dump>";
+#define MAX_PACKET_LEN 23
static gboolean dct3trace_read(wtap *wth, int *err, gchar **err_info,
gint64 *data_offset);
int is_low = 0;
int c;
+ /* Clamp to maximum packet size */
+ if (end - in > MAX_PACKET_LEN*2) /* As we're reading nibbles */
+ end = in + MAX_PACKET_LEN*2;
+
while (in < end)
{
c = hc2b(in[0]);
in++;
}
- return out - out_start;
+ return (int)(out - out_start);
}
static int
xml_get_int(int *val, const unsigned char *str, const unsigned char *pattern)
{
- char *ptr;
+ const char *ptr;
char *start, *end;
char buf[32];
- ptr = strstr((char *)str, (char *)pattern);
+ ptr = strstr((const char *)str, (const char *)pattern);
if (ptr == NULL)
return -1;
start = strchr(ptr, '"');
end = strchr(start, '"');
if (end == NULL)
return -3;
+ if (end - start > 31)
+ return -4;
memcpy(buf, start, end - start);
buf[end - start] = '\0';
* a DCT3 trace file.
*
* Returns TRUE if it is, FALSE if it isn't or if we get an I/O error;
- * if we get an I/O error, "*err" will be set to a non-zero value.
+ * if we get an I/O error, "*err" will be set to a non-zero value
+ * and "*err_info" will be set to null or an additional error string.
*/
-static gboolean dct3trace_check_file_type(wtap *wth, int *err)
+static gboolean dct3trace_check_file_type(wtap *wth, int *err, gchar **err_info)
{
char line1[64], line2[64];
if (file_eof(wth->fh))
*err = 0;
else
- *err = file_error(wth->fh);
+ *err = file_error(wth->fh, err_info);
}
return FALSE;
}
-int dct3trace_open(wtap *wth, int *err, gchar **err_info _U_)
+int dct3trace_open(wtap *wth, int *err, gchar **err_info)
{
/* Look for Gammu DCT3 trace header */
- if (!dct3trace_check_file_type(wth, err))
+ if (!dct3trace_check_file_type(wth, err, err_info))
{
if (*err == 0)
return 0;
}
-static gboolean dct3trace_get_packet(FILE *fh, union wtap_pseudo_header *pseudo_header,
+static gboolean dct3trace_get_packet(FILE_T fh, union wtap_pseudo_header *pseudo_header,
unsigned char *buf, int *len, int *err, gchar **err_info)
{
unsigned char line[1024];
else
{
/* If not got any data return error */
- *err = WTAP_ERR_BAD_RECORD;
+ *err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("dct3trace: record without data");
return FALSE;
}
if( ret != 0 )
{
- *err = WTAP_ERR_BAD_RECORD;
+ *err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("dct3trace: record missing mandatory attributes");
return FALSE;
}
}
else if( !have_data && memcmp(dct3trace_magic_l2_start, line, strlen(dct3trace_magic_l2_start)) == 0 )
{
- /* For uplink packets we don't get the raw L1, so have to recreate it from the L2 */
+ /* For uplink packets we might not get the raw L1, so have to recreate it from the L2 */
/* Parse L2 header if didn't get data from L1 <l2 ...> */
int data_len = 0;
char *ptr = strstr(line, "data=\"");
}
}
- *err = file_error(fh);
+ *err = file_error(fh, err_info);
if (*err == 0)
{
*err = WTAP_ERR_SHORT_READ;
{
guint64 offset = file_tell(wth->fh);
int buf_len;
- char buf[23];
+ unsigned char buf[MAX_PACKET_LEN];
if( !dct3trace_get_packet(wth->fh, &wth->pseudo_header, buf, &buf_len, err, err_info) )
{
int *err, gchar **err_info)
{
int buf_len;
- char buf[23];
+ unsigned char buf[MAX_PACKET_LEN];
if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
{
if( len != buf_len && len != -1 )
{
- *err = WTAP_ERR_BAD_RECORD;
+ *err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("dct3trace: requested length %d doesn't match record length %d",
len, buf_len);
return FALSE;
}
+ if( buf_len > MAX_PACKET_LEN)
+ {
+ *err = WTAP_ERR_BAD_FILE;
+ *err_info = g_strdup_printf("dct3trace: record length %d too long", buf_len);
+ return FALSE;
+ }
+
memcpy( pd, buf, buf_len );
return TRUE;
}