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.
This commit is contained in:
Shankara Pailoor 2019-01-02 13:15:28 -08:00 committed by Dmitry V. Levin
parent b9a262af78
commit 3798b04eab
11 changed files with 297 additions and 12 deletions

1
NEWS
View File

@ -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.

View File

@ -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 { \

View File

@ -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=");

3
tests/.gitignore vendored
View File

@ -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

View File

@ -410,6 +410,7 @@ EXTRA_DIST = \
setreugid.c \
setugid.c \
sigaltstack.expected \
sockaddr_xlat.c \
sockname.c \
stack-fcall.h \
strace-C.expected \

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
#include "sockaddr_xlat.c"

View File

@ -0,0 +1,2 @@
#define XLAT_RAW 1
#include "sockaddr_xlat.c"

View File

@ -0,0 +1,2 @@
#define XLAT_VERBOSE 1
#include "sockaddr_xlat.c"

184
tests/sockaddr_xlat.c Normal file
View File

@ -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 <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);
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;
}