]> granicus.if.org Git - strace/commitdiff
improve {set,get}sockopt
authorJohn Hughes <john@Calva.COM>
Wed, 22 May 2002 15:46:49 +0000 (15:46 +0000)
committerJohn Hughes <john@Calva.COM>
Wed, 22 May 2002 15:46:49 +0000 (15:46 +0000)
ChangeLog
net.c

index 3ff34663019fde128eb66a92d8193b704476ec26..6b47263bab2f9ad13d30f28b8d9dd27d53878689 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2002-05-22  John Hughes <john@calva.com>
+
+       * net.c: Simplify {get,set}sockopt, decode SO_LINGER, cope with
+       options that are not just ints, cope with systems that don't
+       #define SOL_TCP and so on.
+
 2002-05-21  John Hughes <john@calva.com>
 
        * strace.c: Fix warning if POLL_HACK is used.
diff --git a/net.c b/net.c
index 068f84cfba9be3d01ca9e704866fab237d8ce238..fc5bb9ee69a3c974b8345f36270b944d343cae3d 100644 (file)
--- a/net.c
+++ b/net.c
@@ -278,6 +278,8 @@ static struct xlat socketlayers[] = {
 #endif
        { SOL_SOCKET,   "SOL_SOCKET"    },      /* Never used! */
 };
