]> granicus.if.org Git - strace/blobdiff - net.c
Add a enum for decoding to tprint_iov() and tprint_iov_upto()
[strace] / net.c
diff --git a/net.c b/net.c
index 8ba5e130572c778c3e8cdba28737a9a5f1fda23c..a55fb640d4c79050dab27b8ce38d692feb666937 100644 (file)
--- a/net.c
+++ b/net.c
@@ -46,7 +46,7 @@
 #include <arpa/inet.h>
 #include <net/if.h>
 #include <asm/types.h>
-#if defined(__GLIBC__)
+#ifdef HAVE_NETIPX_IPX_H
 # include <netipx/ipx.h>
 #else
 # include <linux/ipx.h>
 
 #include "xlat/msg_flags.h"
 
-#if defined(AF_PACKET) /* from e.g. linux/if_packet.h */
-# include "xlat/af_packet_types.h"
-#endif
+#include "xlat/af_packet_types.h"
 
 static void
 print_ifindex(unsigned int ifindex)
@@ -125,15 +123,9 @@ typedef union {
        struct sockaddr sa;
        struct sockaddr_in sin;
        struct sockaddr_un sau;
-#ifdef HAVE_INET_NTOP
        struct sockaddr_in6 sa6;
-#endif
-#if defined(AF_IPX)
        struct sockaddr_ipx sipx;
-#endif
-#ifdef AF_PACKET
        struct sockaddr_ll ll;
-#endif
        struct sockaddr_nl nl;
 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
        struct sockaddr_hci hci;
@@ -143,9 +135,11 @@ typedef union {
 #endif
 } sockaddr_buf_t;
 
-static void
-print_sockaddr(struct tcb *tcp, const sockaddr_buf_t *addr, const int addrlen)
+void
+print_sockaddr(struct tcb *tcp, const void *const buf, const int addrlen)
 {
+       const sockaddr_buf_t *const addr = buf;
+
        tprints("{sa_family=");
        printxval(addrfams, addr->sa.sa_family, "AF_???");
        tprints(", ");
@@ -170,7 +164,7 @@ print_sockaddr(struct tcb *tcp, const sockaddr_buf_t *addr, const int addrlen)
                tprintf("sin_port=htons(%u), sin_addr=inet_addr(\"%s\")",
                        ntohs(addr->sin.sin_port), inet_ntoa(addr->sin.sin_addr));
                break;
-#ifdef HAVE_INET_NTOP
+
        case AF_INET6:
                {
                        char string_addr[100];
@@ -180,39 +174,35 @@ print_sockaddr(struct tcb *tcp, const sockaddr_buf_t *addr, const int addrlen)
                                ", \"%s\", &sin6_addr), sin6_flowinfo=%u",
                                ntohs(addr->sa6.sin6_port), string_addr,
                                addr->sa6.sin6_flowinfo);
-# ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
+#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
                        tprints(", sin6_scope_id=");
-#  if defined IN6_IS_ADDR_LINKLOCAL && defined IN6_IS_ADDR_MC_LINKLOCAL
+# if defined IN6_IS_ADDR_LINKLOCAL && defined IN6_IS_ADDR_MC_LINKLOCAL
                        if (IN6_IS_ADDR_LINKLOCAL(&addr->sa6.sin6_addr)
                            || IN6_IS_ADDR_MC_LINKLOCAL(&addr->sa6.sin6_addr))
                                print_ifindex(addr->sa6.sin6_scope_id);
                        else
-#  endif
+# endif
                                tprintf("%u", addr->sa6.sin6_scope_id);
-# endif /* HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID */
+#endif /* HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID */
                }
                break;
-#endif
-#if defined(AF_IPX)
+
        case AF_IPX:
                {
+                       tprintf("sipx_port=htons(%u)"
+                               ", sipx_network=htonl(%08x)"
+                               ", sipx_node=[",
+                               ntohs(addr->sipx.sipx_port),
+                               ntohl(addr->sipx.sipx_network));
                        int i;
-                       tprintf("sipx_port=htons(%u), ",
-                                       ntohs(addr->sipx.sipx_port));
-                       /* Yes, I know, this does not look too
-                        * strace-ish, but otherwise the IPX
-                        * addresses just look monstrous...
-                        * Anyways, feel free if you don't like
-                        * this way.. :)
-                        */
-                       tprintf("%08lx:", (unsigned long)ntohl(addr->sipx.sipx_network));
-                       for (i = 0; i < IPX_NODE_LEN; i++)
-                               tprintf("%02x", addr->sipx.sipx_node[i]);
-                       tprintf("/[%02x]", addr->sipx.sipx_type);
+                       for (i = 0; i < IPX_NODE_LEN; ++i) {
+                               tprintf("%s%02x", i ? ", " : "",
+                                       addr->sipx.sipx_node[i]);
+                       }
+                       tprintf("], sipx_type=%02x", addr->sipx.sipx_type);
                }
                break;
-#endif /* AF_IPX */
-#ifdef AF_PACKET
+
        case AF_PACKET:
                {
                        int i;
@@ -228,11 +218,11 @@ print_sockaddr(struct tcb *tcp, const sockaddr_buf_t *addr, const int addrlen)
                }
                break;
 
-#endif /* AF_PACKET */
        case AF_NETLINK:
                tprintf("pid=%d, groups=%08x", addr->nl.nl_pid, addr->nl.nl_groups);
                break;
-#if defined(AF_BLUETOOTH) && defined(HAVE_BLUETOOTH_BLUETOOTH_H)
+
+#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
        case AF_BLUETOOTH:
                tprintf("{sco_bdaddr=%02X:%02X:%02X:%02X:%02X:%02X} or "
                        "{rc_bdaddr=%02X:%02X:%02X:%02X:%02X:%02X, rc_channel=%d} or "
@@ -251,7 +241,8 @@ print_sockaddr(struct tcb *tcp, const sockaddr_buf_t *addr, const int addrlen)
                        addr->l2.l2_bdaddr.b[5], btohs(addr->l2.l2_cid),
                        btohs(addr->hci.hci_dev));
                break;
-#endif /* AF_BLUETOOTH && HAVE_BLUETOOTH_BLUETOOTH_H */
+#endif /* HAVE_BLUETOOTH_BLUETOOTH_H */
+
        /* AF_AX25 AF_APPLETALK AF_NETROM AF_BRIDGE AF_AAL5
        AF_X25 AF_ROSE etc. still need to be done */
 
@@ -264,25 +255,31 @@ print_sockaddr(struct tcb *tcp, const sockaddr_buf_t *addr, const int addrlen)
        tprints("}");
 }
 
