summaryrefslogtreecommitdiff
path: root/src/apps/adpctl
diff options
context:
space:
mode:
Diffstat (limited to 'src/apps/adpctl')
-rw-r--r--src/apps/adpctl/VBoxNetAdpCtl.cpp61
1 files changed, 50 insertions, 11 deletions
diff --git a/src/apps/adpctl/VBoxNetAdpCtl.cpp b/src/apps/adpctl/VBoxNetAdpCtl.cpp
index bfaae180..2e46d36b 100644
--- a/src/apps/adpctl/VBoxNetAdpCtl.cpp
+++ b/src/apps/adpctl/VBoxNetAdpCtl.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -26,6 +26,7 @@
#include <unistd.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
+#include <sys/stat.h>
#include <fcntl.h>
#ifdef RT_OS_LINUX
# include <net/if.h>
@@ -61,8 +62,9 @@ typedef struct VBoxNetAdpReq
} VBOXNETADPREQ;
typedef VBOXNETADPREQ *PVBOXNETADPREQ;
-
-#define VBOXADPCTL_IFCONFIG_PATH "/sbin/ifconfig"
+#define VBOXADPCTL_IFCONFIG_PATH1 "/sbin/ifconfig"
+#define VBOXADPCTL_IFCONFIG_PATH2 "/bin/ifconfig"
+static char *g_pszIfConfig;
#if defined(RT_OS_LINUX)
# define VBOXADPCTL_DEL_CMD "del"
@@ -82,6 +84,16 @@ static void showUsage(void)
fprintf(stderr, " | VBoxNetAdpCtl <adapter> remove\n");
}
+static void setPathIfConfig(void)
+{
+ struct stat s;
+ if ( !stat(VBOXADPCTL_IFCONFIG_PATH1, &s)
+ && S_ISREG(s.st_mode))
+ g_pszIfConfig = (char*)VBOXADPCTL_IFCONFIG_PATH1;
+ else
+ g_pszIfConfig = (char*)VBOXADPCTL_IFCONFIG_PATH2;
+}
+
static int executeIfconfig(const char *pcszAdapterName, const char *pcszArg1,
const char *pcszArg2 = NULL,
const char *pcszArg3 = NULL,
@@ -90,7 +102,7 @@ static int executeIfconfig(const char *pcszAdapterName, const char *pcszArg1,
{
const char * const argv[] =
{
- VBOXADPCTL_IFCONFIG_PATH,
+ g_pszIfConfig,
pcszAdapterName,
pcszArg1, /* [address family] */
pcszArg2, /* address */
@@ -109,7 +121,7 @@ static int executeIfconfig(const char *pcszAdapterName, const char *pcszArg1,
rc = EXIT_FAILURE;
break;
case 0: /* Child process. */
- if (execve(VBOXADPCTL_IFCONFIG_PATH, (char * const*)argv, envp) == -1)
+ if (execve(argv[0], (char * const*)argv, envp) == -1)
rc = EXIT_FAILURE;
break;
default: /* Parent process. */
@@ -129,7 +141,7 @@ static bool removeAddresses(char *pszAdapterName)
char aszAddresses[MAX_ADDRESSES][MAX_ADDRLEN];
int rc;
int fds[2];
- char * const argv[] = { (char*)VBOXADPCTL_IFCONFIG_PATH, pszAdapterName, NULL };
+ char * const argv[] = { g_pszIfConfig, pszAdapterName, NULL };
char * const envp[] = { (char*)"LC_ALL=C", NULL };
memset(aszAddresses, 0, sizeof(aszAddresses));
@@ -149,7 +161,7 @@ static bool removeAddresses(char *pszAdapterName)
close(STDOUT_FILENO);
rc = dup2(fds[1], STDOUT_FILENO);
if (rc >= 0)
- execve(VBOXADPCTL_IFCONFIG_PATH, argv, envp);
+ execve(argv[0], argv, envp);
return false;
}
@@ -250,6 +262,8 @@ int main(int argc, char *argv[])
bool fRemove = false;
VBOXNETADPREQ Req;
+ setPathIfConfig();
+
switch (argc)
{
case 5:
@@ -300,6 +314,7 @@ int main(int argc, char *argv[])
return -1;
}
struct ifreq IfReq;
+ struct ethtool_value EthToolVal;
struct ethtool_cmd EthToolReq;
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0)
@@ -309,22 +324,46 @@ int main(int argc, char *argv[])
perror("VBoxNetAdpCtl: failed to open control socket");
return ADPCTLERR_SOCKET_FAILED;
}
+ /* Get link status first. */
+ memset(&EthToolVal, 0, sizeof(EthToolVal));
memset(&IfReq, 0, sizeof(IfReq));
snprintf(IfReq.ifr_name, sizeof(IfReq.ifr_name), "%s", pszAdapterName);
- EthToolReq.cmd = ETHTOOL_GSET;
- IfReq.ifr_data = (caddr_t)&EthToolReq;
+
+ EthToolVal.cmd = ETHTOOL_GLINK;
+ IfReq.ifr_data = (caddr_t)&EthToolVal;
rc = ioctl(fd, SIOCETHTOOL, &IfReq);
if (rc == 0)
{
- printf("%u", EthToolReq.speed);
+ if (EthToolVal.data)
+ {
+ memset(&IfReq, 0, sizeof(IfReq));
+ snprintf(IfReq.ifr_name, sizeof(IfReq.ifr_name), "%s", pszAdapterName);
+ EthToolReq.cmd = ETHTOOL_GSET;
+ IfReq.ifr_data = (caddr_t)&EthToolReq;
+ rc = ioctl(fd, SIOCETHTOOL, &IfReq);
+ if (rc == 0)
+ {
+ printf("%u", EthToolReq.speed);
+ }
+ else
+ {
+ fprintf(stderr, "VBoxNetAdpCtl: Error while retrieving link "
+ "speed for %s: ", pszAdapterName);
+ perror("VBoxNetAdpCtl: ioctl failed");
+ rc = ADPCTLERR_IOCTL_FAILED;
+ }
+ }
+ else
+ printf("0");
}
else
{
fprintf(stderr, "VBoxNetAdpCtl: Error while retrieving link "
- "speed for %s: ", pszAdapterName);
+ "status for %s: ", pszAdapterName);
perror("VBoxNetAdpCtl: ioctl failed");
rc = ADPCTLERR_IOCTL_FAILED;
}
+
close(fd);
return rc;
}