VirtualBox

vbox的更動 54541 路徑 trunk/src/VBox/NetworkServices


忽略:
時間撮記:
2015-2-27 上午01:51:42 (10 年 以前)
作者:
vboxsync
訊息:

VBoxNetDHCP: Quick and dirty code to pass extra DHCP options to clients.
Doesn't cache settings. Only works for hex-encoded options for now.

檔案:
修改 1 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/NetworkServices/DHCP/Config.cpp

    r54504 r54541  
    3232#include <VBox/version.h>
    3333
     34#include <VBox/com/array.h>
    3435#include <VBox/com/string.h>
    3536
     
    10001001
    10011002
     1003/*
     1004 * XXX: TODO: Share decoding code with DHCPServer::addOption.
     1005 */
     1006static int parseDhcpOptionText(const char *pszText,
     1007                               int *pOptCode, char **ppszOptText, int *pOptEncoding)
     1008{
     1009    uint8_t u8Code;
     1010    uint32_t u32Enc;
     1011    char *pszNext;
     1012    int rc;
     1013
     1014    rc = RTStrToUInt8Ex(pszText, &pszNext, 10, &u8Code);
     1015    if (!RT_SUCCESS(rc))
     1016        return VERR_PARSE_ERROR;
     1017
     1018    switch (*pszNext)
     1019    {
     1020        case ':':           /* support legacy format too */
     1021        {
     1022            u32Enc = 0;
     1023            break;
     1024        }
     1025
     1026        case '=':
     1027        {
     1028            u32Enc = 1;
     1029            break;
     1030        }
     1031
     1032        case '@':
     1033        {
     1034            rc = RTStrToUInt32Ex(pszNext + 1, &pszNext, 10, &u32Enc);
     1035            if (!RT_SUCCESS(rc))
     1036                return VERR_PARSE_ERROR;
     1037            if (*pszNext != '=')
     1038                return VERR_PARSE_ERROR;
     1039            break;
     1040        }
     1041
     1042        default:
     1043            return VERR_PARSE_ERROR;
     1044    }
     1045
     1046    *pOptCode = u8Code;
     1047    *ppszOptText = pszNext + 1;
     1048    *pOptEncoding = (int)u32Enc;
     1049
     1050    return VINF_SUCCESS;
     1051}
     1052
     1053
     1054/*
     1055 * XXX: Since encoding info is "smuggled" through the API and is not
     1056 * exposed properly we don't have a common definition we can use here.
     1057 *
     1058 * TODO: We can define the encodings enum in the IDL without breaking
     1059 * backward compatibility.  This will provide the authoritative
     1060 * definition.
     1061 */
     1062static int fillDhcpOption(RawOption &opt, const std::string &OptText, int OptEncoding)
     1063{
     1064    int rc;
     1065 
     1066    if (OptEncoding == /* HEX */ 1)
     1067    {
     1068        if (OptText.empty())
     1069            return VERR_INVALID_PARAMETER;
     1070
     1071        size_t cbRawOpt = 0;
     1072        char *pszNext = const_cast<char *>(OptText.c_str());
     1073        while (*pszNext != '\0')
     1074        {
     1075            if (cbRawOpt == 256)
     1076                return VERR_INVALID_PARAMETER;
     1077
     1078            uint8_t u8Byte;
     1079            rc = RTStrToUInt8Ex(pszNext, &pszNext, 16, &u8Byte);
     1080            if (!RT_SUCCESS(rc))
     1081                return rc;
     1082
     1083            if (*pszNext == ':')
     1084                ++pszNext;
     1085            else if (*pszNext != '\0')
     1086                return VERR_PARSE_ERROR;
     1087
     1088            opt.au8RawOpt[cbRawOpt] = u8Byte;
     1089            ++cbRawOpt;
     1090        }
     1091        opt.cbRawOpt = (uint8_t)cbRawOpt;
     1092    }
     1093    else if (OptEncoding == /* LEGACY */ 0)
     1094    {
     1095        /*
     1096         * XXX: TODO: encode "known" option opt.u8OptId
     1097         */
     1098        return VERR_INVALID_PARAMETER;
     1099    }
     1100
     1101    return VINF_SUCCESS;
     1102}
     1103
     1104
    10021105int NetworkManager::processParameterReqList(const Client& client, const uint8_t *pu8ReqList,
    10031106                                            int cReqList, std::vector<RawOption>& extra)
    10041107{
     1108    int rc;
     1109
    10051110    const Lease l = client.lease();
    10061111
    10071112    const NetworkConfigEntity *pNetCfg = l.getConfig();
     1113
     1114    /*
     1115     * XXX: Brute-force.  Unfortunately, there's no notification event
     1116     * for changes.  Should at least cache the options for a short
     1117     * time, enough to last discover/offer/request/ack cycle.
     1118     */
     1119    typedef std::map< int, std::pair<std::string, int> > DhcpOptionMap;
     1120    DhcpOptionMap OptMap;
     1121
     1122    if (!m->m_DhcpServer.isNull())
     1123    {
     1124        com::SafeArray<BSTR> strings;
     1125        com::Bstr str;
     1126        HRESULT hrc;
     1127        int OptCode, OptEncoding;
     1128        char *pszOptText;
     1129
     1130        strings.setNull();
     1131        hrc = m->m_DhcpServer->COMGETTER(GlobalOptions)(ComSafeArrayAsOutParam(strings));
     1132        AssertComRC(hrc);
     1133        for (size_t i = 0; i < strings.size(); ++i)
     1134        {
     1135            com::Utf8Str encoded(strings[i]);
     1136            rc = parseDhcpOptionText(encoded.c_str(),
     1137                                     &OptCode, &pszOptText, &OptEncoding);
     1138            if (!RT_SUCCESS(rc))
     1139                continue;
     1140
     1141            OptMap[OptCode] = std::make_pair(pszOptText, OptEncoding);
     1142        }
     1143
     1144        const RTMAC &mac = client.getMacAddress();
     1145        char strMac[6*2+1] = "";
     1146        RTStrPrintf(strMac, sizeof(strMac), "%02x%02x%02x%02x%02x%02x",
     1147                    mac.au8[0], mac.au8[1], mac.au8[2],
     1148                    mac.au8[3], mac.au8[4], mac.au8[5]);
     1149
     1150        strings.setNull();
     1151        hrc = m->m_DhcpServer->COMGETTER(MacOptions)(com::Bstr(strMac).raw(),
     1152                                                     ComSafeArrayAsOutParam(strings));
     1153        AssertComRC(hrc);
     1154        for (size_t i = 0; i < strings.size(); ++i)
     1155        {
     1156            com::Utf8Str text(strings[i]);
     1157            rc = parseDhcpOptionText(text.c_str(),
     1158                                     &OptCode, &pszOptText, &OptEncoding);
     1159            if (!RT_SUCCESS(rc))
     1160                continue;
     1161
     1162            OptMap[OptCode] = std::make_pair(pszOptText, OptEncoding);
     1163        }
     1164    }
    10081165
    10091166    /* request parameter list */
     
    10611218                break;
    10621219            default:
    1063                 Log(("opt: %d is ignored\n", u8Req));
    1064                 fIgnore = true;
     1220                {
     1221                    DhcpOptionMap::const_iterator it = OptMap.find((int)u8Req);
     1222                    if (it == OptMap.cend())
     1223                    {
     1224                        Log(("opt: %d is ignored\n", u8Req));
     1225                        fIgnore = true;
     1226                    }
     1227                    else
     1228                    {
     1229                        std::string OptText((*it).second.first);
     1230                        int OptEncoding((*it).second.second);
     1231
     1232                        rc = fillDhcpOption(opt, OptText, OptEncoding);
     1233                        if (!RT_SUCCESS(rc))
     1234                        {
     1235                            fIgnore = true;
     1236                            break;
     1237                        }
     1238                    }
     1239                }
    10651240                break;
    10661241        }
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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