improve {set,get}sockopt
diff --git a/net.c b/net.c
index 068f84c..fc5bb9e 100644
--- a/net.c
+++ b/net.c
@@ -278,6 +278,8 @@
 #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 @@
 	{ 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"	},
+#endif
+#ifdef IP_PKTOPTIONS
+	{ IP_PKTOPTIONS,	"IP_PKTOPTIONS"		},
+#endif
+#ifdef IP_MTU_DISCOVER
 	{ IP_MTU_DISCOVER,	"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 @@
 };
 #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 @@
 {
 	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 @@
 {
 	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]);
-			printnum(tcp, tcp->u_arg[3], "%ld");
-			tprintf(", %lu", tcp->u_arg[4]);
-			break;
+			tprintf("%lu", tcp->u_arg[2]);
 		}
+
+		/* default arg printing */
+
+		tprintf (", ");
+		
+		if (tcp->u_arg[4] == sizeof (int)) {
+			printnum(tcp, tcp->u_arg[3], "%ld");
+		}
+		else {
+			printstr (tcp, tcp->u_arg[3], tcp->u_arg[4]);
+		}
+		
+		tprintf(", %lu", tcp->u_arg[4]);
 	}
 	return 0;
 }