VirtualBox

Changeset 41977 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jul 2, 2012 8:52:58 AM (13 years ago)
Author:
vboxsync
Message:

NAT: extract DNS functions to slirp_dns.c.

Handle resolv.conf-less Linux distributions.

Location:
trunk/src/VBox/Devices/Network/slirp
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/slirp/bootp.c

    r40421 r41977  
    708708            if (parameter_list[i] == RFC1533_DNS)
    709709            {
    710                 slirp_release_dns_list(pData);
    711                 slirp_init_dns_list(pData);
     710                slirpReleaseDnsSettings(pData);
     711                slirpInitializeDnsSettings(pData);
    712712                pData->dnsLastUpdate = curtime;
    713713                break;
  • trunk/src/VBox/Devices/Network/slirp/slirp.c

    r41855 r41977  
    289289}
    290290
    291 #ifdef RT_OS_WINDOWS
    292 static int get_dns_addr_domain(PNATState pData,
    293                                const char **ppszDomain)
    294 {
    295     ULONG flags = GAA_FLAG_INCLUDE_PREFIX; /*GAA_FLAG_INCLUDE_ALL_INTERFACES;*/ /* all interfaces registered in NDIS */
    296     PIP_ADAPTER_ADDRESSES pAdapterAddr = NULL;
    297     PIP_ADAPTER_ADDRESSES pAddr = NULL;
    298     PIP_ADAPTER_DNS_SERVER_ADDRESS pDnsAddr = NULL;
    299     ULONG size;
    300     int wlen = 0;
    301     char *pszSuffix;
    302     struct dns_domain_entry *pDomain = NULL;
    303     ULONG ret = ERROR_SUCCESS;
    304 
    305     /* @todo add SKIPing flags to get only required information */
    306 
    307     /* determine size of buffer */
    308     size = 0;
    309     ret = pData->pfGetAdaptersAddresses(AF_INET, 0, NULL /* reserved */, pAdapterAddr, &size);
    310     if (ret != ERROR_BUFFER_OVERFLOW)
    311     {
    312         Log(("NAT: error %lu occurred on capacity detection operation\n", ret));
    313         return -1;
    314     }
    315     if (size == 0)
    316     {
    317         Log(("NAT: Win socket API returns non capacity\n"));
    318         return -1;
    319     }
    320 
    321     pAdapterAddr = RTMemAllocZ(size);
    322     if (!pAdapterAddr)
    323     {
    324         Log(("NAT: No memory available\n"));
    325         return -1;
    326     }
    327     ret = pData->pfGetAdaptersAddresses(AF_INET, 0, NULL /* reserved */, pAdapterAddr, &size);
    328     if (ret != ERROR_SUCCESS)
    329     {
    330         Log(("NAT: error %lu occurred on fetching adapters info\n", ret));
    331         RTMemFree(pAdapterAddr);
    332         return -1;
    333     }
    334 
    335     for (pAddr = pAdapterAddr; pAddr != NULL; pAddr = pAddr->Next)
    336     {
    337         int found;
    338         if (pAddr->OperStatus != IfOperStatusUp)
    339             continue;
    340 
    341         for (pDnsAddr = pAddr->FirstDnsServerAddress; pDnsAddr != NULL; pDnsAddr = pDnsAddr->Next)
    342         {
    343             struct sockaddr *SockAddr = pDnsAddr->Address.lpSockaddr;
    344             struct in_addr  InAddr;
    345             struct dns_entry *pDns;
    346 
    347             if (SockAddr->sa_family != AF_INET)
    348                 continue;
    349 
    350             InAddr = ((struct sockaddr_in *)SockAddr)->sin_addr;
    351 
    352             /* add dns server to list */
    353             pDns = RTMemAllocZ(sizeof(struct dns_entry));
    354             if (!pDns)
    355             {
    356                 Log(("NAT: Can't allocate buffer for DNS entry\n"));
    357                 RTMemFree(pAdapterAddr);
    358                 return VERR_NO_MEMORY;
    359             }
    360 
    361             Log(("NAT: adding %RTnaipv4 to DNS server list\n", InAddr));
    362             if ((InAddr.s_addr & RT_H2N_U32_C(IN_CLASSA_NET)) == RT_N2H_U32_C(INADDR_LOOPBACK & IN_CLASSA_NET))
    363                 pDns->de_addr.s_addr = RT_H2N_U32(RT_N2H_U32(pData->special_addr.s_addr) | CTL_ALIAS);
    364             else
    365                 pDns->de_addr.s_addr = InAddr.s_addr;
    366 
    367             TAILQ_INSERT_HEAD(&pData->pDnsList, pDns, de_list);
    368 
    369             if (pAddr->DnsSuffix == NULL)
    370                 continue;
    371 
    372             /* uniq */
    373             RTUtf16ToUtf8(pAddr->DnsSuffix, &pszSuffix);
    374             if (!pszSuffix || strlen(pszSuffix) == 0)
    375             {
    376                 RTStrFree(pszSuffix);
    377                 continue;
    378             }
    379 
    380             found = 0;
    381             LIST_FOREACH(pDomain, &pData->pDomainList, dd_list)
    382             {
    383                 if (   pDomain->dd_pszDomain != NULL
    384                     && strcmp(pDomain->dd_pszDomain, pszSuffix) == 0)
    385                 {
    386                     found = 1;
    387                     RTStrFree(pszSuffix);
    388                     break;
    389                 }
    390             }
    391             if (!found)
    392             {
    393                 pDomain = RTMemAllocZ(sizeof(struct dns_domain_entry));
    394                 if (!pDomain)
    395                 {
    396                     Log(("NAT: not enough memory\n"));
    397                     RTStrFree(pszSuffix);
    398                     RTMemFree(pAdapterAddr);
    399                     return VERR_NO_MEMORY;
    400                 }
    401                 pDomain->dd_pszDomain = pszSuffix;
    402                 Log(("NAT: adding domain name %s to search list\n", pDomain->dd_pszDomain));
    403                 LIST_INSERT_HEAD(&pData->pDomainList, pDomain, dd_list);
    404             }
    405         }
    406     }
    407     RTMemFree(pAdapterAddr);
    408     return 0;
    409 }
    410 
    411 #else /* !RT_OS_WINDOWS */
    412 
    413 static int RTFileGets(RTFILE File, void *pvBuf, size_t cbBufSize, size_t *pcbRead)
    414 {
    415     size_t cbRead;
    416     char bTest;
    417     int rc = VERR_NO_MEMORY;
    418     char *pu8Buf = (char *)pvBuf;
    419     *pcbRead = 0;
    420 
    421     while (   RT_SUCCESS(rc = RTFileRead(File, &bTest, 1, &cbRead))
    422            && (pu8Buf - (char *)pvBuf) < cbBufSize)
    423     {
    424         if (cbRead == 0)
    425             return VERR_EOF;
    426 
    427         if (bTest == '\r' || bTest == '\n')
    428         {
    429             *pu8Buf = 0;
    430             return VINF_SUCCESS;
    431         }
    432         *pu8Buf = bTest;
    433          pu8Buf++;
    434         (*pcbRead)++;
    435     }
    436     return rc;
    437 }
    438 
    439 static int get_dns_addr_domain(PNATState pData, const char **ppszDomain)
    440 {
    441     char buff[512];
    442     char buff2[256];
    443     RTFILE f;
    444     int cNameserversFound = 0;
    445     bool fWarnTooManyDnsServers = false;
    446     struct in_addr tmp_addr;
    447     int rc;
    448     size_t bytes;
    449 
    450 # ifdef RT_OS_OS2
    451     /* Try various locations. */
    452     char *etc = getenv("ETC");
    453     if (etc)
    454     {
    455         RTStrmPrintf(buff, sizeof(buff), "%s/RESOLV2", etc);
    456         rc = RTFileOpen(&f, buff, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
    457     }
    458     if (RT_FAILURE(rc))
    459     {
    460         RTStrmPrintf(buff, sizeof(buff), "%s/RESOLV2", _PATH_ETC);
    461         rc = RTFileOpen(&f, buff, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
    462     }
    463     if (RT_FAILURE(rc))
    464     {
    465         RTStrmPrintf(buff, sizeof(buff), "%s/resolv.conf", _PATH_ETC);
    466         rc = RTFileOpen(&f, buff, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
    467     }
    468 # else /* !RT_OS_OS2 */
    469 #  ifndef DEBUG_vvl
    470     rc = RTFileOpen(&f, "/etc/resolv.conf", RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
    471 #  else
    472     char *home = getenv("HOME");
    473     RTStrPrintf(buff, sizeof(buff), "%s/resolv.conf", home);
    474     rc = RTFileOpen(&f, buff, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
    475     if (RT_SUCCESS(rc))
    476     {
    477         Log(("NAT: DNS we're using %s\n", buff));
    478     }
    479     else
    480     {
    481         rc = RTFileOpen(&f, "/etc/resolv.conf", RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
    482         Log(("NAT: DNS we're using %s\n", buff));
    483     }
    484 #  endif
    485 # endif /* !RT_OS_OS2 */
    486     if (RT_FAILURE(rc))
    487         return -1;
    488 
    489     if (ppszDomain)
    490         *ppszDomain = NULL;
    491 
    492     Log(("NAT: DNS Servers:\n"));
    493     while (    RT_SUCCESS(rc = RTFileGets(f, buff, sizeof(buff), &bytes))
    494             && rc != VERR_EOF)
    495     {
    496         struct dns_entry *pDns = NULL;
    497         if (   cNameserversFound == 4
    498             && !fWarnTooManyDnsServers
    499             && sscanf(buff, "nameserver%*[ \t]%255s", buff2) == 1)
    500         {
    501             fWarnTooManyDnsServers = true;
    502             LogRel(("NAT: too many nameservers registered.\n"));
    503         }
    504         if (   sscanf(buff, "nameserver%*[ \t]%255s", buff2) == 1
    505             && cNameserversFound < 4) /* Unix doesn't accept more than 4 name servers*/
    506         {
    507             if (!inet_aton(buff2, &tmp_addr))
    508                 continue;
    509 
    510             /* localhost mask */
    511             pDns = RTMemAllocZ(sizeof (struct dns_entry));
    512             if (!pDns)
    513             {
    514                 Log(("can't alloc memory for DNS entry\n"));
    515                 return -1;
    516             }
    517 
    518             /* check */
    519             pDns->de_addr.s_addr = tmp_addr.s_addr;
    520             if ((pDns->de_addr.s_addr & RT_H2N_U32_C(IN_CLASSA_NET)) == RT_N2H_U32_C(INADDR_LOOPBACK & IN_CLASSA_NET))
    521             {
    522                 pDns->de_addr.s_addr = RT_H2N_U32(RT_N2H_U32(pData->special_addr.s_addr) | CTL_ALIAS);
    523             }
    524             TAILQ_INSERT_HEAD(&pData->pDnsList, pDns, de_list);
    525             cNameserversFound++;
    526         }
    527         if ((!strncmp(buff, "domain", 6) || !strncmp(buff, "search", 6)))
    528         {
    529             char *tok;
    530             char *saveptr;
    531             struct dns_domain_entry *pDomain = NULL;
    532             int fFoundDomain = 0;
    533             tok = strtok_r(&buff[6], " \t\n", &saveptr);
    534             LIST_FOREACH(pDomain, &pData->pDomainList, dd_list)
    535             {
    536                 if (   tok != NULL
    537                     && strcmp(tok, pDomain->dd_pszDomain) == 0)
    538                 {
    539                     fFoundDomain = 1;
    540                     break;
    541                 }
    542             }
    543             if (tok != NULL && !fFoundDomain)
    544             {
    545                 pDomain = RTMemAllocZ(sizeof(struct dns_domain_entry));
    546                 if (!pDomain)
    547                 {
    548                     Log(("NAT: not enought memory to add domain list\n"));
    549                     return VERR_NO_MEMORY;
    550                 }
    551                 pDomain->dd_pszDomain = RTStrDup(tok);
    552                 Log(("NAT: adding domain name %s to search list\n", pDomain->dd_pszDomain));
    553                 LIST_INSERT_HEAD(&pData->pDomainList, pDomain, dd_list);
    554             }
    555         }
    556     }
    557     RTFileClose(f);
    558     if (!cNameserversFound)
    559         return -1;
    560     return 0;
    561 }
    562 
    563 #endif /* !RT_OS_WINDOWS */
    564 
    565 int slirp_init_dns_list(PNATState pData)
    566 {
    567     TAILQ_INIT(&pData->pDnsList);
    568     LIST_INIT(&pData->pDomainList);
    569     return get_dns_addr_domain(pData, NULL);
    570 }
    571 
    572 void slirp_release_dns_list(PNATState pData)
    573 {
    574     struct dns_entry *pDns = NULL;
    575     struct dns_domain_entry *pDomain = NULL;
    576 
    577     while (!TAILQ_EMPTY(&pData->pDnsList))
    578     {
    579         pDns = TAILQ_FIRST(&pData->pDnsList);
    580         TAILQ_REMOVE(&pData->pDnsList, pDns, de_list);
    581         RTMemFree(pDns);
    582     }
    583 
    584     while (!LIST_EMPTY(&pData->pDomainList))
    585     {
    586         pDomain = LIST_FIRST(&pData->pDomainList);
    587         LIST_REMOVE(pDomain, dd_list);
    588         if (pDomain->dd_pszDomain != NULL)
    589             RTStrFree(pDomain->dd_pszDomain);
    590         RTMemFree(pDomain);
    591     }
    592 }
    593 
    594 int get_dns_addr(PNATState pData)
    595 {
    596     return get_dns_addr_domain(pData, NULL);
    597 }
    598 
    599291int slirp_init(PNATState *ppData, uint32_t u32NetAddr, uint32_t u32Netmask,
    600292               bool fPassDomain, bool fUseHostResolver, int i32AliasMode,
    601293               int iIcmpCacheLimit, void *pvUser)
    602294{
    603     int fNATfailed = 0;
    604295    int rc;
    605296    PNATState pData;
     
    661352    /* set default addresses */
    662353    inet_aton("127.0.0.1", &loopback_addr);
    663     if (!pData->fUseHostResolver)
    664     {
    665         if (slirp_init_dns_list(pData) < 0)
    666             fNATfailed = 1;
    667 
    668         dnsproxy_init(pData);
    669     }
     354    rc = slirpInitializeDnsSettings(pData);
     355    AssertRCReturn(rc, VINF_NAT_DNS);
     356
    670357    if (i32AliasMode & ~(PKT_ALIAS_LOG|PKT_ALIAS_SAME_PORTS|PKT_ALIAS_PROXY_ONLY))
    671358    {
     
    703390    inet_aton("192.168.1.25", &pData->pInSockAddrHomeAddress[0].sin_addr);
    704391    pData->pInSockAddrHomeAddress[0].sin_family = AF_INET;
    705 #ifdef RT_OS_DARWIN
     392# ifdef RT_OS_DARWIN
    706393    pData->pInSockAddrHomeAddress[0].sin_len = sizeof(struct sockaddr_in);
    707 #endif
    708 #endif
    709     return fNATfailed ? VINF_NAT_DNS : VINF_SUCCESS;
     394# endif
     395#endif
     396    return VINF_SUCCESS;
    710397}
    711398
     
    805492
    806493    slirp_link_down(pData);
    807     slirp_release_dns_list(pData);
     494    slirpReleaseDnsSettings(pData);
    808495    ftp_alias_unload(pData);
    809496    nbt_alias_unload(pData);
  • trunk/src/VBox/Devices/Network/slirp/slirp.h

    r39287 r41977  
    269269
    270270#include "slirp_state.h"
     271#include "slirp_dns.h"
    271272
    272273#undef PVM /* XXX Mac OS X hack */
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