]> granicus.if.org Git - strace/blobdiff - sock.c
Add argument to tprint_iov() specifying whether to decode each iovec
[strace] / sock.c
diff --git a/sock.c b/sock.c
index 462df22b116407a3fc9c8541fbff5a231086f48c..bbbdd5b9908352e3eb1df3fb5ba08b8d8a08fa3e 100644 (file)
--- a/sock.c
+++ b/sock.c
@@ -47,8 +47,6 @@
 #endif
 #include <net/if.h>
 
-extern const struct xlat addrfams[];
-
 static const struct xlat iffflags[] = {
        { IFF_UP,               "IFF_UP"                },
        { IFF_BROADCAST,        "IFF_BROADCAST"         },
@@ -70,10 +68,7 @@ static const struct xlat iffflags[] = {
 
 
 static void
-print_addr(tcp, addr, ifr)
-struct tcb *tcp;
-long addr;
-struct ifreq *ifr;
+print_addr(struct tcb *tcp, long addr, struct ifreq *ifr)
 {
        if (ifr->ifr_addr.sa_family == AF_INET) {
                struct sockaddr_in *sinp;
@@ -84,9 +79,7 @@ struct ifreq *ifr;
 }
 
 int
-sock_ioctl(tcp, code, arg)
-struct tcb *tcp;
-long code, arg;
+sock_ioctl(struct tcb *tcp, long code, long arg)
 {
        struct ifreq ifr;
        struct ifconf ifc;
@@ -95,8 +88,8 @@ long code, arg;
 
        if (entering(tcp)) {
                if (code == SIOCGIFCONF) {
-                       umove(tcp, tcp->u_arg[2], &ifc);
-                       if (ifc.ifc_buf == NULL)
+                       if (umove(tcp, tcp->u_arg[2], &ifc) >= 0
+                           && ifc.ifc_buf == NULL)
                                tprintf(", {%d -> ", ifc.ifc_len);
                        else
                                tprintf(", {");
@@ -136,23 +129,38 @@ long code, arg;
                return 1;
 #ifdef LINUX
        case SIOCGIFNAME:
+       case SIOCSIFNAME:
        case SIOCGIFINDEX:
        case SIOCGIFADDR:
+       case SIOCSIFADDR:
        case SIOCGIFDSTADDR:
+       case SIOCSIFDSTADDR:
        case SIOCGIFBRDADDR:
+       case SIOCSIFBRDADDR:
        case SIOCGIFNETMASK:
+       case SIOCSIFNETMASK:
        case SIOCGIFFLAGS:
+       case SIOCSIFFLAGS:
        case SIOCGIFMETRIC:
+       case SIOCSIFMETRIC:
        case SIOCGIFMTU:
+       case SIOCSIFMTU:
        case SIOCGIFSLAVE:
+       case SIOCSIFSLAVE:
        case SIOCGIFHWADDR:
-               umove(tcp, tcp->u_arg[2], &ifr);
-                if (syserror(tcp)) {
-                       if (code == SIOCGIFNAME)
+       case SIOCSIFHWADDR:
+       case SIOCGIFTXQLEN:
+       case SIOCSIFTXQLEN:
+       case SIOCGIFMAP:
+       case SIOCSIFMAP:
+               if (umove(tcp, tcp->u_arg[2], &ifr) < 0)
+                       tprintf(", %#lx", tcp->u_arg[2]);
+               else if (syserror(tcp)) {
+                       if (code == SIOCGIFNAME || code == SIOCSIFNAME)
                                tprintf(", {ifr_index=%d, ifr_name=???}", ifr.ifr_ifindex);
                        else
                                tprintf(", {ifr_name=\"%s\", ???}", ifr.ifr_name);
-               } else if (code == SIOCGIFNAME)
+               } else if (code == SIOCGIFNAME || code == SIOCSIFNAME)
                        tprintf(", {ifr_index=%d, ifr_name=\"%s\"}",
                                ifr.ifr_ifindex, ifr.ifr_name);
                else {
@@ -162,28 +170,33 @@ long code, arg;
                                tprintf("ifr_index=%d", ifr.ifr_ifindex);
                                break;
                        case SIOCGIFADDR:
+                       case SIOCSIFADDR:
                                str = "ifr_addr";
                        case SIOCGIFDSTADDR:
-                               if (str == NULL)
+                       case SIOCSIFDSTADDR:
+                               if (!str)
                                        str = "ifr_dstaddr";
                        case SIOCGIFBRDADDR:
-                               if (str == NULL)
+                       case SIOCSIFBRDADDR:
+                               if (!str)
                                        str = "ifr_broadaddr";
                        case SIOCGIFNETMASK:
-                               if (str == NULL)
+                       case SIOCSIFNETMASK:
+                               if (!str)
                                        str = "ifr_netmask";
                                tprintf("%s={", str);
                                printxval(addrfams,
                                          ifr.ifr_addr.sa_family,
-                                         "AF_???");
+                                         "AF_???");
                                tprintf(", ");
                                print_addr(tcp, ((long) tcp->u_arg[2]
-                                                + offsetof (struct ifreq,
+                                                + offsetof(struct ifreq,
                                                             ifr_addr.sa_data)),
                                           &ifr);
                                tprintf("}");
                                break;
                        case SIOCGIFHWADDR:
+                       case SIOCSIFHWADDR:
                                /* XXX Are there other hardware addresses
                                   than 6-byte MACs?  */
                                bytes = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
@@ -192,26 +205,49 @@ long code, arg;
                                        bytes[3], bytes[4], bytes[5]);
                                break;
                        case SIOCGIFFLAGS:
+                       case SIOCSIFFLAGS:
                                tprintf("ifr_flags=");
                                printflags(iffflags, ifr.ifr_flags, "IFF_???");
                                break;
                        case SIOCGIFMETRIC:
+                       case SIOCSIFMETRIC:
                                tprintf("ifr_metric=%d", ifr.ifr_metric);
                                break;
                        case SIOCGIFMTU:
+                       case SIOCSIFMTU:
                                tprintf("ifr_mtu=%d", ifr.ifr_mtu);
                                break;
                        case SIOCGIFSLAVE:
+                       case SIOCSIFSLAVE:
                                tprintf("ifr_slave=\"%s\"", ifr.ifr_slave);
                                break;
+                       case SIOCGIFTXQLEN:
+                       case SIOCSIFTXQLEN:
+                               tprintf("ifr_qlen=%d", ifr.ifr_qlen);
+                               break;
+                       case SIOCGIFMAP:
+                       case SIOCSIFMAP:
+                               tprintf("ifr_map={mem_start=%#lx, "
+                                       "mem_end=%#lx, base_addr=%#x, "
+                                       "irq=%u, dma=%u, port=%u}",
+                                       ifr.ifr_map.mem_start,
+                                       ifr.ifr_map.mem_end,
+                                       (unsigned) ifr.ifr_map.base_addr,
+                                       (unsigned) ifr.ifr_map.irq,
+                                       (unsigned) ifr.ifr_map.dma,
+                                       (unsigned) ifr.ifr_map.port);
+                               break;
                        }
                        tprintf("}");
                }
                return 1;
        case SIOCGIFCONF:
-               umove(tcp, tcp->u_arg[2], &ifc);
+               if (umove(tcp, tcp->u_arg[2], &ifc) < 0) {
+                       tprintf("???}");
+                       return 1;
+               }
                tprintf("%d, ", ifc.ifc_len);
-                if (syserror(tcp)) {
+               if (syserror(tcp)) {
                        tprintf("%lx", (unsigned long) ifc.ifc_buf);
                } else if (ifc.ifc_buf == NULL) {
                        tprintf("NULL");
@@ -219,8 +255,12 @@ long code, arg;
                        int i;
                        unsigned nifra = ifc.ifc_len / sizeof(struct ifreq);
                        struct ifreq ifra[nifra];
-                       umoven(tcp, (unsigned long) ifc.ifc_buf, sizeof(ifra),
-                              (char *) ifra);
+
+                       if (umoven(tcp, (unsigned long) ifc.ifc_buf,
+                               sizeof(ifra), (char *) ifra) < 0) {
+                               tprintf("%lx}", (unsigned long) ifc.ifc_buf);
+                               return 1;
+                       }
                        tprintf("{");
                        for (i = 0; i < nifra; ++i ) {
                                if (i > 0)
@@ -233,7 +273,7 @@ long code, arg;
                                                  "AF_???");
                                        tprintf(", ");
                                        print_addr(tcp, ((long) tcp->u_arg[2]
-                                                        + offsetof (struct ifreq,
+                                                        + offsetof(struct ifreq,
                                                                     ifr_addr.sa_data)
                                                         + ((char *) &ifra[i]
                                                            - (char *) &ifra[0])),