From: Shankara Pailoor Date: Wed, 2 Jan 2019 21:15:28 +0000 (-0800) Subject: Honor xlat styles when decoding sockaddr_in, sockaddr_in6, and sockaddr_ll X-Git-Tag: v5.0~76 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3798b04eabc32bfc3dec5f4dccc4bbff55c566d4;p=strace Honor xlat styles when decoding sockaddr_in, sockaddr_in6, and sockaddr_ll * print_fields.h (PRINT_FIELD_NET_PORT): Handle xlat styles. * sockaddr.c (print_sll_protocol): New function. (print_sockaddr_data_ll, print_inet_addr, print_sockaddr_data_in6): Handle xlat styles. * NEWS: Mention this. * tests/sockaddr_xlat.c: New file. * tests/sockaddr_xlat-Xabbrev.c: Likewise. * tests/sockaddr_xlat-Xraw.c: Likewise. * tests/sockaddr_xlat-Xverbose.c: Likewise. * tests/Makefile.am (EXTRA_DIST): Add sockaddr_xlat.c. * tests/gen_tests.in (sockaddr_xlat-Xabbrev, sockaddr_xlat-Xraw, sockaddr_xlat-Xverbose): New tests. * tests/pure_executables.list: Add sockaddr_xlat-Xabbrev, sockaddr_xlat-Xraw, and sockaddr_xlat-Xverbose. * tests/.gitignore: Likewise. --- diff --git a/NEWS b/NEWS index b81507fe..151b2cfd 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,7 @@ Noteworthy changes in release ?.?? (????-??-??) =============================================== * Improvements + * Enhanced xlat styles support configured by -X option. * Updated lists of BPF_*, BTRFS_*, FAN_*, IFLA_*, KERN_*, KVM_CAP_*, NDA_*, NETNSA_*, NT_*, PR_*, REL_*, SECCOMP_*, SCTP_*, UDP_*, V4L2_*, and *_MAGIC constants. diff --git a/print_fields.h b/print_fields.h index 9185ba74..b231be2d 100644 --- a/print_fields.h +++ b/print_fields.h @@ -171,9 +171,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 b4a8c3be..b5abb5b7 100644 --- a/sockaddr.c +++ b/sockaddr.c @@ -76,20 +76,51 @@ 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); + + 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)) 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 +189,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); + + 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 +415,39 @@ 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); + + 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); + 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/Makefile.am b/tests/Makefile.am index c4728909..cf2b8b83 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -410,6 +410,7 @@ EXTRA_DIST = \ setreugid.c \ setugid.c \ sigaltstack.expected \ + sockaddr_xlat.c \ sockname.c \ stack-fcall.h \ strace-C.expected \ diff --git a/tests/gen_tests.in b/tests/gen_tests.in index 72758df5..e2e70a12 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 -Xabbrev -e trace=connect +sockaddr_xlat-Xraw -Xraw -e trace=connect +sockaddr_xlat-Xverbose -Xverbose -e trace=connect 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..a4cb109c --- /dev/null +++ b/tests/sockaddr_xlat.c @@ -0,0 +1,184 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include + +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); + 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); + 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 = { + .sin_family = AF_INET, + .sin_port = htons(h_port), + .sin_addr.s_addr = inet_addr(h_addr) + }; + 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); + + 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) +{ + struct sockaddr_in6 in6 = { + .sin6_family = AF_INET6, + .sin6_port = htons(12345), + .sin6_flowinfo = htonl(123456890), + .sin6_scope_id = 0xfacefeed + }; + + validate_in6(&in6, "12:34:56:78:90:ab:cd:ef"); + validate_in6(&in6, "::"); + validate_in6(&in6, "::1"); +} + +int +main(void) +{ + check_ll(); + check_in(); + check_in6(); + puts("+++ exited with 0 +++"); + return 0; +}