-void
+int
 printsock(struct tcb *tcp, long addr, int addrlen)
 {
-       sockaddr_buf_t addrbuf;
-
        if (addrlen < 2) {
                printaddr(addr);
-               return;
+               return -1;
        }
 
-       if (addrlen > (int) sizeof(addrbuf))
-               addrlen = sizeof(addrbuf);
+       union {
+               struct sockaddr sa;
+               struct sockaddr_storage storage;
+               char pad[sizeof(struct sockaddr_storage) + 1];
+       } addrbuf;
+
+       if ((unsigned) addrlen > sizeof(addrbuf.storage))
+               addrlen = sizeof(addrbuf.storage);
 
-       memset(&addrbuf, 0, sizeof(addrbuf));
        if (umoven_or_printaddr(tcp, addr, addrlen, addrbuf.pad))
-               return;
-       addrbuf.pad[sizeof(addrbuf.pad) - 1] = '\0';
+               return -1;
+
+       memset(&addrbuf.pad[addrlen], 0, sizeof(addrbuf.pad) - addrlen);
 
        print_sockaddr(tcp, &addrbuf, addrlen);
+
+       return addrbuf.sa.sa_family;
 }
 
 #include "xlat/scmvals.h"
@@ -439,8 +436,7 @@ print_cmsg_ip_recverr(struct tcb *tcp, const void *cmsg_data,
                ", ee_info=%u, ee_data=%u, offender=",
                err->ee_errno, err->ee_origin, err->ee_type,
                err->ee_code, err->ee_info, err->ee_data);
-       print_sockaddr(tcp, (const void *) &err->offender,
-               sizeof(err->offender));
+       print_sockaddr(tcp, &err->offender, sizeof(err->offender));
        tprints("}");
 }
 
