DevINIP.cpp revision 01644b3fb3841a1b087fb2a5b8c2870d9876541b
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/* $Id$ */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/** @file
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * DevINIP - Internal Network IP stack device/service.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/*
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync * Copyright (C) 2007-2009 Oracle Corporation
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * available from http://www.virtualbox.org. This file is free software;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * you can redistribute it and/or modify it under the terms of the GNU
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * General Public License (GPL) as published by the Free Software
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/*******************************************************************************
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync* Header Files *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync*******************************************************************************/
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#define LOG_GROUP LOG_GROUP_DEV_INIP
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsync#include <iprt/cdefs.h> /* include early to allow RT_C_DECLS_BEGIN hack */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include <iprt/mem.h> /* include anything of ours that the lwip headers use. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include <iprt/semaphore.h>
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include <iprt/thread.h>
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include <iprt/alloca.h>
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/* All lwip header files are not C++ safe. So hack around this. */
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsyncRT_C_DECLS_BEGIN
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include "lwip/sys.h"
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include "lwip/stats.h"
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include "lwip/mem.h"
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include "lwip/memp.h"
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include "lwip/pbuf.h"
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include "lwip/netif.h"
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync#ifndef VBOX_WITH_NEW_LWIP
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync# include "ipv4/lwip/ip.h"
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync#else
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync# include "lwip/api.h"
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync# include "lwip/tcp_impl.h"
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync# include "ipv6/lwip/ethip6.h"
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync#endif
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync#include "lwip/udp.h"
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync#include "lwip/tcp.h"
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include "lwip/tcpip.h"
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include "lwip/sockets.h"
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include "netif/etharp.h"
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsyncRT_C_DECLS_END
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <VBox/vmm/pdmdev.h>
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <VBox/vmm/pdmnetifs.h>
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <VBox/vmm/tm.h>
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#include <iprt/assert.h>
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync#include <iprt/string.h>
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync#include <iprt/uuid.h>
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
f5e53763b0a581b0299e98028c6c52192eb06785vboxsync#include "VBoxDD.h"
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/*******************************************************************************
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync* Macros and Defines *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync*******************************************************************************/
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/** Maximum frame size this device can handle. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#define DEVINIP_MAX_FRAME 1514
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/*******************************************************************************
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync* Structures and Typedefs *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync*******************************************************************************/
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Internal Network IP stack device instance data.
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync *
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * @implements PDMIBASE
787c7e6ef15f993c455c374f5158e7bb753b1c33vboxsync * @implements PDMINETWORKDOWN
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsynctypedef struct DEVINTNETIP
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync /** The base interface for LUN\#0. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync PDMIBASE IBase;
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync /** The network port this device provides (LUN\#0). */
787c7e6ef15f993c455c374f5158e7bb753b1c33vboxsync PDMINETWORKDOWN INetworkDown;
114aab25ffaeef9fba3a27b58ac0c07296bb5814vboxsync /** The network configuration port this device provides (LUN\#0). */
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync PDMINETWORKCONFIG INetworkConfig;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /** The base interface of the network driver below us. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync PPDMIBASE pDrvBase;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /** The connector of the network driver below us. */
787c7e6ef15f993c455c374f5158e7bb753b1c33vboxsync PPDMINETWORKUP pDrv;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /** Pointer to the device instance. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync PPDMDEVINSR3 pDevIns;
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync /** MAC address. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync RTMAC MAC;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /** Static IP address of the interface. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync char *pszIP;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /** Netmask of the interface. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync char *pszNetmask;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /** Gateway for the interface. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync char *pszGateway;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /** lwIP network interface description. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync struct netif IntNetIF;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /** lwIP ARP timer. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync PTMTIMERR3 ARPTimer;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /** lwIP TCP fast timer. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync PTMTIMERR3 TCPFastTimer;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /** lwIP TCP slow timer. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync PTMTIMERR3 TCPSlowTimer;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /** lwIP semaphore to coordinate TCPIP init/terminate. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync sys_sem_t LWIPTcpInitSem;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /** hack: get linking right. remove this eventually, once the device
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * provides a proper interface to all IP stack functions. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync const void *pLinkHack;
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync /** Flag whether the link is up. */
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync bool fLnkUp;
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync /** Flag whether the configuration is IPv6 */
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync bool fIpv6;
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync /** Static IPv6 address of the interface. */
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync char *pszIP6;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync} DEVINTNETIP, *PDEVINTNETIP;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/*******************************************************************************
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync* Global Variables *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync*******************************************************************************/
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Pointer to the (only) instance data in this device.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic PDEVINTNETIP g_pDevINIPData = NULL;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * really ugly hack to avoid linking problems on unix style platforms
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * using .a libraries for now.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic const PFNRT g_pDevINILinkHack[] =
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync (PFNRT)lwip_socket,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync (PFNRT)lwip_close,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync (PFNRT)lwip_setsockopt,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync (PFNRT)lwip_recv,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync (PFNRT)lwip_send,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync (PFNRT)lwip_select
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync};
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/*******************************************************************************
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync* Internal Functions *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync*******************************************************************************/
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic DECLCALLBACK(void) devINIPARPTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic DECLCALLBACK(void) devINIPTCPFastTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic DECLCALLBACK(void) devINIPTCPSlowTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic DECLCALLBACK(err_t) devINIPOutput(struct netif *netif, struct pbuf *p,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync struct ip_addr *ipaddr);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic DECLCALLBACK(err_t) devINIPOutputRaw(struct netif *netif,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync struct pbuf *p);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic DECLCALLBACK(err_t) devINIPInterface(struct netif *netif);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * ARP cache timeout handling for lwIP.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param pDevIns Device instance.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param pTimer Pointer to timer.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsyncstatic DECLCALLBACK(void) devINIPARPTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsync PDEVINTNETIP pThis = (PDEVINTNETIP)pvUser;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync LogFlow(("%s: pDevIns=%p pTimer=%p\n", __FUNCTION__, pDevIns, pTimer));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync lwip_etharp_tmr();
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync TMTimerSetMillies(pThis->ARPTimer, ARP_TMR_INTERVAL);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync LogFlow(("%s: return\n", __FUNCTION__));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * TCP fast timer handling for lwIP.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param pDevIns Device instance.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param pTimer Pointer to timer.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsyncstatic DECLCALLBACK(void) devINIPTCPFastTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsync PDEVINTNETIP pThis = (PDEVINTNETIP)pvUser;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync LogFlow(("%s: pDevIns=%p pTimer=%p\n", __FUNCTION__, pDevIns, pTimer));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync lwip_tcp_fasttmr();
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync TMTimerSetMillies(pThis->TCPFastTimer, TCP_FAST_INTERVAL);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync LogFlow(("%s: return\n", __FUNCTION__));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * TCP slow timer handling for lwIP.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param pDevIns Device instance.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param pTimer Pointer to timer.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsyncstatic DECLCALLBACK(void) devINIPTCPSlowTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsync PDEVINTNETIP pThis = (PDEVINTNETIP)pvUser;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync LogFlow(("%s: pDevIns=%p pTimer=%p\n", __FUNCTION__, pDevIns, pTimer));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync lwip_tcp_slowtmr();
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync TMTimerSetMillies(pThis->TCPSlowTimer, TCP_SLOW_INTERVAL);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync LogFlow(("%s: return\n", __FUNCTION__));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Output a TCP/IP packet on the interface. Uses the generic lwIP ARP
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * code to resolve the address and call the link-level packet function.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @returns lwIP error code
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param netif Interface on which to send IP packet.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param p Packet data.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param ipaddr Destination IP address.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic DECLCALLBACK(err_t) devINIPOutput(struct netif *netif, struct pbuf *p,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync struct ip_addr *ipaddr)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync err_t lrc;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync LogFlow(("%s: netif=%p p=%p ipaddr=%#04x\n", __FUNCTION__, netif, p,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync ipaddr->addr));
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync#ifndef VBOX_WITH_NEW_LWIP
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync lrc = lwip_etharp_output(netif, ipaddr, p);
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync#else
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync lrc = lwip_etharp_output(netif, p, ipaddr);
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync#endif
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync LogFlow(("%s: return %d\n", __FUNCTION__, lrc));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return lrc;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Output a raw packet on the interface.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @returns lwIP error code
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param netif Interface on which to send frame.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param p Frame data.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic DECLCALLBACK(err_t) devINIPOutputRaw(struct netif *netif,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync struct pbuf *p)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync int rc = VINF_SUCCESS;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync LogFlow(("%s: netif=%p p=%p\n", __FUNCTION__, netif, p));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync Assert(g_pDevINIPData);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync Assert(g_pDevINIPData->pDrv);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* Silently ignore packets being sent while lwIP isn't set up. */
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync if (g_pDevINIPData)
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync {
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync PPDMSCATTERGATHER pSgBuf;
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync rc = g_pDevINIPData->pDrv->pfnBeginXmit(g_pDevINIPData->pDrv, true /* fOnWorkerThread */);
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync if (RT_FAILURE(rc))
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync return ERR_IF;
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync rc = g_pDevINIPData->pDrv->pfnAllocBuf(g_pDevINIPData->pDrv, DEVINIP_MAX_FRAME, NULL /*pGso*/, &pSgBuf);
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync if (RT_SUCCESS(rc))
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#if ETH_PAD_SIZE
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync lwip_pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#endif
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync uint8_t *pbBuf = pSgBuf ? (uint8_t *)pSgBuf->aSegs[0].pvSeg : NULL;
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync size_t cbBuf = 0;
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync for (struct pbuf *q = p; q != NULL; q = q->next)
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync {
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync if (cbBuf + q->len <= DEVINIP_MAX_FRAME)
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync {
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync if (RT_LIKELY(pbBuf))
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync {
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync memcpy(pbBuf, q->payload, q->len);
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync pbBuf += q->len;
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync }
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync cbBuf += q->len;
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync }
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync else
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync {
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync LogRel(("INIP: exceeded frame size\n"));
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync break;
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync }
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync }
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync if (cbBuf)
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync {
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync pSgBuf->cbUsed = cbBuf;
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync rc = g_pDevINIPData->pDrv->pfnSendBuf(g_pDevINIPData->pDrv, pSgBuf, true /* fOnWorkerThread */);
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync }
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync else
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync rc = g_pDevINIPData->pDrv->pfnFreeBuf(g_pDevINIPData->pDrv, pSgBuf);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#if ETH_PAD_SIZE
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync lwip_pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#endif
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync }
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync g_pDevINIPData->pDrv->pfnEndXmit(g_pDevINIPData->pDrv);
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync err_t lrc = ERR_OK;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (RT_FAILURE(rc))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync lrc = ERR_IF;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync LogFlow(("%s: return %d (vbox: %Rrc)\n", __FUNCTION__, rc, lrc));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return lrc;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Implements the ethernet interface backend initialization for lwIP.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @returns lwIP error code
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param netif Interface to configure.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic DECLCALLBACK(err_t) devINIPInterface(struct netif *netif)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync LogFlow(("%s: netif=%p\n", __FUNCTION__, netif));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync Assert(g_pDevINIPData != NULL);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync netif->state = g_pDevINIPData;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync netif->hwaddr_len = sizeof(g_pDevINIPData->MAC);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync memcpy(netif->hwaddr, &g_pDevINIPData->MAC, sizeof(g_pDevINIPData->MAC));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync netif->mtu = DEVINIP_MAX_FRAME;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync netif->flags = NETIF_FLAG_BROADCAST;
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync#ifdef VBOX_WITH_NEW_LWIP
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync /* @todo: why explicit ARP routing required for 1.2.0 case? */
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync netif->flags |= NETIF_FLAG_ETHARP;
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync netif->flags |= NETIF_FLAG_ETHERNET;
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync if (g_pDevINIPData->fIpv6)
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync {
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync /* @todo: Don't bother user with entering IPv6 address explicitly,
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync * instead what is required here that IPv6 local-address generation ?
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync */
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync if (!inet6_aton(g_pDevINIPData->pszIP6, &netif->ip6_addr[0]))
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync {
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync PDMDEV_SET_ERROR(g_pDevINIPData->pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync N_("Configuration error: Invalid \"IPv6\" value"));
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync return ERR_IF;
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync }
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync netif_ip6_addr_set_state(netif, 0, IP6_ADDR_VALID);
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync netif->output_ip6 = ethip6_output;
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync netif->ip6_autoconfig_enabled=1;
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync }
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync else
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync netif->output = lwip_etharp_output;
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync#else
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync netif->output = devINIPOutput;
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync#endif
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync netif->linkoutput = devINIPOutputRaw;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync lwip_etharp_init();
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync TMTimerSetMillies(g_pDevINIPData->ARPTimer, ARP_TMR_INTERVAL);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync LogFlow(("%s: success\n", __FUNCTION__));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return ERR_OK;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync/**
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync * Parses CFGM parameters related to network connection
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync */
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsyncstatic DECLCALLBACK(int) devINIPNetworkConfiguration(PPDMDEVINS pDevIns, PDEVINTNETIP pThis, PCFGMNODE pCfg)
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync{
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync int rc = VINF_SUCCESS;
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync rc = CFGMR3QueryStringAlloc(pCfg, "IP", &pThis->pszIP);
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync if (RT_FAILURE(rc))
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync {
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync PDMDEV_SET_ERROR(pDevIns, rc,
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync N_("Configuration error: Failed to get the \"IP\" value"));
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync return rc;
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync }
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync#ifdef VBOX_WITH_NEW_LWIP
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync rc = CFGMR3QueryStringAlloc(pCfg, "IPv6", &pThis->pszIP6);
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync if (RT_SUCCESS(rc))
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync pThis->fIpv6 = true;
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync else if (rc != VERR_CFGM_VALUE_NOT_FOUND)
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync {
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync PDMDEV_SET_ERROR(pDevIns, rc,
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync N_("Configuration error: Failed to get the \"IPv6\" value"));
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync AssertReturn(rc, rc);
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync }
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync#endif
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync rc = CFGMR3QueryStringAlloc(pCfg, "Netmask", &pThis->pszNetmask);
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync if (RT_FAILURE(rc))
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync {
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync PDMDEV_SET_ERROR(pDevIns, rc,
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync N_("Configuration error: Failed to get the \"Netmask\" value"));
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync return rc;
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync }
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync rc = CFGMR3QueryStringAlloc(pCfg, "Gateway", &pThis->pszGateway);
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync if ( RT_FAILURE(rc)
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync && rc != VERR_CFGM_VALUE_NOT_FOUND)
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync {
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync PDMDEV_SET_ERROR(pDevIns, rc,
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync N_("Configuration error: Failed to get the \"Gateway\" value"));
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync return rc;
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync }
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync return VINF_SUCCESS;
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync}
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Wait until data can be received.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @returns VBox status code. VINF_SUCCESS means there is at least one receive descriptor available.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param pInterface PDM network port interface pointer.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param cMillies Number of milliseconds to wait. 0 means return immediately.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
fbf08fabb4c4b383d6aa2830c2bd5b943a26f10cvboxsyncstatic DECLCALLBACK(int) devINIPNetworkDown_WaitInputAvail(PPDMINETWORKDOWN pInterface, RTMSINTERVAL cMillies)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync LogFlow(("%s: pInterface=%p\n", __FUNCTION__, pInterface));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync LogFlow(("%s: return VINF_SUCCESS\n", __FUNCTION__));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return VINF_SUCCESS;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Receive data and pass it to lwIP for processing.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @returns VBox status code
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param pInterface PDM network port interface pointer.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param pvBuf Pointer to frame data.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param cb Frame size.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
fbf08fabb4c4b383d6aa2830c2bd5b943a26f10cvboxsyncstatic DECLCALLBACK(int) devINIPNetworkDown_Input(PPDMINETWORKDOWN pInterface,
fbf08fabb4c4b383d6aa2830c2bd5b943a26f10cvboxsync const void *pvBuf, size_t cb)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync const uint8_t *pbBuf = (const uint8_t *)pvBuf;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync size_t len = cb;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync const struct eth_hdr *ethhdr;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync struct pbuf *p, *q;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync int rc = VINF_SUCCESS;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync LogFlow(("%s: pInterface=%p pvBuf=%p cb=%lu\n", __FUNCTION__, pInterface,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pvBuf, cb));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync Assert(g_pDevINIPData);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync Assert(g_pDevINIPData->pDrv);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* Silently ignore packets being received while lwIP isn't set up. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (!g_pDevINIPData)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync goto out;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#if ETH_PAD_SIZE
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#endif
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* We allocate a pbuf chain of pbufs from the pool. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync p = lwip_pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (p != NULL)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#if ETH_PAD_SIZE
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync lwip_pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#endif
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync for (q = p; q != NULL; q = q->next)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* Fill the buffers, and clean out unused buffer space. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync memcpy(q->payload, pbBuf, RT_MIN(cb, q->len));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pbBuf += RT_MIN(cb, q->len);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (q->len > cb)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync memset(((uint8_t *)q->payload) + cb, '\0', q->len - cb);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync cb -= RT_MIN(cb, q->len);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync ethhdr = (const struct eth_hdr *)p->payload;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync struct netif *iface = &g_pDevINIPData->IntNetIF;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync err_t lrc;
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync#ifndef VBOX_WITH_NEW_LWIP
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync switch (htons(ethhdr->type))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync case ETHTYPE_IP: /* IP packet */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync lwip_pbuf_header(p, -(ssize_t)sizeof(struct eth_hdr));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync lrc = iface->input(p, iface);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (lrc)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = VERR_NET_IO_ERROR;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync break;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync case ETHTYPE_ARP: /* ARP packet */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync lwip_etharp_arp_input(iface, (struct eth_addr *)iface->hwaddr, p);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync break;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync default:
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync lwip_pbuf_free(p);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync#else
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync /* We've setup flags NETIF_FLAG_ETHARP and NETIF_FLAG_ETHERNET
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync * so this should be thread-safe.
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync */
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync tcpip_input(p,iface);
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync#endif
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncout:
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync LogFlow(("%s: return %Rrc\n", __FUNCTION__, rc));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return rc;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
fbf08fabb4c4b383d6aa2830c2bd5b943a26f10cvboxsync/**
a7d402dcc23137e7b9527be6de80400043a5fbf4vboxsync * @interface_method_impl{PDMINETWORKDOWN,pfnXmitPending}
fbf08fabb4c4b383d6aa2830c2bd5b943a26f10cvboxsync */
a7d402dcc23137e7b9527be6de80400043a5fbf4vboxsyncstatic DECLCALLBACK(void) devINIPNetworkDown_XmitPending(PPDMINETWORKDOWN pInterface)
fbf08fabb4c4b383d6aa2830c2bd5b943a26f10cvboxsync{
fbf08fabb4c4b383d6aa2830c2bd5b943a26f10cvboxsync NOREF(pInterface);
fbf08fabb4c4b383d6aa2830c2bd5b943a26f10cvboxsync}
fbf08fabb4c4b383d6aa2830c2bd5b943a26f10cvboxsync
fbf08fabb4c4b383d6aa2830c2bd5b943a26f10cvboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Signals the end of lwIP TCPIP initialization.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param arg opaque argument, here the pointer to the semaphore.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic DECLCALLBACK(void) devINIPTcpipInitDone(void *arg)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync sys_sem_t *sem = (sys_sem_t *)arg;
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync#ifndef VBOX_WITH_NEW_LWIP
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync lwip_sys_sem_signal(*sem);
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync#else
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync lwip_sys_sem_signal(sem);
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync#endif
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync/**
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync * Gets the current Media Access Control (MAC) address.
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync *
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync * @returns VBox status code.
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync * @param pInterface Pointer to the interface structure containing the called function pointer.
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync * @param pMac Where to store the MAC address.
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync * @thread EMT
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync */
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsyncstatic DECLCALLBACK(int) devINIPGetMac(PPDMINETWORKCONFIG pInterface, PRTMAC pMac)
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync{
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync PDEVINTNETIP pThis = RT_FROM_MEMBER(pInterface, DEVINTNETIP, INetworkConfig);
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync memcpy(pMac, pThis->MAC.au8, sizeof(RTMAC));
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync return VINF_SUCCESS;
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync}
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync/**
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync * Gets the new link state.
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync *
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync * @returns The current link state.
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync * @param pInterface Pointer to the interface structure containing the called function pointer.
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync * @thread EMT
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync */
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsyncstatic DECLCALLBACK(PDMNETWORKLINKSTATE) devINIPGetLinkState(PPDMINETWORKCONFIG pInterface)
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync{
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync PDEVINTNETIP pThis = RT_FROM_MEMBER(pInterface, DEVINTNETIP, INetworkConfig);
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync if (pThis->fLnkUp)
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync return PDMNETWORKLINKSTATE_UP;
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync return PDMNETWORKLINKSTATE_DOWN;
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync}
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync/**
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync * Sets the new link state.
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync *
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync * @returns VBox status code.
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync * @param pInterface Pointer to the interface structure containing the called function pointer.
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync * @param enmState The new link state
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync */
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsyncstatic DECLCALLBACK(int) devINIPSetLinkState(PPDMINETWORKCONFIG pInterface, PDMNETWORKLINKSTATE enmState)
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync{
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync PDEVINTNETIP pThis = RT_FROM_MEMBER(pInterface, DEVINTNETIP, INetworkConfig);
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync bool fNewUp = enmState == PDMNETWORKLINKSTATE_UP;
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync if (fNewUp != pThis->fLnkUp)
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync {
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync if (fNewUp)
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync {
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync LogFlowFunc(("Link is up\n"));
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync pThis->fLnkUp = true;
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync }
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync else
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync {
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync LogFlowFunc(("Link is down\n"));
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync pThis->fLnkUp = false;
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync }
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync if (pThis->pDrv)
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync pThis->pDrv->pfnNotifyLinkChanged(pThis->pDrv, enmState);
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync }
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync return VINF_SUCCESS;
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync}
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync/* -=-=-=-=- PDMIBASE -=-=-=-=- */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * @interface_method_impl{PDMIBASE,pfnQueryInterface}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic DECLCALLBACK(void *) devINIPQueryInterface(PPDMIBASE pInterface,
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync const char *pszIID)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync PDEVINTNETIP pThis = RT_FROM_MEMBER(pInterface, DEVINTNETIP, IBase);
a39ea3668b7019c23a68936259545f9b71bce1aavboxsync PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThis->IBase);
787c7e6ef15f993c455c374f5158e7bb753b1c33vboxsync PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKDOWN, &pThis->INetworkDown);
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKCONFIG, &pThis->INetworkConfig);
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync return NULL;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync/* -=-=-=-=- PDMDEVREG -=-=-=-=- */
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync/**
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync * Destruct a device instance.
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync *
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync * Most VM resources are freed by the VM. This callback is provided so that any non-VM
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync * resources can be freed correctly.
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync *
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync * @returns VBox status.
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync * @param pDevIns The device instance data.
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync */
e74eef731a813e4e06680c587a6759b9974b29c9vboxsyncstatic DECLCALLBACK(int) devINIPDestruct(PPDMDEVINS pDevIns)
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync{
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync PDEVINTNETIP pThis = PDMINS_2_DATA(pDevIns, PDEVINTNETIP);
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync LogFlow(("%s: pDevIns=%p\n", __FUNCTION__, pDevIns));
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync if (g_pDevINIPData != NULL)
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync {
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync netif_set_down(&pThis->IntNetIF);
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync netif_remove(&pThis->IntNetIF);
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync tcpip_terminate();
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync#ifndef VBOX_WITH_NEW_LWIP
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync lwip_sys_sem_wait(pThis->LWIPTcpInitSem);
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync lwip_sys_sem_free(pThis->LWIPTcpInitSem);
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync#else
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync lwip_sys_sem_wait(&pThis->LWIPTcpInitSem, 0);
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync lwip_sys_sem_free(&pThis->LWIPTcpInitSem);
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync#endif
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync }
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync if (pThis->pszIP)
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync MMR3HeapFree(pThis->pszIP);
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync if (pThis->pszNetmask)
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync MMR3HeapFree(pThis->pszNetmask);
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync if (pThis->pszGateway)
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync MMR3HeapFree(pThis->pszGateway);
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync LogFlow(("%s: success\n", __FUNCTION__));
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync return VINF_SUCCESS;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync}
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
cad8876b46f9e366c4a1007a40c27ca1df078950vboxsync * @interface_method_impl{PDMDEVREG,pfnConstruct}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic DECLCALLBACK(int) devINIPConstruct(PPDMDEVINS pDevIns, int iInstance,
c28fa006ba669ad8f26ae31d00a338379c04ea1bvboxsync PCFGMNODE pCfg)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync PDEVINTNETIP pThis = PDMINS_2_DATA(pDevIns, PDEVINTNETIP);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync int rc = VINF_SUCCESS;
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync#ifdef VBOX_WITH_NEW_LWIP
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync err_t errRc = ERR_OK;
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync#endif
c28fa006ba669ad8f26ae31d00a338379c04ea1bvboxsync LogFlow(("%s: pDevIns=%p iInstance=%d pCfg=%p\n", __FUNCTION__,
c28fa006ba669ad8f26ae31d00a338379c04ea1bvboxsync pDevIns, iInstance, pCfg));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync Assert(iInstance == 0);
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Validate the config.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync if (!CFGMR3AreValuesValid(pCfg, "MAC\0IP\0"
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync#ifdef VBOX_WITH_NEW_LWIP
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync "IPv6\0"
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync#endif
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync "Netmask\0Gateway\0"))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync N_("Unknown Internal Networking IP configuration option"));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync goto out;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Init the static parts.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pThis->pszIP = NULL;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pThis->pszNetmask = NULL;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pThis->pszGateway = NULL;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* Pointer to device instance */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pThis->pDevIns = pDevIns;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* IBase */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pThis->IBase.pfnQueryInterface = devINIPQueryInterface;
787c7e6ef15f993c455c374f5158e7bb753b1c33vboxsync /* INetworkDown */
fbf08fabb4c4b383d6aa2830c2bd5b943a26f10cvboxsync pThis->INetworkDown.pfnWaitReceiveAvail = devINIPNetworkDown_WaitInputAvail;
fbf08fabb4c4b383d6aa2830c2bd5b943a26f10cvboxsync pThis->INetworkDown.pfnReceive = devINIPNetworkDown_Input;
a7d402dcc23137e7b9527be6de80400043a5fbf4vboxsync pThis->INetworkDown.pfnXmitPending = devINIPNetworkDown_XmitPending;
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync /* INetworkConfig */
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync pThis->INetworkConfig.pfnGetMac = devINIPGetMac;
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync pThis->INetworkConfig.pfnGetLinkState = devINIPGetLinkState;
72730eaca1e865cb4503d6f8f00bc00bc5e1c038vboxsync pThis->INetworkConfig.pfnSetLinkState = devINIPSetLinkState;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Get the configuration settings.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
c28fa006ba669ad8f26ae31d00a338379c04ea1bvboxsync rc = CFGMR3QueryBytes(pCfg, "MAC", &pThis->MAC, sizeof(pThis->MAC));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (rc == VERR_CFGM_NOT_BYTES)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync char szMAC[64];
c28fa006ba669ad8f26ae31d00a338379c04ea1bvboxsync rc = CFGMR3QueryString(pCfg, "MAC", &szMAC[0], sizeof(szMAC));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (RT_SUCCESS(rc))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync char *macStr = &szMAC[0];
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync char *pMac = (char *)&pThis->MAC;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync for (uint32_t i = 0; i < 6; i++)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if ( !*macStr || !*(macStr + 1)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync || *macStr == ':' || *(macStr + 1) == ':')
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = PDMDEV_SET_ERROR(pDevIns,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync N_("Configuration error: Invalid \"MAC\" value"));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync goto out;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync char c1 = *macStr++ - '0';
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (c1 > 9)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync c1 -= 7;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync char c2 = *macStr++ - '0';
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (c2 > 9)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync c2 -= 7;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *pMac++ = ((c1 & 0x0f) << 4) | (c2 & 0x0f);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (i != 5 && *macStr == ':')
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync macStr++;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (RT_FAILURE(rc))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync PDMDEV_SET_ERROR(pDevIns, rc,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync N_("Configuration error: Failed to get the \"MAC\" value"));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync goto out;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
01644b3fb3841a1b087fb2a5b8c2870d9876541bvboxsync rc = devINIPNetworkConfiguration(pDevIns, pThis, pCfg);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (RT_FAILURE(rc))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync goto out;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Attach driver and query the network connector interface.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = PDMDevHlpDriverAttach(pDevIns, 0, &pThis->IBase, &pThis->pDrvBase,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync "Network Port");
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (RT_FAILURE(rc))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pThis->pDrvBase = NULL;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pThis->pDrv = NULL;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync goto out;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync else
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
787c7e6ef15f993c455c374f5158e7bb753b1c33vboxsync pThis->pDrv = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMINETWORKUP);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (!pThis->pDrv)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
787c7e6ef15f993c455c374f5158e7bb753b1c33vboxsync AssertMsgFailed(("Failed to obtain the PDMINETWORKUP interface!\n"));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = VERR_PDM_MISSING_INTERFACE_BELOW;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync goto out;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync struct ip_addr ipaddr, netmask, gw;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync struct in_addr ip;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (!inet_aton(pThis->pszIP, &ip))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync N_("Configuration error: Invalid \"IP\" value"));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync goto out;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync memcpy(&ipaddr, &ip, sizeof(ipaddr));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (!inet_aton(pThis->pszNetmask, &ip))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync N_("Configuration error: Invalid \"Netmask\" value"));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync goto out;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync memcpy(&netmask, &ip, sizeof(netmask));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (pThis->pszGateway)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (!inet_aton(pThis->pszGateway, &ip))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = PDMDEV_SET_ERROR(pDevIns,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync N_("Configuration error: Invalid \"Gateway\" value"));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync goto out;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync memcpy(&gw, &ip, sizeof(gw));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync else
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync inet_aton(pThis->pszIP, &ip);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync memcpy(&gw, &ip, sizeof(gw));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Initialize lwIP.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync lwip_stats_init();
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync lwip_sys_init();
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#if MEM_LIBC_MALLOC == 0
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync lwip_mem_init();
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#endif
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync lwip_memp_init();
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync lwip_pbuf_init();
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync lwip_netif_init();
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsync rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, devINIPARPTimer, pThis,
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsync TMTIMER_FLAGS_NO_CRIT_SECT, "lwIP ARP", &pThis->ARPTimer);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (RT_FAILURE(rc))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync goto out;
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsync rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, devINIPTCPFastTimer, pThis,
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsync TMTIMER_FLAGS_NO_CRIT_SECT, "lwIP fast TCP", &pThis->TCPFastTimer);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (RT_FAILURE(rc))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync goto out;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync TMTimerSetMillies(pThis->TCPFastTimer, TCP_FAST_INTERVAL);
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsync rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, devINIPTCPSlowTimer, pThis,
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsync TMTIMER_FLAGS_NO_CRIT_SECT, "lwIP slow TCP", &pThis->TCPSlowTimer);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (RT_FAILURE(rc))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync goto out;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync TMTimerSetMillies(pThis->TCPFastTimer, TCP_SLOW_INTERVAL);
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync#ifndef VBOX_WITH_NEW_LWIP
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pThis->LWIPTcpInitSem = lwip_sys_sem_new(0);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync lwip_tcpip_init(devINIPTcpipInitDone, &pThis->LWIPTcpInitSem);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync lwip_sys_sem_wait(pThis->LWIPTcpInitSem);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync#else
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync errRc = lwip_sys_sem_new(&pThis->LWIPTcpInitSem, 0);
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync /* VERR_INTERNAL_ERROR perhaps should be replaced with right error code */
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync AssertReturn(errRc == ERR_OK, VERR_INTERNAL_ERROR);
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync {
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync lwip_tcpip_init(devINIPTcpipInitDone, &pThis->LWIPTcpInitSem);
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync lwip_sys_sem_wait(&pThis->LWIPTcpInitSem, 0);
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync }
1e61c2f4dd6e398ffa2028c55f1e0170b53fa7a3vboxsync#endif
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /*
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Set up global pointer to interface data.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync g_pDevINIPData = pThis;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync struct netif *ret;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pThis->IntNetIF.name[0] = 'I';
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pThis->IntNetIF.name[1] = 'N';
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync ret = netif_add(&pThis->IntNetIF, &ipaddr, &netmask, &gw, NULL,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync devINIPInterface, lwip_tcpip_input);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (!ret)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync {
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = VERR_NET_NO_NETWORK;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync goto out;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync }
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync lwip_netif_set_default(&pThis->IntNetIF);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync lwip_netif_set_up(&pThis->IntNetIF);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* link hack */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync pThis->pLinkHack = g_pDevINILinkHack;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncout:
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync LogFlow(("%s: return %Rrc\n", __FUNCTION__, rc));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return rc;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Query whether lwIP is initialized or not. Since there is only a single
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * instance of this device ever for a VM, it can be a global function.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @returns True if lwIP is initialized.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncbool DevINIPConfigured(void)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return g_pDevINIPData != NULL;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync}
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/**
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Internal network IP stack device registration record.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncconst PDMDEVREG g_DeviceINIP =
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync{
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* u32Version */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync PDM_DEVREG_VERSION,
2c8ee291fb75c4a6f05df160f5d67f4e9ef1cabcvboxsync /* szName */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync "IntNetIP",
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* szRCMod/szR0Mod */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync "",
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync "",
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* pszDescription */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync "Internal Network IP stack device",
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* fFlags */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync PDM_DEVREG_FLAGS_DEFAULT_BITS,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* fClass. As this is used by the storage devices, it must come earlier. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync PDM_DEVREG_CLASS_VMM_DEV,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* cMaxInstances */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync 1,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* cbInstance */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync sizeof(DEVINTNETIP),
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* pfnConstruct */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync devINIPConstruct,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* pfnDestruct */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync devINIPDestruct,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* pfnRelocate */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync NULL,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* pfnIOCtl */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync NULL,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* pfnPowerOn */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync NULL,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* pfnReset */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync NULL,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* pfnSuspend */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync NULL,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* pfnResume */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync NULL,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* pfnAttach */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync NULL,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* pfnDetach */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync NULL,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* pfnQueryInterface */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync NULL,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* pfnInitComplete */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync NULL,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* pfnPowerOff */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync NULL,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* pfnSoftReset */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync NULL,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* u32VersionEnd */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync PDM_DEVREG_VERSION
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync};