From dc7901f5c3d3047126d38a3f73306468660f5f6c Mon Sep 17 00:00:00 2001 From: Eugene Syromyatnikov Date: Mon, 7 May 2018 00:04:18 +0200 Subject: [PATCH] Add a common MAC address printing routine * print_mac.c: New file. * Makefile.am (strace_SOURCES): Add it. * defs.h (sprint_mac_addr): New declaration. (print_mac_addr): New function, a thin wrapper around sprint_mac_addr. * print_fields.h (PRINT_FIELD_MAC, PRINT_FIELD_MAC_SZ): New macros. * rtnl_link.c (decode_ifla_bridge_id): Use PRINT_FIELD_MAC for bridge address printing. * sock.c (print_ifreq) : Use print_mac_addr for ifr_hwaddr printing. * sockaddr.c (print_sockaddr_data_bt): Use print_mac_addr for {sco,rc,l2}_bdaddr field printing. Co-Authored-by: Dmitry V. Levin --- Makefile.am | 1 + defs.h | 10 +++++++++ print_fields.h | 13 ++++++++++++ print_mac.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ rtnl_link.c | 7 +++---- sock.c | 7 ++----- sockaddr.c | 21 +++++++------------ 7 files changed, 91 insertions(+), 23 deletions(-) create mode 100644 print_mac.c diff --git a/Makefile.am b/Makefile.am index b384254d..776da965 100644 --- a/Makefile.am +++ b/Makefile.am @@ -242,6 +242,7 @@ strace_SOURCES = \ print_group_req.c \ print_fields.h \ print_ifindex.c \ + print_mac.c \ print_mq_attr.c \ print_msgbuf.c \ print_sg_req_info.c \ diff --git a/defs.h b/defs.h index 86073a8a..9f8535c9 100644 --- a/defs.h +++ b/defs.h @@ -687,6 +687,9 @@ extern const char *sprintflags_ex(const char *prefix, const struct xlat *xlat, extern const char *sprinttime(long long sec); extern const char *sprinttime_nsec(long long sec, unsigned long long nsec); extern const char *sprinttime_usec(long long sec, unsigned long long usec); + +extern const char *sprint_mac_addr(const uint8_t addr[], size_t size); + extern void print_symbolic_mode_t(unsigned int); extern void print_numeric_umode_t(unsigned short); extern void print_numeric_long_umask(unsigned long); @@ -969,6 +972,13 @@ extern void tprints(const char *str); extern void tprintf_comment(const char *fmt, ...) ATTRIBUTE_FORMAT((printf, 1, 2)); extern void tprints_comment(const char *str); +static inline void +print_mac_addr(const char *prefix, const uint8_t addr[], size_t size) +{ + tprints(prefix); + tprints(sprint_mac_addr(addr, size)); +} + #if SUPPORTED_PERSONALITIES > 1 extern void set_personality(unsigned int personality); extern unsigned current_personality; diff --git a/print_fields.h b/print_fields.h index 48775088..ff3ebbc3 100644 --- a/print_fields.h +++ b/print_fields.h @@ -220,4 +220,17 @@ printpath((tcp_), (where_).field_); \ } while (0) +#define PRINT_FIELD_MAC(prefix_, where_, field_) \ + PRINT_FIELD_MAC_SZ((prefix_), (where_), field_, \ + ARRAY_SIZE((where_).field_)) + +#define PRINT_FIELD_MAC_SZ(prefix_, where_, field_, size_) \ + do { \ + static_assert(sizeof(((where_).field_)[0]) == 1, \ + "MAC address is not a byte array"); \ + STRACE_PRINTF("%s%s=", (prefix_), #field_); \ + print_mac_addr("", (const uint8_t *) ((where_).field_), \ + (size_)); \ + } while (0) + #endif /* !STRACE_PRINT_FIELDS_H */ diff --git a/print_mac.c b/print_mac.c new file mode 100644 index 00000000..e384f75a --- /dev/null +++ b/print_mac.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018 The strace developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "defs.h" + +#include "error_prints.h" +#include "xstring.h" + +#ifndef MAX_ADDR_LEN +# define MAX_ADDR_LEN 32 +#endif + +const char * +sprint_mac_addr(const uint8_t addr[], size_t size) +{ + static char res[MAX_ADDR_LEN * 3]; + + if (size > MAX_ADDR_LEN) { + error_func_msg("Address size (%zu) is more than maximum " + "supported (%u)", size, MAX_ADDR_LEN); + + return NULL; + } + + char *ptr = res; + + for (size_t i = 0; i < size; i++) + ptr = xappendstr(res, ptr, "%s%02x", i ? ":" : "", addr[i]); + + return res; +} diff --git a/rtnl_link.c b/rtnl_link.c index c725705f..2ef2d63a 100644 --- a/rtnl_link.c +++ b/rtnl_link.c @@ -113,10 +113,9 @@ decode_ifla_bridge_id(struct tcb *const tcp, if (len < sizeof(id)) return false; else if (!umove_or_printaddr(tcp, addr, &id)) { - tprintf("{prio=[%u, %u], addr=%02x:%02x:%02x:%02x:%02x:%02x}", - id.prio[0], id.prio[1], - id.addr[0], id.addr[1], id.addr[2], - id.addr[3], id.addr[4], id.addr[5]); + tprintf("{prio=[%u, %u]", id.prio[0], id.prio[1]); + PRINT_FIELD_MAC(", ", id, addr); + tprints("}"); } return true; diff --git a/sock.c b/sock.c index 7361a7df..3f6fac50 100644 --- a/sock.c +++ b/sock.c @@ -78,11 +78,8 @@ print_ifreq(struct tcb *const tcp, const unsigned int code, case SIOCGIFHWADDR: { /* XXX Are there other hardware addresses than 6-byte MACs? */ - const unsigned char *bytes = - (unsigned char *) &ifr->ifr_hwaddr.sa_data; - tprintf("ifr_hwaddr=%02x:%02x:%02x:%02x:%02x:%02x", - bytes[0], bytes[1], bytes[2], - bytes[3], bytes[4], bytes[5]); + print_mac_addr("ifr_hwaddr=", + (const uint8_t *) &ifr->ifr_hwaddr.sa_data, 6); break; } case SIOCSIFFLAGS: diff --git a/sockaddr.c b/sockaddr.c index ea07c0b0..bd16eb2f 100644 --- a/sockaddr.c +++ b/sockaddr.c @@ -384,29 +384,22 @@ print_sockaddr_data_bt(const void *const buf, const int addrlen) } case sizeof(struct sockaddr_sco): { const struct sockaddr_sco *const sco = buf; - tprintf("sco_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x", - sco->sco_bdaddr.b[0], sco->sco_bdaddr.b[1], - sco->sco_bdaddr.b[2], sco->sco_bdaddr.b[3], - sco->sco_bdaddr.b[4], sco->sco_bdaddr.b[5]); + print_mac_addr("sco_bdaddr=", sco->sco_bdaddr.b, + sizeof(sco->sco_bdaddr.b)); break; } case sizeof(struct sockaddr_rc): { const struct sockaddr_rc *const rc = buf; - tprintf("rc_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x" - ", rc_channel=%u", - rc->rc_bdaddr.b[0], rc->rc_bdaddr.b[1], - rc->rc_bdaddr.b[2], rc->rc_bdaddr.b[3], - rc->rc_bdaddr.b[4], rc->rc_bdaddr.b[5], - rc->rc_channel); + print_mac_addr("rc_bdaddr=", rc->rc_bdaddr.b, + sizeof(rc->rc_bdaddr.b)); + tprintf(", rc_channel=%u", rc->rc_channel); break; } case sizeof(struct sockaddr_l2): { const struct sockaddr_l2 *const l2 = buf; print_bluetooth_l2_psm("l2_psm=", l2->l2_psm); - tprintf(", l2_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x", - l2->l2_bdaddr.b[0], l2->l2_bdaddr.b[1], - l2->l2_bdaddr.b[2], l2->l2_bdaddr.b[3], - l2->l2_bdaddr.b[4], l2->l2_bdaddr.b[5]); + print_mac_addr(", l2_bdaddr=", l2->l2_bdaddr.b, + sizeof(l2->l2_bdaddr.b)); print_bluetooth_l2_cid(", l2_cid=", l2->l2_cid); tprints(", l2_bdaddr_type="); printxval_index(bdaddr_types, l2->l2_bdaddr_type, -- 2.40.0