VirtualBox

Ignore:
Timestamp:
Nov 20, 2013 7:13:46 AM (11 years ago)
Author:
vboxsync
Message:

DHCP: first-level DHCP request packet processing moved to NetworkManager class.
warning [-Wdelete-incomplete].

File:
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/NetworkServices/DHCP/NetworkManagerDhcp.cpp

    r49561 r49563  
    11/* $Id$ */
    22/** @file
    3  * VBoxNetDHCP - DHCP Service for connecting to IntNet.
     3 * NetworkManagerDhcp - Network Manager part handling Dhcp.
    44 */
    55
    66/*
    7  * Copyright (C) 2009-2011 Oracle Corporation
     7 * Copyright (C) 2013 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1616 */
    1717
    18 /** @page pg_net_dhcp       VBoxNetDHCP
    19  *
    20  * Write a few words...
    21  *
    22  */
    23 
    2418/*******************************************************************************
    2519*   Header Files                                                               *
    2620*******************************************************************************/
    27 #include <VBox/com/com.h>
    28 #include <VBox/com/listeners.h>
    29 #include <VBox/com/string.h>
    30 #include <VBox/com/Guid.h>
    31 #include <VBox/com/array.h>
    32 #include <VBox/com/ErrorInfo.h>
    33 #include <VBox/com/errorprint.h>
    34 #include <VBox/com/EventQueue.h>
    35 #include <VBox/com/VirtualBox.h>
    36 
    37 #include <iprt/alloca.h>
    38 #include <iprt/buildconfig.h>
    39 #include <iprt/err.h>
    40 #include <iprt/net.h>                   /* must come before getopt */
    41 #include <iprt/getopt.h>
    42 #include <iprt/initterm.h>
    43 #include <iprt/message.h>
     21#include <iprt/asm.h>
     22#include <iprt/cdefs.h>
     23#include <iprt/net.h>
    4424#include <iprt/param.h>
    4525#include <iprt/path.h>
     
    4828#include <iprt/string.h>
    4929
    50 #include <VBox/sup.h>
    51 #include <VBox/intnet.h>
    52 #include <VBox/intnetinline.h>
    53 #include <VBox/vmm/vmm.h>
    54 #include <VBox/version.h>
    55 
    56 
    57 #include "../NetLib/VBoxNetLib.h"
    5830#include "../NetLib/shared_ptr.h"
    5931
     
    6335#include <map>
    6436
    65 #include "../NetLib/VBoxNetBaseService.h"
    66 
    67 #ifdef RT_OS_WINDOWS /* WinMain */
    68 # include <Windows.h>
    69 # include <stdlib.h>
    70 # ifdef INET_ADDRSTRLEN
    71 /* On Windows INET_ADDRSTRLEN defined as 22 Ws2ipdef.h, because it include port number */
    72 #  undef INET_ADDRSTRLEN
    73 # endif
    74 # define INET_ADDRSTRLEN 16
    75 #else
    76 # include <netinet/in.h>
    77 #endif
    78 
    79 
     37#include <VBox/sup.h>
     38#include <VBox/intnet.h>
    8039#include "Config.h"
    81 /*******************************************************************************
    82 *   Structures and Typedefs                                                    *
    83 *******************************************************************************/
    84 /**
    85  * DHCP server instance.
    86  */
    87 class VBoxNetDhcp: public VBoxNetBaseService
    88 {
    89 public:
    90     VBoxNetDhcp();
    91     virtual ~VBoxNetDhcp();
    92 
    93     int                 init();
    94     int                 run(void);
    95     void                usage(void) { /* XXX: document options */ };
    96     int                 parseOpt(int rc, const RTGETOPTUNION& getOptVal);
    97 
    98 protected:
    99     bool                handleDhcpMsg(uint8_t uMsgType, PCRTNETBOOTP pDhcpMsg, size_t cb);
    100     bool                handleDhcpReqDiscover(PCRTNETBOOTP pDhcpMsg, size_t cb);
    101     bool                handleDhcpReqRequest(PCRTNETBOOTP pDhcpMsg, size_t cb);
    102     bool                handleDhcpReqDecline(PCRTNETBOOTP pDhcpMsg, size_t cb);
    103     bool                handleDhcpReqRelease(PCRTNETBOOTP pDhcpMsg, size_t cb);
    104 
    105     void                debugPrintV(int32_t iMinLevel, bool fMsg,  const char *pszFmt, va_list va) const;
    106     static const char  *debugDhcpName(uint8_t uMsgType);
    107 
    108 private:
    109     int initNoMain();
    110     int initWithMain();
    111 
    112 protected:
    113     /** @name The DHCP server specific configuration data members.
    114      * @{ */
    115     /*
    116      * XXX: what was the plan? SQL3 or plain text file?
    117      * How it will coexists with managment from VBoxManagement, who should manage db
    118      * in that case (VBoxManage, VBoxSVC ???)
    119      */
    120     std::string         m_LeaseDBName;
    121 
    122     /** @} */
    123 
    124     /* corresponding dhcp server description in Main */
    125     ComPtr<IDHCPServer> m_DhcpServer;
    126 
    127     ComPtr<INATNetwork> m_NATNetwork;
    128 
    129     /*
    130      * We will ignore cmd line parameters IFF there will be some DHCP specific arguments
    131      * otherwise all paramters will come from Main.
    132      */
    133     bool m_fIgnoreCmdLineParameters;
    134 
    135     /*
    136      * -b -n 10.0.1.2 -m 255.255.255.0 -> to the list processing in
    137      */
    138     typedef struct
    139     {
    140         char Key;
    141         std::string strValue;
    142     } CMDLNPRM;
    143     std::list<CMDLNPRM> CmdParameterll;
    144     typedef std::list<CMDLNPRM>::iterator CmdParameterIterator;
    145 
    146     /** @name Debug stuff
    147      * @{  */
    148     int32_t             m_cVerbosity;
    149     uint8_t             m_uCurMsgType;
    150     size_t              m_cbCurMsg;
    151     PCRTNETBOOTP        m_pCurMsg;
    152     VBOXNETUDPHDRS      m_CurHdrs;
    153     /** @} */
    154 };
    155 
    156 /*******************************************************************************
    157 *   Global Variables                                                           *
    158 *******************************************************************************/
    159 /** Pointer to the DHCP server. */
    160 static VBoxNetDhcp *g_pDhcp;
    161 
    162 /* DHCP server specific options */
    163 static RTGETOPTDEF g_aOptionDefs[] =
    164 {
    165   { "--lease-db",       'D',   RTGETOPT_REQ_STRING },
    166   { "--begin-config",   'b',   RTGETOPT_REQ_NOTHING },
    167   { "--gateway",        'g',   RTGETOPT_REQ_IPV4ADDR },
    168   { "--lower-ip",       'l',   RTGETOPT_REQ_IPV4ADDR },
    169   { "--upper-ip",       'u',   RTGETOPT_REQ_IPV4ADDR },
    170 };
    171 
    172 /**
    173  * Construct a DHCP server with a default configuration.
    174  */
    175 VBoxNetDhcp::VBoxNetDhcp()
    176 {
    177     m_Name                  = "VBoxNetDhcp";
    178     m_Network               = "VBoxNetDhcp";
    179     m_TrunkName             = "";
    180     m_enmTrunkType          = kIntNetTrunkType_WhateverNone;
    181     m_MacAddress.au8[0]     = 0x08;
    182     m_MacAddress.au8[1]     = 0x00;
    183     m_MacAddress.au8[2]     = 0x27;
    184     m_MacAddress.au8[3]     = 0x40;
    185     m_MacAddress.au8[4]     = 0x41;
    186     m_MacAddress.au8[5]     = 0x42;
    187     m_Ipv4Address.u         = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10,  0,  2,  5)));
    188 
    189     m_pSession              = NIL_RTR0PTR;
    190     m_cbSendBuf             =  8192;
    191     m_cbRecvBuf             = 51200; /** @todo tune to 64 KB with help from SrvIntR0 */
    192     m_hIf                   = INTNET_HANDLE_INVALID;
    193     m_pIfBuf                = NULL;
    194 
    195     m_cVerbosity            = 0;
    196     m_uCurMsgType           = UINT8_MAX;
    197     m_cbCurMsg              = 0;
    198     m_pCurMsg               = NULL;
    199     memset(&m_CurHdrs, '\0', sizeof(m_CurHdrs));
    200 
    201     m_fIgnoreCmdLineParameters = true;
    202 
    203     for(unsigned int i = 0; i < RT_ELEMENTS(g_aOptionDefs); ++i)
    204         m_vecOptionDefs.push_back(&g_aOptionDefs[i]);
    205 
    206 #if 0 /* enable to hack the code without a mile long argument list. */
    207     VBoxNetDhcpCfg *pDefCfg = new VBoxNetDhcpCfg();
    208     pDefCfg->m_LowerAddr.u    = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10,  0,  2,100)));
    209     pDefCfg->m_UpperAddr.u    = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10,  0,  2,250)));
    210     pDefCfg->m_SubnetMask.u   = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8(255,255,255,  0)));
    211     RTNETADDRIPV4 Addr;
    212     Addr.u                    = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10,  0,  2,  1)));
    213     pDefCfg->m_Routers.push_back(Addr);
    214     Addr.u                    = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10,  0,  2,  2)));
    215     pDefCfg->m_DNSes.push_back(Addr);
    216     pDefCfg->m_DomainName     = "vboxnetdhcp.org";
    217 # if 0
    218     pDefCfg->m_cSecLease      = 60*60; /* 1 hour */
    219 # else
    220     pDefCfg->m_cSecLease      = 30; /* sec */
    221 # endif
    222     pDefCfg->m_TftpServer     = "10.0.2.3"; //??
    223     this->addConfig(pDefCfg);
    224 #endif
    225 }
    226 
    227 
    228 /**
    229  * Destruct a DHCP server.
    230  */
    231 VBoxNetDhcp::~VBoxNetDhcp()
    232 {
    233 }
    234 
    235 
    236 
    237 
    238 /**
    239  * Parse the DHCP specific arguments.
    240  *
    241  * This callback caled for each paramenter so
    242  * ....
    243  * we nee post analisys of the parameters, at least
    244  *    for -b, -g, -l, -u, -m
    245  */
    246 int VBoxNetDhcp::parseOpt(int rc, const RTGETOPTUNION& Val)
    247 {
    248     CMDLNPRM prm;
    249 
    250     /* Ok, we've entered here, thus we can't ignore cmd line parameters anymore */
    251     m_fIgnoreCmdLineParameters = false;
    252 
    253     prm.Key = rc;
    254 
    255     switch (rc)
    256     {
    257         case 'l':
    258         case 'u':
    259         case 'g':
    260         {
    261             char buf[17];
    262             RTStrPrintf(buf, 17, "%RTnaipv4", Val.IPv4Addr.u);
    263             prm.strValue = buf;
    264             CmdParameterll.push_back(prm);
    265         }
    266         break;
    267 
    268         case 'b': // ignore
    269         case 'D': // ignore
    270             break;
    271 
    272         default:
    273             rc = RTGetOptPrintError(rc, &Val);
    274             RTPrintf("Use --help for more information.\n");
    275             return rc;
    276     }
    277 
    278     return VINF_SUCCESS;
    279 }
    280 
    281 int VBoxNetDhcp::init()
    282 {
    283     int rc = this->VBoxNetBaseService::init();
    284     AssertRCReturn(rc, rc);
    285 
    286     NetworkManager *netManager = NetworkManager::getNetworkManager();
    287 
    288     netManager->setOurAddress(m_Ipv4Address);
    289     netManager->setOurNetmask(m_Ipv4Netmask);
    290     netManager->setOurMac(m_MacAddress);
    291    
    292     if (isMainNeeded())
    293         rc = initWithMain();
    294     else
    295         rc = initNoMain();
    296 
    297     AssertRCReturn(rc, rc);
    298 
    299     return VINF_SUCCESS;
    300 }
    301 
    302 /**
    303  * Runs the DHCP server.
    304  *
    305  * @returns exit code + error message to stderr on failure, won't return on
    306  *          success (you must kill this process).
    307  */
    308 int VBoxNetDhcp::run(void)
    309 {
    310 
    311     /* XXX: shortcut should be hidden from network manager */
    312     NetworkManager *netManager = NetworkManager::getNetworkManager();
    313     netManager->setSession(m_pSession);
    314     netManager->setInterface(m_hIf);
    315     netManager->setRingBuffer(m_pIfBuf);
    316 
    317     /*
    318      * The loop.
    319      */
    320     PINTNETRINGBUF  pRingBuf = &m_pIfBuf->Recv;
    321     for (;;)
    322     {
    323         /*
    324          * Wait for a packet to become available.
    325          */
    326         INTNETIFWAITREQ WaitReq;
    327         WaitReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
    328         WaitReq.Hdr.cbReq = sizeof(WaitReq);
    329         WaitReq.pSession = m_pSession;
    330         WaitReq.hIf = m_hIf;
    331         WaitReq.cMillies = 2000; /* 2 secs - the sleep is for some reason uninterruptible... */  /** @todo fix interruptability in SrvIntNet! */
    332         int rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_WAIT, 0, &WaitReq.Hdr);
    333         if (RT_FAILURE(rc))
    334         {
    335             if (rc == VERR_TIMEOUT || rc == VERR_INTERRUPTED)
    336                 continue;
    337             RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: VMMR0_DO_INTNET_IF_WAIT returned %Rrc\n", rc);
    338             return 1;
    339         }
    340 
    341         /*
    342          * Process the receive buffer.
    343          */
    344         while (IntNetRingHasMoreToRead(pRingBuf))
    345         {
    346             size_t  cb;
    347             void   *pv = VBoxNetUDPMatch(m_pIfBuf, RTNETIPV4_PORT_BOOTPS, &m_MacAddress,
    348                                          VBOXNETUDP_MATCH_UNICAST | VBOXNETUDP_MATCH_BROADCAST | VBOXNETUDP_MATCH_CHECKSUM
    349                                          | (m_cVerbosity > 2 ? VBOXNETUDP_MATCH_PRINT_STDERR : 0),
    350                                          &m_CurHdrs, &cb);
    351             if (pv && cb)
    352             {
    353                 PCRTNETBOOTP pDhcpMsg = (PCRTNETBOOTP)pv;
    354                 m_pCurMsg  = pDhcpMsg;
    355                 m_cbCurMsg = cb;
    356 
    357                 uint8_t uMsgType;
    358                 if (RTNetIPv4IsDHCPValid(NULL /* why is this here? */, pDhcpMsg, cb, &uMsgType))
    359                 {
    360                     m_uCurMsgType = uMsgType;
    361                     handleDhcpMsg(uMsgType, pDhcpMsg, cb);
    362                     m_uCurMsgType = UINT8_MAX;
    363                 }
    364                 else
    365                     debugPrint(1, true, "VBoxNetDHCP: Skipping invalid DHCP packet.\n"); /** @todo handle pure bootp clients too? */
    366 
    367                 m_pCurMsg = NULL;
    368                 m_cbCurMsg = 0;
    369             }
    370             else if (VBoxNetArpHandleIt(m_pSession, m_hIf, m_pIfBuf, &m_MacAddress, m_Ipv4Address))
    371             {
    372                 /* nothing */
    373             }
    374 
    375             /* Advance to the next frame. */
    376             IntNetRingSkipFrame(pRingBuf);
    377         }
    378     }
    379 
    380     return 0;
    381 }
    382 
    383 
    384 /**
    385  * Handles a DHCP message.
    386  *
    387  * @returns true if handled, false if not.
    388  * @param   uMsgType        The message type.
    389  * @param   pDhcpMsg        The DHCP message.
    390  * @param   cb              The size of the DHCP message.
    391  */
    392 bool VBoxNetDhcp::handleDhcpMsg(uint8_t uMsgType, PCRTNETBOOTP pDhcpMsg, size_t cb)
    393 {
    394     if (pDhcpMsg->bp_op == RTNETBOOTP_OP_REQUEST)
    395     {
    396         switch (uMsgType)
    397         {
    398             case RTNET_DHCP_MT_DISCOVER:
    399                 return handleDhcpReqDiscover(pDhcpMsg, cb);
    400 
    401             case RTNET_DHCP_MT_REQUEST:
    402                 return handleDhcpReqRequest(pDhcpMsg, cb);
    403 
    404             case RTNET_DHCP_MT_DECLINE:
    405                 return handleDhcpReqDecline(pDhcpMsg, cb);
    406 
    407             case RTNET_DHCP_MT_RELEASE:
    408                 return handleDhcpReqRelease(pDhcpMsg, cb);
    409 
    410             case RTNET_DHCP_MT_INFORM:
    411                 debugPrint(0, true, "Should we handle this?");
    412                 break;
    413 
    414             default:
    415                 debugPrint(0, true, "Unexpected.");
    416                 break;
    417         }
    418     }
    419     return false;
    420 }
    421 
     40#include "ClientDataInt.h"
    42241
    42342/**
     
    42948 * @param   cb          The message size.
    43049 */
    431 bool VBoxNetDhcp::handleDhcpReqDiscover(PCRTNETBOOTP pDhcpMsg, size_t cb)
     50bool NetworkManager::handleDhcpReqDiscover(PCRTNETBOOTP pDhcpMsg, size_t cb)
    43251{
    43352    RawOption opt;
     
    44463
    44564    /* 3. Send of offer */
    446     NetworkManager *networkManager = NetworkManager::getNetworkManager();
    44765
    44866    lease.bindingPhase(true);
    44967    lease.phaseStart(RTTimeMilliTS());
    45068    lease.setExpiration(300); /* 3 min. */
    451     networkManager->offer4Client(client, pDhcpMsg->bp_xid, opt.au8RawOpt, opt.cbRawOpt);
     69    offer4Client(client, pDhcpMsg->bp_xid, opt.au8RawOpt, opt.cbRawOpt);
    45270
    45371    return VINF_SUCCESS;
     
    46381 * @param   cb          The message size.
    46482 */
    465 bool VBoxNetDhcp::handleDhcpReqRequest(PCRTNETBOOTP pDhcpMsg, size_t cb)
     83bool NetworkManager::handleDhcpReqRequest(PCRTNETBOOTP pDhcpMsg, size_t cb)
    46684{
    46785    ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager();
    468     NetworkManager *networkManager = NetworkManager::getNetworkManager();
    46986
    47087    /* 1. find client */
     
    48097            /* send client to INIT state */
    48198            Client c(client);
    482             networkManager->nak(client, pDhcpMsg->bp_xid);
     99            nak(client, pDhcpMsg->bp_xid);
    483100            confManager->expireLease4Client(c);
    484101            return true;
     
    496113            AssertRCReturn(rc, false);
    497114
    498             networkManager->ack(client, pDhcpMsg->bp_xid, opt.au8RawOpt, opt.cbRawOpt);
     115            ack(client, pDhcpMsg->bp_xid, opt.au8RawOpt, opt.cbRawOpt);
    499116        }
    500117    }
    501118    else
    502119    {
    503         networkManager->nak(client, pDhcpMsg->bp_xid);
     120        nak(client, pDhcpMsg->bp_xid);
    504121    }
    505122    return true;
     
    515132 * @param   cb          The message size.
    516133 */
    517 bool VBoxNetDhcp::handleDhcpReqDecline(PCRTNETBOOTP, size_t)
     134bool NetworkManager::handleDhcpReqDecline(PCRTNETBOOTP, size_t)
    518135{
    519136    /** @todo Probably need to match the server IP here to work correctly with
     
    527144
    528145    /** @todo this is not required in the initial implementation, do it later. */
    529     debugPrint(1, true, "DECLINE is not implemented");
    530146    return true;
    531147}
     
    540156 * @param   cb          The message size.
    541157 */
    542 bool VBoxNetDhcp::handleDhcpReqRelease(PCRTNETBOOTP, size_t)
     158bool NetworkManager::handleDhcpReqRelease(PCRTNETBOOTP, size_t)
    543159{
    544160    /** @todo Probably need to match the server IP here to work correctly with
     
    564180
    565181    /** @todo this is not required in the initial implementation, do it later. */
    566     debugPrint(1, true, "RELEASE is not implemented");
    567182    return true;
    568183}
    569184
    570 
    571 /**
    572  * Print debug message depending on the m_cVerbosity level.
    573  *
    574  * @param   iMinLevel       The minimum m_cVerbosity level for this message.
    575  * @param   fMsg            Whether to dump parts for the current DHCP message.
    576  * @param   pszFmt          The message format string.
    577  * @param   va              Optional arguments.
    578  */
    579 void VBoxNetDhcp::debugPrintV(int iMinLevel, bool fMsg, const char *pszFmt, va_list va) const
    580 {
    581     if (iMinLevel <= m_cVerbosity)
    582     {
    583         va_list vaCopy;                 /* This dude is *very* special, thus the copy. */
    584         va_copy(vaCopy, va);
    585         RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: %s: %N\n", iMinLevel >= 2 ? "debug" : "info", pszFmt, &vaCopy);
    586         va_end(vaCopy);
    587 
    588         if (    fMsg
    589             &&  m_cVerbosity >= 2
    590             &&  m_pCurMsg)
    591         {
    592             /* XXX: export this to debugPrinfDhcpMsg or variant and other method export
    593              *  to base class
    594              */
    595             const char *pszMsg = m_uCurMsgType != UINT8_MAX ? debugDhcpName(m_uCurMsgType) : "";
    596             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",
    597                          pszMsg,
    598                          &m_pCurMsg->bp_chaddr,
    599                          m_pCurMsg->bp_ciaddr.au8[0], m_pCurMsg->bp_ciaddr.au8[1], m_pCurMsg->bp_ciaddr.au8[2], m_pCurMsg->bp_ciaddr.au8[3],
    600                          m_pCurMsg->bp_yiaddr.au8[0], m_pCurMsg->bp_yiaddr.au8[1], m_pCurMsg->bp_yiaddr.au8[2], m_pCurMsg->bp_yiaddr.au8[3],
    601                          m_pCurMsg->bp_siaddr.au8[0], m_pCurMsg->bp_siaddr.au8[1], m_pCurMsg->bp_siaddr.au8[2], m_pCurMsg->bp_siaddr.au8[3],
    602                          m_pCurMsg->bp_xid);
    603         }
    604     }
    605 }
    606 
    607 
    608 /**
    609  * Gets the name of given DHCP message type.
    610  *
    611  * @returns Readonly name.
    612  * @param   uMsgType        The message number.
    613  */
    614 /* static */ const char *VBoxNetDhcp::debugDhcpName(uint8_t uMsgType)
    615 {
    616     switch (uMsgType)
    617     {
    618         case 0:                         return "MT_00";
    619         case RTNET_DHCP_MT_DISCOVER:    return "DISCOVER";
    620         case RTNET_DHCP_MT_OFFER:       return "OFFER";
    621         case RTNET_DHCP_MT_REQUEST:     return "REQUEST";
    622         case RTNET_DHCP_MT_DECLINE:     return "DECLINE";
    623         case RTNET_DHCP_MT_ACK:         return "ACK";
    624         case RTNET_DHCP_MT_NAC:         return "NAC";
    625         case RTNET_DHCP_MT_RELEASE:     return "RELEASE";
    626         case RTNET_DHCP_MT_INFORM:      return "INFORM";
    627         case 9:                         return "MT_09";
    628         case 10:                        return "MT_0a";
    629         case 11:                        return "MT_0b";
    630         case 12:                        return "MT_0c";
    631         case 13:                        return "MT_0d";
    632         case 14:                        return "MT_0e";
    633         case 15:                        return "MT_0f";
    634         case 16:                        return "MT_10";
    635         case 17:                        return "MT_11";
    636         case 18:                        return "MT_12";
    637         case 19:                        return "MT_13";
    638         case UINT8_MAX:                 return "MT_ff";
    639         default:                        return "UNKNOWN";
    640     }
    641 }
    642 
    643 
    644 int VBoxNetDhcp::initNoMain()
    645 {
    646     CmdParameterIterator it;
    647 
    648     RTNETADDRIPV4 networkId;
    649     networkId.u = m_Ipv4Address.u & m_Ipv4Netmask.u;
    650     RTNETADDRIPV4 netmask = m_Ipv4Netmask;
    651 
    652     RTNETADDRIPV4 UpperAddress;
    653     RTNETADDRIPV4 LowerAddress = networkId;
    654     UpperAddress.u = RT_H2N_U32(RT_N2H_U32(LowerAddress.u) | RT_N2H_U32(netmask.u));
    655 
    656     for (it = CmdParameterll.begin(); it != CmdParameterll.end(); ++it)
    657     {
    658         switch(it->Key)
    659         {
    660             case 'l':
    661                 RTNetStrToIPv4Addr(it->strValue.c_str(), &LowerAddress);
    662                 break;
    663 
    664             case 'u':
    665                 RTNetStrToIPv4Addr(it->strValue.c_str(), &UpperAddress);
    666                 break;
    667             case 'b':
    668                 break;
    669                    
    670         }
    671     }
    672        
    673     ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager();
    674     AssertPtrReturn(confManager, VERR_INTERNAL_ERROR);
    675     confManager->addNetwork(unconst(g_RootConfig),
    676                             networkId,
    677                             m_Ipv4Netmask,
    678                             LowerAddress,
    679                             UpperAddress);
    680 
    681     return VINF_SUCCESS;
    682 }
    683 
    684 
    685 int VBoxNetDhcp::initWithMain()
    686 {
    687     /* ok, here we should initiate instance of dhcp server
    688      * and listener for Dhcp configuration events
    689      */
    690     AssertRCReturn(virtualbox.isNull(), VERR_INTERNAL_ERROR);
    691 
    692     HRESULT hrc = virtualbox->FindDHCPServerByNetworkName(com::Bstr(m_Network.c_str()).raw(),
    693                                                   m_DhcpServer.asOutParam());
    694     AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
    695 
    696     hrc = virtualbox->FindNATNetworkByName(com::Bstr(m_Network.c_str()).raw(),
    697                                            m_NATNetwork.asOutParam());
    698 
    699     BOOL fNeedDhcpServer = false;
    700     if (FAILED(m_NATNetwork->COMGETTER(NeedDhcpServer)(&fNeedDhcpServer)))
    701         return VERR_INTERNAL_ERROR;
    702 
    703     if (!fNeedDhcpServer)
    704         return VERR_CANCELLED;
    705 
    706     RTNETADDRIPV4 gateway;
    707     com::Bstr strGateway;
    708 
    709     hrc = m_NATNetwork->COMGETTER(Gateway)(strGateway.asOutParam());
    710     AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
    711     RTNetStrToIPv4Addr(com::Utf8Str(strGateway).c_str(), &gateway);
    712 
    713     ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager();
    714     AssertPtrReturn(confManager, VERR_INTERNAL_ERROR);
    715     confManager->addToAddressList(RTNET_DHCP_OPT_ROUTERS, gateway);
    716 
    717     unsigned int i;
    718     unsigned int count_strs;
    719     com::SafeArray<BSTR> strs;
    720     std::map<RTNETADDRIPV4, uint32_t> MapIp4Addr2Off;
    721 
    722     hrc = m_NATNetwork->COMGETTER(LocalMappings)(ComSafeArrayAsOutParam(strs));
    723     if (   SUCCEEDED(hrc)
    724            && (count_strs = strs.size()))
    725     {
    726         for (i = 0; i < count_strs; ++i)
    727         {
    728             char szAddr[17];
    729             RTNETADDRIPV4 ip4addr;
    730             char *pszTerm;
    731             uint32_t u32Off;
    732             com::Utf8Str strLo2Off(strs[i]);
    733             const char *pszLo2Off = strLo2Off.c_str();
    734 
    735             RT_ZERO(szAddr);
    736 
    737             pszTerm = RTStrStr(pszLo2Off, "=");
    738 
    739             if (   pszTerm
    740                    && (pszTerm - pszLo2Off) <= INET_ADDRSTRLEN)
    741             {
    742                 memcpy(szAddr, pszLo2Off, (pszTerm - pszLo2Off));
    743                 int rc = RTNetStrToIPv4Addr(szAddr, &ip4addr);
    744                 if (RT_SUCCESS(rc))
    745                 {
    746                     u32Off = RTStrToUInt32(pszTerm + 1);
    747                     if (u32Off != 0)
    748                         MapIp4Addr2Off.insert(
    749                           std::map<RTNETADDRIPV4,uint32_t>::value_type(ip4addr, u32Off));
    750                 }
    751             }
    752         }
    753     }
    754 
    755     strs.setNull();
    756     ComPtr<IHost> host;
    757     if (SUCCEEDED(virtualbox->COMGETTER(Host)(host.asOutParam())))
    758     {
    759         if (SUCCEEDED(host->COMGETTER(NameServers)(ComSafeArrayAsOutParam(strs))))
    760         {
    761             RTNETADDRIPV4 addr;
    762 
    763             confManager->flushAddressList(RTNET_DHCP_OPT_DNS);
    764             int rc;
    765             for (i = 0; i < strs.size(); ++i)
    766             {
    767                 rc = RTNetStrToIPv4Addr(com::Utf8Str(strs[i]).c_str(), &addr);
    768                 if (RT_SUCCESS(rc))
    769                 {
    770                     if (addr.au8[0] == 127)
    771                     {
    772                         if (MapIp4Addr2Off[addr] != 0)
    773                         {
    774                             addr.u = RT_H2N_U32(RT_N2H_U32(m_Ipv4Address.u & m_Ipv4Netmask.u)
    775                                                 + MapIp4Addr2Off[addr]);
    776                         }
    777                         else
    778                             continue;
    779                     }
    780 
    781                     confManager->addToAddressList(RTNET_DHCP_OPT_DNS, addr);
    782                 }
    783             }
    784         }
    785 
    786         strs.setNull();
    787 #if 0
    788         if (SUCCEEDED(host->COMGETTER(SearchStrings)(ComSafeArrayAsOutParam(strs))))
    789         {
    790             /* XXX: todo. */;
    791         }
    792         strs.setNull();
    793 #endif
    794         com::Bstr domain;
    795         if (SUCCEEDED(host->COMGETTER(DomainName)(domain.asOutParam())))
    796             confManager->setString(RTNET_DHCP_OPT_DOMAIN_NAME, std::string(com::Utf8Str(domain).c_str()));
    797     }
    798 
    799     com::Bstr strUpperIp, strLowerIp;
    800    
    801     RTNETADDRIPV4 LowerAddress;
    802     RTNETADDRIPV4 UpperAddress;
    803 
    804     hrc = m_DhcpServer->COMGETTER(UpperIP)(strUpperIp.asOutParam());
    805     AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
    806     RTNetStrToIPv4Addr(com::Utf8Str(strUpperIp).c_str(), &UpperAddress);
    807 
    808 
    809     hrc = m_DhcpServer->COMGETTER(LowerIP)(strLowerIp.asOutParam());
    810     AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
    811     RTNetStrToIPv4Addr(com::Utf8Str(strLowerIp).c_str(), &LowerAddress);
    812 
    813     RTNETADDRIPV4 networkId;
    814     networkId.u = m_Ipv4Address.u & m_Ipv4Netmask.u;
    815     std::string name = std::string("default");
    816 
    817     confManager->addNetwork(unconst(g_RootConfig),
    818                             networkId,
    819                             m_Ipv4Netmask,
    820                             LowerAddress,
    821                             UpperAddress);
    822 
    823     com::Bstr bstr;
    824     hrc = virtualbox->COMGETTER(HomeFolder)(bstr.asOutParam());
    825     std::string strXmlLeaseFile(com::Utf8StrFmt("%ls%c%s.leases",
    826                                                 bstr.raw(), RTPATH_DELIMITER, m_Network.c_str()).c_str());
    827     confManager->loadFromFile(strXmlLeaseFile);
    828 
    829     return VINF_SUCCESS;
    830 }
    831 
    832 /**
    833  *  Entry point.
    834  */
    835 extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv)
    836 {
    837     /*
    838      * Instantiate the DHCP server and hand it the options.
    839      */
    840 
    841     VBoxNetDhcp *pDhcp = new VBoxNetDhcp();
    842     if (!pDhcp)
    843     {
    844         RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: new VBoxNetDhcp failed!\n");
    845         return 1;
    846     }
    847     int rc = pDhcp->parseArgs(argc - 1, argv + 1);
    848     if (rc)
    849         return rc;
    850 
    851     pDhcp->init();
    852 
    853     /*
    854      * Try connect the server to the network.
    855      */
    856     rc = pDhcp->tryGoOnline();
    857     if (RT_FAILURE(rc))
    858     {
    859         delete pDhcp;
    860         return 1;
    861     }
    862 
    863     /*
    864      * Process requests.
    865      */
    866     g_pDhcp = pDhcp;
    867     rc = pDhcp->run();
    868     g_pDhcp = NULL;
    869     delete pDhcp;
    870 
    871     return 0;
    872 }
    873 
    874 
    875 #ifndef VBOX_WITH_HARDENING
    876 
    877 int main(int argc, char **argv)
    878 {
    879     int rc = RTR3InitExe(argc, &argv, RTR3INIT_FLAGS_SUPLIB);
    880     if (RT_FAILURE(rc))
    881         return RTMsgInitFailure(rc);
    882 
    883     return TrustedMain(argc, argv);
    884 }
    885 
    886 # ifdef RT_OS_WINDOWS
    887 
    888 static LRESULT CALLBACK WindowProc(HWND hwnd,
    889     UINT uMsg,
    890     WPARAM wParam,
    891     LPARAM lParam
    892 )
    893 {
    894     if(uMsg == WM_DESTROY)
    895     {
    896         PostQuitMessage(0);
    897         return 0;
    898     }
    899     return DefWindowProc (hwnd, uMsg, wParam, lParam);
    900 }
    901 
    902 static LPCWSTR g_WndClassName = L"VBoxNetDHCPClass";
    903 
    904 static DWORD WINAPI MsgThreadProc(__in  LPVOID lpParameter)
    905 {
    906      HWND                 hwnd = 0;
    907      HINSTANCE hInstance = (HINSTANCE)GetModuleHandle (NULL);
    908      bool bExit = false;
    909 
    910      /* Register the Window Class. */
    911      WNDCLASS wc;
    912      wc.style         = 0;
    913      wc.lpfnWndProc   = WindowProc;
    914      wc.cbClsExtra    = 0;
    915      wc.cbWndExtra    = sizeof(void *);
    916      wc.hInstance     = hInstance;
    917      wc.hIcon         = NULL;
    918      wc.hCursor       = NULL;
    919      wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
    920      wc.lpszMenuName  = NULL;
    921      wc.lpszClassName = g_WndClassName;
    922 
    923      ATOM atomWindowClass = RegisterClass(&wc);
    924 
    925      if (atomWindowClass != 0)
    926      {
    927          /* Create the window. */
    928          hwnd = CreateWindowEx (WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,
    929                  g_WndClassName, g_WndClassName,
    930                                                    WS_POPUPWINDOW,
    931                                                   -200, -200, 100, 100, NULL, NULL, hInstance, NULL);
    932 
    933          if (hwnd)
    934          {
    935              SetWindowPos(hwnd, HWND_TOPMOST, -200, -200, 0, 0,
    936                           SWP_NOACTIVATE | SWP_HIDEWINDOW | SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_NOSIZE);
    937 
    938              MSG msg;
    939              while (GetMessage(&msg, NULL, 0, 0))
    940              {
    941                  TranslateMessage(&msg);
    942                  DispatchMessage(&msg);
    943              }
    944 
    945              DestroyWindow (hwnd);
    946 
    947              bExit = true;
    948          }
    949 
    950          UnregisterClass (g_WndClassName, hInstance);
    951      }
    952 
    953      if(bExit)
    954      {
    955          /* no need any accuracy here, in anyway the DHCP server usually gets terminated with TerminateProcess */
    956          exit(0);
    957      }
    958 
    959      return 0;
    960 }
    961 
    962 
    963 /** (We don't want a console usually.) */
    964 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    965 {
    966     NOREF(hInstance); NOREF(hPrevInstance); NOREF(lpCmdLine); NOREF(nCmdShow);
    967 
    968     HANDLE hThread = CreateThread(
    969       NULL, /*__in_opt   LPSECURITY_ATTRIBUTES lpThreadAttributes, */
    970       0, /*__in       SIZE_T dwStackSize, */
    971       MsgThreadProc, /*__in       LPTHREAD_START_ROUTINE lpStartAddress,*/
    972       NULL, /*__in_opt   LPVOID lpParameter,*/
    973       0, /*__in       DWORD dwCreationFlags,*/
    974       NULL /*__out_opt  LPDWORD lpThreadId*/
    975     );
    976 
    977     if(hThread != NULL)
    978         CloseHandle(hThread);
    979 
    980     return main(__argc, __argv);
    981 }
    982 # endif /* RT_OS_WINDOWS */
    983 
    984 #endif /* !VBOX_WITH_HARDENING */
    985 
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette