1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include "capability.h"
29 #include "bus-message.h"
30 #include "bus-internal.h"
34 static char *indent(unsigned level, unsigned flags) {
40 if (flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY && level > 0)
43 if (flags & BUS_MESSAGE_DUMP_WITH_HEADER)
46 p = new(char, n + level*8 + 1);
50 if (flags & BUS_MESSAGE_DUMP_WITH_HEADER) {
55 memset(p + i, ' ', level*8);
61 int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags) {
70 if (flags & BUS_MESSAGE_DUMP_WITH_HEADER) {
72 "%s%s%s Type=%s%s%s Endian=%c Flags=%u Version=%u Priority=%lli",
73 m->header->type == SD_BUS_MESSAGE_METHOD_ERROR ? ansi_highlight_red() :
74 m->header->type == SD_BUS_MESSAGE_METHOD_RETURN ? ansi_highlight_green() :
75 m->header->type != SD_BUS_MESSAGE_SIGNAL ? ansi_highlight() : "", draw_special_char(DRAW_TRIANGULAR_BULLET), ansi_highlight_off(),
76 ansi_highlight(), bus_message_type_to_string(m->header->type), ansi_highlight_off(),
80 (long long) m->priority);
82 /* Display synthetic message serial number in a more readable
83 * format than (uint32_t) -1 */
84 if (BUS_MESSAGE_COOKIE(m) == 0xFFFFFFFFULL)
85 fprintf(f, " Cookie=-1");
87 fprintf(f, " Cookie=%" PRIu64, BUS_MESSAGE_COOKIE(m));
89 if (m->reply_cookie != 0)
90 fprintf(f, " ReplyCookie=%" PRIu64, m->reply_cookie);
95 fprintf(f, " Sender=%s%s%s", ansi_highlight(), m->sender, ansi_highlight_off());
97 fprintf(f, " Destination=%s%s%s", ansi_highlight(), m->destination, ansi_highlight_off());
99 fprintf(f, " Path=%s%s%s", ansi_highlight(), m->path, ansi_highlight_off());
101 fprintf(f, " Interface=%s%s%s", ansi_highlight(), m->interface, ansi_highlight_off());
103 fprintf(f, " Member=%s%s%s", ansi_highlight(), m->member, ansi_highlight_off());
105 if (m->sender || m->destination || m->path || m->interface || m->member)
108 if (sd_bus_error_is_set(&m->error))
111 " ErrorMessage=%s\"%s\"%s\n",
112 ansi_highlight_red(), strna(m->error.name), ansi_highlight_off(),
113 ansi_highlight_red(), strna(m->error.message), ansi_highlight_off());
115 if (m->monotonic != 0)
116 fprintf(f, " Monotonic="USEC_FMT, m->monotonic);
117 if (m->realtime != 0)
118 fprintf(f, " Realtime="USEC_FMT, m->realtime);
120 fprintf(f, " SequenceNumber=%"PRIu64, m->seqnum);
122 if (m->monotonic != 0 || m->realtime != 0 || m->seqnum != 0)
125 bus_creds_dump(&m->creds, f, true);
128 r = sd_bus_message_rewind(m, !(flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY));
130 return log_error_errno(r, "Failed to rewind: %m");
132 if (!(flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY))
133 fprintf(f, "%sMESSAGE \"%s\" {\n", indent(0, flags), strempty(m->root_container.signature));
136 _cleanup_free_ char *prefix = NULL;
137 const char *contents = NULL;
152 r = sd_bus_message_peek_type(m, &type, &contents);
154 return log_error_errno(r, "Failed to peek type: %m");
160 r = sd_bus_message_exit_container(m);
162 return log_error_errno(r, "Failed to exit container: %m");
166 prefix = indent(level, flags);
170 fprintf(f, "%s};\n", prefix);
174 prefix = indent(level, flags);
178 if (bus_type_is_container(type) > 0) {
179 r = sd_bus_message_enter_container(m, type, contents);
181 return log_error_errno(r, "Failed to enter container: %m");
183 if (type == SD_BUS_TYPE_ARRAY)
184 fprintf(f, "%sARRAY \"%s\" {\n", prefix, contents);
185 else if (type == SD_BUS_TYPE_VARIANT)
186 fprintf(f, "%sVARIANT \"%s\" {\n", prefix, contents);
187 else if (type == SD_BUS_TYPE_STRUCT)
188 fprintf(f, "%sSTRUCT \"%s\" {\n", prefix, contents);
189 else if (type == SD_BUS_TYPE_DICT_ENTRY)
190 fprintf(f, "%sDICT_ENTRY \"%s\" {\n", prefix, contents);
197 r = sd_bus_message_read_basic(m, type, &basic);
199 return log_error_errno(r, "Failed to get basic: %m");
205 case SD_BUS_TYPE_BYTE:
206 fprintf(f, "%sBYTE %s%u%s;\n", prefix, ansi_highlight(), basic.u8, ansi_highlight_off());
209 case SD_BUS_TYPE_BOOLEAN:
210 fprintf(f, "%sBOOLEAN %s%s%s;\n", prefix, ansi_highlight(), true_false(basic.i), ansi_highlight_off());
213 case SD_BUS_TYPE_INT16:
214 fprintf(f, "%sINT16 %s%i%s;\n", prefix, ansi_highlight(), basic.s16, ansi_highlight_off());
217 case SD_BUS_TYPE_UINT16:
218 fprintf(f, "%sUINT16 %s%u%s;\n", prefix, ansi_highlight(), basic.u16, ansi_highlight_off());
221 case SD_BUS_TYPE_INT32:
222 fprintf(f, "%sINT32 %s%i%s;\n", prefix, ansi_highlight(), basic.s32, ansi_highlight_off());
225 case SD_BUS_TYPE_UINT32:
226 fprintf(f, "%sUINT32 %s%u%s;\n", prefix, ansi_highlight(), basic.u32, ansi_highlight_off());
229 case SD_BUS_TYPE_INT64:
230 fprintf(f, "%sINT64 %s%"PRIi64"%s;\n", prefix, ansi_highlight(), basic.s64, ansi_highlight_off());
233 case SD_BUS_TYPE_UINT64:
234 fprintf(f, "%sUINT64 %s%"PRIu64"%s;\n", prefix, ansi_highlight(), basic.u64, ansi_highlight_off());
237 case SD_BUS_TYPE_DOUBLE:
238 fprintf(f, "%sDOUBLE %s%g%s;\n", prefix, ansi_highlight(), basic.d64, ansi_highlight_off());
241 case SD_BUS_TYPE_STRING:
242 fprintf(f, "%sSTRING \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
245 case SD_BUS_TYPE_OBJECT_PATH:
246 fprintf(f, "%sOBJECT_PATH \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
249 case SD_BUS_TYPE_SIGNATURE:
250 fprintf(f, "%sSIGNATURE \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
253 case SD_BUS_TYPE_UNIX_FD:
254 fprintf(f, "%sUNIX_FD %s%i%s;\n", prefix, ansi_highlight(), basic.i, ansi_highlight_off());
258 assert_not_reached("Unknown basic type.");
262 if (!(flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY))
263 fprintf(f, "%s};\n\n", indent(0, flags));
268 static void dump_capabilities(
273 int (*has)(sd_bus_creds *c, int capability)) {
275 unsigned long i, last_cap;
289 fprintf(f, "%s%s=%s", terse ? " " : "", name, terse ? "" : ansi_highlight());
290 last_cap = cap_last_cap();
298 fprintf(f, terse ? "\n " : "\n ");
300 fprintf(f, "%s", strna(capability_to_name(i)));
315 fputs(ansi_highlight_off(), f);
318 int bus_creds_dump(sd_bus_creds *c, FILE *f, bool terse) {
319 bool audit_sessionid_is_set = false, audit_loginuid_is_set = false;
320 const char *u = NULL, *uu = NULL, *s = NULL, *sl = NULL;
321 uid_t owner, audit_loginuid;
322 uint32_t audit_sessionid;
323 char **cmdline = NULL, **well_known = NULL;
324 const char *prefix, *color, *suffix;
340 color = ansi_highlight();
342 off = ansi_highlight_off();
343 suffix = strappenda(off, "\n");
346 if (c->mask & SD_BUS_CREDS_PID)
347 fprintf(f, "%sPID=%s"PID_FMT"%s", prefix, color, c->pid, suffix);
348 if (c->mask & SD_BUS_CREDS_TID)
349 fprintf(f, "%sTID=%s"PID_FMT"%s", prefix, color, c->tid, suffix);
351 if (terse && ((c->mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_TID))))
354 if (c->mask & SD_BUS_CREDS_UID)
355 fprintf(f, "%sUID=%s"UID_FMT"%s", prefix, color, c->uid, suffix);
356 if (c->mask & SD_BUS_CREDS_EUID)
357 fprintf(f, "%sEUID=%s"UID_FMT"%s", prefix, color, c->euid, suffix);
358 if (c->mask & SD_BUS_CREDS_SUID)
359 fprintf(f, "%sSUID=%s"UID_FMT"%s", prefix, color, c->suid, suffix);
360 if (c->mask & SD_BUS_CREDS_FSUID)
361 fprintf(f, "%sFSUID=%s"UID_FMT"%s", prefix, color, c->fsuid, suffix);
362 r = sd_bus_creds_get_owner_uid(c, &owner);
364 fprintf(f, "%sOwnerUID=%s"UID_FMT"%s", prefix, color, owner, suffix);
365 if (c->mask & SD_BUS_CREDS_GID)
366 fprintf(f, "%sGID=%s"GID_FMT"%s", prefix, color, c->gid, suffix);
367 if (c->mask & SD_BUS_CREDS_EGID)
368 fprintf(f, "%sEGID=%s"GID_FMT"%s", prefix, color, c->egid, suffix);
369 if (c->mask & SD_BUS_CREDS_SGID)
370 fprintf(f, "%sSGID=%s"GID_FMT"%s", prefix, color, c->sgid, suffix);
371 if (c->mask & SD_BUS_CREDS_FSGID)
372 fprintf(f, "%sFSGID=%s"GID_FMT"%s", prefix, color, c->fsgid, suffix);
374 if (c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
377 fprintf(f, "%sSupplementaryGIDs=%s", prefix, color);
378 for (i = 0; i < c->n_supplementary_gids; i++)
379 fprintf(f, "%s" GID_FMT, i > 0 ? " " : "", c->supplementary_gids[i]);
380 fprintf(f, "%s", suffix);
383 if (terse && ((c->mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
384 SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
385 SD_BUS_CREDS_SUPPLEMENTARY_GIDS)) || r >= 0))
388 if (c->mask & SD_BUS_CREDS_COMM)
389 fprintf(f, "%sComm=%s%s%s", prefix, color, c->comm, suffix);
390 if (c->mask & SD_BUS_CREDS_TID_COMM)
391 fprintf(f, "%sTIDComm=%s%s%s", prefix, color, c->tid_comm, suffix);
392 if (c->mask & SD_BUS_CREDS_EXE)
393 fprintf(f, "%sExe=%s%s%s", prefix, color, c->exe, suffix);
395 if (terse && (c->mask & (SD_BUS_CREDS_EXE|SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM)))
398 if (sd_bus_creds_get_cmdline(c, &cmdline) >= 0) {
401 fprintf(f, "%sCommandLine=%s", prefix, color);
402 STRV_FOREACH(i, cmdline) {
409 fprintf(f, "%s", suffix);
412 if (c->mask & SD_BUS_CREDS_SELINUX_CONTEXT)
413 fprintf(f, "%sLabel=%s%s%s", prefix, color, c->label, suffix);
414 if (c->mask & SD_BUS_CREDS_DESCRIPTION)
415 fprintf(f, "%sDescription=%s%s%s", prefix, color, c->description, suffix);
417 if (terse && (c->mask & (SD_BUS_CREDS_SELINUX_CONTEXT|SD_BUS_CREDS_DESCRIPTION)))
420 if (c->mask & SD_BUS_CREDS_CGROUP)
421 fprintf(f, "%sCGroup=%s%s%s", prefix, color, c->cgroup, suffix);
422 sd_bus_creds_get_unit(c, &u);
424 fprintf(f, "%sUnit=%s%s%s", prefix, color, u, suffix);
425 sd_bus_creds_get_user_unit(c, &uu);
427 fprintf(f, "%sUserUnit=%s%s%s", prefix, color, uu, suffix);
428 sd_bus_creds_get_slice(c, &sl);
430 fprintf(f, "%sSlice=%s%s%s", prefix, color, sl, suffix);
431 sd_bus_creds_get_session(c, &s);
433 fprintf(f, "%sSession=%s%s%s", prefix, color, s, suffix);
435 if (terse && ((c->mask & SD_BUS_CREDS_CGROUP) || u || uu || sl || s))
438 if (sd_bus_creds_get_audit_login_uid(c, &audit_loginuid) >= 0) {
439 audit_loginuid_is_set = true;
440 fprintf(f, "%sAuditLoginUID=%s"UID_FMT"%s", prefix, color, audit_loginuid, suffix);
442 if (sd_bus_creds_get_audit_session_id(c, &audit_sessionid) >= 0) {
443 audit_sessionid_is_set = true;
444 fprintf(f, "%sAuditSessionID=%s%"PRIu32"%s", prefix, color, audit_sessionid, suffix);
447 if (terse && (audit_loginuid_is_set || audit_sessionid_is_set))
450 if (c->mask & SD_BUS_CREDS_UNIQUE_NAME)
451 fprintf(f, "%sUniqueName=%s%s%s", prefix, color, c->unique_name, suffix);
453 if (sd_bus_creds_get_well_known_names(c, &well_known) >= 0) {
456 fprintf(f, "%sWellKnownNames=%s", prefix, color);
457 STRV_FOREACH(i, well_known) {
464 fprintf(f, "%s", suffix);
467 if (terse && (c->mask & SD_BUS_CREDS_UNIQUE_NAME || well_known))
470 dump_capabilities(c, f, "EffectiveCapabilities", terse, sd_bus_creds_has_effective_cap);
471 dump_capabilities(c, f, "PermittedCapabilities", terse, sd_bus_creds_has_permitted_cap);
472 dump_capabilities(c, f, "InheritableCapabilities", terse, sd_bus_creds_has_inheritable_cap);
473 dump_capabilities(c, f, "BoundingCapabilities", terse, sd_bus_creds_has_bounding_cap);
479 * For details about the file format, see:
481 * http://wiki.wireshark.org/Development/LibpcapFileFormat
484 typedef struct _packed_ pcap_hdr_s {
485 uint32_t magic_number; /* magic number */
486 uint16_t version_major; /* major version number */
487 uint16_t version_minor; /* minor version number */
488 int32_t thiszone; /* GMT to local correction */
489 uint32_t sigfigs; /* accuracy of timestamps */
490 uint32_t snaplen; /* max length of captured packets, in octets */
491 uint32_t network; /* data link type */
494 typedef struct _packed_ pcaprec_hdr_s {
495 uint32_t ts_sec; /* timestamp seconds */
496 uint32_t ts_usec; /* timestamp microseconds */
497 uint32_t incl_len; /* number of octets of packet saved in file */
498 uint32_t orig_len; /* actual length of packet */
501 int bus_pcap_header(size_t snaplen, FILE *f) {
504 .magic_number = 0xa1b2c3d4U,
507 .thiszone = 0, /* UTC */
509 .network = 231, /* D-Bus */
516 assert((size_t) (uint32_t) snaplen == snaplen);
518 hdr.snaplen = (uint32_t) snaplen;
520 fwrite(&hdr, 1, sizeof(hdr), f);
526 int bus_message_pcap_frame(sd_bus_message *m, size_t snaplen, FILE *f) {
527 struct bus_body_part *part;
528 pcaprec_hdr_t hdr = {};
538 assert((size_t) (uint32_t) snaplen == snaplen);
540 if (m->realtime != 0)
541 timeval_store(&tv, m->realtime);
543 assert_se(gettimeofday(&tv, NULL) >= 0);
545 hdr.ts_sec = tv.tv_sec;
546 hdr.ts_usec = tv.tv_usec;
547 hdr.orig_len = BUS_MESSAGE_SIZE(m);
548 hdr.incl_len = MIN(hdr.orig_len, snaplen);
550 /* write the pcap header */
551 fwrite(&hdr, 1, sizeof(hdr), f);
553 /* write the dbus header */
554 w = MIN(BUS_MESSAGE_BODY_BEGIN(m), snaplen);
555 fwrite(m->header, 1, w, f);
558 /* write the dbus body */
559 MESSAGE_FOREACH_PART(part, i, m) {
563 w = MIN(part->size, snaplen);
564 fwrite(part->data, 1, w, f);