Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stdafx.h"
- #include "MX.h"
- bool GetOwnMXServers(std::vector<MX_Information>& results)
- {
- char externIP[IP4_ADDRESS_STRING_BUFFER_LENGTH] = {0};
- // Can't get ip by chance
- if(!get_public_IP(externIP))
- {
- return false;
- }
- if(NOT_A_IP == inet_addr(externIP))
- {
- return false;
- }
- return GetMXServers(externIP, results);
- }
- bool GetMXServers(std::string server, std::vector<MX_Information>& results)
- {
- char reversedIP[DNS_MAX_IP4_REVERSE_NAME_BUFFER_LENGTH] = {0}, // for PtrLookup
- lookupDomain[PTR_NAME_LENGTH] = {0},
- *lookup2LevelDomain = NULL;
- // is a IP
- if(NOT_A_IP != inet_addr(server.c_str()))
- {
- GenerateReverseLookupIP(server.c_str(), reversedIP);
- if(!PtrLookup(reversedIP, lookupDomain))
- return false;
- }
- else
- strncpy_s(lookupDomain, sizeof(lookupDomain), server.c_str(),
- min(strlen(server.c_str()), PTR_NAME_LENGTH-1));
- // Lookup: 75-171-211-203.hlrn.qwest.net / gmail.com
- if(MXLookup(lookupDomain, results))
- return true;
- // becomes: qwest.net / gmail.com
- lookup2LevelDomain = Get2LevelDomain(lookupDomain);
- // Hopefully becomes: mx4.qwest.net / alt4.gmail-smtp-in.l.google.com
- if(MXLookup(lookup2LevelDomain, results))
- return true;
- return false;
- }
- static bool SortMxRecords(MX_Information const& lhs, MX_Information const& rhs)
- {
- return lhs.prefernce < rhs.prefernce;
- }
- static bool MXLookup(const char* name, std::vector<MX_Information>& results)
- {
- DNS_STATUS status;
- PDNS_RECORD pDnsRecord = NULL;
- DNS_FREE_TYPE freetype = DnsFreeRecordListDeep;
- PIP4_ARRAY pSrvList = NULL;
- MX_Information mxi;
- if(!name)
- return false;
- status = DnsQuery_A(name,
- DNS_TYPE_MX,
- DNS_QUERY_STANDARD,
- NULL,
- &pDnsRecord,
- NULL);
- if(DNS_RCODE_NOERROR != status)
- {
- // printf(__FUNCTION__ "() Err: %i:%i\n", status, GetLastError());
- return false;
- }
- for (PDNS_RECORD pRecord = pDnsRecord; pRecord != NULL; pRecord = pRecord->pNext)
- {
- if (DNS_TYPE_MX != pRecord->wType)
- continue;
- mxi.name = (char*)pRecord->Data.MX.pNameExchange;
- mxi.prefernce = pRecord->Data.MX.wPreference;
- results.push_back(mxi);
- /*printf("\nSection: %s\n", SectionToString(pRecord->Flags.S.Section));
- printf("\nSection: %X\n", pRecord->Flags.S.Section);
- printf( "Domain Name: %s\n", (char*) pRecord->pName);
- printf( "Record Type: %d\n", pRecord->wType);
- printf( "Time-To-Live: %d\n", pRecord->dwTtl);
- if (pRecord->wType == DNS_TYPE_MX)
- {
- printf(" MX Server: %s\n", (char*) pRecord->Data.MX.pNameExchange);
- printf(" Preference: %d\n", pRecord->Data.MX.wPreference);
- }
- */
- }
- // Sort so the servers are tried in the correct order
- std::sort(results.begin(), results.end(), SortMxRecords);
- DnsRecordListFree(pDnsRecord, freetype);
- return true;
- }
- static bool PtrLookup(const char* name, char* result)
- {
- DNS_STATUS status = DNS_RCODE_NOERROR;
- PDNS_RECORD pDnsRecord = NULL;
- PIP4_ARRAY pSrvList = NULL;
- if(!name || !result)
- return false;
- if(!(pSrvList = (PIP4_ARRAY) LocalAlloc(LPTR, sizeof(IP4_ARRAY))))
- return false;
- pSrvList->AddrCount = 1;
- pSrvList->AddrArray[0] = inet_addr("8.8.8.8"); //Google DNS server IP address
- status = DnsQuery_A(name,
- DNS_TYPE_PTR,
- DNS_QUERY_STANDARD,
- NULL,
- &pDnsRecord,
- NULL);
- LocalFree(pSrvList);
- if(DNS_RCODE_NOERROR != status)
- {
- // printf(__FUNCTION__ "() Err: %i:%i\n", status, GetLastError());
- return false;
- }
- // Explanation in MXLookup()
- strncpy_s(result, PTR_NAME_LENGTH, (char*)pDnsRecord->Data.PTR.pNameHost, PTR_NAME_LENGTH);
- DnsRecordListFree(pDnsRecord, DnsFreeRecordListDeep);
- return true;
- }
- static void GenerateReverseLookupIP(const char* ip, char* result)
- {
- const char* end = ".in-addr.arpa.";
- char ipParts[4][4] = {0};
- const char* ipPartStart = ip, *ipPartEnd = NULL;
- if(!ip || !result)
- return;
- for(unsigned int i = 0; i < 4; i++)
- {
- ipPartEnd = strstr(ipPartStart, ".");
- // Last part of ip
- // TODO Does it work with the last byte as "X", "XX", "XXX"
- if(!ipPartEnd)
- ipPartEnd = ipPartStart + strlen(ipPartStart);
- strncpy_s(ipParts[i], 4, ipPartStart, ipPartEnd - ipPartStart);
- ipPartStart = ipPartEnd + 1;
- }
- wsprintfA(result, "%s.%s.%s.%s%s", ipParts[3], ipParts[2], ipParts[1], ipParts[0], end);
- }
- static char* Get2LevelDomain(char* domain)
- {
- char* end = domain + strlen(domain);
- bool foundDot = false;
- if(!domain)
- return NULL;
- while(end > domain)
- {
- if(*end == '.')
- {
- if(foundDot)
- return end+1;
- else
- foundDot = true;
- }
- end--;
- }
- return NULL;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement