VirtualBox

Changeset 39766 in vbox for trunk/src/VBox/Devices/Network


Ignore:
Timestamp:
Jan 13, 2012 7:28:55 PM (13 years ago)
Author:
vboxsync
Message:

NAT: host resolver can use user-defined mapping instead of host provided mappings.
o need to test alias resolving.
o code is disabled (VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER) need more testing.
o CFGM configuration:

# VBoxManage setextradata deb6-i386 "VBoxInternal/Devices/e1000/0/LUN#0/AttachedDriver/Config/HostResolverMappings/1/HostIP" 127.0.0.1
# VBoxManage setextradata deb6-i386 "VBoxInternal/Devices/e1000/0/LUN#0/AttachedDriver/Config/HostResolverMappings/1/HostName" update.microsoft.com

Host resolver should be on

# VBoxManage modifyvm deb6-i386 --natdnshostresolver1 on

Location:
trunk/src/VBox/Devices/Network
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/DrvNAT.cpp

    r39550 r39766  
    10091009}
    10101010
     1011#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
     1012static int drvNATConstructDNSMappings(unsigned iInstance, PDRVNAT pThis, PCFGMNODE pMappingsCfg)
     1013{
     1014    int rc = VINF_SUCCESS;
     1015    LogFlowFunc(("ENTER: iInstance:%d\n", iInstance));
     1016    for (PCFGMNODE pNode = CFGMR3GetFirstChild(pMappingsCfg); pNode; pNode = CFGMR3GetNextChild(pNode))
     1017    {
     1018        if (!CFGMR3AreValuesValid(pNode, "HostName\0HostIP\0"))
     1019            return PDMDRV_SET_ERROR(pThis->pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES,
     1020                                    N_("Unknown configuration in dns mapping"));
     1021        char szHostName[255];
     1022        RT_ZERO(szHostName);
     1023        GET_STRING(rc, pThis, pNode, "HostName", szHostName[0], sizeof(szHostName));
     1024        struct in_addr HostIP;
     1025        GETIP_DEF(rc, pThis, pNode, HostIP, INADDR_ANY);
     1026        slirp_add_host_resolver_mapping(pThis->pNATState, szHostName, HostIP.s_addr);
     1027    }
     1028    LogFlowFunc(("LEAVE: %Rrc\n", rc));
     1029    return rc;
     1030}
     1031#endif /* !VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER */
     1032
    10111033
    10121034/**
     
    10261048    for (PCFGMNODE pNode = CFGMR3GetFirstChild(pCfg); pNode; pNode = CFGMR3GetNextChild(pNode))
    10271049    {
     1050#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
     1051        char szNodeName[32];
     1052        CFGMR3GetName(pNode, szNodeName, 32);
     1053        if (   !RTStrICmp(szNodeName, "HostResolverMappings")
     1054            || !RTStrICmp(szNodeName, "AttachedDriver"))
     1055            continue;
     1056#endif
    10281057        /*
    10291058         * Validate the port forwarding config.
     
    11591188                              "SockRcv\0SockSnd\0TcpRcv\0TcpSnd\0"
    11601189                              "ICMPCacheLimit\0"
    1161                               "SoMaxConnection\0"))
     1190                              "SoMaxConnection\0"
     1191#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
     1192                              "HostResolverMappings\0"
     1193#endif
     1194                            ))
    11621195        return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES,
    11631196                                N_("Unknown NAT configuration option, only supports PassDomain,"
     
    12931326#endif
    12941327
     1328#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
     1329        PCFGMNODE pMappingsCfg = CFGMR3GetChild(pCfg, "HostResolverMappings");
     1330
     1331        if (pMappingsCfg)
     1332        {
     1333            rc = drvNATConstructDNSMappings(pDrvIns->iInstance, pThis, pMappingsCfg);
     1334            AssertRC(rc);
     1335        }
     1336#endif
    12951337        rc = drvNATConstructRedir(pDrvIns->iInstance, pThis, pCfg, Network);
    12961338        if (RT_SUCCESS(rc))
  • trunk/src/VBox/Devices/Network/slirp/libalias/alias_dns.c

    r39101 r39766  
    6868
    6969/* see RFC 1035(4.1) */
    70 static int dns_alias_handler(PNATState pData, int type);
     70static int  dns_alias_handler(PNATState pData, int type);
    7171static void CStr2QStr(const char *pcszStr, char *pszQStr, size_t cQStr);
    7272static void QStr2CStr(const char *pcszQStr, char *pszStr, size_t cStr);
     73#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
     74static void alterHostentWithDataFromDNSMap(PNATState pData, struct hostent *pHostent);
     75#endif
    7376
    7477static int
    75 fingerprint(struct libalias *la, struct ip *pip, struct alias_data *ah)
     78fingerprint(struct libalias *la, struct ip *pIp, struct alias_data *ah)
    7679{
    7780
    7881    NOREF(la);
    79     NOREF(pip);
     82    NOREF(pIp);
    8083    if (!ah->dport || !ah->sport || !ah->lnk)
    8184        return -1;
     
    9396}
    9497
    95 static void doanswer(union dnsmsg_header *hdr, struct dns_meta_data *pReqMeta, char *qname, struct ip *pip, struct hostent *h)
     98static void doanswer(union dnsmsg_header *pHdr, struct dns_meta_data *pReqMeta, char *pszQname, struct ip *pIp, struct hostent *pHostent)
    9699{
    97100    int i;
    98101
    99     if (!h)
    100     {
    101         hdr->X.qr = 1; /* response */
    102         hdr->X.aa = 1;
    103         hdr->X.rd = 1;
    104         hdr->X.rcode = 3;
     102    if (!pHostent)
     103    {
     104        pHdr->X.qr = 1; /* response */
     105        pHdr->X.aa = 1;
     106        pHdr->X.rd = 1;
     107        pHdr->X.rcode = 3;
    105108    }
    106109    else
     
    117120#if 0
    118121        /* here is no compressed names+answers + new query */
    119         m_inc(m, h->h_length * sizeof(struct dnsmsg_answer) + strlen(qname) + 2 * sizeof(uint16_t));
     122        m_inc(m, pHostent->h_length * sizeof(struct dnsmsg_answer) + strlen(pszQname) + 2 * sizeof(uint16_t));
    120123#endif
    121         packet_len = (pip->ip_hl << 2)
     124        packet_len = (pIp->ip_hl << 2)
    122125                   + sizeof(struct udphdr)
    123126                   + sizeof(union dnsmsg_header)
    124                    + strlen(qname)
     127                   + strlen(pszQname)
    125128                   + sizeof(struct dns_meta_data); /* ip + udp + header + query */
    126         query = (char *)&hdr[1];
    127 
    128         strcpy(query, qname);
    129         query += strlen(qname) + 1;
     129        query = (char *)&pHdr[1];
     130
     131        strcpy(query, pszQname);
     132        query += strlen(pszQname) + 1;
    130133        /* class & type informations lay right after symbolic inforamtion. */
    131134        meta = (struct dns_meta_data *)query;
     
    136139        answers = (char *)&meta[1];
    137140
    138         off = (char *)&hdr[1] - (char *)hdr;
     141        off = (char *)&pHdr[1] - (char *)pHdr;
    139142        off |= (0x3 << 14);
    140143
    141144        /* add aliases */
    142         for (cstr = h->h_aliases; *cstr; cstr++)
     145        for (cstr = pHostent->h_aliases; *cstr; cstr++)
    143146        {
    144147            uint16_t len;
     
    148151            ans->meta.class = htons(1);
    149152            *(uint32_t *)ans->ttl = htonl(3600); /* 1h */
    150             c = (addr_off == (uint16_t)~0 ? h->h_name : *cstr);
     153            c = (addr_off == (uint16_t)~0 ? pHostent->h_name : *cstr);
    151154            len = strlen(c) + 2;
    152155            ans->rdata_len = htons(len);
    153156            ans->rdata[len - 1] = 0;
    154157            CStr2QStr(c, (char *)ans->rdata, len);
    155             off = (char *)&ans->rdata - (char *)hdr;
     158            off = (char *)&ans->rdata - (char *)pHdr;
    156159            off |= (0x3 << 14);
    157160            if (addr_off == (uint16_t)~0)
     
    159162            answers = (char *)&ans[1] + len - 2;  /* note: 1 symbol already counted */
    160163            packet_len += sizeof(struct dnsmsg_answer) + len - 2;
    161             hdr->X.ancount++;
     164            pHdr->X.ancount++;
    162165        }
    163166        /* add addresses */
    164167
    165         for(i = 0; i < h->h_length && h->h_addr_list[i] != NULL; ++i)
     168        for(i = 0; i < pHostent->h_length && pHostent->h_addr_list[i] != NULL; ++i)
    166169        {
    167170            struct dnsmsg_answer *ans = (struct dnsmsg_answer *)answers;
     
    172175            *(uint32_t *)ans->ttl = htonl(3600); /* 1h */
    173176            ans->rdata_len = htons(4); /* IPv4 */
    174             *(uint32_t *)ans->rdata = *(uint32_t *)h->h_addr_list[i];
     177            *(uint32_t *)ans->rdata = *(uint32_t *)pHostent->h_addr_list[i];
    175178            answers = (char *)&ans[1] + 2;
    176179            packet_len += sizeof(struct dnsmsg_answer) + 3;
    177             hdr->X.ancount++;
    178         }
    179         hdr->X.qr = 1; /* response */
    180         hdr->X.aa = 1;
    181         hdr->X.rd = 1;
    182         hdr->X.ra = 1;
    183         hdr->X.rcode = 0;
    184         HTONS(hdr->X.ancount);
     180            pHdr->X.ancount++;
     181        }
     182        pHdr->X.qr = 1; /* response */
     183        pHdr->X.aa = 1;
     184        pHdr->X.rd = 1;
     185        pHdr->X.ra = 1;
     186        pHdr->X.rcode = 0;
     187        HTONS(pHdr->X.ancount);
    185188        /* don't forget update m_len */
    186         pip->ip_len = htons(packet_len);
     189        pIp->ip_len = htons(packet_len);
    187190    }
    188191}
    189192
    190193static int
    191 protohandler(struct libalias *la, struct ip *pip, struct alias_data *ah)
     194protohandler(struct libalias *la, struct ip *pIp, struct alias_data *ah)
    192195{
    193196    int i;
    194197    /* Parse dns request */
    195198    char *qw_qname = NULL;
    196     struct hostent *h = NULL;
    197     char cname[255];
     199    struct hostent *pHostent = NULL;
     200    char pszCname[255];
    198201    int cname_len = 0;
    199202    struct dns_meta_data *meta;
    200203
    201204    struct udphdr *udp = NULL;
    202     union dnsmsg_header *hdr = NULL;
     205    union dnsmsg_header *pHdr = NULL;
    203206    NOREF(la);
    204207    NOREF(ah);
    205     udp = (struct udphdr *)ip_next(pip);
    206     hdr = (union dnsmsg_header *)udp_next(udp);
    207 
    208     if (hdr->X.qr == 1)
     208    udp = (struct udphdr *)ip_next(pIp);
     209    pHdr = (union dnsmsg_header *)udp_next(udp);
     210
     211    if (pHdr->X.qr == 1)
    209212        return 0; /* this is respose */
    210213
    211     memset(cname, 0, sizeof(cname));
    212     qw_qname = (char *)&hdr[1];
    213     Assert((ntohs(hdr->X.qdcount) == 1));
    214     if ((ntohs(hdr->X.qdcount) != 1))
     214    memset(pszCname, 0, sizeof(pszCname));
     215    qw_qname = (char *)&pHdr[1];
     216    Assert((ntohs(pHdr->X.qdcount) == 1));
     217    if ((ntohs(pHdr->X.qdcount) != 1))
    215218    {
    216219        static bool fMultiWarn;
     
    223226    }
    224227
    225     for (i = 0; i < ntohs(hdr->X.qdcount); ++i)
     228    for (i = 0; i < ntohs(pHdr->X.qdcount); ++i)
    226229    {
    227230        meta = (struct dns_meta_data *)(qw_qname + strlen(qw_qname) + 1);
    228         Log(("qname:%s qtype:%hd qclass:%hd\n",
     231        Log(("pszQname:%s qtype:%hd qclass:%hd\n",
    229232            qw_qname, ntohs(meta->type), ntohs(meta->class)));
    230233
    231         QStr2CStr(qw_qname, cname, sizeof(cname));
    232         cname_len = RTStrNLen(cname, sizeof(cname));
     234        QStr2CStr(qw_qname, pszCname, sizeof(pszCname));
     235        cname_len = RTStrNLen(pszCname, sizeof(pszCname));
    233236        /* Some guests like win-xp adds _dot_ after host name
    234237         * and after domain name (not passed with host resolver)
     
    236239         */
    237240        if (   cname_len > 2
    238             && cname[cname_len - 1] == '.'
    239             && cname[cname_len - 2] == '.')
    240         {
    241             cname[cname_len - 1] = 0;
    242             cname[cname_len - 2] = 0;
    243         }
    244         h = gethostbyname(cname);
    245         fprintf(stderr, "cname:%s\n", cname);
    246         doanswer(hdr, meta, qw_qname, pip, h);
     241            && pszCname[cname_len - 1] == '.'
     242            && pszCname[cname_len - 2] == '.')
     243        {
     244            pszCname[cname_len - 1] = 0;
     245            pszCname[cname_len - 2] = 0;
     246        }
     247        pHostent = gethostbyname(pszCname);
     248#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
     249        if (   pHostent
     250            && !LIST_EMPTY(&la->pData->DNSMapHead))
     251            alterHostentWithDataFromDNSMap(la->pData, pHostent);
     252#endif
     253        fprintf(stderr, "pszCname:%s\n", pszCname);
     254        doanswer(pHdr, meta, qw_qname, pIp, pHostent);
    247255    }
    248256
     
    252260     */
    253261    udp->uh_sum = 0;
    254     udp->uh_ulen = ntohs(htons(pip->ip_len) - (pip->ip_hl << 2));
    255     pip->ip_sum = 0;
    256     pip->ip_sum = LibAliasInternetChecksum(la, (uint16_t *)pip, pip->ip_hl << 2);
     262    udp->uh_ulen = ntohs(htons(pIp->ip_len) - (pIp->ip_hl << 2));
     263    pIp->ip_sum = 0;
     264    pIp->ip_sum = LibAliasInternetChecksum(la, (uint16_t *)pIp, pIp->ip_hl << 2);
    257265    return 0;
    258266}
     
    367375    return error;
    368376}
     377
     378#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
     379static void alterHostentWithDataFromDNSMap(PNATState pData, struct hostent *pHostent)
     380{
     381    PDNSMAPPINGENTRY pDNSMapingEntry = NULL;
     382    bool fMatch = false;
     383    LIST_FOREACH(pDNSMapingEntry, &pData->DNSMapHead, MapList)
     384    {
     385        char **pszAlias = NULL;
     386        if (!strcmp(pDNSMapingEntry->pszCName, pHostent->h_name))
     387        {
     388            fMatch = true;
     389            break;
     390        }
     391
     392        for (pszAlias = pHostent->h_aliases; *pszAlias && !fMatch; pszAlias++)
     393        {
     394            if (!strcmp(pDNSMapingEntry->pszCName, *pszAlias))
     395            {
     396
     397                PDNSMAPPINGENTRY pDnsMapping = RTMemAllocZ(sizeof(DNSMAPPINGENTRY));
     398                fMatch = true;
     399                if (!pDnsMapping)
     400                {
     401                    LogFunc(("Can't allocate DNSMAPPINGENTRY\n"));
     402                    LogFlowFuncLeave();
     403                    return;
     404                }
     405                pDnsMapping->u32IpAddress = pDNSMapingEntry->u32IpAddress;
     406                pDnsMapping->pszCName = RTStrDup(pHostent->h_name);
     407                if (!pDnsMapping->pszCName)
     408                {
     409                    LogFunc(("Can't allocate enough room for %s\n", pHostent->h_name));
     410                    RTMemFree(pDnsMapping);
     411                    LogFlowFuncLeave();
     412                    return;
     413                }
     414                LIST_INSERT_HEAD(&pData->DNSMapHead, pDnsMapping, MapList);
     415            }
     416        }
     417        if (fMatch)
     418            break;
     419    }
     420
     421    /* h_lenght is lenght of h_addr_list in bytes, so we check that we have enough space for IPv4 address */
     422    if (   fMatch
     423        && pHostent->h_length >= sizeof(uint32_t)
     424        && pDNSMapingEntry)
     425    {
     426        pHostent->h_length = 1;
     427        *(uint32_t *)pHostent->h_addr_list[0] = pDNSMapingEntry->u32IpAddress;
     428    }
     429
     430}
     431#endif
  • trunk/src/VBox/Devices/Network/slirp/libslirp.h

    r38971 r39766  
    148148# endif
    149149
     150#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
     151void  slirp_add_host_resolver_mapping(PNATState pData, const char *pszHostName, uint32_t u32HostIP);
     152#endif
     153
    150154#ifdef __cplusplus
    151155}
  • trunk/src/VBox/Devices/Network/slirp/slirp.c

    r39599 r39766  
    799799    nbt_alias_unload(pData);
    800800    if (pData->fUseHostResolver)
     801    {
    801802        dns_alias_unload(pData);
     803#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
     804        while (!LIST_EMPTY(&pData->DNSMapHead))
     805        {
     806            PDNSMAPPINGENTRY pDnsEntry = LIST_FIRST(&pData->DNSMapHead);
     807            LIST_REMOVE(pDnsEntry, MapList);
     808            RTStrFree(pDnsEntry->pszCName);
     809            RTMemFree(pDnsEntry);
     810        }
     811#endif
     812    }
    802813    while (!LIST_EMPTY(&instancehead))
    803814    {
     
    21472158    LogFlowFuncLeave();
    21482159}
     2160#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
     2161void  slirp_add_host_resolver_mapping(PNATState pData, const char *pszHostName, uint32_t u32HostIP)
     2162{
     2163    LogFlowFunc(("ENTER: pszHostName:%s, u32HostIP:%RTnaipv4\n", pszHostName, u32HostIP));
     2164    if (   pszHostName
     2165        || u32HostIP != INADDR_ANY
     2166        || u32HostIP != INADDR_BROADCAST)
     2167    {
     2168        PDNSMAPPINGENTRY pDnsMapping = RTMemAllocZ(sizeof(DNSMAPPINGENTRY));
     2169        if (!pDnsMapping)
     2170        {
     2171            LogFunc(("Can't allocate DNSMAPPINGENTRY\n"));
     2172            LogFlowFuncLeave();
     2173            return;
     2174        }
     2175        pDnsMapping->u32IpAddress = u32HostIP;
     2176        pDnsMapping->pszCName = RTStrDup(pszHostName);
     2177        if (!pDnsMapping->pszCName)
     2178        {
     2179            LogFunc(("Can't allocate enough room for %s\n", pszHostName));
     2180            RTMemFree(pDnsMapping);
     2181            LogFlowFuncLeave();
     2182            return;
     2183        }
     2184        LIST_INSERT_HEAD(&pData->DNSMapHead, pDnsMapping, MapList);
     2185    }
     2186    LogFlowFuncLeave();
     2187}
     2188#endif
    21492189
    21502190/* updates the arp cache
  • trunk/src/VBox/Devices/Network/slirp/slirp_state.h

    r39550 r39766  
    6565};
    6666LIST_HEAD(dns_domain_list_head, dns_domain_entry);
     67
     68#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
     69typedef struct DNSMAPPINGENTRY
     70{
     71    char        *pszCName;
     72    uint32_t    u32IpAddress;
     73    LIST_ENTRY(DNSMAPPINGENTRY) MapList;
     74} DNSMAPPINGENTRY, *PDNSMAPPINGENTRY;
     75typedef LIST_HEAD(DNSMAPPINGLISTHEAD, DNSMAPPINGENTRY) DNSMAPPINGLISTHEAD;
     76#endif
    6777
    6878struct dns_entry
     
    298308    int cInHomeAddressSize;
    299309#endif
     310#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
     311    DNSMAPPINGLISTHEAD DNSMapHead;
     312#endif
    300313} NATState;
    301314
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