Wiretap: Add support for Android Logcat
Now Androit Logcat (Logger) binary logs are supported. Try "adb logcat -Bf /sdcard/log.logcat; adb pull /sdcard/log.logcat". Also there is possibility to save logs to text format like by "adb". Change-Id: If7bfc53d3fbd549a0978d1dbf96f3fff671fd601 Reviewed-on: https://code.wireshark.org/review/235 Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
parent
27ad4c0331
commit
a68e3a410c
|
@ -28,6 +28,7 @@
|
|||
#include <epan/expert.h>
|
||||
#include <epan/exported_pdu.h>
|
||||
#include <epan/tap.h>
|
||||
#include <wiretap/wtap.h>
|
||||
|
||||
static int proto_logcat = -1;
|
||||
|
||||
|
@ -282,6 +283,8 @@ proto_register_logcat(void)
|
|||
void
|
||||
proto_reg_handoff_logcat(void)
|
||||
{
|
||||
dissector_add_uint("wtap_encap", WTAP_ENCAP_LOGCAT, logcat_handle);
|
||||
|
||||
dissector_add_handle("tcp.port", logcat_handle);
|
||||
|
||||
exported_pdu_tap = find_tap_id(EXPORT_PDU_TAP_NAME_LOGCAT);
|
||||
|
|
|
@ -51,6 +51,7 @@ set(CLEAN_FILES
|
|||
k12.c
|
||||
lanalyzer.c
|
||||
libpcap.c
|
||||
logcat.c
|
||||
merge.c
|
||||
mpeg.c
|
||||
mime_file.c
|
||||
|
|
|
@ -56,6 +56,7 @@ NONGENERATED_C_FILES = \
|
|||
mime_file.c \
|
||||
k12.c \
|
||||
lanalyzer.c \
|
||||
logcat.c \
|
||||
libpcap.c \
|
||||
merge.c \
|
||||
mpeg.c \
|
||||
|
@ -114,9 +115,9 @@ NONGENERATED_HEADER_FILES = \
|
|||
k12.h \
|
||||
lanalyzer.h \
|
||||
libpcap.h \
|
||||
logcat.h \
|
||||
merge.h \
|
||||
mpeg.h \
|
||||
mpeg.h \
|
||||
mp2t.h \
|
||||
netmon.h \
|
||||
netscreen.h \
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
#include "5views.h"
|
||||
#include "erf.h"
|
||||
#include "hcidump.h"
|
||||
#include "logcat.h"
|
||||
#include "network_instruments.h"
|
||||
#include "k12.h"
|
||||
#include "ber.h"
|
||||
|
@ -360,6 +361,7 @@ static struct open_info open_info_base[] = {
|
|||
{ "Hcidump", OPEN_INFO_HEURISTIC, hcidump_open, NULL, NULL },
|
||||
{ "Commview", OPEN_INFO_HEURISTIC, commview_open, "ncf", NULL },
|
||||
{ "Nstrace", OPEN_INFO_HEURISTIC, nstrace_open, "txt", NULL },
|
||||
{ "Logcat ", OPEN_INFO_HEURISTIC, logcat_open, "logcat", NULL },
|
||||
/* ASCII trace files from Telnet sessions. */
|
||||
{ "Ascend", OPEN_INFO_HEURISTIC, ascend_open, "txt", NULL },
|
||||
{ "Toshiba", OPEN_INFO_HEURISTIC, toshiba_open, "txt", NULL },
|
||||
|
@ -1420,7 +1422,33 @@ static const struct file_type_subtype_info dump_open_table_base[] = {
|
|||
/* WTAP_FILE_NETSCALER_3_0 */
|
||||
{ "NetScaler Trace (Version 3.0)", "nstrace30", "cap", NULL,
|
||||
TRUE, FALSE, 0,
|
||||
nstrace_30_dump_can_write_encap, nstrace_dump_open, NULL }
|
||||
nstrace_30_dump_can_write_encap, nstrace_dump_open, NULL },
|
||||
|
||||
/* WTAP_FILE_LOGCAT */
|
||||
{ "Android Logcat Binary format", "logcat", "logcat", NULL,
|
||||
FALSE, FALSE, 0,
|
||||
logcat_dump_can_write_encap, logcat_binary_dump_open, NULL },
|
||||
{ "Android Logcat Brief text format", "logcat-brief", NULL, NULL,
|
||||
FALSE, FALSE, 0,
|
||||
logcat_dump_can_write_encap, logcat_text_brief_dump_open, NULL },
|
||||
{ "Android Logcat Process text format", "logcat-process", NULL, NULL,
|
||||
FALSE, FALSE, 0,
|
||||
logcat_dump_can_write_encap, logcat_text_process_dump_open, NULL },
|
||||
{ "Android Logcat Tag text format", "logcat-tag", NULL, NULL,
|
||||
FALSE, FALSE, 0,
|
||||
logcat_dump_can_write_encap, logcat_text_tag_dump_open, NULL },
|
||||
{ "Android Logcat Time text format", "logcat-time", NULL, NULL,
|
||||
FALSE, FALSE, 0,
|
||||
logcat_dump_can_write_encap, logcat_text_time_dump_open, NULL },
|
||||
{ "Android Logcat Thread text format", "logcat-thread", NULL, NULL,
|
||||
FALSE, FALSE, 0,
|
||||
logcat_dump_can_write_encap, logcat_text_thread_dump_open, NULL },
|
||||
{ "Android Logcat Threadtime text format", "logcat-threadtime", NULL, NULL,
|
||||
FALSE, FALSE, 0,
|
||||
logcat_dump_can_write_encap, logcat_text_threadtime_dump_open, NULL },
|
||||
{ "Android Logcat Long text format", "logcat-long", NULL, NULL,
|
||||
FALSE, FALSE, 0,
|
||||
logcat_dump_can_write_encap, logcat_text_long_dump_open, NULL }
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,574 @@
|
|||
/* logcat.c
|
||||
*
|
||||
* Copyright 2014, Michal Labedzki for Tieto Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "wtap-int.h"
|
||||
#include "file_wrappers.h"
|
||||
#include "buffer.h"
|
||||
|
||||
#include "logcat.h"
|
||||
|
||||
enum dump_type_t {
|
||||
DUMP_BINARY,
|
||||
DUMP_BRIEF,
|
||||
DUMP_PROCESS,
|
||||
DUMP_TAG,
|
||||
DUMP_TIME,
|
||||
DUMP_THREAD,
|
||||
DUMP_THREADTIME,
|
||||
DUMP_LONG
|
||||
};
|
||||
|
||||
struct dumper_t {
|
||||
enum dump_type_t type;
|
||||
};
|
||||
|
||||
static gchar get_priority(const guint8 *priority) {
|
||||
static gchar priorities[] = "??VDIWEFS";
|
||||
|
||||
if (*priority >= (guint8) sizeof(priorities))
|
||||
return '?';
|
||||
|
||||
return priorities[(int) *priority];
|
||||
}
|
||||
|
||||
static gchar *logcat_log(const struct dumper_t *dumper, guint32 seconds,
|
||||
gint microseconds, gint pid, gint tid, gchar priority, const gchar *tag,
|
||||
const gchar *log)
|
||||
{
|
||||
gchar time_buffer[15];
|
||||
time_t datetime;
|
||||
|
||||
datetime = (time_t) seconds;
|
||||
|
||||
switch (dumper->type) {
|
||||
case DUMP_BRIEF:
|
||||
return g_strdup_printf("%c/%s(%5i): %s\n",
|
||||
priority, tag, pid, log);
|
||||
case DUMP_PROCESS:
|
||||
return g_strdup_printf("%c(%5i) %s (%s)\n",
|
||||
priority, pid, log, tag);
|
||||
case DUMP_TAG:
|
||||
return g_strdup_printf("%c/%s: %s\n",
|
||||
priority, tag, log);
|
||||
case DUMP_THREAD:
|
||||
return g_strdup_printf("%c(%5i:%5i) %s\n",
|
||||
priority, pid, tid, log);
|
||||
case DUMP_TIME:
|
||||
strftime(time_buffer, sizeof(time_buffer), "%m-%d %H:%M:%S",
|
||||
gmtime(&datetime));
|
||||
return g_strdup_printf("%s.%03i %c/%s(%5i): %s\n",
|
||||
time_buffer, microseconds, priority, tag, pid, log);
|
||||
case DUMP_THREADTIME:
|
||||
strftime(time_buffer, sizeof(time_buffer), "%m-%d %H:%M:%S",
|
||||
gmtime(&datetime));
|
||||
return g_strdup_printf("%s.%03i %5i:%5i %c %s: %s\n",
|
||||
time_buffer, microseconds, pid, tid, priority, tag, log);
|
||||
case DUMP_LONG:
|
||||
strftime(time_buffer, sizeof(time_buffer), "%m-%d %H:%M:%S",
|
||||
gmtime(&datetime));
|
||||
return g_strdup_printf("[ %s.%03i %5i:%5i %c/%s ]\n%s\n\n",
|
||||
time_buffer, microseconds, pid, tid, priority, tag, log);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static gint detect_version(wtap *wth, int *err, gchar **err_info)
|
||||
{
|
||||
gint bytes_read;
|
||||
guint16 payload_length;
|
||||
guint16 try_header_size;
|
||||
guint8 *buffer;
|
||||
gint64 file_offset;
|
||||
guint32 log_length;
|
||||
guint32 tag_length;
|
||||
guint16 tmp;
|
||||
|
||||
file_offset = file_tell(wth->fh);
|
||||
|
||||
bytes_read = file_read(&tmp, 2, wth->fh);
|
||||
if (bytes_read != 2) {
|
||||
*err = file_error(wth->fh, err_info);
|
||||
if (*err == 0 && bytes_read != 0)
|
||||
*err = WTAP_ERR_SHORT_READ;
|
||||
return -1;
|
||||
}
|
||||
payload_length = pletoh16(&tmp);
|
||||
|
||||
bytes_read = file_read(&tmp, 2, wth->fh);
|
||||
if (bytes_read != 2) {
|
||||
*err = file_error(wth->fh, err_info);
|
||||
if (*err == 0 && bytes_read != 0)
|
||||
*err = WTAP_ERR_SHORT_READ;
|
||||
return -1;
|
||||
}
|
||||
try_header_size = pletoh16(&tmp);
|
||||
|
||||
buffer = (guint8 *) g_malloc(5 * 4 + payload_length);
|
||||
bytes_read = file_read(buffer, 5 * 4 + payload_length, wth->fh);
|
||||
if (bytes_read != 5 * 4 + payload_length) {
|
||||
if (bytes_read != 4 * 4 + payload_length) {
|
||||
*err = file_error(wth->fh, err_info);
|
||||
if (*err == 0 && bytes_read != 0)
|
||||
*err = WTAP_ERR_SHORT_READ;
|
||||
g_free(buffer);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (try_header_size == 24) {
|
||||
tag_length = strlen(buffer + 5 * 4 + 1) + 1;
|
||||
log_length = strlen(buffer + 5 * 4 + 1 + tag_length) + 1;
|
||||
if (payload_length == 1 + tag_length + log_length) {
|
||||
g_free(buffer);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
tag_length = strlen(buffer + 4 * 4 + 1) + 1;
|
||||
log_length = strlen(buffer + 4 * 4 + 1 + tag_length) + 1;
|
||||
if (payload_length == 1 + tag_length + log_length) {
|
||||
if (file_seek(wth->fh, file_offset + 4 * 4 + 1 + tag_length + log_length, SEEK_SET, err) == -1) {
|
||||
g_free(buffer);
|
||||
return -1;
|
||||
}
|
||||
g_free(buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
g_free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gboolean logcat_read(wtap *wth, int *err, gchar **err_info,
|
||||
gint64 *data_offset)
|
||||
{
|
||||
gint bytes_read;
|
||||
gint packet_size;
|
||||
guint16 payload_length;
|
||||
guint16 tmp;
|
||||
guint8 *buf;
|
||||
struct logcat_phdr *logcat;
|
||||
|
||||
*data_offset = file_tell(wth->fh);
|
||||
|
||||
bytes_read = file_read(&tmp, 2, wth->fh);
|
||||
if (bytes_read != 2) {
|
||||
*err = file_error(wth->fh, err_info);
|
||||
if (*err == 0 && bytes_read != 0)
|
||||
*err = WTAP_ERR_SHORT_READ;
|
||||
return FALSE;
|
||||
}
|
||||
payload_length = pletoh16(&tmp);
|
||||
|
||||
if (file_seek(wth->fh, *data_offset, SEEK_SET, err) == -1)
|
||||
return FALSE;
|
||||
|
||||
logcat = (struct logcat_phdr *) wth->priv;
|
||||
|
||||
if (logcat->version == 1) {
|
||||
packet_size = 5 * 4 + payload_length;
|
||||
} else if (logcat->version == 2) {
|
||||
packet_size = 6 * 4 + payload_length;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
buffer_assure_space(wth->frame_buffer, packet_size);
|
||||
buf = buffer_start_ptr(wth->frame_buffer);
|
||||
|
||||
bytes_read = file_read(buf, packet_size, wth->fh);
|
||||
if (bytes_read != packet_size) {
|
||||
*err = file_error(wth->fh, err_info);
|
||||
if (*err == 0)
|
||||
*err = WTAP_ERR_SHORT_READ;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
wth->phdr.presence_flags = WTAP_HAS_TS | WTAP_HAS_CAP_LEN;
|
||||
wth->phdr.ts.secs = (time_t) pletoh32(buf + 12);
|
||||
wth->phdr.ts.nsecs = (int) pletoh32(buf + 16);
|
||||
wth->phdr.caplen = packet_size;
|
||||
wth->phdr.len = packet_size;
|
||||
|
||||
wth->phdr.pseudo_header.logcat.version = logcat->version;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean logcat_seek_read(wtap *wth, gint64 seek_off,
|
||||
struct wtap_pkthdr *phdr, Buffer *buf,
|
||||
int *err, gchar **err_info)
|
||||
{
|
||||
gint bytes_read;
|
||||
gint packet_size;
|
||||
guint16 payload_length;
|
||||
guint tmp[4];
|
||||
struct logcat_phdr *logcat;
|
||||
|
||||
if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
|
||||
return FALSE;
|
||||
|
||||
bytes_read = file_read(&tmp, 2, wth->random_fh);
|
||||
if (bytes_read != 2) {
|
||||
*err = file_error(wth->random_fh, err_info);
|
||||
if (*err == 0 && bytes_read != 0)
|
||||
*err = WTAP_ERR_SHORT_READ;
|
||||
return FALSE;
|
||||
}
|
||||
payload_length = pletoh16(tmp);
|
||||
|
||||
logcat = (struct logcat_phdr *) wth->priv;
|
||||
|
||||
if (logcat->version == 1) {
|
||||
packet_size = 5 * 4 + payload_length;
|
||||
} else if (logcat->version == 2) {
|
||||
packet_size = 6 * 4 + payload_length;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (file_seek(wth->random_fh, seek_off + 12, SEEK_SET, err) == -1)
|
||||
return FALSE;
|
||||
|
||||
bytes_read = file_read(&tmp, 4, wth->random_fh);
|
||||
if (bytes_read != 4) {
|
||||
*err = file_error(wth->random_fh, err_info);
|
||||
if (*err == 0 && bytes_read != 0)
|
||||
*err = WTAP_ERR_SHORT_READ;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
phdr->ts.secs = (time_t) pletoh32(tmp);
|
||||
|
||||
bytes_read = file_read(tmp, 4, wth->random_fh);
|
||||
if (bytes_read != 4) {
|
||||
*err = file_error(wth->random_fh, err_info);
|
||||
if (*err == 0 && bytes_read != 0)
|
||||
*err = WTAP_ERR_SHORT_READ;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
phdr->ts.nsecs = (int) pletoh32(tmp);
|
||||
|
||||
phdr->presence_flags = WTAP_HAS_TS | WTAP_HAS_CAP_LEN;
|
||||
phdr->caplen = packet_size;
|
||||
phdr->len = packet_size;
|
||||
|
||||
phdr->pseudo_header.logcat.version = logcat->version;
|
||||
|
||||
if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
|
||||
return FALSE;
|
||||
|
||||
return wtap_read_packet_bytes(wth->random_fh, buf, packet_size, err, err_info);
|
||||
}
|
||||
|
||||
int logcat_open(wtap *wth, int *err, gchar **err_info _U_)
|
||||
{
|
||||
int local_err;
|
||||
gchar *local_err_info;
|
||||
gint version;
|
||||
gint tmp_version;
|
||||
struct logcat_phdr *logcat;
|
||||
|
||||
/* check first 3 packets (or 2 or 1 if EOF) versions to check file format is correct */
|
||||
version = detect_version(wth, &local_err, &local_err_info);
|
||||
if (version <= 0)
|
||||
return 0;
|
||||
|
||||
tmp_version = detect_version(wth, &local_err, &local_err_info);
|
||||
if (tmp_version < 0 && !file_eof(wth->fh)) {
|
||||
return 0;
|
||||
} else if (tmp_version > 0) {
|
||||
if (tmp_version != version)
|
||||
return 0;
|
||||
|
||||
tmp_version = detect_version(wth, &local_err, &local_err_info);
|
||||
if (tmp_version != version && !file_eof(wth->fh))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (file_seek(wth->fh, 0, SEEK_SET, err) == -1)
|
||||
return -1;
|
||||
|
||||
logcat = (struct logcat_phdr *) g_malloc(sizeof(struct logcat_phdr));
|
||||
logcat->version = version;
|
||||
|
||||
wth->priv = logcat;
|
||||
|
||||
wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_LOGCAT;
|
||||
wth->file_encap = WTAP_ENCAP_LOGCAT;
|
||||
wth->snapshot_length = 0;
|
||||
|
||||
wth->subtype_read = logcat_read;
|
||||
wth->subtype_seek_read = logcat_seek_read;
|
||||
wth->tsprecision = WTAP_FILE_TSPREC_USEC;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int logcat_dump_can_write_encap(int encap)
|
||||
{
|
||||
if (encap == WTAP_ENCAP_PER_PACKET)
|
||||
return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
|
||||
|
||||
if (encap != WTAP_ENCAP_LOGCAT)
|
||||
return WTAP_ERR_UNSUPPORTED_ENCAP;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gboolean logcat_binary_dump(wtap_dumper *wdh,
|
||||
const struct wtap_pkthdr *phdr,
|
||||
const guint8 *pd, int *err)
|
||||
{
|
||||
if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
|
||||
return FALSE;
|
||||
|
||||
wdh->bytes_dumped += phdr->caplen;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean logcat_binary_dump_open(wtap_dumper *wdh, int *err)
|
||||
{
|
||||
wdh->subtype_write = logcat_binary_dump;
|
||||
wdh->subtype_close = NULL;
|
||||
|
||||
switch (wdh->file_type_subtype) {
|
||||
case WTAP_FILE_TYPE_SUBTYPE_LOGCAT:
|
||||
wdh->tsprecision = WTAP_FILE_TSPREC_USEC;
|
||||
break;
|
||||
|
||||
default:
|
||||
*err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean logcat_dump_text(wtap_dumper *wdh,
|
||||
const struct wtap_pkthdr *phdr,
|
||||
const guint8 *pd, int *err)
|
||||
{
|
||||
gchar *buf;
|
||||
gint length;
|
||||
gchar priority;
|
||||
const gchar *tag;
|
||||
const gint *pid;
|
||||
const gint *tid;
|
||||
const gchar *log;
|
||||
gchar *log_part;
|
||||
const gchar *str_begin;
|
||||
const gchar *str_end;
|
||||
const guint32 *datetime;
|
||||
const guint32 *nanoseconds;
|
||||
const union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header;
|
||||
const struct dumper_t *dumper = (const struct dumper_t *) wdh->priv;
|
||||
|
||||
if (pseudo_header->logcat.version == 1) {
|
||||
pid = (const gint *) (pd + 4);
|
||||
tid = (const gint *) (pd + 2 * 4);
|
||||
datetime = (const guint32 *) (pd + 3 * 4);
|
||||
nanoseconds = (const guint32 *) (pd + 4 * 4);
|
||||
priority = get_priority((const guint8 *) (pd + 5 * 4));
|
||||
tag = (const gchar *) (pd + 5 * 4 + 1);
|
||||
log = tag + strlen(tag) + 1;
|
||||
} else if (pseudo_header->logcat.version == 2) {
|
||||
pid = (const gint *) (pd + 4);
|
||||
tid = (const gint *) (pd + 2 * 4);
|
||||
datetime = (const guint32 *) (pd + 3 * 4);
|
||||
nanoseconds = (const guint32 *) (pd + 4 * 4);
|
||||
priority = get_priority((const guint8 *) (pd + 6 * 4));
|
||||
tag = (const char *) (pd + 6 * 4 + 1);
|
||||
log = tag + strlen(tag) + 1;
|
||||
} else {
|
||||
*err = WTAP_ERR_UNSUPPORTED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
str_begin = str_end = log;
|
||||
while (dumper->type != DUMP_LONG && (str_end = strchr(str_begin, '\n'))) {
|
||||
log_part = (gchar *) g_malloc(str_end - str_begin + 1);
|
||||
strncpy(log_part, str_begin, str_end - str_begin);
|
||||
log_part[str_end - str_begin] = '\0';
|
||||
str_begin = str_end + 1;
|
||||
|
||||
buf = logcat_log(dumper, *datetime, *nanoseconds / 1000000, *pid, *tid,
|
||||
priority, tag, log_part);
|
||||
if (!buf) {
|
||||
g_free(log_part);
|
||||
return FALSE;
|
||||
}
|
||||
g_free(log_part);
|
||||
length = strlen(buf);
|
||||
|
||||
if (!wtap_dump_file_write(wdh, buf, length, err)) {
|
||||
g_free(buf);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
wdh->bytes_dumped += length;
|
||||
|
||||
g_free(buf);
|
||||
}
|
||||
|
||||
if (*str_begin != '\0') {
|
||||
log_part = (gchar *) g_malloc(strlen(str_begin) + 1);
|
||||
strncpy(log_part, str_begin, strlen(str_begin));
|
||||
log_part[strlen(str_begin)] = '\0';
|
||||
|
||||
buf = logcat_log(dumper, *datetime, *nanoseconds / 1000000, *pid, *tid,
|
||||
priority, tag, log_part);
|
||||
if (!buf) {
|
||||
g_free(log_part);
|
||||
return FALSE;
|
||||
}
|
||||
g_free(log_part);
|
||||
length = strlen(buf);
|
||||
|
||||
if (!wtap_dump_file_write(wdh, buf, length, err)) {
|
||||
g_free(buf);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
wdh->bytes_dumped += length;
|
||||
g_free(buf);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean logcat_text_brief_dump_open(wtap_dumper *wdh, int *err _U_)
|
||||
{
|
||||
struct dumper_t *dumper;
|
||||
|
||||
dumper = (struct dumper_t *) g_malloc(sizeof(struct dumper_t));
|
||||
dumper->type = DUMP_BRIEF;
|
||||
|
||||
wdh->priv = dumper;
|
||||
wdh->subtype_write = logcat_dump_text;
|
||||
wdh->subtype_close = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean logcat_text_process_dump_open(wtap_dumper *wdh, int *err _U_)
|
||||
{
|
||||
struct dumper_t *dumper;
|
||||
|
||||
dumper = (struct dumper_t *) g_malloc(sizeof(struct dumper_t));
|
||||
dumper->type = DUMP_PROCESS;
|
||||
|
||||
wdh->priv = dumper;
|
||||
wdh->subtype_write = logcat_dump_text;
|
||||
wdh->subtype_close = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean logcat_text_tag_dump_open(wtap_dumper *wdh, int *err _U_)
|
||||
{
|
||||
struct dumper_t *dumper;
|
||||
|
||||
dumper = (struct dumper_t *) g_malloc(sizeof(struct dumper_t));
|
||||
dumper->type = DUMP_TAG;
|
||||
|
||||
wdh->priv = dumper;
|
||||
wdh->subtype_write = logcat_dump_text;
|
||||
wdh->subtype_close = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean logcat_text_time_dump_open(wtap_dumper *wdh, int *err _U_)
|
||||
{
|
||||
struct dumper_t *dumper;
|
||||
|
||||
dumper = (struct dumper_t *) g_malloc(sizeof(struct dumper_t));
|
||||
dumper->type = DUMP_TIME;
|
||||
|
||||
wdh->priv = dumper;
|
||||
wdh->subtype_write = logcat_dump_text;
|
||||
wdh->subtype_close = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean logcat_text_thread_dump_open(wtap_dumper *wdh, int *err _U_)
|
||||
{
|
||||
struct dumper_t *dumper;
|
||||
|
||||
dumper = (struct dumper_t *) g_malloc(sizeof(struct dumper_t));
|
||||
dumper->type = DUMP_THREAD;
|
||||
|
||||
wdh->priv = dumper;
|
||||
wdh->subtype_write = logcat_dump_text;
|
||||
wdh->subtype_close = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean logcat_text_threadtime_dump_open(wtap_dumper *wdh, int *err _U_)
|
||||
{
|
||||
struct dumper_t *dumper;
|
||||
|
||||
dumper = (struct dumper_t *) g_malloc(sizeof(struct dumper_t));
|
||||
dumper->type = DUMP_THREADTIME;
|
||||
|
||||
wdh->priv = dumper;
|
||||
wdh->subtype_write = logcat_dump_text;
|
||||
wdh->subtype_close = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean logcat_text_long_dump_open(wtap_dumper *wdh, int *err _U_)
|
||||
{
|
||||
struct dumper_t *dumper;
|
||||
|
||||
dumper = (struct dumper_t *) g_malloc(sizeof(struct dumper_t));
|
||||
dumper->type = DUMP_LONG;
|
||||
|
||||
wdh->priv = dumper;
|
||||
wdh->subtype_write = logcat_dump_text;
|
||||
wdh->subtype_close = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - http://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=4 tabstop=8 expandtab:
|
||||
* :indentSize=4:tabSize=8:noTabs=true:
|
||||
*/
|
|
@ -0,0 +1,54 @@
|
|||
/* logcat.h
|
||||
*
|
||||
* Copyright 2014, Michal Labedzki for Tieto Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __LOGCAT_H__
|
||||
#define __LOGCAT_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "wtap.h"
|
||||
|
||||
int logcat_open(wtap *wth, int *err, gchar **err_info);
|
||||
|
||||
gboolean logcat_binary_dump_open(wtap_dumper *wdh, int *err);
|
||||
gboolean logcat_text_brief_dump_open(wtap_dumper *wdh, int *err);
|
||||
gboolean logcat_text_process_dump_open(wtap_dumper *wdh, int *err);
|
||||
gboolean logcat_text_tag_dump_open(wtap_dumper *wdh, int *err);
|
||||
gboolean logcat_text_time_dump_open(wtap_dumper *wdh, int *err);
|
||||
gboolean logcat_text_thread_dump_open(wtap_dumper *wdh, int *err);
|
||||
gboolean logcat_text_threadtime_dump_open(wtap_dumper *wdh, int *err);
|
||||
gboolean logcat_text_long_dump_open(wtap_dumper *wdh, int *err);
|
||||
|
||||
int logcat_dump_can_write_encap(int encap);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Editor modelines - http://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=4 tabstop=8 expandtab:
|
||||
* :indentSize=4:tabSize=8:noTabs=true:
|
||||
*/
|
|
@ -254,6 +254,14 @@ extern "C" {
|
|||
#define WTAP_ENCAP_BLUETOOTH_BREDR_BB 161
|
||||
#define WTAP_ENCAP_BLUETOOTH_LE_LL_WITH_PHDR 162
|
||||
#define WTAP_ENCAP_NSTRACE_3_0 163
|
||||
#define WTAP_ENCAP_LOGCAT 164
|
||||
#define WTAP_ENCAP_LOGCAT_BRIEF 165
|
||||
#define WTAP_ENCAP_LOGCAT_PROCESS 166
|
||||
#define WTAP_ENCAP_LOGCAT_TAG 167
|
||||
#define WTAP_ENCAP_LOGCAT_THREAD 168
|
||||
#define WTAP_ENCAP_LOGCAT_TIME 169
|
||||
#define WTAP_ENCAP_LOGCAT_THREADTIME 170
|
||||
#define WTAP_ENCAP_LOGCAT_LONG 171
|
||||
/* After adding new item here, please also add new item to encap_table_base array */
|
||||
|
||||
#define WTAP_NUM_ENCAP_TYPES wtap_get_num_encap_types()
|
||||
|
@ -330,6 +338,14 @@ extern "C" {
|
|||
#define WTAP_FILE_TYPE_SUBTYPE_CAMINS 64
|
||||
#define WTAP_FILE_TYPE_SUBTYPE_STANAG_4607 65
|
||||
#define WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0 66
|
||||
#define WTAP_FILE_TYPE_SUBTYPE_LOGCAT 67
|
||||
#define WTAP_FILE_TYPE_SUBTYPE_LOGCAT_BRIEF 68
|
||||
#define WTAP_FILE_TYPE_SUBTYPE_LOGCAT_PROCESS 69
|
||||
#define WTAP_FILE_TYPE_SUBTYPE_LOGCAT_TAG 70
|
||||
#define WTAP_FILE_TYPE_SUBTYPE_LOGCAT_THREAD 71
|
||||
#define WTAP_FILE_TYPE_SUBTYPE_LOGCAT_TIME 72
|
||||
#define WTAP_FILE_TYPE_SUBTYPE_LOGCAT_THREADTIME 73
|
||||
#define WTAP_FILE_TYPE_SUBTYPE_LOGCAT_LONG 74
|
||||
|
||||
#define WTAP_NUM_FILE_TYPES_SUBTYPES wtap_get_num_file_types_subtypes()
|
||||
|
||||
|
@ -865,6 +881,11 @@ struct gsm_um_phdr {
|
|||
#define GSM_UM_CHANNEL_AGCH 7
|
||||
#define GSM_UM_CHANNEL_PCH 8
|
||||
|
||||
/* pseudo header for WTAP_ENCAP_LOGCAT */
|
||||
struct logcat_phdr {
|
||||
gint version;
|
||||
};
|
||||
|
||||
union wtap_pseudo_header {
|
||||
struct eth_phdr eth;
|
||||
struct x25_phdr x25;
|
||||
|
@ -890,6 +911,7 @@ union wtap_pseudo_header {
|
|||
struct nstr_phdr nstr;
|
||||
struct nokia_phdr nokia;
|
||||
struct llcp_phdr llcp;
|
||||
struct logcat_phdr logcat;
|
||||
};
|
||||
|
||||
struct wtap_pkthdr {
|
||||
|
|
Loading…
Reference in New Issue