ws2_32: Better trace setsockopt/getsockopt

Bruno Jesus 00cpxxx at gmail.com
Mon Jan 5 20:49:19 CST 2015


The intention of this patch is to make it easier to read winsock logs,
for setsockopt it even displays the value if its size is less than 5
bytes.

Turns this:
WS_setsockopt socket: 003c, level 0x0, name 0xa, ptr 0x32f5f8, len 1
WS_setsockopt socket: 003c, level 0xffff, name 0x1006, ptr 0x32fc2c, len 4
WS_setsockopt socket: 003c, level 0xffff, name 0x80, ptr 0x32fc28, len 4
WS_getsockopt socket: 0094, level 0x3e8, name 0x4000, ptr 0x32fc04, len 4
WS_getsockopt socket: 003c, level 0xffff, name 0x1009, ptr 0x32f68c, len 128

Into:
trace_sockopt setsockopt (socket 003c, level IPPROTO_IP, name
IP_MULTICAST_TTL, optval 0x32f5f8 (10), len 1)
trace_sockopt getsockopt (socket 003c, level SOL_SOCKET, name
SO_PROTOCOL_INFOA, optval 0x32fab0, len 0x32fc24 (744))
trace_sockopt getsockopt (socket 00b0, level SOL_SOCKET, name
SO_CONNECT_TIME, optval 0x32f97c, len 0x32fbbc (4))
trace_sockopt getsockopt (socket 0094, level NSPROTO_IPX, name
IPX_PTYPE, optval 0x32fc04, len 0x32fc08 (4))
trace_sockopt setsockopt (socket 003c, level SOL_SOCKET, name
SO_SNDTIMEO, optval 0x32fc2c (997000), len 4)
-------------- next part --------------
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 4edc38f..df2ff2e 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -258,6 +258,9 @@ static int WS2_recv_base( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
                           LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
                           LPWSABUF lpControlBuffer );
 
+static void trace_sockopt(const char *func, SOCKET s, INT level,
+                          INT optname, const char *optval, INT *optlen, INT optlenval);
+
 /* critical section to protect some non-reentrant net function */
 static CRITICAL_SECTION csWSgetXXXbyYYY;
 static CRITICAL_SECTION_DEBUG critsect_debug =
@@ -3051,8 +3054,8 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level,
     int fd;
     INT ret = 0;
 
