Advertisement
Ghostriax-Atrocity

MX.cpp

Apr 11th, 2015
223
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.55 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include "MX.h"
  3.  
  4. bool GetOwnMXServers(std::vector<MX_Information>& results)
  5. {
  6. char externIP[IP4_ADDRESS_STRING_BUFFER_LENGTH] = {0};
  7.  
  8. // Can't get ip by chance
  9. if(!get_public_IP(externIP))
  10. {
  11. return false;
  12. }
  13.  
  14. if(NOT_A_IP == inet_addr(externIP))
  15. {
  16. return false;
  17. }
  18.  
  19. return GetMXServers(externIP, results);
  20. }
  21.  
  22. bool GetMXServers(std::string server, std::vector<MX_Information>& results)
  23. {
  24. char reversedIP[DNS_MAX_IP4_REVERSE_NAME_BUFFER_LENGTH] = {0}, // for PtrLookup
  25. lookupDomain[PTR_NAME_LENGTH] = {0},
  26. *lookup2LevelDomain = NULL;
  27.  
  28. // is a IP
  29. if(NOT_A_IP != inet_addr(server.c_str()))
  30. {
  31. GenerateReverseLookupIP(server.c_str(), reversedIP);
  32. if(!PtrLookup(reversedIP, lookupDomain))
  33. return false;
  34. }
  35. else
  36. strncpy_s(lookupDomain, sizeof(lookupDomain), server.c_str(),
  37. min(strlen(server.c_str()), PTR_NAME_LENGTH-1));
  38.  
  39. // Lookup: 75-171-211-203.hlrn.qwest.net / gmail.com
  40. if(MXLookup(lookupDomain, results))
  41. return true;
  42.  
  43. // becomes: qwest.net / gmail.com
  44. lookup2LevelDomain = Get2LevelDomain(lookupDomain);
  45.  
  46. // Hopefully becomes: mx4.qwest.net / alt4.gmail-smtp-in.l.google.com
  47. if(MXLookup(lookup2LevelDomain, results))
  48. return true;
  49.  
  50. return false;
  51. }
  52.  
  53. static bool SortMxRecords(MX_Information const& lhs, MX_Information const& rhs)
  54. {
  55. return lhs.prefernce < rhs.prefernce;
  56. }
  57.  
  58.  
  59. static bool MXLookup(const char* name, std::vector<MX_Information>& results)
  60. {
  61. DNS_STATUS status;
  62. PDNS_RECORD pDnsRecord = NULL;
  63. DNS_FREE_TYPE freetype = DnsFreeRecordListDeep;
  64. PIP4_ARRAY pSrvList = NULL;
  65. MX_Information mxi;
  66.  
  67. if(!name)
  68. return false;
  69.  
  70. status = DnsQuery_A(name,
  71. DNS_TYPE_MX,
  72. DNS_QUERY_STANDARD,
  73. NULL,
  74. &pDnsRecord,
  75. NULL);
  76. if(DNS_RCODE_NOERROR != status)
  77. {
  78. // printf(__FUNCTION__ "() Err: %i:%i\n", status, GetLastError());
  79. return false;
  80. }
  81.  
  82. for (PDNS_RECORD pRecord = pDnsRecord; pRecord != NULL; pRecord = pRecord->pNext)
  83. {
  84. if (DNS_TYPE_MX != pRecord->wType)
  85. continue;
  86.  
  87. mxi.name = (char*)pRecord->Data.MX.pNameExchange;
  88. mxi.prefernce = pRecord->Data.MX.wPreference;
  89. results.push_back(mxi);
  90.  
  91. /*printf("\nSection: %s\n", SectionToString(pRecord->Flags.S.Section));
  92. printf("\nSection: %X\n", pRecord->Flags.S.Section);
  93. printf( "Domain Name: %s\n", (char*) pRecord->pName);
  94. printf( "Record Type: %d\n", pRecord->wType);
  95. printf( "Time-To-Live: %d\n", pRecord->dwTtl);
  96.  
  97. if (pRecord->wType == DNS_TYPE_MX)
  98. {
  99. printf(" MX Server: %s\n", (char*) pRecord->Data.MX.pNameExchange);
  100. printf(" Preference: %d\n", pRecord->Data.MX.wPreference);
  101. }
  102. */
  103. }
  104.  
  105. // Sort so the servers are tried in the correct order
  106. std::sort(results.begin(), results.end(), SortMxRecords);
  107.  
  108. DnsRecordListFree(pDnsRecord, freetype);
  109. return true;
  110. }
  111.  
  112. static bool PtrLookup(const char* name, char* result)
  113. {
  114. DNS_STATUS status = DNS_RCODE_NOERROR;
  115. PDNS_RECORD pDnsRecord = NULL;
  116. PIP4_ARRAY pSrvList = NULL;
  117.  
  118. if(!name || !result)
  119. return false;
  120.  
  121. if(!(pSrvList = (PIP4_ARRAY) LocalAlloc(LPTR, sizeof(IP4_ARRAY))))
  122. return false;
  123. pSrvList->AddrCount = 1;
  124. pSrvList->AddrArray[0] = inet_addr("8.8.8.8"); //Google DNS server IP address
  125.  
  126. status = DnsQuery_A(name,
  127. DNS_TYPE_PTR,
  128. DNS_QUERY_STANDARD,
  129. NULL,
  130. &pDnsRecord,
  131. NULL);
  132. LocalFree(pSrvList);
  133. if(DNS_RCODE_NOERROR != status)
  134. {
  135. // printf(__FUNCTION__ "() Err: %i:%i\n", status, GetLastError());
  136. return false;
  137. }
  138.  
  139. // Explanation in MXLookup()
  140. strncpy_s(result, PTR_NAME_LENGTH, (char*)pDnsRecord->Data.PTR.pNameHost, PTR_NAME_LENGTH);
  141.  
  142. DnsRecordListFree(pDnsRecord, DnsFreeRecordListDeep);
  143. return true;
  144.  
  145. }
  146.  
  147. static void GenerateReverseLookupIP(const char* ip, char* result)
  148. {
  149. const char* end = ".in-addr.arpa.";
  150. char ipParts[4][4] = {0};
  151. const char* ipPartStart = ip, *ipPartEnd = NULL;
  152.  
  153. if(!ip || !result)
  154. return;
  155.  
  156. for(unsigned int i = 0; i < 4; i++)
  157. {
  158. ipPartEnd = strstr(ipPartStart, ".");
  159. // Last part of ip
  160. // TODO Does it work with the last byte as "X", "XX", "XXX"
  161. if(!ipPartEnd)
  162. ipPartEnd = ipPartStart + strlen(ipPartStart);
  163. strncpy_s(ipParts[i], 4, ipPartStart, ipPartEnd - ipPartStart);
  164.  
  165. ipPartStart = ipPartEnd + 1;
  166. }
  167.  
  168. wsprintfA(result, "%s.%s.%s.%s%s", ipParts[3], ipParts[2], ipParts[1], ipParts[0], end);
  169. }
  170.  
  171. static char* Get2LevelDomain(char* domain)
  172. {
  173. char* end = domain + strlen(domain);
  174. bool foundDot = false;
  175.  
  176. if(!domain)
  177. return NULL;
  178.  
  179. while(end > domain)
  180. {
  181. if(*end == '.')
  182. {
  183. if(foundDot)
  184. return end+1;
  185. else
  186. foundDot = true;
  187. }
  188. end--;
  189. }
  190.  
  191. return NULL;
  192. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement