]> granicus.if.org Git - strace/blobdiff - sock.c
nlattr: add UID/GID netlink attribute decoders
[strace] / sock.c
diff --git a/sock.c b/sock.c
index e6d63c0b8410f9f58abbaf18c481acb5d29363f9..a520852e7673797337ac6a280f013403d8fe0d58 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,13 +80,89 @@ 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?  */
-               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]);
+               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_SORTED_SIZED("ifr_hwaddr={", ifr->ifr_hwaddr,
+                                             sa_family, arp_hardware_types,
+                                             arp_hardware_types_size,
+                                             "ARPHRD_???");
+               PRINT_FIELD_MAC_SZ(", ", ifr->ifr_hwaddr, sa_data,
+                                  MIN(sizeof(ifr->ifr_hwaddr.sa_data), sz));
+               tprints("}");
                break;
        }
        case SIOCSIFFLAGS:
@@ -173,7 +253,7 @@ decode_ifconf(struct tcb *const tcp, const kernel_ulong_t addr)
                entering_ifc = get_tcb_priv_data(tcp);
 
                if (!entering_ifc) {
-                       error_msg("decode_ifconf: where is my ifconf?");
+                       error_func_msg("where is my ifconf?");
                        return 0;
                }
        }
@@ -198,7 +278,7 @@ decode_ifconf(struct tcb *const tcp, const kernel_ulong_t addr)
                        tprints("}");
                }
 
-               return RVAL_DECODED | 1;
+               return RVAL_IOCTL_DECODED;
        }
 
        if (entering(tcp)) {
@@ -208,7 +288,7 @@ decode_ifconf(struct tcb *const tcp, const kernel_ulong_t addr)
 
                set_tcb_priv_data(tcp, ifc, free);
 
-               return 1;
+               return 0;
        }
 
        /* exiting */
@@ -232,12 +312,12 @@ decode_ifconf(struct tcb *const tcp, const kernel_ulong_t addr)
                print_array(tcp, ptr_to_kulong(ifc->ifc_buf),
                            ifc->ifc_len / sizeof(struct_ifreq),
                            &ifr, sizeof(ifr),
-                           umoven_or_printaddr, print_ifconf_ifreq, NULL);
+                           tfetch_mem, print_ifconf_ifreq, NULL);
        }
 
        tprints("}");
 
-       return RVAL_DECODED | 1;
+       return RVAL_IOCTL_DECODED;
 }
 
 MPERS_PRINTER_DECL(int, sock_ioctl,
@@ -344,7 +424,7 @@ MPERS_PRINTER_DECL(int, sock_ioctl,
                                tprints("{ifr_name=");
                                print_ifname(ifr.ifr_name);
                        }
-                       return 1;
+                       return 0;
                } else {
                        if (syserror(tcp)) {
                                tprints("}");
@@ -371,5 +451,5 @@ MPERS_PRINTER_DECL(int, sock_ioctl,
                return RVAL_DECODED;
        }
 
-       return RVAL_DECODED | 1;
+       return RVAL_IOCTL_DECODED;
 }