-    TRACE("socket: %04lx, level 0x%x, name 0x%x, ptr %p, len %d\n",
-          s, level, optname, optval, optlen ? *optlen : 0);
+    if (TRACE_ON(winsock))
+        trace_sockopt("getsockopt", s, level, optname, (const char*)optval, optlen, 0);
 
     switch(level)
     {
@@ -4834,8 +4837,8 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname,
     struct linger linger;
     struct timeval tval;
 
-    TRACE("socket: %04lx, level 0x%x, name 0x%x, ptr %p, len %d\n",
-          s, level, optname, optval, optlen);
+    if (TRACE_ON(winsock))
+        trace_sockopt("setsockopt", s, level, optname, optval, NULL, optlen);
 
     /* some broken apps pass the value directly instead of a pointer to it */
     if(optlen && IS_INTRESOURCE(optval))
@@ -7684,3 +7687,132 @@ INT WINAPI WSCEnumProtocols( LPINT protocols, LPWSAPROTOCOL_INFOW buffer, LPDWOR
 
     return ret;
 }
+
+static void trace_sockopt(const char *func, SOCKET s, INT level,
+                          INT optname, const char *optval, INT *optlen, INT optlenval)
+{
+    char levelunk[32], optunk[32], valstr[32], lenstr[32];
+    const char *strlevel = levelunk, *stropt = optunk;
+    int len;
+
+    if (optlen) optlenval = *optlen;
+
+    #define DEBUG_SOCKLEVEL(x) case (x): strlevel = #x
+    #define DEBUG_SOCKOPT(x) case (x): stropt = #x; break
+    sprintf(optunk, "WS_0x%x", optname);
+    switch(level)
+    {
+        DEBUG_SOCKLEVEL(WS_SOL_SOCKET);
+        switch(optname)
+        {
+            DEBUG_SOCKOPT(WS_SO_ACCEPTCONN);
+            DEBUG_SOCKOPT(WS_SO_BROADCAST);
+            DEBUG_SOCKOPT(WS_SO_BSP_STATE);
+            DEBUG_SOCKOPT(WS_SO_CONDITIONAL_ACCEPT);
+            DEBUG_SOCKOPT(WS_SO_CONNECT_TIME);
+            DEBUG_SOCKOPT(WS_SO_DEBUG);
+            DEBUG_SOCKOPT(WS_SO_DONTLINGER);
+            DEBUG_SOCKOPT(WS_SO_DONTROUTE);
+            DEBUG_SOCKOPT(WS_SO_ERROR);
+            DEBUG_SOCKOPT(WS_SO_EXCLUSIVEADDRUSE);
+            DEBUG_SOCKOPT(WS_SO_GROUP_ID);
+            DEBUG_SOCKOPT(WS_SO_GROUP_PRIORITY);
+            DEBUG_SOCKOPT(WS_SO_KEEPALIVE);
+            DEBUG_SOCKOPT(WS_SO_LINGER);
+            DEBUG_SOCKOPT(WS_SO_MAX_MSG_SIZE);
+            DEBUG_SOCKOPT(WS_SO_OOBINLINE);
+            DEBUG_SOCKOPT(WS_SO_OPENTYPE);
+            DEBUG_SOCKOPT(WS_SO_PROTOCOL_INFOA);
+            DEBUG_SOCKOPT(WS_SO_PROTOCOL_INFOW);
+            DEBUG_SOCKOPT(WS_SO_RCVBUF);
+            DEBUG_SOCKOPT(WS_SO_RCVTIMEO);
+            DEBUG_SOCKOPT(WS_SO_REUSEADDR);
+            DEBUG_SOCKOPT(WS_SO_SNDBUF);
+            DEBUG_SOCKOPT(WS_SO_SNDTIMEO);
+            DEBUG_SOCKOPT(WS_SO_TYPE);
+        }
+        break;
+
+        DEBUG_SOCKLEVEL(WS_NSPROTO_IPX);
+        switch(optname)
+        {
+            DEBUG_SOCKOPT(WS_IPX_PTYPE);
+            DEBUG_SOCKOPT(WS_IPX_FILTERPTYPE);
+            DEBUG_SOCKOPT(WS_IPX_DSTYPE);
+            DEBUG_SOCKOPT(WS_IPX_RECVHDR);
+            DEBUG_SOCKOPT(WS_IPX_MAXSIZE);
+            DEBUG_SOCKOPT(WS_IPX_ADDRESS);
+            DEBUG_SOCKOPT(WS_IPX_MAX_ADAPTER_NUM);
+        }
+        break;
+
+        DEBUG_SOCKLEVEL(WS_SOL_IRLMP);
+        switch(optname)
+        {
+            DEBUG_SOCKOPT(WS_IRLMP_ENUMDEVICES);
+        }
+        break;
+
+        DEBUG_SOCKLEVEL(WS_IPPROTO_TCP);
+        switch(optname)
+        {
+            DEBUG_SOCKOPT(WS_TCP_BSDURGENT);
+            DEBUG_SOCKOPT(WS_TCP_EXPEDITED_1122);
+            DEBUG_SOCKOPT(WS_TCP_NODELAY);
+        }
+        break;
+
+        DEBUG_SOCKLEVEL(WS_IPPROTO_IP);
+        switch(optname)
+        {
+            DEBUG_SOCKOPT(WS_IP_ADD_MEMBERSHIP);
+            DEBUG_SOCKOPT(WS_IP_DROP_MEMBERSHIP);
+            DEBUG_SOCKOPT(WS_IP_HDRINCL);
+            DEBUG_SOCKOPT(WS_IP_MULTICAST_IF);
+            DEBUG_SOCKOPT(WS_IP_MULTICAST_LOOP);
+            DEBUG_SOCKOPT(WS_IP_MULTICAST_TTL);
+            DEBUG_SOCKOPT(WS_IP_OPTIONS);
+            DEBUG_SOCKOPT(WS_IP_PKTINFO);
+            DEBUG_SOCKOPT(WS_IP_TOS);
+            DEBUG_SOCKOPT(WS_IP_TTL);
+            DEBUG_SOCKOPT(WS_IP_UNICAST_IF);
+            DEBUG_SOCKOPT(WS_IP_DONTFRAGMENT);
+        }
+        break;
+
+        DEBUG_SOCKLEVEL(WS_IPPROTO_IPV6);
+        switch(optname)
+        {
+            DEBUG_SOCKOPT(WS_IPV6_ADD_MEMBERSHIP);
+            DEBUG_SOCKOPT(WS_IPV6_DROP_MEMBERSHIP);
+            DEBUG_SOCKOPT(WS_IPV6_MULTICAST_IF);
+            DEBUG_SOCKOPT(WS_IPV6_MULTICAST_HOPS);
+            DEBUG_SOCKOPT(WS_IPV6_MULTICAST_LOOP);
+            DEBUG_SOCKOPT(WS_IPV6_UNICAST_HOPS);
+            DEBUG_SOCKOPT(WS_IPV6_V6ONLY);
+            DEBUG_SOCKOPT(WS_IPV6_UNICAST_IF);
+            DEBUG_SOCKOPT(WS_IPV6_DONTFRAG);
+        }
+        break;
+        default: sprintf(levelunk, "WS_0x%x", level);
+    }
+    #undef DEBUG_SOCKLEVEL
+    #undef DEBUG_SOCKOPT
+
+    len = sprintf(valstr, "%p", optval);
+    if (!optlen) /* if possible display the value when tracing from setsockopt */
+    {
+        if (optval && !IS_INTRESOURCE(optval) && optlenval >= 1 && optlenval <= sizeof(DWORD))
+        {
+            DWORD value = 0;
+            memcpy(&value, optval, optlenval);
+            sprintf(valstr + len, " (%d)", value);
+        }
+        sprintf(lenstr, "%d", optlenval);
+    }
+    else
+        sprintf(lenstr, "%p (%d)", optlen, *optlen);
+
+    TRACE(" %s (socket %04lx, level %s, name %s, optval %s, len %s)\n",
+          func, s, strlevel + 3, stropt + 3, valstr, lenstr);
+}


More information about the wine-patches mailing list