VBoxNetDHCP.cpp revision f44ef6f585ec10140a343fa5591d282c32c1a3be
/* $Id$ */
/** @file
* VBoxNetDHCP - DHCP Service for connecting to IntNet.
*/
/*
* Copyright (C) 2009-2011 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.
*/
/** @page pg_net_dhcp VBoxNetDHCP
*
* Write a few words...
*
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#include <iprt/buildconfig.h>
#include <iprt/initterm.h>
#include <VBox/intnetinline.h>
#include "../NetLib/VBoxNetLib.h"
#include "../NetLib/shared_ptr.h"
#include <vector>
#include <list>
#include <string>
#include <map>
#include "../NetLib/VBoxNetBaseService.h"
#ifdef RT_OS_WINDOWS /* WinMain */
# include <Windows.h>
# include <stdlib.h>
# ifdef INET_ADDRSTRLEN
/* On Windows INET_ADDRSTRLEN defined as 22 Ws2ipdef.h, because it include port number */
# endif
# define INET_ADDRSTRLEN 16
#else
#endif
#include "Config.h"
/*******************************************************************************
* Structures and Typedefs *
*******************************************************************************/
/**
* DHCP server instance.
*/
class VBoxNetDhcp: public VBoxNetBaseService
{
public:
VBoxNetDhcp();
virtual ~VBoxNetDhcp();
int init();
int run(void);
void usage(void) { /* XXX: document options */ };
int processUDP(void *, size_t);
protected:
private:
int initNoMain();
int initWithMain();
int fetchAndUpdateDnsInfo();
protected:
/** @name The DHCP server specific configuration data members.
* @{ */
/*
* XXX: what was the plan? SQL3 or plain text file?
* How it will coexists with managment from VBoxManagement, who should manage db
* in that case (VBoxManage, VBoxSVC ???)
*/
/** @} */
/* corresponding dhcp server description in Main */
/*
* We will ignore cmd line parameters IFF there will be some DHCP specific arguments
* otherwise all paramters will come from Main.
*/
/*
* -b -n 10.0.1.2 -m 255.255.255.0 -> to the list processing in
*/
typedef struct
{
char Key;
} CMDLNPRM;
/** @name Debug stuff
* @{ */
/** @} */
};
/*******************************************************************************
* Global Variables *
*******************************************************************************/
/** Pointer to the DHCP server. */
static VBoxNetDhcp *g_pDhcp;
/* DHCP server specific options */
static RTGETOPTDEF g_aOptionDefs[] =
{
};
/**
* Construct a DHCP server with a default configuration.
*/
{
/* m_enmTrunkType = kIntNetTrunkType_WhateverNone; */
m_cbCurMsg = 0;
m_fIgnoreCmdLineParameters = true;
for(unsigned int i = 0; i < RT_ELEMENTS(g_aOptionDefs); ++i)
}
/**
* Destruct a DHCP server.
*/
{
}
/**
* Parse the DHCP specific arguments.
*
* This callback caled for each paramenter so
* ....
* we nee post analisys of the parameters, at least
* for -b, -g, -l, -u, -m
*/
{
/* Ok, we've entered here, thus we can't ignore cmd line parameters anymore */
m_fIgnoreCmdLineParameters = false;
switch (rc)
{
case 'l':
case 'u':
case 'g':
{
char buf[17];
}
break;
case 'b': // ignore
case 'D': // ignore
break;
default:
RTPrintf("Use --help for more information.\n");
return rc;
}
return VINF_SUCCESS;
}
int VBoxNetDhcp::init()
{
netManager->setService(this);
if (isMainNeeded())
rc = initWithMain();
else
rc = initNoMain();
return VINF_SUCCESS;
}
/**
* Runs the DHCP server.
*
* @returns exit code + error message to stderr on failure, won't return on
* success (you must kill this process).
*/
int VBoxNetDhcp::run(void)
{
return 0;
}
{
m_cbCurMsg = cbPv;
{
}
else
debugPrint(1, true, "VBoxNetDHCP: Skipping invalid DHCP packet.\n"); /** @todo handle pure bootp clients too? */
m_cbCurMsg = 0;
return VINF_SUCCESS;
}
/**
* Handles a DHCP message.
*
* @returns true if handled, false if not.
* @param uMsgType The message type.
* @param pDhcpMsg The DHCP message.
* @param cb The size of the DHCP message.
*/
{
{
switch (uMsgType)
{
case RTNET_DHCP_MT_DISCOVER:
case RTNET_DHCP_MT_REQUEST:
case RTNET_DHCP_MT_DECLINE:
case RTNET_DHCP_MT_RELEASE:
case RTNET_DHCP_MT_INFORM:
debugPrint(0, true, "Should we handle this?");
break;
default:
debugPrint(0, true, "Unexpected.");
break;
}
}
return false;
}
/**
* Print debug message depending on the m_cVerbosity level.
*
* @param iMinLevel The minimum m_cVerbosity level for this message.
* @param fMsg Whether to dump parts for the current DHCP message.
* @param pszFmt The message format string.
* @param va Optional arguments.
*/
{
if (iMinLevel <= m_cVerbosity)
{
RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: %s: %N\n", iMinLevel >= 2 ? "debug" : "info", pszFmt, &vaCopy);
if ( fMsg
&& m_cVerbosity >= 2
&& m_pCurMsg)
{
/* XXX: export this to debugPrinfDhcpMsg or variant and other method export
* to base class
*/
RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: debug: %8s chaddr=%.6Rhxs ciaddr=%d.%d.%d.%d yiaddr=%d.%d.%d.%d siaddr=%d.%d.%d.%d xid=%#x\n",
m_pCurMsg->bp_ciaddr.au8[0], m_pCurMsg->bp_ciaddr.au8[1], m_pCurMsg->bp_ciaddr.au8[2], m_pCurMsg->bp_ciaddr.au8[3],
m_pCurMsg->bp_yiaddr.au8[0], m_pCurMsg->bp_yiaddr.au8[1], m_pCurMsg->bp_yiaddr.au8[2], m_pCurMsg->bp_yiaddr.au8[3],
m_pCurMsg->bp_siaddr.au8[0], m_pCurMsg->bp_siaddr.au8[1], m_pCurMsg->bp_siaddr.au8[2], m_pCurMsg->bp_siaddr.au8[3],
}
}
}
/**
* Gets the name of given DHCP message type.
*
* @returns Readonly name.
* @param uMsgType The message number.
*/
{
switch (uMsgType)
{
case 0: return "MT_00";
case RTNET_DHCP_MT_DISCOVER: return "DISCOVER";
case RTNET_DHCP_MT_OFFER: return "OFFER";
case RTNET_DHCP_MT_REQUEST: return "REQUEST";
case RTNET_DHCP_MT_DECLINE: return "DECLINE";
case RTNET_DHCP_MT_ACK: return "ACK";
case RTNET_DHCP_MT_NAC: return "NAC";
case RTNET_DHCP_MT_RELEASE: return "RELEASE";
case RTNET_DHCP_MT_INFORM: return "INFORM";
case 9: return "MT_09";
case 10: return "MT_0a";
case 11: return "MT_0b";
case 12: return "MT_0c";
case 13: return "MT_0d";
case 14: return "MT_0e";
case 15: return "MT_0f";
case 16: return "MT_10";
case 17: return "MT_11";
case 18: return "MT_12";
case 19: return "MT_13";
case UINT8_MAX: return "MT_ff";
default: return "UNKNOWN";
}
}
int VBoxNetDhcp::initNoMain()
{
{
{
case 'l':
break;
case 'u':
break;
case 'b':
break;
}
}
return VINF_SUCCESS;
}
int VBoxNetDhcp::initWithMain()
{
/* ok, here we should initiate instance of dhcp server
* and listener for Dhcp configuration events
*/
BOOL fNeedDhcpServer = false;
return VERR_INTERNAL_ERROR;
if (!fNeedDhcpServer)
return VERR_CANCELLED;
int rc = fetchAndUpdateDnsInfo();
return VINF_SUCCESS;
}
int VBoxNetDhcp::fetchAndUpdateDnsInfo()
{
{
/* XXX: here could be several cases: 1. COM error, 2. not found (empty) 3. ? */
/* XXX: Search strings */
{
}
}
return VINF_SUCCESS;
}
/**
* Entry point.
*/
{
/*
* Instantiate the DHCP server and hand it the options.
*/
if (!pDhcp)
{
return 1;
}
if (rc)
return rc;
/*
* Try connect the server to the network.
*/
if (RT_FAILURE(rc))
{
delete pDhcp;
return 1;
}
/*
* Process requests.
*/
delete pDhcp;
return 0;
}
#ifndef VBOX_WITH_HARDENING
{
if (RT_FAILURE(rc))
return RTMsgInitFailure(rc);
}
# ifdef RT_OS_WINDOWS
)
{
if(uMsg == WM_DESTROY)
{
PostQuitMessage(0);
return 0;
}
}
{
bool bExit = false;
/* Register the Window Class. */
wc.cbClsExtra = 0;
wc.cbWndExtra = sizeof(void *);
if (atomWindowClass != 0)
{
/* Create the window. */
if (hwnd)
{
{
}
bExit = true;
}
}
if(bExit)
{
/* no need any accuracy here, in anyway the DHCP server usually gets terminated with TerminateProcess */
exit(0);
}
return 0;
}
/** (We don't want a console usually.) */
{
NULL, /*__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, */
0, /*__in SIZE_T dwStackSize, */
MsgThreadProc, /*__in LPTHREAD_START_ROUTINE lpStartAddress,*/
NULL, /*__in_opt LPVOID lpParameter,*/
0, /*__in DWORD dwCreationFlags,*/
NULL /*__out_opt LPDWORD lpThreadId*/
);
}
# endif /* RT_OS_WINDOWS */
#endif /* !VBOX_WITH_HARDENING */