* 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) <case SIOCGIFHWADDR>: 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 <ldv@altlinux.org>
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 \
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);
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;
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 */
--- /dev/null
+/*
+ * 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;
+}
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;
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:
}
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,