diff options
Diffstat (limited to 'wiretap/logcat.c')
-rw-r--r-- | wiretap/logcat.c | 362 |
1 files changed, 2 insertions, 360 deletions
diff --git a/wiretap/logcat.c b/wiretap/logcat.c index 5ac6e383aa..ff80f99a39 100644 --- a/wiretap/logcat.c +++ b/wiretap/logcat.c @@ -28,53 +28,6 @@ #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; -}; - -/* The log format can be found on: - * https://android.googlesource.com/platform/system/core/+/master/include/log/logger.h - * Log format is assumed to be little-endian (Android platform). - */ -/* maximum size of a message payload in a log entry */ -#define LOGGER_ENTRY_MAX_PAYLOAD 4076 - -struct logger_entry { - guint16 len; /* length of the payload */ - guint16 __pad; /* no matter what, we get 2 bytes of padding */ - gint32 pid; /* generating process's pid */ - gint32 tid; /* generating process's tid */ - gint32 sec; /* seconds since Epoch */ - gint32 nsec; /* nanoseconds */ - char msg[0]; /* the entry's payload */ -}; - -struct logger_entry_v2 { - guint16 len; /* length of the payload */ - guint16 hdr_size; /* sizeof(struct logger_entry_v2) */ - gint32 pid; /* generating process's pid */ - gint32 tid; /* generating process's tid */ - gint32 sec; /* seconds since Epoch */ - gint32 nsec; /* nanoseconds */ - union { - /* v1: not present */ - guint32 euid; /* v2: effective UID of logger */ - guint32 lid; /* v3: log id of the payload */ - }; - char msg[0]; /* the entry's payload */ -}; - /* Returns '?' for invalid priorities */ static gchar get_priority(const guint8 priority) { static gchar priorities[] = "??VDIWEFS"; @@ -85,51 +38,6 @@ static gchar get_priority(const guint8 priority) { return priorities[priority]; } -static gchar *logcat_log(const struct dumper_t *dumper, guint32 seconds, - gint milliseconds, 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/%-8s(%5i): %s\n", - priority, tag, pid, log); - case DUMP_PROCESS: - /* NOTE: Last parameter should be "process name", not tag; - Unfortunately, we do not have process name */ - return g_strdup_printf("%c(%5i) %s (%s)\n", - priority, pid, log, ""); - case DUMP_TAG: - return g_strdup_printf("%c/%-8s: %s\n", - priority, tag, log); - case DUMP_THREAD: - return g_strdup_printf("%c(%5i:0x%02x) %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/%-8s(%5i): %s\n", - time_buffer, milliseconds, 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 %-8s: %s\n", - time_buffer, milliseconds, 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:0x%02x %c/%s ]\n%s\n\n", - time_buffer, milliseconds, pid, tid, priority, tag, log); - default: - return NULL; - } - -} - static gint detect_version(wtap *wth, int *err, gchar **err_info) { gint bytes_read; @@ -228,63 +136,7 @@ static gint detect_version(wtap *wth, int *err, gchar **err_info) return -1; } -static gint buffered_detect_version(const guint8 *pd) -{ - struct logger_entry *log_entry; - struct logger_entry_v2 *log_entry_v2; - gint version; - guint8 *msg_payload = NULL; - guint8 *msg_part; - guint8 *msg_end; - guint16 msg_len; - - log_entry_v2 = (struct logger_entry_v2 *) pd; - log_entry = (struct logger_entry *) pd; - - /* must contain at least priority and two nulls as separator */ - if (log_entry->len < 3) - return -1; - - /* payload length may not exceed the maximum payload size */ - if (log_entry->len > LOGGER_ENTRY_MAX_PAYLOAD) - return -1; - - /* cannot rely on __pad being 0 for v1, use heuristics to find out what - * version is in use. First assume the smallest msg. */ - for (version = 1; version <= 2; ++version) { - if (version == 1) { - msg_payload = log_entry->msg; - } else if (version == 2) { - /* v2 is 4 bytes longer */ - msg_payload = log_entry_v2->msg; - if (log_entry_v2->hdr_size != sizeof(*log_entry_v2)) - continue; - } - - /* A v2 msg has a 32-bit userid instead of v1 priority */ - if (get_priority(msg_payload[0]) == '?') - continue; - - /* Is there a terminating '\0' for the tag? */ - msg_part = (guint8 *) memchr(msg_payload, '\0', log_entry->len - 1); - if (msg_part == NULL) - continue; - - /* if msg is '\0'-terminated, is it equal to the payload len? */ - ++msg_part; - msg_len = (guint16)(log_entry->len - (msg_part - msg_payload)); - msg_end = (guint8 *) memchr(msg_part, '\0', msg_len); - /* is the end of the buffer (-1) equal to the end of msg? */ - if (msg_end && (msg_payload + log_entry->len - 1 != msg_end)) - continue; - - return version; - } - - return -1; -} - -static gint exported_pdu_length(const guint8 *pd) { +gint logcat_exported_pdu_length(const guint8 *pd) { guint16 *tag; guint16 *tag_length; gint length = 0; @@ -457,7 +309,7 @@ static gboolean logcat_binary_dump(wtap_dumper *wdh, if (wdh->encap == WTAP_ENCAP_WIRESHARK_UPPER_PDU) { gint skipped_length; - skipped_length = exported_pdu_length(pd); + skipped_length = logcat_exported_pdu_length(pd); pd += skipped_length; caplen -= skipped_length; } @@ -489,216 +341,6 @@ gboolean logcat_binary_dump_open(wtap_dumper *wdh, int *err) 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 struct logger_entry *log_entry; - const struct logger_entry_v2 *log_entry_v2; - gint payload_length; - const gchar *tag; - gint32 pid; - gint32 tid; - gint32 seconds; - gint32 milliseconds; - const gchar *msg_begin; - gint msg_pre_skip; - gchar *log; - gchar *log_part; - gchar *log_next; - gint logcat_version; - const struct dumper_t *dumper = (const struct dumper_t *) wdh->priv; - - /* We can only write packet records. */ - if (phdr->rec_type != REC_TYPE_PACKET) { - *err = WTAP_ERR_REC_TYPE_UNSUPPORTED; - return FALSE; - } - - /* Skip EXPORTED_PDU*/ - if (wdh->encap == WTAP_ENCAP_WIRESHARK_UPPER_PDU) { - gint skipped_length; - - skipped_length = exported_pdu_length(pd); - pd += skipped_length; - - logcat_version = buffered_detect_version(pd); - } else { - const union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header; - - logcat_version = pseudo_header->logcat.version; - } - - log_entry = (struct logger_entry *) pd; - log_entry_v2 = (struct logger_entry_v2 *) pd; - - payload_length = GINT32_FROM_LE(log_entry->len); - pid = GINT32_FROM_LE(log_entry->pid); - tid = GINT32_FROM_LE(log_entry->tid); - seconds = GINT32_FROM_LE(log_entry->sec); - milliseconds = GINT32_FROM_LE(log_entry->nsec) / 1000000; - - /* msg: <prio:1><tag:N>\0<msg:N>\0 with N >= 0, last \0 can be missing */ - if (logcat_version == 1) { - priority = get_priority(log_entry->msg[0]); - tag = log_entry->msg + 1; - msg_pre_skip = 1 + (gint) strlen(tag) + 1; - msg_begin = log_entry->msg + msg_pre_skip; - } else if (logcat_version == 2) { - priority = get_priority(log_entry_v2->msg[0]); - tag = log_entry_v2->msg + 1; - msg_pre_skip = 1 + (gint) strlen(tag) + 1; - msg_begin = log_entry_v2->msg + msg_pre_skip; - } else { - *err = WTAP_ERR_UNSUPPORTED; - return FALSE; - } - - /* copy the message part. If a nul byte was missing, it will be added. */ - log = g_strndup(msg_begin, payload_length - msg_pre_skip); - - /* long format: display one header followed by the whole message (which may - * contain new lines). Other formats: include tag, etc. with each line */ - log_next = log; - do { - log_part = log_next; - if (dumper->type == DUMP_LONG) { - /* read until end, there is no next string */ - log_next = NULL; - } else { - /* read until next newline */ - log_next = strchr(log_part, '\n'); - if (log_next != NULL) { - *log_next = '\0'; - ++log_next; - /* ignore trailing newline */ - if (*log_next == '\0') { - log_next = NULL; - } - } - } - - buf = logcat_log(dumper, seconds, milliseconds, pid, tid, - priority, tag, log_part); - if (!buf) { - g_free(log); - return FALSE; - } - length = (guint32)strlen(buf); - - if (!wtap_dump_file_write(wdh, buf, length, err)) { - g_free(log); - return FALSE; - } - - wdh->bytes_dumped += length; - } while (log_next != NULL); - - g_free(log); - 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 * |