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"
28 #include "bus-message.h"
29 #include "bus-internal.h"
33 static char *indent(unsigned level, unsigned flags) {
39 if (flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY && level > 0)
42 if (flags & BUS_MESSAGE_DUMP_WITH_HEADER)
45 p = new(char, n + level*8 + 1);
49 if (flags & BUS_MESSAGE_DUMP_WITH_HEADER) {
54 memset(p + i, ' ', level*8);
60 int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags) {
69 if (flags & BUS_MESSAGE_DUMP_WITH_HEADER) {
71 "%s%s%s Type=%s%s%s Endian=%c Flags=%u Version=%u Priority=%lli",
72 m->header->type == SD_BUS_MESSAGE_METHOD_ERROR ? ansi_highlight_red() :
73 m->header->type == SD_BUS_MESSAGE_METHOD_RETURN ? ansi_highlight_green() :
74 m->header->type != SD_BUS_MESSAGE_SIGNAL ? ansi_highlight() : "", draw_special_char(DRAW_TRIANGULAR_BULLET), ansi_highlight_off(),
75 ansi_highlight(), bus_message_type_to_string(m->header->type), ansi_highlight_off(),
79 (long long) m->priority);
81 /* Display synthetic message serial number in a more readable
82 * format than (uint32_t) -1 */
83 if (BUS_MESSAGE_COOKIE(m) == 0xFFFFFFFFULL)
84 fprintf(f, " Cookie=-1");
86 fprintf(f, " Cookie=%" PRIu64, BUS_MESSAGE_COOKIE(m));
88 if (m->reply_cookie != 0)
89 fprintf(f, " ReplyCookie=%" PRIu64, m->reply_cookie);
94 fprintf(f, " Sender=%s%s%s", ansi_highlight(), m->sender, ansi_highlight_off());
96 fprintf(f, " Destination=%s%s%s", ansi_highlight(), m->destination, ansi_highlight_off());
98 fprintf(f, " Path=%s%s%s", ansi_highlight(), m->path, ansi_highlight_off());
100 fprintf(f, " Interface=%s%s%s", ansi_highlight(), m->interface, ansi_highlight_off());
102 fprintf(f, " Member=%s%s%s", ansi_highlight(), m->member, ansi_highlight_off());
104 if (m->sender || m->destination || m->path || m->interface || m->member)
107 if (sd_bus_error_is_set(&m->error))
110 " ErrorMessage=%s\"%s\"%s\n",
111 ansi_highlight_red(), strna(m->error.name), ansi_highlight_off(),
112 ansi_highlight_red(), strna(m->error.message), ansi_highlight_off());
114 if (m->monotonic != 0)
115 fprintf(f, " Monotonic="USEC_FMT, m->monotonic);
116 if (m->realtime != 0)
117 fprintf(f, " Realtime="USEC_FMT, m->realtime);
119 fprintf(f, " SequenceNumber=%"PRIu64, m->seqnum);
121 if (m->monotonic != 0 || m->realtime != 0 || m->seqnum != 0)
124 bus_creds_dump(&m->creds, f, true);
127 r = sd_bus_message_rewind(m, !(flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY));
129 return log_error_errno(r, "Failed to rewind: %m");
131 if (!(flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY))
132 fprintf(f, "%sMESSAGE \"%s\" {\n", indent(0, flags), strempty(m->root_container.signature));
135 _cleanup_free_ char *prefix = NULL;
136 const char *contents = NULL;
151 r = sd_bus_message_peek_type(m, &type, &contents);
153 return log_error_errno(r, "Failed to peek type: %m");
159 r = sd_bus_message_exit_container(m);
161 return log_error_errno(r, "Failed to exit container: %m");
165 prefix = indent(level, flags);
169 fprintf(f, "%s};\n", prefix);
173 prefix = indent(level, flags);
177 if (bus_type_is_container(type) > 0) {
178 r = sd_bus_message_enter_container(m, type, contents);
180 return log_error_errno(r, "Failed to enter container: %m");
182 if (type == SD_BUS_TYPE_ARRAY)
183 fprintf(f, "%sARRAY \"%s\" {\n", prefix, contents);
184 else if (type == SD_BUS_TYPE_VARIANT)
185 fprintf(f, "%sVARIANT \"%s\" {\n", prefix, contents);
186 else if (type == SD_BUS_TYPE_STRUCT)
187 fprintf(f, "%sSTRUCT \"%s\" {\n", prefix, contents);
188 else if (type == SD_BUS_TYPE_DICT_ENTRY)
189 fprintf(f, "%sDICT_ENTRY \"%s\" {\n", prefix, contents);
196 r = sd_bus_message_read_basic(m, type, &basic);
198 return log_error_errno(r, "Failed to get basic: %m");
204 case SD_BUS_TYPE_BYTE:
205 fprintf(f, "%sBYTE %s%u%s;\n", prefix, ansi_highlight(), basic.u8, ansi_highlight_off());
208 case SD_BUS_TYPE_BOOLEAN:
209 fprintf(f, "%sBOOLEAN %s%s%s;\n", prefix, ansi_highlight(), true_false(basic.i), ansi_highlight_off());
212 case SD_BUS_TYPE_INT16:
213 fprintf(f, "%sINT16 %s%i%s;\n", prefix, ansi_highlight(), basic.s16, ansi_highlight_off());
216 case SD_BUS_TYPE_UINT16:
217 fprintf(f, "%sUINT16 %s%u%s;\n", prefix, ansi_highlight(), basic.u16, ansi_highlight_off());
220 case SD_BUS_TYPE_INT32:
221 fprintf(f, "%sINT32 %s%i%s;\n", prefix, ansi_highlight(), basic.s32, ansi_highlight_off());
224 case SD_BUS_TYPE_UINT32:
225 fprintf(f, "%sUINT32 %s%u%s;\n", prefix, ansi_highlight(), basic.u32, ansi_highlight_off());
228 case SD_BUS_TYPE_INT64:
229 fprintf(f, "%sINT64 %s%"PRIi64"%s;\n", prefix, ansi_highlight(), basic.s64, ansi_highlight_off());
232 case SD_BUS_TYPE_UINT64:
233 fprintf(f, "%sUINT64 %s%"PRIu64"%s;\n", prefix, ansi_highlight(), basic.u64, ansi_highlight_off());
236 case SD_BUS_TYPE_DOUBLE:
237 fprintf(f, "%sDOUBLE %s%g%s;\n", prefix, ansi_highlight(), basic.d64, ansi_highlight_off());
240 case SD_BUS_TYPE_STRING:
241 fprintf(f, "%sSTRING \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
244 case SD_BUS_TYPE_OBJECT_PATH:
245 fprintf(f, "%sOBJECT_PATH \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
248 case SD_BUS_TYPE_SIGNATURE:
249 fprintf(f, "%sSIGNATURE \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
252 case SD_BUS_TYPE_UNIX_FD:
253 fprintf(f, "%sUNIX_FD %s%i%s;\n", prefix, ansi_highlight(), basic.i, ansi_highlight_off());
257 assert_not_reached("Unknown basic type.");
261 if (!(flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY))
262 fprintf(f, "%s};\n\n", indent(0, flags));
267 static void dump_capabilities(
272 int (*has)(sd_bus_creds *c, int capability)) {
274 unsigned long i, last_cap;
288 fprintf(f, "%s%s=%s", terse ? " " : "", name, terse ? "" : ansi_highlight());
289 last_cap = cap_last_cap();
293 _cleanup_cap_free_charp_ char *t;
298 fprintf(f, terse ? "\n " : "\n ");
316 fputs(ansi_highlight_off(), f);
319 int bus_creds_dump(sd_bus_creds *c, FILE *f, bool terse) {
320 bool audit_sessionid_is_set = false, audit_loginuid_is_set = false;
321 const char *u = NULL, *uu = NULL, *s = NULL, *sl = NULL;
322 uid_t owner, audit_loginuid;
323 uint32_t audit_sessionid;
324 char **cmdline = NULL, **well_known = NULL;
325 const char *prefix, *color, *suffix;
341 color = ansi_highlight();
343 off = ansi_highlight_off();
344 suffix = strappenda(off, "\n");
347 if (c->mask & SD_BUS_CREDS_PID)
348 fprintf(f, "%sPID=%s"PID_FMT"%s", prefix, color, c->pid, suffix);
349 if (c->mask & SD_BUS_CREDS_TID)
350 fprintf(f, "%sTID=%s"PID_FMT"%s", prefix, color, c->tid, suffix);
352 if (terse && ((c->mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_TID))))
355 if (c->mask & SD_BUS_CREDS_UID)
356 fprintf(f, "%sUID=%s"UID_FMT"%s", prefix, color, c->uid, suffix);
357 if (c->mask & SD_BUS_CREDS_EUID)
358 fprintf(f, "%sEUID=%s"UID_FMT"%s", prefix, color, c->euid, suffix);
359 if (c->mask & SD_BUS_CREDS_SUID)
360 fprintf(f, "%sSUID=%s"UID_FMT"%s", prefix, color, c->suid, suffix);
361 if (c->mask & SD_BUS_CREDS_FSUID)
362 fprintf(f, "%sFSUID=%s"UID_FMT"%s", prefix, color, c->fsuid, suffix);
363 r = sd_bus_creds_get_owner_uid(c, &owner);
365 fprintf(f, "%sOwnerUID=%s"UID_FMT"%s", prefix, color, owner, suffix);
366 if (c->mask & SD_BUS_CREDS_GID)
367 fprintf(f, "%sGID=%s"GID_FMT"%s", prefix, color, c->gid, suffix);
368 if (c->mask & SD_BUS_CREDS_EGID)
369 fprintf(f, "%sEGID=%s"GID_FMT"%s", prefix, color, c->egid, suffix);
370 if (c->mask & SD_BUS_CREDS_SGID)
371 fprintf(f, "%sSGID=%s"GID_FMT"%s", prefix, color, c->sgid, suffix);
372 if (c->mask & SD_BUS_CREDS_FSGID)
373 fprintf(f, "%sFSGID=%s"GID_FMT"%s", prefix, color, c->fsgid, suffix);
375 if (c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
378 fprintf(f, "%sSupplementaryGIDs=%s", prefix, color);
379 for (i = 0; i < c->n_supplementary_gids; i++)
380 fprintf(f, "%s" GID_FMT, i > 0 ? " " : "", c->supplementary_gids[i]);
381 fprintf(f, "%s", suffix);
384 if (terse && ((c->mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
385 SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
386 SD_BUS_CREDS_SUPPLEMENTARY_GIDS)) || r >= 0))
389 if (c->mask & SD_BUS_CREDS_COMM)
390 fprintf(f, "%sComm=%s%s%s", prefix, color, c->comm, suffix);
391 if (c->mask & SD_BUS_CREDS_TID_COMM)
392 fprintf(f, "%sTIDComm=%s%s%s", prefix, color, c->tid_comm, suffix);
393 if (c->mask & SD_BUS_CREDS_EXE)
394 fprintf(f, "%sExe=%s%s%s", prefix, color, c->exe, suffix);
396 if (terse && (c->mask & (SD_BUS_CREDS_EXE|SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM)))
399 if (sd_bus_creds_get_cmdline(c, &cmdline) >= 0) {
402 fprintf(f, "%sCommandLine=%s", prefix, color);
403 STRV_FOREACH(i, cmdline) {
410 fprintf(f, "%s", suffix);
413 if (c->mask & SD_BUS_CREDS_SELINUX_CONTEXT)
414 fprintf(f, "%sLabel=%s%s%s", prefix, color, c->label, suffix);
415 if (c->mask & SD_BUS_CREDS_DESCRIPTION)
416 fprintf(f, "%sDescription=%s%s%s", prefix, color, c->description, suffix);
418 if (terse && (c->mask & (SD_BUS_CREDS_SELINUX_CONTEXT|SD_BUS_CREDS_DESCRIPTION)))
421 if (c->mask & SD_BUS_CREDS_CGROUP)
422 fprintf(f, "%sCGroup=%s%s%s", prefix, color, c->cgroup, suffix);
423 sd_bus_creds_get_unit(c, &u);
425 fprintf(f, "%sUnit=%s%s%s", prefix, color, u, suffix);
426 sd_bus_creds_get_user_unit(c, &uu);
428 fprintf(f, "%sUserUnit=%s%s%s", prefix, color, uu, suffix);
429 sd_bus_creds_get_slice(c, &sl);
431 fprintf(f, "%sSlice=%s%s%s", prefix, color, sl, suffix);
432 sd_bus_creds_get_session(c, &s);
434 fprintf(f, "%sSession=%s%s%s", prefix, color, s, suffix);
436 if (terse && ((c->mask & SD_BUS_CREDS_CGROUP) || u || uu || sl || s))
439 if (sd_bus_creds_get_audit_login_uid(c, &audit_loginuid) >= 0) {
440 audit_loginuid_is_set = true;
441 fprintf(f, "%sAuditLoginUID=%s"UID_FMT"%s", prefix, color, audit_loginuid, suffix);
443 if (sd_bus_creds_get_audit_session_id(c, &audit_sessionid) >= 0) {
444 audit_sessionid_is_set = true;
445 fprintf(f, "%sAuditSessionID=%s%"PRIu32"%s", prefix, color, audit_sessionid, suffix);
448 if (terse && (audit_loginuid_is_set || audit_sessionid_is_set))
451 if (c->mask & SD_BUS_CREDS_UNIQUE_NAME)
452 fprintf(f, "%sUniqueName=%s%s%s", prefix, color, c->unique_name, suffix);
454 if (sd_bus_creds_get_well_known_names(c, &well_known) >= 0) {
457 fprintf(f, "%sWellKnownNames=%s", prefix, color);
458 STRV_FOREACH(i, well_known) {
465 fprintf(f, "%s", suffix);
468 if (terse && (c->mask & SD_BUS_CREDS_UNIQUE_NAME || well_known))
471 dump_capabilities(c, f, "EffectiveCapabilities", terse, sd_bus_creds_has_effective_cap);
472 dump_capabilities(c, f, "PermittedCapabilities", terse, sd_bus_creds_has_permitted_cap);
473 dump_capabilities(c, f, "InheritableCapabilities", terse, sd_bus_creds_has_inheritable_cap);
474 dump_capabilities(c, f, "BoundingCapabilities", terse, sd_bus_creds_has_bounding_cap);
480 * For details about the file format, see:
482 * http://wiki.wireshark.org/Development/LibpcapFileFormat
485 typedef struct _packed_ pcap_hdr_s {
486 uint32_t magic_number; /* magic number */
487 uint16_t version_major; /* major version number */
488 uint16_t version_minor; /* minor version number */
489 int32_t thiszone; /* GMT to local correction */
490 uint32_t sigfigs; /* accuracy of timestamps */
491 uint32_t snaplen; /* max length of captured packets, in octets */
492 uint32_t network; /* data link type */
495 typedef struct _packed_ pcaprec_hdr_s {
496 uint32_t ts_sec; /* timestamp seconds */
497 uint32_t ts_usec; /* timestamp microseconds */
498 uint32_t incl_len; /* number of octets of packet saved in file */
499 uint32_t orig_len; /* actual length of packet */
502 int bus_pcap_header(size_t snaplen, FILE *f) {
505 .magic_number = 0xa1b2c3d4U,
508 .thiszone = 0, /* UTC */
510 .network = 231, /* D-Bus */
517 assert((size_t) (uint32_t) snaplen == snaplen);
519 hdr.snaplen = (uint32_t) snaplen;
521 fwrite(&hdr, 1, sizeof(hdr), f);
527 int bus_message_pcap_frame(sd_bus_message *m, size_t snaplen, FILE *f) {
528 struct bus_body_part *part;
529 pcaprec_hdr_t hdr = {};
539 assert((size_t) (uint32_t) snaplen == snaplen);
541 if (m->realtime != 0)
542 timeval_store(&tv, m->realtime);
544 assert_se(gettimeofday(&tv, NULL) >= 0);
546 hdr.ts_sec = tv.tv_sec;
547 hdr.ts_usec = tv.tv_usec;
548 hdr.orig_len = BUS_MESSAGE_SIZE(m);
549 hdr.incl_len = MIN(hdr.orig_len, snaplen);
551 /* write the pcap header */
552 fwrite(&hdr, 1, sizeof(hdr), f);
554 /* write the dbus header */
555 w = MIN(BUS_MESSAGE_BODY_BEGIN(m), snaplen);
556 fwrite(m->header, 1, w, f);
559 /* write the dbus body */
560 MESSAGE_FOREACH_PART(part, i, m) {
564 w = MIN(part->size, snaplen);
565 fwrite(part->data, 1, w, f);