+/*** WARNING: DANGER WILL ROBINSON: NOTE "socketlayers" array above
+     falls into "protocols" array below!!!!   This is intended!!! ***/
 static struct xlat protocols[] = {
        { IPPROTO_IP,   "IPPROTO_IP"    },
        { IPPROTO_ICMP, "IPPROTO_ICMP"  },
@@ -447,36 +449,84 @@ static struct xlat sockoptions[] = {
        { 0,            NULL            },
 };
 
+#if !defined (SOL_IP) && defined (IPPROTO_IP)
+#define SOL_IP IPPROTO_IP
+#endif
+
 #ifdef SOL_IP
 static struct xlat sockipoptions[] = {
+#ifdef IP_TOS
        { IP_TOS,               "IP_TOS"                },
+#endif
+#ifdef IP_TTL
        { IP_TTL,               "IP_TTL"                },
-#if defined(IP_HDRINCL)
+#endif
+#ifdef IP_HDRINCL
        { IP_HDRINCL,           "IP_HDRINCL"            },
 #endif
-#if defined(IP_OPTIONS)
+#ifdef IP_OPTIONS
        { IP_OPTIONS,           "IP_OPTIONS"            },
 #endif
+#ifdef IP_ROUTER_ALERT
        { IP_ROUTER_ALERT,      "IP_ROUTER_ALERT"       },
-#if defined(IP_RECVOPTIONS)
+#endif
+#ifdef IP_RECVOPTIONS
        { IP_RECVOPTIONS,       "IP_RECVOPTIONS"        },
 #endif
+#ifdef IP_RECVOPTS
+       { IP_RECVOPTS,          "IP_RECVOPTS"           },
+#endif
+#ifdef IP_RECVRETOPTS
+       { IP_RECVRETOPTS,       "IP_RECVRETOPTS"        },
+#endif
+#ifdef IP_RECVDSTADDR
+       { IP_RECVDSTADDR,       "IP_RECVDSTADDR"        },
+#endif
+#ifdef IP_RETOPTS
        { IP_RETOPTS,           "IP_RETOPTS"            },
+#endif
+#ifdef IP_PKTINFO
        { IP_PKTINFO,           "IP_PKTINFO"            },
-       { IP_PKTOPTIONS,        "IP_PKTOPTIONS" },
-       { IP_MTU_DISCOVER,      "IP_MTU_DISCOVER"       },
+#endif
+#ifdef IP_PKTOPTIONS
+       { IP_PKTOPTIONS,        "IP_PKTOPTIONS"         },
+#endif
+#ifdef IP_MTU_DISCOVER
        { IP_MTU_DISCOVER,      "IP_MTU_DISCOVER"       },
+#endif
+#ifdef IP_RECVERR
        { IP_RECVERR,           "IP_RECVERR"            },
+#endif
+#ifdef IP_RECVTTL
        { IP_RECVTTL,           "IP_RECRECVTTL"         },
+#endif
+#ifdef IP_RECVTOS
        { IP_RECVTOS,           "IP_RECRECVTOS"         },
-#if defined(IP_MTU)
+#endif
+#ifdef IP_MTU
        { IP_MTU,               "IP_MTU"                },
 #endif
+#ifdef IP_MULTICAST_IF
        { IP_MULTICAST_IF,      "IP_MULTICAST_IF"       },
+#endif
+#ifdef IP_MULTICAST_TTL
        { IP_MULTICAST_TTL,     "IP_MULTICAST_TTL"      },
+#endif
+#ifdef IP_MULTICAST_LOOP
        { IP_MULTICAST_LOOP,    "IP_MULTICAST_LOOP"     },
+#endif
+#ifdef IP_ADD_MEMBERSHIP
        { IP_ADD_MEMBERSHIP,    "IP_ADD_MEMBERSHIP"     },
+#endif
+#ifdef IP_DROP_MEMBERSHIP
        { IP_DROP_MEMBERSHIP,   "IP_DROP_MEMBERSHIP"    },
+#endif
+#ifdef IP_BROADCAST_IF
+       { IP_BROADCAST_IF,      "IP_BROADCAST_IF"       },
+#endif
+#ifdef IP_RECVIFINDEX
+       { IP_RECVIFINDEX,       "IP_RECVIFINDEX"        },
+#endif
        { 0,                    NULL                    },
 };
 #endif /* SOL_IP */
@@ -514,6 +564,10 @@ static struct xlat sockpacketoptions[] = {
 };
 #endif /* SOL_PACKET */
 
+#if  !defined (SOL_TCP) && defined (IPPROTO_TCP)
+#define SOL_TCP IPPROTO_TCP
+#endif
+
 #ifdef SOL_TCP
 static struct xlat socktcpoptions[] = {
        { TCP_NODELAY,          "TCP_NODELAY"   },
@@ -1161,58 +1215,79 @@ struct tcb *tcp;
 {
        if (entering(tcp)) {
                tprintf("%ld, ", tcp->u_arg[0]);
+               printxval(socketlayers, tcp->u_arg[1], "SOL_???");
+               tprintf (", ");
                switch (tcp->u_arg[1]) {
                case SOL_SOCKET:
-                       tprintf("SOL_SOCKET, ");
                        printxval(sockoptions, tcp->u_arg[2], "SO_???");
-                       tprintf(", ");
                        break;
 #ifdef SOL_IP
                case SOL_IP:
-                       tprintf("SOL_IP, ");
                        printxval(sockipoptions, tcp->u_arg[2], "IP_???");
-                       tprintf(", ");
                        break;
 #endif
 #ifdef SOL_IPX
                case SOL_IPX:
-                       tprintf("SOL_IPX, ");
                        printxval(sockipxoptions, tcp->u_arg[2], "IPX_???");
-                       tprintf(", ");
                        break;
 #endif
 #ifdef SOL_PACKET
                case SOL_PACKET:
-                       tprintf("SOL_PACKET, ");
                        printxval(sockpacketoptions, tcp->u_arg[2], "PACKET_???");
-                       tprintf(", ");
                        break;
 #endif
 #ifdef SOL_TCP
                case SOL_TCP:
-                       tprintf("SOL_TCP, ");
                        printxval(socktcpoptions, tcp->u_arg[2], "TCP_???");
-                       tprintf(", ");
                        break;
 #endif
 
                /* SOL_AX25 SOL_ROSE SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25
                 * etc. still need work */
                default: 
-                       /* XXX - should know socket family here */
-                       printxval(socketlayers, tcp->u_arg[1], "SOL_???");
-                       tprintf(", %lu, ", tcp->u_arg[2]);
+                       tprintf("%lu", tcp->u_arg[2]);
                        break;
                }
        } else {
-               if (syserror(tcp)) {
-                       tprintf("%#lx, %#lx",
+               long len;
+               if (syserror(tcp) || umove (tcp, tcp->u_arg[4], &len) < 0) {
+                       tprintf(", %#lx, %#lx",
                                tcp->u_arg[3], tcp->u_arg[4]);
                        return 0;
                }
-               printnum(tcp, tcp->u_arg[3], "%ld");
-               tprintf(", ");
-               printnum(tcp, tcp->u_arg[4], "%ld");
+
+               switch (tcp->u_arg[1]) {
+               case SOL_SOCKET:
+                       switch (tcp->u_arg[2]) {
+#ifdef SO_LINGER
+                       case SO_LINGER:
+                               if (len == sizeof (struct linger)) {
+                                       struct linger linger;
+                                       if (umove (tcp,
+                                                  tcp->u_arg[3],
+                                                  &linger) < 0)
+                                               break;
+                                       tprintf(", {onoff=%d, linger=%d}, "
+                                               "[%ld]",
+                                               linger.l_onoff,
+                                               linger.l_linger,
+                                               len);
+                                       return 0;
+                               }
+                               break;
+#endif
+                       }
+                       break;
+               }
+
+               tprintf (", ");
+               if (len == sizeof (int)) {
+                       printnum(tcp, tcp->u_arg[3], "%ld");
+               }
+               else {
+                       printstr (tcp, tcp->u_arg[3], len);
+               }
+               tprintf(", [%ld]", len);
        }
        return 0;
 }
@@ -1250,80 +1325,85 @@ struct tcb *tcp;
 {
        if (entering(tcp)) {
                tprintf("%ld, ", tcp->u_arg[0]);
+               printxval(socketlayers, tcp->u_arg[1], "IPPROTO_???");
+               tprintf (", ");
                switch (tcp->u_arg[1]) {
                case SOL_SOCKET:
-                       tprintf("SOL_SOCKET, ");
                        printxval(sockoptions, tcp->u_arg[2], "SO_???");
-                       tprintf(", ");
-                       printnum(tcp, tcp->u_arg[3], "%ld");
-                       tprintf(", %lu", tcp->u_arg[4]);
+                       switch (tcp->u_arg[2]) {
+#if defined(SO_LINGER)
+                       case SO_LINGER:
+                               if (tcp->u_arg[4] == sizeof (struct linger)) {
+                                       struct linger linger;
+                                       if (umove (tcp,
+                                                  tcp->u_arg[3],
+                                                  &linger) < 0)
+                                               break;
+                                       tprintf(", {onoff=%d, linger=%d}, %lu",
+                                               linger.l_onoff,
+                                               linger.l_linger,
+                                               tcp->u_arg[4]);
+                                       return 0;
+                               }
+                               break;
+#endif
+                       }
                        break;
 #ifdef SOL_IP
                case SOL_IP:
-                       tprintf("SOL_IP, ");
                        printxval(sockipoptions, tcp->u_arg[2], "IP_???");
-                       tprintf(", ");
-                       printnum(tcp, tcp->u_arg[3], "%ld");
-                       tprintf(", %lu", tcp->u_arg[4]);
                        break;
 #endif
 #ifdef SOL_IPX
                case SOL_IPX:
-                       tprintf("SOL_IPX, ");
                        printxval(sockipxoptions, tcp->u_arg[2], "IPX_???");
-                       tprintf(", ");
-                       printnum(tcp, tcp->u_arg[3], "%ld");
-                       tprintf(", %lu", tcp->u_arg[4]);
                        break;
 #endif
 #ifdef SOL_PACKET
                case SOL_PACKET:
-                       tprintf("SOL_PACKET, ");
                        printxval(sockpacketoptions, tcp->u_arg[2], "PACKET_???");
-                       tprintf(", ");
                        /* TODO: decode packate_mreq for PACKET_*_MEMBERSHIP */
-                       printnum(tcp, tcp->u_arg[3], "%ld");
-                       tprintf(", %lu", tcp->u_arg[4]);
                        break;
 #endif
 #ifdef SOL_TCP
                case SOL_TCP:
-                       tprintf("SOL_TCP, ");
                        printxval(socktcpoptions, tcp->u_arg[2], "TCP_???");
-                       tprintf(", ");
-                       printnum(tcp, tcp->u_arg[3], "%ld");
-                       tprintf(", %lu", tcp->u_arg[4]);
                        break;
 #endif
 #ifdef SOL_RAW
                case SOL_RAW:
-                       tprintf("SOL_RAW, ");
                        printxval(sockrawoptions, tcp->u_arg[2], "RAW_???");
-                       tprintf(", ");
                        switch (tcp->u_arg[2]) {
 #if defined(ICMP_FILTER)
-                               case ICMP_FILTER:
-                                       printicmpfilter(tcp, tcp->u_arg[3]);
-                                       break;
+                       case ICMP_FILTER:
+                               tprintf(", ");
+                               printicmpfilter(tcp, tcp->u_arg[3]);
+                               tprintf(", %lu", tcp->u_arg[4]);
+                               return 0;
 #endif
-                               default:
-                                       printnum(tcp, tcp->u_arg[3], "%ld");
-                                       break;
                        }
-                       tprintf(", %lu", tcp->u_arg[4]);
                        break;
 #endif
 
                /* SOL_AX25 SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25 
                 * etc. still need work  */
+
                default:
-                       /* XXX - should know socket family here */
-                       printxval(socketlayers, tcp->u_arg[1], "IPPROTO_???");
-                       tprintf(", %lu, ", tcp->u_arg[2]);
+                       tprintf("%lu", tcp->u_arg[2]);
+               }
+
+               /* default arg printing */
+
+               tprintf (", ");
+               
+               if (tcp->u_arg[4] == sizeof (int)) {
                        printnum(tcp, tcp->u_arg[3], "%ld");
-                       tprintf(", %lu", tcp->u_arg[4]);
-                       break;
                }
+               else {
+                       printstr (tcp, tcp->u_arg[3], tcp->u_arg[4]);
+               }
+               
+               tprintf(", %lu", tcp->u_arg[4]);
        }
        return 0;
 }