@@ -586,8 +582,9 @@ do_msghdr(struct tcb *tcp, struct msghdr *msg, unsigned long data_size)
        printsock(tcp, (long)msg->msg_name, msg->msg_namelen);
 
        tprintf(", msg_iov(%lu)=", (unsigned long)msg->msg_iovlen);
+
        tprint_iov_upto(tcp, (unsigned long)msg->msg_iovlen,
-                  (unsigned long)msg->msg_iov, 1, data_size);
+                       (unsigned long)msg->msg_iov, IOV_DECODE_STR, data_size);
 
 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
        tprintf(", msg_controllen=%lu", (unsigned long)msg->msg_controllen);
@@ -780,27 +777,20 @@ SYS_FUNC(socket)
        tprints(", ");
        switch (tcp->u_arg[0]) {
        case AF_INET:
-#ifdef AF_INET6
        case AF_INET6:
-#endif
                printxval(inet_protocols, tcp->u_arg[2], "IPPROTO_???");
                break;
-#ifdef AF_IPX
-       case AF_IPX:
-               /* BTW: I don't believe this.. */
-               tprints("[");
-               printxval(addrfams, tcp->u_arg[2], "AF_???");
-               tprints("]");
-               break;
-#endif /* AF_IPX */
+
        case AF_NETLINK:
                printxval(netlink_protocols, tcp->u_arg[2], "NETLINK_???");
                break;
-#if defined(AF_BLUETOOTH) && defined(HAVE_BLUETOOTH_BLUETOOTH_H)
+
+#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
        case AF_BLUETOOTH:
                printxval(bt_protocols, tcp->u_arg[2], "BTPROTO_???");
                break;
 #endif
+
        default:
                tprintf("%lu", tcp->u_arg[2]);
                break;
@@ -1179,7 +1169,6 @@ print_sockopt_fd_level_name(struct tcb *tcp, int fd, unsigned int level,
        tprints(", ");
 }
 
-#ifdef SO_LINGER
 static void
 print_linger(struct tcb *tcp, long addr, int len)
 {
@@ -1195,7 +1184,6 @@ print_linger(struct tcb *tcp, long addr, int len)
                linger.l_onoff,
                linger.l_linger);
 }
-#endif /* SO_LINGER */
 
 #ifdef SO_PEERCRED
 static void
@@ -1262,11 +1250,9 @@ print_getsockopt(struct tcb *tcp, unsigned int level, unsigned int name,
        switch (level) {
        case SOL_SOCKET:
                switch (name) {
-#ifdef SO_LINGER
                case SO_LINGER:
                        print_linger(tcp, addr, len);
                        goto done;
-#endif
 #ifdef SO_PEERCRED
                case SO_PEERCRED:
                        print_ucred(tcp, addr, len);
@@ -1364,7 +1350,6 @@ print_mreq6(struct tcb *tcp, long addr, unsigned int len)
        if (umove_or_printaddr(tcp, addr, &mreq))
                return;
 
-#ifdef HAVE_INET_NTOP
        const struct in6_addr *in6 = &mreq.ipv6mr_multiaddr;
        char address[INET6_ADDRSTRLEN];
 
@@ -1377,7 +1362,6 @@ print_mreq6(struct tcb *tcp, long addr, unsigned int len)
        print_ifindex(mreq.ipv6mr_interface);
        tprints("}");
        return;
-#endif /* HAVE_INET_NTOP */
 
 fail:
        printstr(tcp, addr, len);
@@ -1397,8 +1381,7 @@ print_group_req(struct tcb *tcp, long addr, int len)
        }
 
        tprintf("{gr_interface=%u, gr_group=", greq.gr_interface);
-       print_sockaddr(tcp, (const void *) &greq.gr_group,
-                      sizeof(greq.gr_group));
+       print_sockaddr(tcp, &greq.gr_group, sizeof(greq.gr_group));
        tprintf("}");
 
 }
@@ -1458,11 +1441,9 @@ print_setsockopt(struct tcb *tcp, unsigned int level, unsigned int name,
        switch (level) {
        case SOL_SOCKET:
                switch (name) {
-#ifdef SO_LINGER
                case SO_LINGER:
                        print_linger(tcp, addr, len);
                        goto done;
-#endif
                }
                break;