1 | // SPDX-License-Identifier: LGPL-2.1 |
2 | // Copyright (C) 2018, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> |
3 | |
4 | #include "trace/beauty/beauty.h" |
5 | #include <sys/socket.h> |
6 | #include <sys/types.h> |
7 | #include <sys/un.h> |
8 | #include <arpa/inet.h> |
9 | |
10 | #include "trace/beauty/generated/sockaddr.c" |
11 | DEFINE_STRARRAY(socket_families, "PF_" ); |
12 | |
13 | static size_t af_inet__scnprintf(struct sockaddr *sa, char *bf, size_t size) |
14 | { |
15 | struct sockaddr_in *sin = (struct sockaddr_in *)sa; |
16 | char tmp[16]; |
17 | return scnprintf(bf, size, ", port: %d, addr: %s" , ntohs(sin->sin_port), |
18 | inet_ntop(sin->sin_family, &sin->sin_addr, tmp, sizeof(tmp))); |
19 | } |
20 | |
21 | static size_t af_inet6__scnprintf(struct sockaddr *sa, char *bf, size_t size) |
22 | { |
23 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; |
24 | u32 flowinfo = ntohl(sin6->sin6_flowinfo); |
25 | char tmp[512]; |
26 | size_t printed = scnprintf(bf, size, ", port: %d, addr: %s" , ntohs(sin6->sin6_port), |
27 | inet_ntop(sin6->sin6_family, &sin6->sin6_addr, tmp, sizeof(tmp))); |
28 | if (flowinfo != 0) |
29 | printed += scnprintf(bf + printed, size - printed, ", flowinfo: %lu" , flowinfo); |
30 | if (sin6->sin6_scope_id != 0) |
31 | printed += scnprintf(bf + printed, size - printed, ", scope_id: %lu" , sin6->sin6_scope_id); |
32 | |
33 | return printed; |
34 | } |
35 | |
36 | static size_t af_local__scnprintf(struct sockaddr *sa, char *bf, size_t size) |
37 | { |
38 | struct sockaddr_un *sun = (struct sockaddr_un *)sa; |
39 | return scnprintf(bf, size, ", path: %s" , sun->sun_path); |
40 | } |
41 | |
42 | static size_t (*af_scnprintfs[])(struct sockaddr *sa, char *bf, size_t size) = { |
43 | [AF_LOCAL] = af_local__scnprintf, |
44 | [AF_INET] = af_inet__scnprintf, |
45 | [AF_INET6] = af_inet6__scnprintf, |
46 | }; |
47 | |
48 | static size_t syscall_arg__scnprintf_augmented_sockaddr(struct syscall_arg *arg, char *bf, size_t size) |
49 | { |
50 | struct sockaddr *sa = (struct sockaddr *)arg->augmented.args; |
51 | char family[32]; |
52 | size_t printed; |
53 | |
54 | strarray__scnprintf(&strarray__socket_families, family, sizeof(family), "%d" , arg->show_string_prefix, sa->sa_family); |
55 | printed = scnprintf(bf, size, "{ .family: %s" , family); |
56 | |
57 | if (sa->sa_family < ARRAY_SIZE(af_scnprintfs) && af_scnprintfs[sa->sa_family]) |
58 | printed += af_scnprintfs[sa->sa_family](sa, bf + printed, size - printed); |
59 | |
60 | return printed + scnprintf(bf + printed, size - printed, " }" ); |
61 | } |
62 | |
63 | size_t syscall_arg__scnprintf_sockaddr(char *bf, size_t size, struct syscall_arg *arg) |
64 | { |
65 | if (arg->augmented.args) |
66 | return syscall_arg__scnprintf_augmented_sockaddr(arg, bf, size); |
67 | |
68 | return scnprintf(bf, size, "%#lx" , arg->val); |
69 | } |
70 | |