2005-02-02 Roland McGrath <roland@redhat.com>
* sock.c (iffflags): New variable, table of IFF_* values.
(print_addr): New function.
(sock_ioctl): Handle SIOCGIFADDR, SIOCGIFDSTADDR, SIOCGIFBRDADDR,
SIOCGIFNETMASK, SIOCGIFFLAGS, SIOCGIFMETRIC, SIOCGIFMTU, SIOCGIFSLAVE,
SIOCGIFHWADDR. Use print_addr for SIOCGIFCONF, SIOCGIFNAME, and
SIOCGIFINDEX, and fix their output.
From Ulrich Drepper <drepper@redhat.com>.
Fixes RH#138223.
diff --git a/sock.c b/sock.c
index be7a5b8..787bf92 100644
--- a/sock.c
+++ b/sock.c
@@ -49,6 +49,40 @@
extern const struct xlat addrfams[];
+static const struct xlat iffflags[] = {
+ { IFF_UP, "IFF_UP" },
+ { IFF_BROADCAST, "IFF_BROADCAST" },
+ { IFF_DEBUG, "IFF_DEBUG" },
+ { IFF_LOOPBACK, "IFF_LOOPBACK" },
+ { IFF_POINTOPOINT, "IFF_POINTOPOINT" },
+ { IFF_NOTRAILERS, "IFF_NOTRAILERS" },
+ { IFF_RUNNING, "IFF_RUNNING" },
+ { IFF_NOARP, "IFF_NOARP" },
+ { IFF_PROMISC, "IFF_PROMISC" },
+ { IFF_ALLMULTI, "IFF_ALLMULTI" },
+ { IFF_MASTER, "IFF_MASTER" },
+ { IFF_SLAVE, "IFF_SLAVE" },
+ { IFF_MULTICAST, "IFF_MULTICAST" },
+ { IFF_PORTSEL, "IFF_PORTSEL" },
+ { IFF_AUTOMEDIA, "IFF_AUTOMEDIA" },
+ { 0, NULL }
+};
+
+
+static void
+print_addr(tcp, addr, ifr)
+struct tcb *tcp;
+long addr;
+struct ifreq *ifr;
+{
+ if (ifr->ifr_addr.sa_family == AF_INET) {
+ struct sockaddr_in *sinp;
+ sinp = (struct sockaddr_in *) &ifr->ifr_addr;
+ tprintf("inet_addr(\"%s\")", inet_ntoa(sinp->sin_addr));
+ } else
+ printstr(tcp, addr, sizeof(ifr->ifr_addr.sa_data));
+}
+
int
sock_ioctl(tcp, code, arg)
struct tcb *tcp;
@@ -56,6 +90,8 @@
{
struct ifreq ifr;
struct ifconf ifc;
+ const char *str = NULL;
+ unsigned char *bytes;
if (entering(tcp)) {
if (code == SIOCGIFCONF) {
@@ -101,15 +137,76 @@
#ifdef LINUX
case SIOCGIFNAME:
case SIOCGIFINDEX:
+ case SIOCGIFADDR:
+ case SIOCGIFDSTADDR:
+ case SIOCGIFBRDADDR:
+ case SIOCGIFNETMASK:
+ case SIOCGIFFLAGS:
+ case SIOCGIFMETRIC:
+ case SIOCGIFMTU:
+ case SIOCGIFSLAVE:
+ case SIOCGIFHWADDR:
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\"}",
+ tprintf(", {ifr_index=%d, ifr_name=???}", ifr.ifr_ifindex);
+ else
+ tprintf(", {ifr_name=\"%s\", ???}", ifr.ifr_name);
+ } else if (code == SIOCGIFNAME)
+ tprintf(", {ifr_index=%d, ifr_name=\"%s\"}",
ifr.ifr_ifindex, ifr.ifr_name);
+ else {
+ tprintf(", {ifr_name=\"%s\", ", ifr.ifr_name);
+ switch (code) {
+ case SIOCGIFINDEX:
+ tprintf("ifr_index=%d", ifr.ifr_ifindex);
+ break;
+ case SIOCGIFADDR:
+ str = "ifr_addr";
+ case SIOCGIFDSTADDR:
+ if (str == NULL)
+ str = "ifr_dstaddr";
+ case SIOCGIFBRDADDR:
+ if (str == NULL)
+ str = "ifr_broadaddr";
+ case SIOCGIFNETMASK:
+ if (str == NULL)
+ str = "ifr_netmask";
+ tprintf("%s={", str);
+ printxval(addrfams,
+ ifr.ifr_addr.sa_family,
+ "AF_???");
+ tprintf(", ");
+ print_addr(tcp, ((long) tcp->u_arg[2]
+ + offsetof (struct ifreq,
+ ifr_addr.sa_data)),
+ &ifr);
+ tprintf("}");
+ break;
+ case SIOCGIFHWADDR:
+ /* XXX Are there other hardware addresses
+ than 6-byte MACs? */
+ bytes = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
+ tprintf("ifr_hwaddr=%02x:%02x:%02x:%02x:%02x:%02x",
+ bytes[0], bytes[1], bytes[2],
+ bytes[3], bytes[4], bytes[5]);
+ break;
+ case SIOCGIFFLAGS:
+ tprintf("ifr_flags=");
+ printflags(iffflags, ifr.ifr_flags);
+ break;
+ case SIOCGIFMETRIC:
+ tprintf("ifr_metric=%d", ifr.ifr_metric);
+ break;
+ case SIOCGIFMTU:
+ tprintf("ifr_mtu=%d", ifr.ifr_mtu);
+ break;
+ case SIOCGIFSLAVE:
+ tprintf("ifr_slave=\"%s\"", ifr.ifr_slave);
+ break;
+ }
+ tprintf("}");
+ }
return 1;
case SIOCGIFCONF:
umove(tcp, tcp->u_arg[2], &ifc);
@@ -135,15 +232,12 @@
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));
+ print_addr(tcp, ((long) tcp->u_arg[2]
+ + offsetof (struct ifreq,
+ ifr_addr.sa_data)
+ + ((char *) &ifra[i]
+ - (char *) &ifra[0])),
+ &ifra[i]);
} else
tprintf("...");
tprintf("}}");