/* $Id$ */
/** @file
* VBoxNetAdp - Virtual Network Adapter Driver (Host), Linux Specific Code.
*/
/*
* 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 "the-linux-kernel.h"
#include "version-generated.h"
#include "product-generated.h"
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/miscdevice.h>
#include <iprt/initterm.h>
/*
#include <iprt/semaphore.h>
#include <iprt/spinlock.h>
*/
#include "../VBoxNetAdpInternal.h"
/*******************************************************************************
* Defined Constants And Macros *
*******************************************************************************/
/*******************************************************************************
* Internal Functions *
*******************************************************************************/
static int VBoxNetAdpLinuxInit(void);
static void VBoxNetAdpLinuxUnload(void);
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) */
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) */
/*******************************************************************************
* Global Variables *
*******************************************************************************/
MODULE_LICENSE("GPL");
#ifdef MODULE_VERSION
#endif
/**
* The (common) global data.
*/
{
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) */
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) */
};
/** The miscdevice structure. */
{
# endif
};
struct VBoxNetAdpPriv
{
};
{
return 0;
}
{
return 0;
}
{
/* Update the stats. */
/* Update transmission time stamp. */
/* Nothing else to do, just free the sk_buff. */
return 0;
}
{
}
};
#endif
{
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) */
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) */
}
{
/* No need for private data. */
#endif
if (pNetDev)
{
int err;
{
if (!err)
{
return VINF_SUCCESS;
}
}
else
{
LogRel(("VBoxNetAdp: failed to set MAC address (dev->dev_addr == NULL)\n"));
}
}
return rc;
}
{
}
/**
* Device open. Called on open /dev/vboxnetctl
*
* @param pInode Pointer to inode info structure.
* @param pFilp Associated file pointer.
*/
{
#ifdef VBOX_WITH_HARDENING
/*
* Only root is allowed to access the device, enforce it!
*/
if (!capable(CAP_SYS_ADMIN))
{
Log(("VBoxNetAdpLinuxOpen: admin privileges required!\n"));
return -EPERM;
}
#endif
return 0;
}
/**
* Close device.
*
* @param pInode Pointer to inode info structure.
* @param pFilp Associated file pointer.
*/
{
Log(("VBoxNetAdpLinuxClose: pid=%d/%d %s\n",
return 0;
}
/**
* Device I/O Control entry point.
*
* @param pFilp Associated file pointer.
* @param uCmd The function specified to ioctl().
* @param ulArg The argument specified to ioctl().
*/
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) */
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) */
{
int rc;
Log(("VBoxNetAdpLinuxIOCtl: param len %#x; uCmd=%#x; add=%#x\n", _IOC_SIZE(uCmd), uCmd, VBOXNETADP_CTL_ADD));
{
Log(("VBoxNetAdpLinuxIOCtl: bad ioctl sizeof(Req)=%#x _IOC_SIZE=%#x; uCmd=%#x.\n", sizeof(Req), _IOC_SIZE(uCmd), uCmd));
return -EINVAL;
}
switch (uCmd)
{
case VBOXNETADP_CTL_ADD:
{
return -EFAULT;
}
{
if (pAdp)
{
return -EINVAL;
}
}
if (RT_FAILURE(rc))
{
}
{
/* this is really bad! */
/** @todo remove the adapter again? */
printk(KERN_ERR "VBoxNetAdpLinuxIOCtl: copy_to_user(%#lx,,%#zx); uCmd=%#x!\n", ulArg, sizeof(Req), uCmd);
return -EFAULT;
}
break;
case VBOXNETADP_CTL_REMOVE:
{
return -EFAULT;
}
if (!pAdp)
{
return -EINVAL;
}
if (RT_FAILURE(rc))
{
return -EINVAL;
}
break;
default:
return -EINVAL;
}
return 0;
}
{
/*
* Init linux-specific members.
*/
return VINF_SUCCESS;
}
/**
* Initialize module.
*
* @returns appropriate status code.
*/
{
int rc;
/*
* Initialize IPRT.
*/
if (RT_SUCCESS(rc))
{
Log(("VBoxNetAdpLinuxInit\n"));
rc = vboxNetAdpInit();
if (RT_SUCCESS(rc))
{
if (rc)
{
return rc;
}
LogRel(("VBoxNetAdp: Successfully started.\n"));
return 0;
}
else
}
else
return -RTErrConvertToErrno(rc);
}
/**
* Unload the module.
*
* @todo We have to prevent this if we're busy!
*/
{
int rc;
Log(("VBoxNetAdpLinuxUnload\n"));
/*
* Undo the work done during start (in reverse order).
*/
/* Remove control device */
if (rc < 0)
{
}
RTR0Term();
Log(("VBoxNetAdpLinuxUnload - done\n"));
}