Changeset 43203 in vbox for trunk/src/VBox
- Timestamp:
- Sep 5, 2012 1:21:19 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/socket.cpp
r43183 r43203 685 685 686 686 /* 687 * new function to allow ipv4 and ipv6 addresses to be resolved.687 * new function to allow both ipv4 and ipv6 addresses to be resolved. 688 688 * breaks compatibility with windows before 2000 689 689 * will change when the new ipv6 struct will be added 690 690 * temporary solution 691 691 */ 692 RTDECL(int) RTSocketGetAddrInfo(const char *psz, char *pszResult, size_t *resultSize, PRTNETADDRTYPE pAddrType) 693 { 692 RTDECL(int) RTSocketGetAddrInfo(const char *pszHost, char *pszResult, size_t *pcbResult, PRTNETADDRTYPE penmAddrType) 693 { 694 AssertPtrReturn(pszHost, VERR_INVALID_POINTER); 695 AssertPtrReturn(pcbResult, VERR_INVALID_POINTER); 696 AssertPtrNullReturn(penmAddrType, VERR_INVALID_POINTER); 697 AssertPtrNullReturn(pszResult, VERR_INVALID_POINTER); 698 694 699 #if defined(RT_OS_OS2) 695 700 return VERR_NOT_SUPPORTED; 696 701 #else 697 int rc = 0; 698 size_t resSize = 0; 699 uint8_t *pubDummy = NULL; 700 701 struct sockaddr_in *pgrSa = NULL; 702 struct sockaddr_in6 *pgrSa6 = NULL; 703 702 int rc; 703 uint8_t const *pbDummy = NULL; 704 705 struct addrinfo *pgrResults = NULL; 706 struct addrinfo *pgrResult = NULL; 707 708 if (*pcbResult < 16) 709 return VERR_NET_ADDRESS_NOT_AVAILABLE; 710 711 /* Setup the hint. */ 704 712 struct addrinfo grHints; 705 struct addrinfo *pgrResults = NULL, *pgrResult = NULL; 706 707 char szIpV4Address[16]; 708 char szIpV6Address[40]; 709 char szDummy[10]; 710 711 char *pszIpV4Address = NULL, *pszIpV6Address = NULL; 712 713 memset(szIpV4Address, '\0', 16); 714 memset(szIpV6Address, '\0', 40); 715 memset(szDummy, '\0', 10); 716 717 memset(&grHints, 0, sizeof(struct addrinfo)); 718 719 if (*resultSize < 16) 720 return VERR_NET_ADDRESS_NOT_AVAILABLE; 721 722 resSize = *resultSize; 723 724 grHints.ai_family = AF_UNSPEC; 725 726 if (*pAddrType == RTNETADDRTYPE_IPV6) 727 grHints.ai_family = AF_INET6; 728 729 if (*pAddrType == RTNETADDRTYPE_IPV4) 730 grHints.ai_family = AF_INET; 731 732 if (*pAddrType == RTNETADDRTYPE_INVALID || !pAddrType) // yes, it's been set before... 733 grHints.ai_family = AF_UNSPEC; 734 713 RT_ZERO(grHints); 735 714 grHints.ai_socktype = 0; 736 grHints.ai_flags = 0;715 grHints.ai_flags = 0; 737 716 grHints.ai_protocol = 0; 738 739 #ifdef RT_OS_WINDOWS 717 grHints.ai_family = AF_UNSPEC; 718 if (penmAddrType) 719 { 720 switch (*penmAddrType) 721 { 722 case RTNETADDRTYPE_INVALID: 723 /*grHints.ai_family = AF_UNSPEC;*/ 724 break; 725 case RTNETADDRTYPE_IPV4: 726 grHints.ai_family = AF_INET; 727 break; 728 case RTNETADDRTYPE_IPV6: 729 grHints.ai_family = AF_INET6; 730 break; 731 default: 732 AssertFailedReturn(VERR_INVALID_PARAMETER); 733 } 734 } 735 736 # ifdef RT_OS_WINDOWS 740 737 /* 741 738 * Winsock2 init 742 739 */ 743 / / *FIXME* someone should check if we really need 2, 2 here740 /** @todo someone should check if we really need 2, 2 here */ 744 741 WORD wVersionRequested = MAKEWORD(2, 2); 745 742 WSADATA wsaData; 746 747 743 rc = WSAStartup(wVersionRequested, &wsaData); 748 749 744 if (wsaData.wVersion != wVersionRequested) 750 745 { … … 752 747 return VERR_NOT_SUPPORTED; 753 748 } 754 # endif755 756 rc = getaddrinfo(psz, "", &grHints, &pgrResults);757 749 # endif 750 751 /** @todo r=bird: getaddrinfo and freeaddrinfo breaks the additions on NT4. */ 752 rc = getaddrinfo(pszHost, "", &grHints, &pgrResults); 758 753 if (rc != 0) 759 754 return VERR_NET_ADDRESS_NOT_AVAILABLE; … … 766 761 767 762 pgrResult = pgrResults->ai_next; 768 769 763 if (!pgrResult) 764 { 765 /** @todo r=bird: Missing freeaddrinfo call? */ 770 766 return VERR_NET_ADDRESS_NOT_AVAILABLE; 771 767 } 768 769 rc = VINF_SUCCESS; 770 RTNETADDRTYPE enmAddrType = RTNETADDRTYPE_INVALID; 771 size_t cchIpAddress; 772 char szIpAddress[48]; 772 773 if (pgrResult->ai_family == AF_INET) 773 774 { 774 pgrSa = (sockaddr_in *)pgrResult->ai_addr; 775 776 pszIpV4Address = &szIpV4Address[0]; 777 778 pubDummy = (uint8_t *)&pgrSa->sin_addr; 779 780 for (int i = 0; i < 4; i++) 781 { 782 memset(szDummy, '\0', 10); 783 784 size_t cb = RTStrPrintf(szDummy, 10, "%u", *pubDummy); 785 786 if (!cb || cb > 3 || cb < 1) 787 return VERR_NET_ADDRESS_NOT_AVAILABLE; 788 789 memcpy(pszIpV4Address, szDummy, cb); 790 791 pszIpV4Address = (pszIpV4Address + cb); 792 793 if (i < 3) 794 { 795 *pszIpV4Address = '.'; 796 pszIpV4Address++; 797 } 798 pubDummy++; 799 } 800 801 pgrResult = NULL; 802 pgrSa = NULL; 803 pubDummy = NULL; 804 freeaddrinfo(pgrResults); 805 806 if (strlen(szIpV4Address) >= resSize) 807 { 808 memset(pszResult, 0, resSize); 809 *resultSize = strlen(szIpV4Address) + 1; 810 return VERR_BUFFER_OVERFLOW; 811 } 775 struct sockaddr_in const *pgrSa = (struct sockaddr_in const *)pgrResult->ai_addr; 776 pbDummy = (uint8_t const *)&pgrSa->sin_addr; 777 cchIpAddress = RTStrPrintf(szIpAddress, sizeof(szIpAddress), "%u.%u.%u.%u", 778 pbDummy[0], pbDummy[1], pbDummy[2], pbDummy[3]); 779 Assert(cchIpAddress >= 7 && cchIpAddress < sizeof(szIpAddress) - 1); 780 enmAddrType = RTNETADDRTYPE_IPV4; 781 } 782 else if (pgrResult->ai_family == AF_INET6) 783 { 784 struct sockaddr_in6 const *pgrSa6 = (struct sockaddr_in6 const *)pgrResult->ai_addr; 785 pbDummy = (uint8_t const *) &pgrSa6->sin6_addr; 786 char szTmp[32+1]; 787 size_t cchTmp = RTStrPrintf(szTmp, sizeof(szTmp), 788 "%02x%02x%02x%02x" 789 "%02x%02x%02x%02x" 790 "%02x%02x%02x%02x" 791 "%02x%02x%02x%02x", 792 pbDummy[0], pbDummy[1], pbDummy[2], pbDummy[3], 793 pbDummy[4], pbDummy[5], pbDummy[6], pbDummy[7], 794 pbDummy[8], pbDummy[9], pbDummy[10], pbDummy[11], 795 pbDummy[12], pbDummy[13], pbDummy[14], pbDummy[15]); 796 Assert(cchTmp == 32); 797 rc = rtStrToIpAddr6Str(szTmp, szIpAddress, sizeof(szIpAddress), NULL, 0, true); 798 if (RT_SUCCESS(rc)) 799 cchIpAddress = strlen(szIpAddress); 812 800 else 813 801 { 814 memcpy(pszResult, szIpV4Address, strlen(szIpV4Address)); 815 *resultSize = strlen(szIpV4Address); 816 return VINF_SUCCESS; 802 szIpAddress[0] = '\0'; 803 cchIpAddress = 0; 817 804 } 818 } 819 820 if (pgrResult->ai_family == AF_INET6) 821 { 822 pgrSa6 = (sockaddr_in6 *) pgrResult->ai_addr; 823 824 pszIpV6Address = &szIpV6Address[0]; 825 826 pubDummy = (uint8_t *) &pgrSa6->sin6_addr; 827 828 for (int i = 0; i < 16; i++) 829 { 830 memset(szDummy, '\0', 10); 831 832 size_t cb = RTStrPrintf(szDummy, 10, "%02x", *pubDummy); 833 834 if (cb != 2) 835 return VERR_NET_ADDRESS_NOT_AVAILABLE; 836 837 memcpy(pszIpV6Address, szDummy, cb); 838 839 pszIpV6Address = pszIpV6Address + cb; 840 pubDummy++; 841 } 842 843 pubDummy = NULL; 844 pgrSa6 = NULL; 845 pgrResult = NULL; 846 freeaddrinfo(pgrResults); 847 848 if (strlen(szIpV6Address) == 32) 849 { 850 if (strlen(szIpV6Address) + 8 >= resSize) 851 { 852 *resultSize = 41; 853 memset(pszResult, 0, resSize); 854 return VERR_BUFFER_OVERFLOW; 855 } 856 else 857 { 858 memset(pszResult, '\0', resSize); 859 rc = rtStrToIpAddr6Str(szIpV6Address, pszResult, resSize, NULL, 0, true); 860 861 if (rc != 0) 862 return VERR_NET_ADDRESS_NOT_AVAILABLE; 863 864 *resultSize = strlen(pszResult); 865 866 return VINF_SUCCESS; 867 } 868 } 869 else 870 { 871 return VERR_NET_ADDRESS_NOT_AVAILABLE; 872 } 873 874 } // AF_INET6 875 return VERR_NET_ADDRESS_NOT_AVAILABLE; 805 enmAddrType = RTNETADDRTYPE_IPV6; 806 } 807 else 808 rc = VERR_NET_ADDRESS_NOT_AVAILABLE; 809 freeaddrinfo(pgrResults); 810 811 /* 812 * Copy out the result. 813 */ 814 size_t const cbResult = *pcbResult; 815 *pcbResult = cchIpAddress + 1; 816 if (cchIpAddress < cbResult) 817 memcpy(pszResult, szIpAddress, cchIpAddress + 1); 818 else 819 { 820 RT_BZERO(pszResult, cbResult); 821 if (RT_SUCCESS(rc)) 822 rc = VERR_BUFFER_OVERFLOW; 823 } 824 if (penmAddrType && RT_SUCCESS(rc)) 825 *penmAddrType = enmAddrType; 826 return rc; 876 827 #endif /* !RT_OS_OS2 */ 877 828 }
Note:
See TracChangeset
for help on using the changeset viewer.