]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/bus-dump.c
tmpfiles: accurately report creation results
[thirdparty/systemd.git] / src / libsystemd / sd-bus / bus-dump.c
CommitLineData
3db0e46b
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2013 Lennart Poettering
7
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.
12
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.
17
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/>.
20***/
21
3db0e46b
LP
22#include "util.h"
23#include "capability.h"
24#include "strv.h"
5b12334d 25#include "audit.h"
1f70b087 26#include "macro.h"
2822da4f 27#include "cap-list.h"
3db0e46b
LP
28
29#include "bus-message.h"
30#include "bus-internal.h"
31#include "bus-type.h"
32#include "bus-dump.h"
33
d55192ad 34static char *indent(unsigned level, unsigned flags) {
f8cfb5f5 35 char *p;
d55192ad 36 unsigned n, i = 0;
f8cfb5f5 37
d55192ad
LP
38 n = 0;
39
40 if (flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY && level > 0)
41 level -= 1;
42
43 if (flags & BUS_MESSAGE_DUMP_WITH_HEADER)
44 n += 2;
45
46 p = new(char, n + level*8 + 1);
f8cfb5f5
LP
47 if (!p)
48 return NULL;
49
d55192ad
LP
50 if (flags & BUS_MESSAGE_DUMP_WITH_HEADER) {
51 p[i++] = ' ';
52 p[i++] = ' ';
53 }
54
55 memset(p + i, ' ', level*8);
56 p[i + level*8] = 0;
f8cfb5f5
LP
57
58 return p;
59}
60
d55192ad 61int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags) {
3db0e46b
LP
62 unsigned level = 1;
63 int r;
3db0e46b
LP
64
65 assert(m);
66
67 if (!f)
68 f = stdout;
69
d55192ad 70 if (flags & BUS_MESSAGE_DUMP_WITH_HEADER) {
3db0e46b 71 fprintf(f,
1fa2f38f 72 "%s%s%s Type=%s%s%s Endian=%c Flags=%u Version=%u Priority=%"PRIi64,
f8cfb5f5
LP
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(),
3db0e46b 76 ansi_highlight(), bus_message_type_to_string(m->header->type), ansi_highlight_off(),
f8cfb5f5 77 m->header->endian,
3db0e46b 78 m->header->flags,
ca7b42c8 79 m->header->version,
1fa2f38f 80 m->priority);
a009c158
LS
81
82 /* Display synthetic message serial number in a more readable
83 * format than (uint32_t) -1 */
693eb9a2
LP
84 if (BUS_MESSAGE_COOKIE(m) == 0xFFFFFFFFULL)
85 fprintf(f, " Cookie=-1");
a009c158 86 else
42c4ebcb 87 fprintf(f, " Cookie=%" PRIu64, BUS_MESSAGE_COOKIE(m));
3db0e46b 88
693eb9a2 89 if (m->reply_cookie != 0)
42c4ebcb 90 fprintf(f, " ReplyCookie=%" PRIu64, m->reply_cookie);
3db0e46b
LP
91
92 fputs("\n", f);
93
94 if (m->sender)
95 fprintf(f, " Sender=%s%s%s", ansi_highlight(), m->sender, ansi_highlight_off());
96 if (m->destination)
97 fprintf(f, " Destination=%s%s%s", ansi_highlight(), m->destination, ansi_highlight_off());
98 if (m->path)
99 fprintf(f, " Path=%s%s%s", ansi_highlight(), m->path, ansi_highlight_off());
100 if (m->interface)
101 fprintf(f, " Interface=%s%s%s", ansi_highlight(), m->interface, ansi_highlight_off());
102 if (m->member)
103 fprintf(f, " Member=%s%s%s", ansi_highlight(), m->member, ansi_highlight_off());
104
105 if (m->sender || m->destination || m->path || m->interface || m->member)
106 fputs("\n", f);
107
108 if (sd_bus_error_is_set(&m->error))
109 fprintf(f,
110 " ErrorName=%s%s%s"
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());
114
3db0e46b 115 if (m->monotonic != 0)
de0671ee 116 fprintf(f, " Monotonic="USEC_FMT, m->monotonic);
3db0e46b 117 if (m->realtime != 0)
de0671ee 118 fprintf(f, " Realtime="USEC_FMT, m->realtime);
6a0e376c 119 if (m->seqnum != 0)
de0671ee 120 fprintf(f, " SequenceNumber=%"PRIu64, m->seqnum);
3db0e46b 121
6a0e376c 122 if (m->monotonic != 0 || m->realtime != 0 || m->seqnum != 0)
3db0e46b
LP
123 fputs("\n", f);
124
d0b2babf 125 bus_creds_dump(&m->creds, f, true);
3db0e46b
LP
126 }
127
d55192ad 128 r = sd_bus_message_rewind(m, !(flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY));
23bbb0de
MS
129 if (r < 0)
130 return log_error_errno(r, "Failed to rewind: %m");
3db0e46b 131
ee04388a
LP
132 if (!(flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY)) {
133 _cleanup_free_ char *prefix = NULL;
134
135 prefix = indent(0, flags);
136 if (!prefix)
137 return log_oom();
138
139 fprintf(f, "%sMESSAGE \"%s\" {\n", prefix, strempty(m->root_container.signature));
140 }
3db0e46b 141
f168c273 142 for (;;) {
3db0e46b
LP
143 _cleanup_free_ char *prefix = NULL;
144 const char *contents = NULL;
145 char type;
146 union {
147 uint8_t u8;
148 uint16_t u16;
149 int16_t s16;
150 uint32_t u32;
151 int32_t s32;
152 uint64_t u64;
153 int64_t s64;
154 double d64;
155 const char *string;
156 int i;
157 } basic;
158
159 r = sd_bus_message_peek_type(m, &type, &contents);
23bbb0de
MS
160 if (r < 0)
161 return log_error_errno(r, "Failed to peek type: %m");
3db0e46b
LP
162
163 if (r == 0) {
164 if (level <= 1)
165 break;
166
167 r = sd_bus_message_exit_container(m);
23bbb0de
MS
168 if (r < 0)
169 return log_error_errno(r, "Failed to exit container: %m");
3db0e46b
LP
170
171 level--;
172
d55192ad 173 prefix = indent(level, flags);
3db0e46b
LP
174 if (!prefix)
175 return log_oom();
176
177 fprintf(f, "%s};\n", prefix);
178 continue;
179 }
180
d55192ad 181 prefix = indent(level, flags);
3db0e46b
LP
182 if (!prefix)
183 return log_oom();
184
185 if (bus_type_is_container(type) > 0) {
186 r = sd_bus_message_enter_container(m, type, contents);
23bbb0de
MS
187 if (r < 0)
188 return log_error_errno(r, "Failed to enter container: %m");
3db0e46b
LP
189
190 if (type == SD_BUS_TYPE_ARRAY)
191 fprintf(f, "%sARRAY \"%s\" {\n", prefix, contents);
192 else if (type == SD_BUS_TYPE_VARIANT)
193 fprintf(f, "%sVARIANT \"%s\" {\n", prefix, contents);
194 else if (type == SD_BUS_TYPE_STRUCT)
195 fprintf(f, "%sSTRUCT \"%s\" {\n", prefix, contents);
196 else if (type == SD_BUS_TYPE_DICT_ENTRY)
197 fprintf(f, "%sDICT_ENTRY \"%s\" {\n", prefix, contents);
198
199 level ++;
200
201 continue;
202 }
203
204 r = sd_bus_message_read_basic(m, type, &basic);
23bbb0de
MS
205 if (r < 0)
206 return log_error_errno(r, "Failed to get basic: %m");
3db0e46b
LP
207
208 assert(r > 0);
209
210 switch (type) {
211
212 case SD_BUS_TYPE_BYTE:
213 fprintf(f, "%sBYTE %s%u%s;\n", prefix, ansi_highlight(), basic.u8, ansi_highlight_off());
214 break;
215
216 case SD_BUS_TYPE_BOOLEAN:
5232c42e 217 fprintf(f, "%sBOOLEAN %s%s%s;\n", prefix, ansi_highlight(), true_false(basic.i), ansi_highlight_off());
3db0e46b
LP
218 break;
219
220 case SD_BUS_TYPE_INT16:
221 fprintf(f, "%sINT16 %s%i%s;\n", prefix, ansi_highlight(), basic.s16, ansi_highlight_off());
222 break;
223
224 case SD_BUS_TYPE_UINT16:
225 fprintf(f, "%sUINT16 %s%u%s;\n", prefix, ansi_highlight(), basic.u16, ansi_highlight_off());
226 break;
227
228 case SD_BUS_TYPE_INT32:
229 fprintf(f, "%sINT32 %s%i%s;\n", prefix, ansi_highlight(), basic.s32, ansi_highlight_off());
230 break;
231
232 case SD_BUS_TYPE_UINT32:
233 fprintf(f, "%sUINT32 %s%u%s;\n", prefix, ansi_highlight(), basic.u32, ansi_highlight_off());
234 break;
235
236 case SD_BUS_TYPE_INT64:
de0671ee 237 fprintf(f, "%sINT64 %s%"PRIi64"%s;\n", prefix, ansi_highlight(), basic.s64, ansi_highlight_off());
3db0e46b
LP
238 break;
239
240 case SD_BUS_TYPE_UINT64:
de0671ee 241 fprintf(f, "%sUINT64 %s%"PRIu64"%s;\n", prefix, ansi_highlight(), basic.u64, ansi_highlight_off());
3db0e46b
LP
242 break;
243
244 case SD_BUS_TYPE_DOUBLE:
245 fprintf(f, "%sDOUBLE %s%g%s;\n", prefix, ansi_highlight(), basic.d64, ansi_highlight_off());
246 break;
247
248 case SD_BUS_TYPE_STRING:
249 fprintf(f, "%sSTRING \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
250 break;
251
252 case SD_BUS_TYPE_OBJECT_PATH:
253 fprintf(f, "%sOBJECT_PATH \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
254 break;
255
256 case SD_BUS_TYPE_SIGNATURE:
257 fprintf(f, "%sSIGNATURE \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
258 break;
259
260 case SD_BUS_TYPE_UNIX_FD:
261 fprintf(f, "%sUNIX_FD %s%i%s;\n", prefix, ansi_highlight(), basic.i, ansi_highlight_off());
262 break;
263
264 default:
265 assert_not_reached("Unknown basic type.");
266 }
267 }
268
ee04388a
LP
269 if (!(flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY)) {
270 _cleanup_free_ char *prefix = NULL;
271
272 prefix = indent(0, flags);
273 if (!prefix)
274 return log_oom();
275
276 fprintf(f, "%s};\n\n", prefix);
277 }
d55192ad 278
3db0e46b
LP
279 return 0;
280}
5b12334d
LP
281
282static void dump_capabilities(
283 sd_bus_creds *c,
284 FILE *f,
285 const char *name,
d0b2babf 286 bool terse,
5b12334d
LP
287 int (*has)(sd_bus_creds *c, int capability)) {
288
289 unsigned long i, last_cap;
290 unsigned n = 0;
291 int r;
292
293 assert(c);
294 assert(f);
295 assert(name);
296 assert(has);
297
298 i = 0;
299 r = has(c, i);
300 if (r < 0)
301 return;
302
d0b2babf 303 fprintf(f, "%s%s=%s", terse ? " " : "", name, terse ? "" : ansi_highlight());
5b12334d
LP
304 last_cap = cap_last_cap();
305
306 for (;;) {
307 if (r > 0) {
5ce70e5b 308
5b12334d
LP
309 if (n > 0)
310 fputc(' ', f);
311 if (n % 4 == 3)
d0b2babf 312 fprintf(f, terse ? "\n " : "\n ");
5b12334d 313
2822da4f 314 fprintf(f, "%s", strna(capability_to_name(i)));
5b12334d
LP
315 n++;
316 }
317
318 i++;
319
320 if (i > last_cap)
321 break;
322
323 r = has(c, i);
324 }
325
326 fputs("\n", f);
d0b2babf
LP
327
328 if (!terse)
329 fputs(ansi_highlight_off(), f);
5b12334d
LP
330}
331
d0b2babf 332int bus_creds_dump(sd_bus_creds *c, FILE *f, bool terse) {
5b12334d
LP
333 bool audit_sessionid_is_set = false, audit_loginuid_is_set = false;
334 const char *u = NULL, *uu = NULL, *s = NULL, *sl = NULL;
335 uid_t owner, audit_loginuid;
336 uint32_t audit_sessionid;
49b832c5 337 char **cmdline = NULL, **well_known = NULL;
d0b2babf 338 const char *prefix, *color, *suffix;
5b12334d
LP
339 int r;
340
341 assert(c);
342
343 if (!f)
344 f = stdout;
345
d0b2babf
LP
346 if (terse) {
347 prefix = " ";
348 suffix = "";
349 color = "";
350 } else {
351 const char *off;
352
353 prefix = "";
354 color = ansi_highlight();
355
356 off = ansi_highlight_off();
357 suffix = strappenda(off, "\n");
358 }
359
5b12334d 360 if (c->mask & SD_BUS_CREDS_PID)
d0b2babf 361 fprintf(f, "%sPID=%s"PID_FMT"%s", prefix, color, c->pid, suffix);
5b12334d 362 if (c->mask & SD_BUS_CREDS_TID)
d0b2babf 363 fprintf(f, "%sTID=%s"PID_FMT"%s", prefix, color, c->tid, suffix);
705a415f 364
32802361 365 if (terse && ((c->mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_TID))))
705a415f
LP
366 fputs("\n", f);
367
5b12334d 368 if (c->mask & SD_BUS_CREDS_UID)
d0b2babf 369 fprintf(f, "%sUID=%s"UID_FMT"%s", prefix, color, c->uid, suffix);
705a415f
LP
370 if (c->mask & SD_BUS_CREDS_EUID)
371 fprintf(f, "%sEUID=%s"UID_FMT"%s", prefix, color, c->euid, suffix);
372 if (c->mask & SD_BUS_CREDS_SUID)
373 fprintf(f, "%sSUID=%s"UID_FMT"%s", prefix, color, c->suid, suffix);
374 if (c->mask & SD_BUS_CREDS_FSUID)
375 fprintf(f, "%sFSUID=%s"UID_FMT"%s", prefix, color, c->fsuid, suffix);
5b12334d
LP
376 r = sd_bus_creds_get_owner_uid(c, &owner);
377 if (r >= 0)
d0b2babf 378 fprintf(f, "%sOwnerUID=%s"UID_FMT"%s", prefix, color, owner, suffix);
5b12334d 379 if (c->mask & SD_BUS_CREDS_GID)
d0b2babf 380 fprintf(f, "%sGID=%s"GID_FMT"%s", prefix, color, c->gid, suffix);
705a415f
LP
381 if (c->mask & SD_BUS_CREDS_EGID)
382 fprintf(f, "%sEGID=%s"GID_FMT"%s", prefix, color, c->egid, suffix);
383 if (c->mask & SD_BUS_CREDS_SGID)
384 fprintf(f, "%sSGID=%s"GID_FMT"%s", prefix, color, c->sgid, suffix);
385 if (c->mask & SD_BUS_CREDS_FSGID)
386 fprintf(f, "%sFSGID=%s"GID_FMT"%s", prefix, color, c->fsgid, suffix);
387
02581590
LP
388 if (c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
389 unsigned i;
390
391 fprintf(f, "%sSupplementaryGIDs=%s", prefix, color);
392 for (i = 0; i < c->n_supplementary_gids; i++)
393 fprintf(f, "%s" GID_FMT, i > 0 ? " " : "", c->supplementary_gids[i]);
394 fprintf(f, "%s", suffix);
395 }
396
705a415f 397 if (terse && ((c->mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
02581590
LP
398 SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
399 SD_BUS_CREDS_SUPPLEMENTARY_GIDS)) || r >= 0))
5b12334d
LP
400 fputs("\n", f);
401
5b12334d 402 if (c->mask & SD_BUS_CREDS_COMM)
d0b2babf 403 fprintf(f, "%sComm=%s%s%s", prefix, color, c->comm, suffix);
5b12334d 404 if (c->mask & SD_BUS_CREDS_TID_COMM)
d0b2babf 405 fprintf(f, "%sTIDComm=%s%s%s", prefix, color, c->tid_comm, suffix);
5cf4f2d1
LP
406 if (c->mask & SD_BUS_CREDS_EXE)
407 fprintf(f, "%sExe=%s%s%s", prefix, color, c->exe, suffix);
14008e4e 408
d0b2babf 409 if (terse && (c->mask & (SD_BUS_CREDS_EXE|SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM)))
14008e4e
LP
410 fputs("\n", f);
411
5b12334d
LP
412 if (sd_bus_creds_get_cmdline(c, &cmdline) >= 0) {
413 char **i;
414
d0b2babf 415 fprintf(f, "%sCommandLine=%s", prefix, color);
5b12334d
LP
416 STRV_FOREACH(i, cmdline) {
417 if (i != cmdline)
418 fputc(' ', f);
419
420 fputs(*i, f);
421 }
422
d0b2babf 423 fprintf(f, "%s", suffix);
5b12334d
LP
424 }
425
5cf4f2d1
LP
426 if (c->mask & SD_BUS_CREDS_SELINUX_CONTEXT)
427 fprintf(f, "%sLabel=%s%s%s", prefix, color, c->label, suffix);
428 if (c->mask & SD_BUS_CREDS_DESCRIPTION)
429 fprintf(f, "%sDescription=%s%s%s", prefix, color, c->description, suffix);
430
431 if (terse && (c->mask & (SD_BUS_CREDS_SELINUX_CONTEXT|SD_BUS_CREDS_DESCRIPTION)))
432 fputs("\n", f);
433
5b12334d 434 if (c->mask & SD_BUS_CREDS_CGROUP)
d0b2babf 435 fprintf(f, "%sCGroup=%s%s%s", prefix, color, c->cgroup, suffix);
c7fbd996 436 (void) sd_bus_creds_get_unit(c, &u);
5b12334d 437 if (u)
d0b2babf 438 fprintf(f, "%sUnit=%s%s%s", prefix, color, u, suffix);
c7fbd996 439 (void) sd_bus_creds_get_user_unit(c, &uu);
5b12334d 440 if (uu)
d0b2babf 441 fprintf(f, "%sUserUnit=%s%s%s", prefix, color, uu, suffix);
c7fbd996 442 (void) sd_bus_creds_get_slice(c, &sl);
5b12334d 443 if (sl)
d0b2babf 444 fprintf(f, "%sSlice=%s%s%s", prefix, color, sl, suffix);
c7fbd996 445 (void) sd_bus_creds_get_session(c, &s);
5b12334d 446 if (s)
d0b2babf 447 fprintf(f, "%sSession=%s%s%s", prefix, color, s, suffix);
5b12334d 448
d0b2babf 449 if (terse && ((c->mask & SD_BUS_CREDS_CGROUP) || u || uu || sl || s))
5b12334d
LP
450 fputs("\n", f);
451
452 if (sd_bus_creds_get_audit_login_uid(c, &audit_loginuid) >= 0) {
453 audit_loginuid_is_set = true;
d0b2babf 454 fprintf(f, "%sAuditLoginUID=%s"UID_FMT"%s", prefix, color, audit_loginuid, suffix);
5b12334d
LP
455 }
456 if (sd_bus_creds_get_audit_session_id(c, &audit_sessionid) >= 0) {
457 audit_sessionid_is_set = true;
d0b2babf 458 fprintf(f, "%sAuditSessionID=%s%"PRIu32"%s", prefix, color, audit_sessionid, suffix);
5b12334d
LP
459 }
460
d0b2babf 461 if (terse && (audit_loginuid_is_set || audit_sessionid_is_set))
5b12334d
LP
462 fputs("\n", f);
463
49b832c5 464 if (c->mask & SD_BUS_CREDS_UNIQUE_NAME)
d0b2babf 465 fprintf(f, "%sUniqueName=%s%s%s", prefix, color, c->unique_name, suffix);
49b832c5
LP
466
467 if (sd_bus_creds_get_well_known_names(c, &well_known) >= 0) {
468 char **i;
469
d0b2babf 470 fprintf(f, "%sWellKnownNames=%s", prefix, color);
49b832c5
LP
471 STRV_FOREACH(i, well_known) {
472 if (i != well_known)
473 fputc(' ', f);
474
475 fputs(*i, f);
476 }
477
d0b2babf 478 fprintf(f, "%s", suffix);
49b832c5
LP
479 }
480
d0b2babf 481 if (terse && (c->mask & SD_BUS_CREDS_UNIQUE_NAME || well_known))
3310dfd5
LP
482 fputc('\n', f);
483
d0b2babf
LP
484 dump_capabilities(c, f, "EffectiveCapabilities", terse, sd_bus_creds_has_effective_cap);
485 dump_capabilities(c, f, "PermittedCapabilities", terse, sd_bus_creds_has_permitted_cap);
486 dump_capabilities(c, f, "InheritableCapabilities", terse, sd_bus_creds_has_inheritable_cap);
487 dump_capabilities(c, f, "BoundingCapabilities", terse, sd_bus_creds_has_bounding_cap);
5b12334d
LP
488
489 return 0;
490}
1f70b087
LP
491
492/*
493 * For details about the file format, see:
494 *
495 * http://wiki.wireshark.org/Development/LibpcapFileFormat
496 */
497
498typedef struct _packed_ pcap_hdr_s {
499 uint32_t magic_number; /* magic number */
500 uint16_t version_major; /* major version number */
501 uint16_t version_minor; /* minor version number */
502 int32_t thiszone; /* GMT to local correction */
503 uint32_t sigfigs; /* accuracy of timestamps */
504 uint32_t snaplen; /* max length of captured packets, in octets */
505 uint32_t network; /* data link type */
506} pcap_hdr_t ;
507
508typedef struct _packed_ pcaprec_hdr_s {
509 uint32_t ts_sec; /* timestamp seconds */
510 uint32_t ts_usec; /* timestamp microseconds */
511 uint32_t incl_len; /* number of octets of packet saved in file */
512 uint32_t orig_len; /* actual length of packet */
513} pcaprec_hdr_t;
514
515int bus_pcap_header(size_t snaplen, FILE *f) {
516
517 pcap_hdr_t hdr = {
518 .magic_number = 0xa1b2c3d4U,
519 .version_major = 2,
520 .version_minor = 4,
521 .thiszone = 0, /* UTC */
522 .sigfigs = 0,
523 .network = 231, /* D-Bus */
524 };
525
526 if (!f)
527 f = stdout;
528
529 assert(snaplen > 0);
530 assert((size_t) (uint32_t) snaplen == snaplen);
531
532 hdr.snaplen = (uint32_t) snaplen;
533
534 fwrite(&hdr, 1, sizeof(hdr), f);
535 fflush(f);
536
537 return 0;
538}
539
540int bus_message_pcap_frame(sd_bus_message *m, size_t snaplen, FILE *f) {
541 struct bus_body_part *part;
542 pcaprec_hdr_t hdr = {};
543 struct timeval tv;
544 unsigned i;
545 size_t w;
546
547 if (!f)
548 f = stdout;
549
550 assert(m);
551 assert(snaplen > 0);
552 assert((size_t) (uint32_t) snaplen == snaplen);
553
554 if (m->realtime != 0)
555 timeval_store(&tv, m->realtime);
556 else
557 assert_se(gettimeofday(&tv, NULL) >= 0);
558
559 hdr.ts_sec = tv.tv_sec;
560 hdr.ts_usec = tv.tv_usec;
561 hdr.orig_len = BUS_MESSAGE_SIZE(m);
562 hdr.incl_len = MIN(hdr.orig_len, snaplen);
563
564 /* write the pcap header */
565 fwrite(&hdr, 1, sizeof(hdr), f);
566
567 /* write the dbus header */
568 w = MIN(BUS_MESSAGE_BODY_BEGIN(m), snaplen);
569 fwrite(m->header, 1, w, f);
570 snaplen -= w;
571
572 /* write the dbus body */
573 MESSAGE_FOREACH_PART(part, i, m) {
574 if (snaplen <= 0)
575 break;
576
577 w = MIN(part->size, snaplen);
578 fwrite(part->data, 1, w, f);
579 snaplen -= w;
580 }
581
582 fflush(f);
583
584 return 0;
585}