]> granicus.if.org Git - strace/commitdiff
sock: guess ifr_hwaddr size in SIOCSIFHWADDR/SIOCGIFHWADDR
authorEugene Syromyatnikov <evgsyr@gmail.com>
Mon, 7 May 2018 06:34:44 +0000 (08:34 +0200)
committerDmitry V. Levin <ldv@altlinux.org>
Wed, 23 May 2018 23:27:43 +0000 (23:27 +0000)
And make the output more structured.

* sock.c: Include xlat/arp_hardware_types.h in XLAT_MACROS_ONLY mode.
(print_ifreq) <case SIOCSIFHWADDR, case SIOCGIFHWADDR>: Introduce
hwaddr_sizes array, print ifr_hwaddr.sa_family, print ifr_hwaddr.sa_data
using hwaddr_sizes and PRINT_FIELD_MAC_SZ.

sock.c

diff --git a/sock.c b/sock.c
index 3f6fac500146efe9e28fb17483864f70195c1737..bad5f05f22f466ad9c214401e208adba2f0ba2c7 100644 (file)
--- a/sock.c
+++ b/sock.c
@@ -47,6 +47,10 @@ typedef struct ifreq struct_ifreq;
 
 #include "xlat/iffflags.h"
 
+#define XLAT_MACROS_ONLY
+# include "xlat/arp_hardware_types.h"
+#undef XLAT_MACROS_ONLY
+
 static void
 print_ifname(const char *ifname)
 {
@@ -76,10 +80,87 @@ print_ifreq(struct tcb *const tcp, const unsigned int code,
                break;
        case SIOCSIFHWADDR:
        case SIOCGIFHWADDR: {
-               /* XXX Are there other hardware addresses
-                  than 6-byte MACs?  */
-               print_mac_addr("ifr_hwaddr=",
-                              (const uint8_t *) &ifr->ifr_hwaddr.sa_data, 6);
+               static uint8_t hwaddr_sizes[] = {
+                       [0 ... ARPHRD_IEEE802_TR] = 255,
+
+                       [ARPHRD_NETROM]     =  7 /* AX25_ADDR_LEN */,
+                       [ARPHRD_ETHER]      =  6 /* ETH_ALEN */,
+                       /* ARPHRD_EETHER - no actual devices in Linux */
+                       [ARPHRD_AX25]       =  7 /* AX25_ADDR_LEN */,
+                       /* ARPHRD_PRONET - no actual devices in Linux */
+                       /* ARPHRD_CHAOS - no actual devices in Linux */
+                       [ARPHRD_IEEE802]    =  6 /* FC_ALEN */,
+                       [ARPHRD_ARCNET]     =  1 /* ARCNET_ALEN */,
+                       /* ARPHRD_APPLETLK - no actual devices in Linux */
+                       [ARPHRD_DLCI]       = sizeof(short),
+                       /* ARPHRD_ATM - no explicit setting */
+                       /* ARPHRD_METRICOM - no actual devices in Linux */
+                       [ARPHRD_IEEE1394]   = 16 /* FWNET_ALEN */,
+                       [ARPHRD_EUI64]      =  8 /* EUI64_ADDR_LEN */,
+                       [ARPHRD_INFINIBAND] = 20 /* INFINIBAND_ALEN */,
+                       [ARPHRD_SLIP]       =  0,
+                       /* ARPHRD_CSLIP - no actual devices in Linux */
+                       /* ARPHRD_SLIP6 - no actual devices in Linux */
+                       /* ARPHRD_CSLIP6 - no actual devices in Linux */
+                       /* ARPHRD_RSRVD - no actual devices in Linux */
+                       /* ARPHRD_ADAPT - no actual devices in Linux */
+                       [ARPHRD_ROSE]       =  5 /* ROSE_ADDR_LEN */,
+                       [ARPHRD_X25]        =  0,
+                       /* ARPHRD_HWX25 - no actual devices in Linux */
+                       [ARPHRD_CAN]        =  0,
+                       [ARPHRD_PPP]        =  0,
+                       /* ARPHRD_CISCO - no actual devices in Linux */
+                       /* ARPHRD_LAPB - no actual devices in Linux */
+                       /* ARPHRD_DDCMP - no actual devices in Linux */
+                       [ARPHRD_RAWHDLC]    =  0,
+                       [ARPHRD_RAWIP]      =  0,
+                       [ARPHRD_TUNNEL]     =  4 /* IPIP */,
+                       [ARPHRD_TUNNEL6]    = 16 /* sizeof(struct in6_addr) */,
+                       /* ARPHRD_FRAD - no actual devices in Linux */
+                       /* ARPHRD_SKIP - no actual devices in Linux */
+                       [ARPHRD_LOOPBACK]   =  6 /* ETH_ALEN */,
+                       [ARPHRD_LOCALTLK]   =  1 /* LTALK_ALEN */,
+                       [ARPHRD_FDDI]       =  6 /* FDDI_K_ALEN */,
+                       /* ARPHRD_BIF - no actual devices in Linux */
+                       [ARPHRD_SIT]        =  4,
+                       [ARPHRD_IPDDP]      =  0,
+                       [ARPHRD_IPGRE]      =  4,
+                       [ARPHRD_PIMREG]     =  0,
+                       [ARPHRD_HIPPI]      =  6 /* HIPPI_ALEN */,
+                       /* ARPHRD_ASH - no actual devices in Linux */
+                       /* ARPHRD_ECONET - no actual devices in Linux */
+                       [ARPHRD_IRDA]       =  4 /* LAP_ALEN */,
+                       /* ARPHRD_FCPP - no actual devices in Linux */
+                       /* ARPHRD_FCAL - no actual devices in Linux */
+                       /* ARPHRD_FCPL - no actual devices in Linux */
+                       /* ARPHRD_FCFABRIC - no actual devices in Linux */
+                       /* ARPHRD_IEEE802_TR - no actual devices in Linux */
+                       [ARPHRD_IEEE80211]  =  6 /* ETH_ALEN */,
+                       [ARPHRD_IEEE80211_PRISM] = 6 /* ETH_ALEN */,
+                       [ARPHRD_IEEE80211_RADIOTAP] = 6 /* ETH_ALEN */,
+                       [ARPHRD_IEEE802154]
+                               = 8 /* IEEE802154_EXTENDED_ADDR_LEN */,
+                       [ARPHRD_IEEE802154_MONITOR]
+                               = 8 /* IEEE802154_EXTENDED_ADDR_LEN */,
+                       [ARPHRD_PHONET]     =  1,
+                       [ARPHRD_PHONET_PIPE] = 1,
+                       [ARPHRD_CAIF]       =  0,
+                       [ARPHRD_IP6GRE]     = 16 /* sizeof(struct in6_addr) */,
+                       [ARPHRD_NETLINK]    =  0,
+                       [ARPHRD_6LOWPAN]    =  8 /* EUI64_ADDR_LEN */
+                               /* ^ or ETH_ALEN, depending on lltype */,
+                       [ARPHRD_VSOCKMON]   =  0,
+               };
+
+               uint16_t proto = ifr->ifr_hwaddr.sa_family;
+               uint8_t sz = (proto < ARRAY_SIZE(hwaddr_sizes))
+                               ? hwaddr_sizes[proto] : 255;
+
+               PRINT_FIELD_XVAL("ifr_hwaddr={", ifr->ifr_hwaddr, sa_family,
+                                arp_hardware_types, "ARPHRD_???");
+               PRINT_FIELD_MAC_SZ(", ", ifr->ifr_hwaddr, sa_data,
+                                  MIN(sizeof(ifr->ifr_hwaddr.sa_data), sz));
+               tprints("}");
                break;
        }
        case SIOCSIFFLAGS: