2004-07-12  Roland McGrath  <roland@redhat.com>

	* net.c (addrfams): Make variable global.
	* sock.c (sock_ioctl): Decode the arguments for SIOCGIFNAME,
	SIOCGIFINDEX, and SIOCGIFCONF.
	From Ulrich Drepper <drepper@redhat.com>.
	Fixes RH#126917.
diff --git a/sock.c b/sock.c
index 7d1f244..412577a 100644
--- a/sock.c
+++ b/sock.c
@@ -31,9 +31,11 @@
 
 #ifdef LINUX
 #include <sys/socket.h>
+#include <linux/sockios.h>
 #else
 #include <sys/sockio.h>
 #endif
+#include <arpa/inet.h>
 
 #if defined (ALPHA) || defined(SH) || defined(SH64)
 #ifdef HAVE_SYS_IOCTL_H
@@ -42,14 +44,28 @@
 #include <ioctls.h>
 #endif
 #endif
+#include <net/if.h>
+
+extern struct xlat addrfams[];
 
 int
 sock_ioctl(tcp, code, arg)
 struct tcb *tcp;
 long code, arg;
 {
-	if (entering(tcp))
+	struct ifreq ifr;
+	struct ifconf ifc;
+
+	if (entering(tcp)) {
+		if (code == SIOCGIFCONF) {
+			umove(tcp, tcp->u_arg[2], &ifc);
+			if (ifc.ifc_buf == NULL)
+				tprintf(", {%d -> ", ifc.ifc_len);
+			else
+				tprintf(", {");
+		}
 		return 0;
+	}
 
 	switch (code) {
 #ifdef SIOCSHIWAT
@@ -81,6 +97,61 @@
 #endif
 		printnum(tcp, arg, ", %#d");
 		return 1;
+#ifdef LINUX
+	case SIOCGIFNAME:
+	case SIOCGIFINDEX:
+		umove(tcp, tcp->u_arg[2], &ifr);
+                if (syserror(tcp)) {
+			if (code == SIOCGIFNAME)
+				tprintf(", {%d, ???}", ifr.ifr_ifindex);
+			else if (code == SIOCGIFINDEX)
+				tprintf(", {???, \"%s\"}", ifr.ifr_name);
+		} else
+			tprintf(", {%d, \"%s\"}",
+				ifr.ifr_ifindex, ifr.ifr_name);
+		return 1;
+	case SIOCGIFCONF:
+		umove(tcp, tcp->u_arg[2], &ifc);
+		tprintf("%d, ", ifc.ifc_len);
+                if (syserror(tcp)) {
+			tprintf("%lx", (unsigned long) ifc.ifc_buf);
+		} else if (ifc.ifc_buf == NULL) {
+			tprintf("NULL");
+		} else {
+			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);
+			tprintf("{");
+			for (i = 0; i < nifra; ++i ) {
+				if (i > 0)
+					tprintf(", ");
+				tprintf("{\"%s\", {",
+					ifra[i].ifr_name);
+				if (verbose(tcp)) {
+					printxval(addrfams,
+						  ifra[i].ifr_addr.sa_family,
+						  "AF_???");
+					tprintf(", ");
+					if (ifra[i].ifr_addr.sa_family == AF_INET) {
+						struct sockaddr_in *sinp;
+						sinp = (struct sockaddr_in *) &ifra[i].ifr_addr;
+						tprintf("inet_addr(\"%s\")",
+							inet_ntoa(sinp->sin_addr));
+					} else
+						printstr(tcp,
+							 (long) &ifra[i].ifr_addr.sa_data,
+							 sizeof(ifra[i].ifr_addr.sa_data));
+				} else
+					tprintf("...");
+				tprintf("}}");
+			}
+			tprintf("}");
+		}
+		tprintf("}");
+		return 1;
+#endif
 	default:
 		return 0;
 	}