Network order or Host order for raw xlat style
Dmitry V. Levin
ldv at altlinux.org
Tue Jan 8 00:30:08 UTC 2019
On Sun, Jan 06, 2019 at 05:18:22PM -0800, shankarapailoor wrote:
[...]
> Subject: [PATCH v3] handle xlat styles when decoding sockaddr_in and
> sockaddr_in6
It's not just sockaddr_in and sockaddr_in6, but also sockaddr_ll.
> * print_fields.h (PRINT_FIELD_INET4_ADDR, PRINT_FIELD_NET_PORT):
> Handle XLAT_RAW and XLAT_VERBOSE.
> * sockaddr.c (print_sockaddr_data_ll, print_inet_addr,
> print_sockaddr_data_in6): Likewise.
> * sockaddr.c (print_sll_protocol): New function
> * tests/sockaddr_xlat.c.c: New file.
> * tests/sockaddr_xlat-Xabbrev.c: Likewise.
> * tests/sockaddr_xlat-Xraw.c: Likewise.
> * tests/sockaddr_xlat-Xverbose.c: Likewise.
> * tests/gen_tests.in (sockaddr_xlat, sockaddr_xlat-Xabbrev,
> sockaddr_xlat-Xraw, sockaddr_xlat-Xverbose): New tests.
> * tests/pure_executables.list: Add sockaddr_xlat, sockaddr_xlat-Xabbrev,
> sockaddr_xlat-Xraw, sockaddr_xlat-Xverbose.
> * tests/.gitignore: Likewise.
You haven't added the sockaddr_xlat test mentioned above.
There is a choice between two variants: either add the sockaddr_xlat test
or add sockaddr_xlat.c to EXTRA_DIST in tests/Makefile.am,
otherwise "make dist" won't work.
btw, this is a GNU style ChangeLog record, it doesn't need any indentation.
> ---
> print_fields.h | 56 ++++++++--
> sockaddr.c | 84 +++++++++++++--
> tests/.gitignore | 3 +
> tests/gen_tests.in | 3 +
> tests/pure_executables.list | 3 +
> tests/sockaddr_xlat-Xabbrev.c | 1 +
> tests/sockaddr_xlat-Xraw.c | 2 +
> tests/sockaddr_xlat-Xverbose.c | 2 +
> tests/sockaddr_xlat.c | 190 +++++++++++++++++++++++++++++++++
> 9 files changed, 329 insertions(+), 15 deletions(-)
> create mode 100644 tests/sockaddr_xlat-Xabbrev.c
> create mode 100644 tests/sockaddr_xlat-Xraw.c
> create mode 100644 tests/sockaddr_xlat-Xverbose.c
> create mode 100644 tests/sockaddr_xlat.c
>
> diff --git a/print_fields.h b/print_fields.h
> index bcab1b73..9a0a167b 100644
> --- a/print_fields.h
> +++ b/print_fields.h
> @@ -159,9 +159,33 @@
> sizeof((where_).field_), #field_); \
> } while (0)
>
> -# define PRINT_FIELD_INET4_ADDR(prefix_, where_, field_) \
> - STRACE_PRINTF("%s%s=inet_addr(\"%s\")", (prefix_), #field_, \
> - inet_ntoa((where_).field_))
> +#define PRINT_FIELD_INET4_ADDR(prefix_, where_, field_) \
> + do { \
> + STRACE_PRINTF("%s%s=", (prefix_), #field_); \
> + \
> + if (xlat_verbose(xlat_verbosity) \
> + != XLAT_STYLE_ABBREV) { \
> + print_quoted_string( \
> + (const char *) \
> + &(where_).field_.s_addr, \
> + sizeof((where_).field_.s_addr), \
> + QUOTE_FORCE_HEX); \
> + } \
> + \
> + if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW) \
> + break; \
> + \
> + if (xlat_verbose(xlat_verbosity) \
> + == XLAT_STYLE_VERBOSE) \
> + STRACE_PRINTF(" /* "); \
> + \
> + STRACE_PRINTF("inet_addr(\"%s\")", \
> + inet_ntoa((where_).field_)); \
> + \
> + if (xlat_verbose(xlat_verbosity) \
> + == XLAT_STYLE_VERBOSE) \
> + STRACE_PRINTF(" */"); \
> + } while (0)
As you've probably noticed already, PRINT_FIELD_INET4_ADDR is very similar
to AD_INET case of print_inet_addr. I decided to reduce code duplication
by removing PRINT_FIELD_INET4_ADDR and using PRINT_FIELD_INET_ADDR instead.
Please rebase.
> # define PRINT_FIELD_AX25_ADDR(prefix_, where_, field_) \
> do { \
> @@ -175,9 +199,29 @@
> print_x25_addr(&(where_).field_); \
> } while (0)
>
> -# define PRINT_FIELD_NET_PORT(prefix_, where_, field_) \
> - STRACE_PRINTF("%s%s=htons(%u)", (prefix_), #field_, \
> - ntohs((where_).field_))
> +#define PRINT_FIELD_NET_PORT(prefix_, where_, field_) \
> + do { \
> + STRACE_PRINTF("%s%s=", (prefix_), #field_); \
> + \
> + if (xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV) \
> + print_quoted_string((const char *) \
> + &(where_).field_, \
> + sizeof((where_).field_), \
> + QUOTE_FORCE_HEX); \
> + \
> + if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW) \
> + break; \
> + \
> + if (xlat_verbose(xlat_verbosity) \
> + == XLAT_STYLE_VERBOSE) \
> + STRACE_PRINTF(" /* "); \
> + \
> + STRACE_PRINTF("htons(%u)", ntohs((where_).field_)); \
> + \
> + if (xlat_verbose(xlat_verbosity) \
> + == XLAT_STYLE_VERBOSE) \
> + STRACE_PRINTF(" */"); \
> + } while (0)
>
> # define PRINT_FIELD_IFINDEX(prefix_, where_, field_) \
> do { \
> diff --git a/sockaddr.c b/sockaddr.c
> index 3a37f448..2f7d9987 100644
> --- a/sockaddr.c
> +++ b/sockaddr.c
> @@ -76,20 +76,49 @@ print_inet_addr(const int af,
> case AF_INET:
> if (inet_ntop(af, addr, buf, sizeof(buf))) {
> if (var_name)
> - tprintf("%s=inet_addr(\"%s\")", var_name, buf);
> - else
> - tprintf("inet_addr(\"%s\")", buf);
> + tprintf("%s=", var_name);
> +
> + if (xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
> + print_quoted_string((const char*) addr,
> + len, QUOTE_FORCE_HEX);
We use slightly different indentation style in this project.
> +
> + if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
> + return true;
> +
> + if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
> + tprints(" /* ");
> +
> + tprintf("inet_addr(\"%s\")", buf);
> +
> + if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
> + tprints(" */");
> return true;
> }
> break;
> case AF_INET6:
> if (inet_ntop(af, addr, buf, sizeof(buf))) {
> - if (var_name)
> + if (xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV) {
> + if (var_name)
> + tprintf("%s=", var_name);
> + print_quoted_string(addr, len, QUOTE_FORCE_HEX);
> + }
> +
> + if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
> + return true;
> +
> + if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
> + tprints(" /* ");
> +
> + if (var_name && (xlat_verbose(xlat_verbosity) == XLAT_STYLE_ABBREV))
This line is too long, please wrap it.
> tprintf("inet_pton(%s, \"%s\", &%s)",
> "AF_INET6", buf, var_name);
> else
> tprintf("inet_pton(%s, \"%s\")",
> "AF_INET6", buf);
> +
> + if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
> + tprints(" */");
> +
> return true;
> }
> break;
> @@ -158,7 +187,17 @@ print_sockaddr_data_in6(const void *const buf, const int addrlen)
>
> PRINT_FIELD_NET_PORT("", *sa_in6, sin6_port);
> PRINT_FIELD_INET_ADDR(", ", *sa_in6, sin6_addr, AF_INET6);
> - tprintf(", sin6_flowinfo=htonl(%u)", ntohl(sa_in6->sin6_flowinfo));
> + tprints(", sin6_flowinfo=");
> + if (xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
> + print_quoted_string((const char*) &sa_in6->sin6_flowinfo,
> + sizeof(sa_in6->sin6_flowinfo),
> + QUOTE_FORCE_HEX);
We use slightly different indentation style in this project.
> +
> + if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
> + tprintf(" /* htonl(%u) */", ntohl(sa_in6->sin6_flowinfo));
> +
> + if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_ABBREV)
> + tprintf("htonl(%u)", ntohl(sa_in6->sin6_flowinfo));
>
> if (addrlen <= (int) SIN6_MIN_LEN)
> return;
> @@ -374,15 +413,42 @@ print_sockaddr_data_nl(const void *const buf, const int addrlen)
> PRINT_FIELD_0X(", ", *sa_nl, nl_groups);
> }
>
> +static void
> +print_sll_protocol(const struct sockaddr_ll *const sa_ll)
> +{
> + int x_style = xlat_verbose(xlat_verbosity);
> +
> + tprints("sll_protocol=");
> + if (x_style != XLAT_STYLE_ABBREV)
> + print_quoted_string((const char *) &sa_ll->sll_protocol,
> + sizeof(sa_ll->sll_protocol),
> + QUOTE_FORCE_HEX);
We use slightly different indentation style in this project.
> +
> + if (x_style == XLAT_STYLE_RAW)
> + return;
> +
> + if (x_style == XLAT_STYLE_VERBOSE)
> + tprints(" /* ");
> +
> + tprints("htons(");
> + printxval_search_ex(ethernet_protocols,
> + ntohs(sa_ll->sll_protocol),
> + "ETH_P_???",
> + XLAT_STYLE_ABBREV);
We use slightly different indentation style in this project.
> + tprints(")");
> +
> + if (x_style == XLAT_STYLE_VERBOSE)
> + tprints(" */");
> +
> +}
> +
> static void
> print_sockaddr_data_ll(const void *const buf, const int addrlen)
> {
> const struct sockaddr_ll *const sa_ll = buf;
>
> - tprints("sll_protocol=htons(");
> - printxval_search(ethernet_protocols, ntohs(sa_ll->sll_protocol),
> - "ETH_P_???");
> - PRINT_FIELD_IFINDEX("), ", *sa_ll, sll_ifindex);
> + print_sll_protocol(sa_ll);
> + PRINT_FIELD_IFINDEX(", ", *sa_ll, sll_ifindex);
> tprints(", sll_hatype=");
> printxval_search(arp_hardware_types, sa_ll->sll_hatype, "ARPHRD_???");
> tprints(", sll_pkttype=");
> diff --git a/tests/.gitignore b/tests/.gitignore
> index 9ec7a531..24b17017 100644
> --- a/tests/.gitignore
> +++ b/tests/.gitignore
> @@ -526,6 +526,9 @@ sock_filter-v
> sock_filter-v-Xabbrev
> sock_filter-v-Xraw
> sock_filter-v-Xverbose
> +sockaddr_xlat-Xabbrev
> +sockaddr_xlat-Xraw
> +sockaddr_xlat-Xverbose
> socketcall
> sockopt-sol_netlink
> splice
> diff --git a/tests/gen_tests.in b/tests/gen_tests.in
> index 72758df5..0eeadcc5 100644
> --- a/tests/gen_tests.in
> +++ b/tests/gen_tests.in
> @@ -437,6 +437,9 @@ sock_filter-v -v -e trace=getsockopt,setsockopt
> sock_filter-v-Xabbrev -v -e trace=getsockopt,setsockopt -X abbrev
> sock_filter-v-Xraw -a 37 -v -e trace=getsockopt,setsockopt -X raw
> sock_filter-v-Xverbose -v -e trace=getsockopt,setsockopt -X verbose
> +sockaddr_xlat-Xabbrev -a24 -Xabbrev -e trace=connect
> +sockaddr_xlat-Xraw -a24 -Xraw -e trace=connect
> +sockaddr_xlat-Xverbose -a24 -Xverbose -e trace=connect
I think you don't need -a24 here.
> socketcall -a20
> sockopt-sol_netlink -e trace=getsockopt,setsockopt
> splice
> diff --git a/tests/pure_executables.list b/tests/pure_executables.list
> index 1a523809..23aabb9e 100755
> --- a/tests/pure_executables.list
> +++ b/tests/pure_executables.list
> @@ -443,6 +443,9 @@ sock_filter-v
> sock_filter-v-Xabbrev
> sock_filter-v-Xraw
> sock_filter-v-Xverbose
> +sockaddr_xlat-Xabbrev
> +sockaddr_xlat-Xraw
> +sockaddr_xlat-Xverbose
> socketcall
> sockopt-sol_netlink
> splice
> diff --git a/tests/sockaddr_xlat-Xabbrev.c b/tests/sockaddr_xlat-Xabbrev.c
> new file mode 100644
> index 00000000..e994e5ea
> --- /dev/null
> +++ b/tests/sockaddr_xlat-Xabbrev.c
> @@ -0,0 +1 @@
> +#include "sockaddr_xlat.c"
> diff --git a/tests/sockaddr_xlat-Xraw.c b/tests/sockaddr_xlat-Xraw.c
> new file mode 100644
> index 00000000..fb2d73df
> --- /dev/null
> +++ b/tests/sockaddr_xlat-Xraw.c
> @@ -0,0 +1,2 @@
> +#define XLAT_RAW 1
> +#include "sockaddr_xlat.c"
> diff --git a/tests/sockaddr_xlat-Xverbose.c b/tests/sockaddr_xlat-Xverbose.c
> new file mode 100644
> index 00000000..d628975b
> --- /dev/null
> +++ b/tests/sockaddr_xlat-Xverbose.c
> @@ -0,0 +1,2 @@
> +#define XLAT_VERBOSE 1
> +#include "sockaddr_xlat.c"
> diff --git a/tests/sockaddr_xlat.c b/tests/sockaddr_xlat.c
> new file mode 100644
> index 00000000..425dd305
> --- /dev/null
> +++ b/tests/sockaddr_xlat.c
> @@ -0,0 +1,190 @@
> +/*
> + * Check decoding of sockaddr fields under xlat styles.
> + *
> + * Copyright (c) 2015-2018 The strace developers.
> + * All rights reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +#include "tests.h"
> +#include <stdio.h>
> +#include <sys/socket.h>
> +#include <arpa/inet.h>
> +#include <netinet/in.h>
> +#include <linux/ax25.h>
> +#include <linux/if_arp.h>
> +#include <linux/if_ether.h>
> +#include <linux/if_packet.h>
> +
> +static void
> +check_ll(void)
> +{
> + struct sockaddr_ll c_ll = {
> + .sll_family = AF_PACKET,
> + .sll_protocol = htons(ETH_P_ALL),
> + .sll_ifindex = 0xfacefeed,
> + .sll_hatype = ARPHRD_ETHER,
> + .sll_pkttype = PACKET_HOST,
> + .sll_halen = sizeof(c_ll.sll_addr),
> + .sll_addr = "abcdefgh"
> + };
> + unsigned int len = sizeof(c_ll);
> + struct sockaddr *ll = (void *) &c_ll;
> + int rc = connect(-1, ll, len);
Does it work better than a simple
int rc = connect(-1, (void *) &c_ll, len);
?
> + const char *errstr = sprintrc(rc);
> +
> +#if XLAT_RAW
> + printf("connect(-1, {sa_family=%#x"
> + ", sll_protocol=", AF_PACKET);
No need to wrap this line, it's short enough.
> + print_quoted_hex(&c_ll.sll_protocol, sizeof(c_ll.sll_protocol));
> + printf(", sll_ifindex=%u, sll_hatype=%#x"
> + ", sll_pkttype=%u, sll_halen=%u, sll_addr="
> + "[%#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x]"
> + "}, %u) = %s\n",
> + c_ll.sll_ifindex, ARPHRD_ETHER,
> + PACKET_HOST, c_ll.sll_halen,
> + c_ll.sll_addr[0], c_ll.sll_addr[1],
> + c_ll.sll_addr[2], c_ll.sll_addr[3],
> + c_ll.sll_addr[4], c_ll.sll_addr[5],
> + c_ll.sll_addr[6], c_ll.sll_addr[7],
> + len, errstr);
> +#elif XLAT_VERBOSE
> + printf("connect(-1, {sa_family=%#x /* AF_PACKET */"
> + ", sll_protocol=", AF_PACKET);
> + print_quoted_hex(&c_ll.sll_protocol, sizeof(c_ll.sll_protocol));
> + printf(" /* htons(ETH_P_ALL) */"
> + ", sll_ifindex=%u, sll_hatype=%#x /* ARPHRD_ETHER */"
> + ", sll_pkttype=%u /* PACKET_HOST */, sll_halen=%u, sll_addr="
> + "[%#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x]"
> + "}, %u) = %s\n",
> + c_ll.sll_ifindex, ARPHRD_ETHER,
> + PACKET_HOST, c_ll.sll_halen,
> + c_ll.sll_addr[0], c_ll.sll_addr[1],
> + c_ll.sll_addr[2], c_ll.sll_addr[3],
> + c_ll.sll_addr[4], c_ll.sll_addr[5],
> + c_ll.sll_addr[6], c_ll.sll_addr[7],
> + len, errstr);
> +
> +#else /* XLAT_ABBREV */
> + printf("connect(-1, {sa_family=AF_PACKET"
> + ", sll_protocol=htons(ETH_P_ALL)"
> + ", sll_ifindex=%u, sll_hatype=ARPHRD_ETHER"
> + ", sll_pkttype=PACKET_HOST, sll_halen=%u, sll_addr="
> + "[%#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x]"
> + "}, %u) = %s\n",
> + c_ll.sll_ifindex, c_ll.sll_halen,
> + c_ll.sll_addr[0], c_ll.sll_addr[1],
> + c_ll.sll_addr[2], c_ll.sll_addr[3],
> + c_ll.sll_addr[4], c_ll.sll_addr[5],
> + c_ll.sll_addr[6], c_ll.sll_addr[7],
> + len, errstr);
> +#endif
> +}
> +
> +static void
> +check_in(void)
> +{
> + const unsigned short h_port = 12345;
> + static const char h_addr[] = "127.0.0.1";
> +
> + struct sockaddr_in in;;
Double semicolon?
> + in.sin_family = AF_INET;
> + in.sin_port = htons(h_port);
> + in.sin_addr.s_addr = inet_addr(h_addr);
Could you use designated initializers here the same way you did in check_ll?
> + unsigned int len = sizeof(in);
> + int rc = connect(-1, (void *) &in, len);
> + const char * errstr = sprintrc(rc);
> +#if XLAT_RAW
> + printf("connect(-1, {sa_family=%#x, sin_port=", AF_INET);
> + print_quoted_hex((const void *) &in.sin_port, sizeof(in.sin_port));
> + printf(", sin_addr=");
> + print_quoted_hex((const void *) &in.sin_addr.s_addr,
> + sizeof(in.sin_addr.s_addr));
> + printf("}, %u) = %s\n", len, errstr);
> +#elif XLAT_VERBOSE
> + printf("connect(-1, {sa_family=%#x /* AF_INET */, sin_port=", AF_INET);
> + print_quoted_hex((const void *) &in.sin_port, sizeof(in.sin_port));
> + printf(" /* htons(%hu) */, sin_addr=", h_port);
> + print_quoted_hex((const void *) &in.sin_addr.s_addr,
> + sizeof(in.sin_addr.s_addr));
> + printf(" /* inet_addr(\"%s\") */}, %u) = %s\n",
> + h_addr, len, errstr);
> +#else /* XLAT_ABBREV */
> + printf("connect(-1, {sa_family=AF_INET, sin_port=htons(%hu)"
> + ", sin_addr=inet_addr(\"%s\")}, %u) = %s\n",
> + h_port, h_addr, len, errstr);
> +#endif
> +}
> +
> +static void
> +validate_in6(struct sockaddr_in6 *const in6, const char *const h_addr)
> +{
> + inet_pton(AF_INET6, h_addr, &in6->sin6_addr);
> +
> + in6->sin6_scope_id = 0xfacefeed;
in6->sin6_scope_id seems to be initialized in check_in6.
> + unsigned int len = sizeof(*in6);
> + int rc = connect(-1, (void *) in6, len);
> + const char *errstr = sprintrc(rc);
> +#if XLAT_RAW
> + printf("connect(-1, {sa_family=%#x, sin6_port=", AF_INET6);
> + print_quoted_hex(&in6->sin6_port, sizeof(in6->sin6_port));
> + printf(", sin6_addr=");
> + print_quoted_hex(&in6->sin6_addr, sizeof(struct in6_addr));
> + printf(", sin6_flowinfo=");
> + print_quoted_hex(&in6->sin6_flowinfo, sizeof(in6->sin6_flowinfo));
> + printf(", sin6_scope_id=%u}, %u)"
> + " = %s\n", in6->sin6_scope_id, len, errstr);
> +#elif XLAT_VERBOSE
> + printf("connect(-1, {sa_family=%#x /* AF_INET6 */", AF_INET6);
> + printf(", sin6_port=");
> + print_quoted_hex(&in6->sin6_port, sizeof(in6->sin6_port));
> + printf(" /* htons(%hu) */", ntohs(in6->sin6_port));
> + printf(", sin6_addr=");
> + print_quoted_hex(&in6->sin6_addr, sizeof(struct in6_addr));
> + printf(" /* inet_pton(AF_INET6, \"%s\") */", h_addr);
> + printf(", sin6_flowinfo=");
> + print_quoted_hex(&in6->sin6_flowinfo, sizeof(in6->sin6_flowinfo));
> + printf(" /* htonl(%u) */"
> + ", sin6_scope_id=%u}, %u)"
> + " = %s\n",
> + ntohl(in6->sin6_flowinfo), in6->sin6_scope_id,
> + len, errstr);
> +#else
> + printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
> + ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
> + ", sin6_flowinfo=htonl(%u)"
> + ", sin6_scope_id=%u}, %u)"
> + " = %s\n",
> + ntohs(in6->sin6_port), h_addr,
> + ntohl(in6->sin6_flowinfo), in6->sin6_scope_id,
> + len, errstr);
> +#endif
> +}
> +
> +static void
> +check_in6(void)
> +{
> + const unsigned short h_port = 12345;
> + const unsigned int h_flowinfo = 1234567890;
> + const char *h_addr = "12:34:56:78:90:ab:cd:ef";
> + struct sockaddr_in6 in6;
> +
> + in6.sin6_family = AF_INET6;
> + in6.sin6_port = htons(h_port);
> + in6.sin6_flowinfo = htonl(h_flowinfo);
> + inet_pton(AF_INET6, h_addr, &in6.sin6_addr);
> + in6.sin6_scope_id = 0xfacefeed;
Could you use designated initializers here the same way you did in check_ll?
Note that in6.sin6_addr is initialized later in validate_in6.
> + validate_in6(&in6, h_addr);
> + validate_in6(&in6, "::");
> + validate_in6(&in6, "::1");
Please remove trailing whitespaces, they upset "git am".
> +}
> +
> +int
> +main(int argc, char **argv)
Are you going to use these arguments later?
> +{
> + check_ll();
> + check_in();
> + check_in6();
> + puts("+++ exited with 0 +++");
> + return 0;
> +}
--
ldv
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20190108/e5592c16/attachment.bin>
More information about the Strace-devel
mailing list