DevINIP.cpp revision fd492d285ed33c86dd76bc05d9d4f3e55bc0fb49
/* $Id$ */
/** @file
*/
/*
* Copyright (C) 2007-2009 Sun Microsystems, Inc.
*
* 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.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 USA or visit http://www.sun.com if you need
* additional information or have any questions.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#define LOG_GROUP LOG_GROUP_DEV_INIP
#include <iprt/semaphore.h>
/* All lwip header files are not C++ safe. So hack around this. */
#include "../Builtins.h"
/*******************************************************************************
* Macros and Defines *
*******************************************************************************/
/** Maximum frame size this device can handle. */
#define DEVINIP_MAX_FRAME 1514
/*******************************************************************************
* Structures and Typedefs *
*******************************************************************************/
/**
* Internal Network IP stack device instance data.
*
* @implements PDMIBASE
* @implements PDMINETWORKPORT
*/
typedef struct DEVINTNETIP
{
/** The base interface for LUN\#0. */
/** The network port this device provides (LUN\#0). */
/** The base interface of the network driver below us. */
/** The connector of the network driver below us. */
/** Pointer to the device instance. */
/** MAC adress. */
/** Static IP address of the interface. */
char *pszIP;
/** Netmask of the interface. */
char *pszNetmask;
/** Gateway for the interface. */
char *pszGateway;
/** lwIP network interface description. */
/** lwIP ARP timer. */
/** lwIP TCP fast timer. */
/** lwIP TCP slow timer. */
/** hack: get linking right. remove this eventually, once the device
* provides a proper interface to all IP stack functions. */
const void *pLinkHack;
} DEVINTNETIP, *PDEVINTNETIP;
/*******************************************************************************
* Global Variables *
*******************************************************************************/
/**
* Pointer to the (only) instance data in this device.
*/
/*
* really ugly hack to avoid linking problems on unix style platforms
* using .a libraries for now.
*/
static const PFNRT g_pDevINILinkHack[] =
{
};
/*******************************************************************************
* Internal Functions *
*******************************************************************************/
struct pbuf *p);
/**
* ARP cache timeout handling for lwIP.
*
* @param pDevIns Device instance.
* @param pTimer Pointer to timer.
*/
{
}
/**
* TCP fast timer handling for lwIP.
*
* @param pDevIns Device instance.
* @param pTimer Pointer to timer.
*/
{
}
/**
* TCP slow timer handling for lwIP.
*
* @param pDevIns Device instance.
* @param pTimer Pointer to timer.
*/
{
}
/**
* code to resolve the address and call the link-level packet function.
*
* @returns lwIP error code
* @param netif Interface on which to send IP packet.
* @param p Packet data.
* @param ipaddr Destination IP address.
*/
{
return lrc;
}
/**
* Output a raw packet on the interface.
*
* @returns lwIP error code
* @param netif Interface on which to send frame.
* @param p Frame data.
*/
struct pbuf *p)
{
struct pbuf *q;
int rc = VINF_SUCCESS;
/* Silently ignore packets being sent while lwIP isn't set up. */
if (!g_pDevINIPData)
goto out;
#if ETH_PAD_SIZE
#endif
cbBuf = 0;
{
{
}
else
{
LogRel(("INIP: exceeded frame size\n"));
break;
}
}
if (cbBuf)
#if ETH_PAD_SIZE
#endif
out:
if (RT_FAILURE(rc))
return lrc;
}
/**
* Implements the ethernet interface backend initialization for lwIP.
*
* @returns lwIP error code
* @param netif Interface to configure.
*/
{
return ERR_OK;
}
/**
* Wait until data can be received.
*
* @returns VBox status code. VINF_SUCCESS means there is at least one receive descriptor available.
* @param pInterface PDM network port interface pointer.
* @param cMillies Number of milliseconds to wait. 0 means return immediately.
*/
{
return VINF_SUCCESS;
}
/**
* Receive data and pass it to lwIP for processing.
*
* @returns VBox status code
* @param pInterface PDM network port interface pointer.
* @param pvBuf Pointer to frame data.
* @param cb Frame size.
*/
{
struct pbuf *p, *q;
int rc = VINF_SUCCESS;
/* Silently ignore packets being received while lwIP isn't set up. */
if (!g_pDevINIPData)
goto out;
#if ETH_PAD_SIZE
#endif
/* We allocate a pbuf chain of pbufs from the pool. */
if (p != NULL)
{
#if ETH_PAD_SIZE
#endif
{
/* Fill the buffers, and clean out unused buffer space. */
}
{
case ETHTYPE_IP: /* IP packet */
if (lrc)
break;
case ETHTYPE_ARP: /* ARP packet */
break;
default:
lwip_pbuf_free(p);
}
}
out:
return rc;
}
/**
* Signals the end of lwIP TCPIP initialization.
*
* @param arg opaque argument, here the pointer to the semaphore.
*/
{
}
/**
* @interface_method_impl{PDMIBASE,pfnQueryInterface}
*/
const char *pszIID)
{
return NULL;
}
/**
* Construct an internal networking IP stack device instance.
*
* @returns VBox status.
* @param pDevIns The device instance data.
* If the registration structure is needed, pDevIns->pDevReg points to it.
* @param iInstance Instance number. Use this to figure out which registers
* and such to use.
* he device number is also found in pDevIns->iInstance, but since it's
* likely to be freqently used PDM passes it as parameter.
* @param pCfgHandle Configuration node handle for the device. Use this to obtain the configuration
* of the device instance. It's also found in pDevIns->pCfgHandle, but like
* iInstance it's expected to be used a bit in this function.
*/
{
int rc = VINF_SUCCESS;
/*
* Validate the config.
*/
{
N_("Unknown Internal Networking IP configuration option"));
goto out;
}
/*
* Init the static parts.
*/
/* Pointer to device instance */
/* IBase */
/* INetworkPort */
/*
* Get the configuration settings.
*/
if (rc == VERR_CFGM_NOT_BYTES)
{
char szMAC[64];
if (RT_SUCCESS(rc))
{
for (uint32_t i = 0; i < 6; i++)
{
{
N_("Configuration error: Invalid \"MAC\" value"));
goto out;
}
if (c1 > 9)
c1 -= 7;
if (c2 > 9)
c2 -= 7;
macStr++;
}
}
}
if (RT_FAILURE(rc))
{
N_("Configuration error: Failed to get the \"MAC\" value"));
goto out;
}
if (RT_FAILURE(rc))
{
N_("Configuration error: Failed to get the \"IP\" value"));
goto out;
}
if (RT_FAILURE(rc))
{
N_("Configuration error: Failed to get the \"Netmask\" value"));
goto out;
}
if (rc == VERR_CFGM_VALUE_NOT_FOUND)
rc = VINF_SUCCESS;
if (RT_FAILURE(rc))
{
N_("Configuration error: Failed to get the \"Gateway\" value"));
goto out;
}
/*
* Attach driver and query the network connector interface.
*/
"Network Port");
if (RT_FAILURE(rc))
{
goto out;
}
else
{
{
AssertMsgFailed(("Failed to obtain the PDMINTERFACE_NETWORK_CONNECTOR interface!\n"));
goto out;
}
}
{
N_("Configuration error: Invalid \"IP\" value"));
goto out;
}
{
N_("Configuration error: Invalid \"Netmask\" value"));
goto out;
}
if (pThis->pszGateway)
{
{
N_("Configuration error: Invalid \"Gateway\" value"));
goto out;
}
}
else
{
}
/*
* Initialize lwIP.
*/
#if MEM_LIBC_MALLOC == 0
#endif
if (RT_FAILURE(rc))
goto out;
if (RT_FAILURE(rc))
goto out;
if (RT_FAILURE(rc))
goto out;
{
}
/*
* Set up global pointer to interface data.
*/
if (!ret)
{
goto out;
}
/* link hack */
out:
return rc;
}
/**
* Destruct a device instance.
*
* Most VM resources are freed by the VM. This callback is provided so that any non-VM
* resources can be freed correctly.
*
* @returns VBox status.
* @param pDevIns The device instance data.
*/
{
if (g_pDevINIPData != NULL)
{
}
if (pThis->pszNetmask)
if (pThis->pszGateway)
return VINF_SUCCESS;
}
/**
* Query whether lwIP is initialized or not. Since there is only a single
* instance of this device ever for a VM, it can be a global function.
*
* @returns True if lwIP is initialized.
*/
bool DevINIPConfigured(void)
{
return g_pDevINIPData != NULL;
}
/**
* Internal network IP stack device registration record.
*/
const PDMDEVREG g_DeviceINIP =
{
/* u32Version */
/* szDeviceName */
"IntNetIP",
"",
"",
/* pszDescription */
"Internal Network IP stack device",
/* fFlags */
/* fClass. As this is used by the storage devices, it must come earlier. */
/* cMaxInstances */
1,
/* cbInstance */
sizeof(DEVINTNETIP),
/* pfnConstruct */
/* pfnDestruct */
/* pfnRelocate */
NULL,
/* pfnIOCtl */
NULL,
/* pfnPowerOn */
NULL,
/* pfnReset */
NULL,
/* pfnSuspend */
NULL,
/* pfnResume */
NULL,
/* pfnAttach */
NULL,
/* pfnDetach */
NULL,
/* pfnQueryInterface */
NULL,
/* pfnInitComplete */
NULL,
/* pfnPowerOff */
NULL,
/* pfnSoftReset */
NULL,
/* u32VersionEnd */
};