X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd%2Fsd-bus%2Fbus-dump.c;h=28fcdda77bf103fd11efc667545ca70dec0d0711;hb=d55192add75584f55932ad463ee6b4cc30370c63;hp=78e7597ed540bca227f9fb752b2be0e6e485f4be;hpb=607553f9306286fdccf0b356bc3d1087adfe21c4;p=elogind.git diff --git a/src/libsystemd/sd-bus/bus-dump.c b/src/libsystemd/sd-bus/bus-dump.c index 78e7597ed..28fcdda77 100644 --- a/src/libsystemd/sd-bus/bus-dump.c +++ b/src/libsystemd/sd-bus/bus-dump.c @@ -23,27 +23,41 @@ #include "capability.h" #include "strv.h" #include "audit.h" +#include "macro.h" #include "bus-message.h" #include "bus-internal.h" #include "bus-type.h" #include "bus-dump.h" -static char *indent(unsigned level) { +static char *indent(unsigned level, unsigned flags) { char *p; + unsigned n, i = 0; - p = new(char, 2 + level + 1); + n = 0; + + if (flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY && level > 0) + level -= 1; + + if (flags & BUS_MESSAGE_DUMP_WITH_HEADER) + n += 2; + + p = new(char, n + level*8 + 1); if (!p) return NULL; - p[0] = p[1] = ' '; - memset(p + 2, '\t', level); - p[2 + level] = 0; + if (flags & BUS_MESSAGE_DUMP_WITH_HEADER) { + p[i++] = ' '; + p[i++] = ' '; + } + + memset(p + i, ' ', level*8); + p[i + level*8] = 0; return p; } -int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) { +int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags) { unsigned level = 1; int r; @@ -52,26 +66,27 @@ int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) { if (!f) f = stdout; - if (with_header) { + if (flags & BUS_MESSAGE_DUMP_WITH_HEADER) { fprintf(f, - "%s%s%sType=%s%s%s Endian=%c Flags=%u Version=%u", + "%s%s%s Type=%s%s%s Endian=%c Flags=%u Version=%u Priority=%lli", m->header->type == SD_BUS_MESSAGE_METHOD_ERROR ? ansi_highlight_red() : m->header->type == SD_BUS_MESSAGE_METHOD_RETURN ? ansi_highlight_green() : m->header->type != SD_BUS_MESSAGE_SIGNAL ? ansi_highlight() : "", draw_special_char(DRAW_TRIANGULAR_BULLET), ansi_highlight_off(), ansi_highlight(), bus_message_type_to_string(m->header->type), ansi_highlight_off(), m->header->endian, m->header->flags, - m->header->version); + m->header->version, + (long long) m->priority); /* Display synthetic message serial number in a more readable * format than (uint32_t) -1 */ if (BUS_MESSAGE_COOKIE(m) == 0xFFFFFFFFULL) fprintf(f, " Cookie=-1"); else - fprintf(f, " Cookie=%lu", (unsigned long) BUS_MESSAGE_COOKIE(m)); + fprintf(f, " Cookie=%" PRIu64, BUS_MESSAGE_COOKIE(m)); if (m->reply_cookie != 0) - fprintf(f, " ReplyCookie=%lu", (unsigned long) m->reply_cookie); + fprintf(f, " ReplyCookie=%" PRIu64, m->reply_cookie); fputs("\n", f); @@ -97,23 +112,26 @@ int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) { ansi_highlight_red(), strna(m->error.message), ansi_highlight_off()); if (m->monotonic != 0) - fprintf(f, " Monotonic=%llu", (unsigned long long) m->monotonic); + fprintf(f, " Monotonic="USEC_FMT, m->monotonic); if (m->realtime != 0) - fprintf(f, " Realtime=%llu", (unsigned long long) m->realtime); + fprintf(f, " Realtime="USEC_FMT, m->realtime); + if (m->seqnum != 0) + fprintf(f, " SequenceNumber=%"PRIu64, m->seqnum); - if (m->monotonic != 0 || m->realtime != 0) + if (m->monotonic != 0 || m->realtime != 0 || m->seqnum != 0) fputs("\n", f); bus_creds_dump(&m->creds, f); } - r = sd_bus_message_rewind(m, true); + r = sd_bus_message_rewind(m, !(flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY)); if (r < 0) { log_error("Failed to rewind: %s", strerror(-r)); return r; } - fprintf(f, " MESSAGE \"%s\" {\n", strempty(m->root_container.signature)); + if (!(flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY)) + fprintf(f, "%sMESSAGE \"%s\" {\n", indent(0, flags), strempty(m->root_container.signature)); for (;;) { _cleanup_free_ char *prefix = NULL; @@ -150,7 +168,7 @@ int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) { level--; - prefix = indent(level); + prefix = indent(level, flags); if (!prefix) return log_oom(); @@ -158,7 +176,7 @@ int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) { continue; } - prefix = indent(level); + prefix = indent(level, flags); if (!prefix) return log_oom(); @@ -218,11 +236,11 @@ int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) { break; case SD_BUS_TYPE_INT64: - fprintf(f, "%sINT64 %s%lli%s;\n", prefix, ansi_highlight(), (long long) basic.s64, ansi_highlight_off()); + fprintf(f, "%sINT64 %s%"PRIi64"%s;\n", prefix, ansi_highlight(), basic.s64, ansi_highlight_off()); break; case SD_BUS_TYPE_UINT64: - fprintf(f, "%sUINT64 %s%llu%s;\n", prefix, ansi_highlight(), (unsigned long long) basic.u64, ansi_highlight_off()); + fprintf(f, "%sUINT64 %s%"PRIu64"%s;\n", prefix, ansi_highlight(), basic.u64, ansi_highlight_off()); break; case SD_BUS_TYPE_DOUBLE: @@ -250,7 +268,9 @@ int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) { } } - fprintf(f, " };\n\n"); + if (!(flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY)) + fprintf(f, "%s};\n\n", indent(0, flags)); + return 0; } @@ -316,18 +336,18 @@ int bus_creds_dump(sd_bus_creds *c, FILE *f) { f = stdout; if (c->mask & SD_BUS_CREDS_PID) - fprintf(f, " PID=%lu", (unsigned long) c->pid); + fprintf(f, " PID="PID_FMT, c->pid); if (c->mask & SD_BUS_CREDS_PID_STARTTIME) - fprintf(f, " PIDStartTime=%llu", (unsigned long long) c->pid_starttime); + fprintf(f, " PIDStartTime="USEC_FMT, c->pid_starttime); if (c->mask & SD_BUS_CREDS_TID) - fprintf(f, " TID=%lu", (unsigned long) c->tid); + fprintf(f, " TID="PID_FMT, c->tid); if (c->mask & SD_BUS_CREDS_UID) - fprintf(f, " UID=%lu", (unsigned long) c->uid); + fprintf(f, " UID="UID_FMT, c->uid); r = sd_bus_creds_get_owner_uid(c, &owner); if (r >= 0) - fprintf(f, " OwnerUID=%lu", (unsigned long) owner); + fprintf(f, " OwnerUID="UID_FMT, owner); if (c->mask & SD_BUS_CREDS_GID) - fprintf(f, " GID=%lu", (unsigned long) c->gid); + fprintf(f, " GID="GID_FMT, c->gid); if ((c->mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID|SD_BUS_CREDS_UID|SD_BUS_CREDS_GID)) || r >= 0) fputs("\n", f); @@ -338,10 +358,16 @@ int bus_creds_dump(sd_bus_creds *c, FILE *f) { fprintf(f, " Comm=%s", c->comm); if (c->mask & SD_BUS_CREDS_TID_COMM) fprintf(f, " TIDComm=%s", c->tid_comm); + + if (c->mask & (SD_BUS_CREDS_EXE|SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM)) + fputs("\n", f); + if (c->mask & SD_BUS_CREDS_SELINUX_CONTEXT) fprintf(f, " Label=%s", c->label); + if (c->mask & SD_BUS_CREDS_DESCRIPTION) + fprintf(f, " Description=%s", c->description); - if (c->mask & (SD_BUS_CREDS_EXE|SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM|SD_BUS_CREDS_SELINUX_CONTEXT)) + if (c->mask & (SD_BUS_CREDS_SELINUX_CONTEXT|SD_BUS_CREDS_DESCRIPTION)) fputs("\n", f); if (sd_bus_creds_get_cmdline(c, &cmdline) >= 0) { @@ -378,11 +404,11 @@ int bus_creds_dump(sd_bus_creds *c, FILE *f) { if (sd_bus_creds_get_audit_login_uid(c, &audit_loginuid) >= 0) { audit_loginuid_is_set = true; - fprintf(f, " AuditLoginUID=%lu", (unsigned long) audit_loginuid); + fprintf(f, " AuditLoginUID="UID_FMT, audit_loginuid); } if (sd_bus_creds_get_audit_session_id(c, &audit_sessionid) >= 0) { audit_sessionid_is_set = true; - fprintf(f, " AuditSessionID=%lu", (unsigned long) audit_sessionid); + fprintf(f, " AuditSessionID=%"PRIu32, audit_sessionid); } if (audit_loginuid_is_set || audit_sessionid_is_set) @@ -415,3 +441,98 @@ int bus_creds_dump(sd_bus_creds *c, FILE *f) { return 0; } + +/* + * For details about the file format, see: + * + * http://wiki.wireshark.org/Development/LibpcapFileFormat + */ + +typedef struct _packed_ pcap_hdr_s { + uint32_t magic_number; /* magic number */ + uint16_t version_major; /* major version number */ + uint16_t version_minor; /* minor version number */ + int32_t thiszone; /* GMT to local correction */ + uint32_t sigfigs; /* accuracy of timestamps */ + uint32_t snaplen; /* max length of captured packets, in octets */ + uint32_t network; /* data link type */ +} pcap_hdr_t ; + +typedef struct _packed_ pcaprec_hdr_s { + uint32_t ts_sec; /* timestamp seconds */ + uint32_t ts_usec; /* timestamp microseconds */ + uint32_t incl_len; /* number of octets of packet saved in file */ + uint32_t orig_len; /* actual length of packet */ +} pcaprec_hdr_t; + +int bus_pcap_header(size_t snaplen, FILE *f) { + + pcap_hdr_t hdr = { + .magic_number = 0xa1b2c3d4U, + .version_major = 2, + .version_minor = 4, + .thiszone = 0, /* UTC */ + .sigfigs = 0, + .network = 231, /* D-Bus */ + }; + + if (!f) + f = stdout; + + assert(snaplen > 0); + assert((size_t) (uint32_t) snaplen == snaplen); + + hdr.snaplen = (uint32_t) snaplen; + + fwrite(&hdr, 1, sizeof(hdr), f); + fflush(f); + + return 0; +} + +int bus_message_pcap_frame(sd_bus_message *m, size_t snaplen, FILE *f) { + struct bus_body_part *part; + pcaprec_hdr_t hdr = {}; + struct timeval tv; + unsigned i; + size_t w; + + if (!f) + f = stdout; + + assert(m); + assert(snaplen > 0); + assert((size_t) (uint32_t) snaplen == snaplen); + + if (m->realtime != 0) + timeval_store(&tv, m->realtime); + else + assert_se(gettimeofday(&tv, NULL) >= 0); + + hdr.ts_sec = tv.tv_sec; + hdr.ts_usec = tv.tv_usec; + hdr.orig_len = BUS_MESSAGE_SIZE(m); + hdr.incl_len = MIN(hdr.orig_len, snaplen); + + /* write the pcap header */ + fwrite(&hdr, 1, sizeof(hdr), f); + + /* write the dbus header */ + w = MIN(BUS_MESSAGE_BODY_BEGIN(m), snaplen); + fwrite(m->header, 1, w, f); + snaplen -= w; + + /* write the dbus body */ + MESSAGE_FOREACH_PART(part, i, m) { + if (snaplen <= 0) + break; + + w = MIN(part->size, snaplen); + fwrite(part->data, 1, w, f); + snaplen -= w; + } + + fflush(f); + + return 0; +}