/* $Id$ */
/** @file
* Apps - VBoxAdpCtl, Configuration tool for vboxnetX adapters.
*/
/*
* 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;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#ifdef RT_OS_LINUX
/* Older versions of ethtool.h rely on these: */
typedef unsigned long long u64;
#endif
#ifdef RT_OS_SOLARIS
#endif
/** @todo Error codes must be moved to some header file */
/** @todo These are duplicates from src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdpInternal.h */
typedef struct VBoxNetAdpReq
{
static char *g_pszIfConfig;
#if defined(RT_OS_LINUX)
#elif defined(RT_OS_SOLARIS)
#else
#endif
static void showUsage(void)
{
}
static void setPathIfConfig(void)
{
struct stat s;
if ( !stat(VBOXADPCTL_IFCONFIG_PATH1, &s)
g_pszIfConfig = (char*)VBOXADPCTL_IFCONFIG_PATH1;
else
g_pszIfConfig = (char*)VBOXADPCTL_IFCONFIG_PATH2;
}
{
const char * const argv[] =
{
pcszArg1, /* [address family] */
pcszArg2, /* address */
pcszArg3, /* ['netmask'] */
pcszArg4, /* [network mask] */
pcszArg5, /* [network mask] */
NULL /* terminator */
};
switch (childPid)
{
case -1: /* Something went wrong. */
perror("fork() failed");
rc = EXIT_FAILURE;
break;
case 0: /* Child process. */
rc = EXIT_FAILURE;
break;
default: /* Parent process. */
break;
}
return rc;
}
{
int rc;
if (rc < 0)
return false;
if (pid < 0)
return false;
if (pid == 0)
{
/* child */
if (rc >= 0)
return false;
}
/* parent */
if (!fp)
return false;
int cAddrs;
{
/* We are concerned with IPv6 address lines only. */
continue;
#ifdef RT_OS_LINUX
/* Skip "addr:". */
continue;
#endif
/* Skip link-local addresses. */
continue;
}
for (int i = 0; i < cAddrs; i++)
{
return false;
}
return true;
}
{
if (fd == -1)
{
return ADPCTLERR_NO_CTL_DEV;
}
if (rc == -1)
{
}
return rc;
}
{
{
return ADPCTLERR_BAD_NAME;
}
{
return ADPCTLERR_BAD_NAME;
}
return 0;
}
{
bool fRemove = false;
switch (argc)
{
case 5:
{
/* Add a netmask to existing interface */
{
showUsage();
return 1;
}
pszOption = "netmask";
break;
}
case 4:
{
/* Remove a single address from existing interface */
{
showUsage();
return 1;
}
fRemove = true;
break;
}
case 3:
{
#ifdef RT_OS_LINUX
{
/*
* This ugly hack is needed for retrieving the link speed on
* pre-2.6.33 kernels (see @bugref{6345}).
*/
{
showUsage();
return -1;
}
if (fd < 0)
{
"speed for %s: ", pszAdapterName);
perror("VBoxNetAdpCtl: failed to open control socket");
return ADPCTLERR_SOCKET_FAILED;
}
/* Get link status first. */
if (rc == 0)
{
if (EthToolVal.data)
{
if (rc == 0)
{
}
else
{
"speed for %s: ", pszAdapterName);
perror("VBoxNetAdpCtl: ioctl failed");
}
}
else
printf("0");
}
else
{
"status for %s: ", pszAdapterName);
perror("VBoxNetAdpCtl: ioctl failed");
}
return rc;
}
#endif
if (rc)
return rc;
{
/* Remove an existing interface */
#ifdef RT_OS_SOLARIS
return 1;
#else
#endif
}
{
/* Create an interface with given name */
#ifdef RT_OS_SOLARIS
return 1;
#else
if (rc == 0)
#endif
return rc;
}
break;
}
case 2:
{
/* Create a new interface */
{
#ifdef RT_OS_SOLARIS
return 1;
#else
if (rc == 0)
#endif
return rc;
}
/* Fall through */
}
default:
/* Fall through */
case 1:
showUsage();
return 1;
}
if (rc)
return rc;
if (fRemove)
{
else
{
#if defined(RT_OS_LINUX)
#else
#endif
#ifdef RT_OS_SOLARIS
/* On Solaris we can unplumb the ipv4 interface */
#endif
}
}
else
{
{
#ifdef RT_OS_SOLARIS
/* On Solaris we need to plumb the interface first if it's not already plumbed. */
#endif
/*
* Before we set IPv6 address we'd like to remove
* all previously assigned addresses except the
* self-assigned one.
*/
if (!removeAddresses(pszAdapterName))
rc = EXIT_FAILURE;
else
rc = executeIfconfig(pszAdapterName, "inet6", VBOXADPCTL_ADD_CMD, pszAddress, pszOption, pszNetworkMask);
}
else
{
#ifdef RT_OS_SOLARIS
/* On Solaris we need to plumb the interface first if it's not already plumbed. */
#endif
}
}
return rc;
}