int CSmtpClient::GetSmtpServerName(CEmailMessage* msg, AssyncNotification* scn, std::map<WORD, CString>& host_list) { DNS_RECORD *apResult = NULL; CString sServer; sServer = msg->m_sFrom.Mid(msg->m_sFrom.Find('@')+1); CString sStatusMsg; sStatusMsg.Format(_T("Quering MX record of domain %s"), sServer); scn->SetProgress(sStatusMsg, 2); int r = DnsQuery(sServer, DNS_TYPE_MX, DNS_QUERY_STANDARD, NULL, (PDNS_RECORD*)&apResult, NULL); if(r==0) { while(apResult!=NULL) { if(apResult->wType==DNS_TYPE_MX) { host_list[apResult->Data.MX.wPreference] = CString(apResult->Data.MX.pNameExchange); } apResult = apResult->pNext; } return 0; } sStatusMsg.Format(_T("DNS query failed with code %d"), r); scn->SetProgress(sStatusMsg, 2); return 1; }
bool dnsquery_win(const QString &hostname) { DNS_RECORD *pResult = NULL; DNS_STATUS status = DnsQuery(hostname.toStdWString().c_str(),DNS_TYPE_A,DNS_QUERY_BYPASS_CACHE,NULL,&pResult,NULL); DnsRecordListFree(pResult,DnsFreeRecordList); return (0 == status); }
DNS::HostMap DNS::resolve( const std::string& service, const std::string& proto, const std::string& domain, const LogSink& logInstance ) { const std::string dname = "_" + service + "._" + proto + "." + domain; bool error = false; DNS::HostMap servers; DNS_RECORD* pRecord; if( DnsQuery( dname.c_str(), DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &pRecord, NULL ) == ERROR_SUCCESS ) { DNS_RECORD* pRec = pRecord; do { if( pRec->wType == DNS_TYPE_SRV ) { servers[pRec->Data.SRV.pNameTarget] = pRec->Data.SRV.wPort; } pRec = pRec->pNext; } while( pRec != NULL ); DnsRecordListFree( pRecord, DnsFreeRecordList ); } else error = true; if( error || !servers.size() ) { servers = defaultHostMap( domain, logInstance ); } return servers; }
PDNS_RECORD TraverseDnsCacheTable( _In_ PDNS_RECORD root ) { USHORT typeList[] = { DNS_TYPE_A, DNS_TYPE_AAAA, DNS_TYPE_MX, DNS_TYPE_SRV, DNS_TYPE_PTR }; // Only interested in these queries, to boost traversing performance PDNS_CACHE_ENTRY dnsCacheDataTable = NULL; PDNS_CACHE_ENTRY tablePtr; if (!DnsGetCacheDataTable_I(&dnsCacheDataTable)) goto CleanupExit; tablePtr = dnsCacheDataTable; while (tablePtr) { for (USHORT i = 0; i < ARRAYSIZE(typeList); i++) { DNS_STATUS dnsStatus; PDNS_RECORD dnsQueryResultPtr; dnsStatus = DnsQuery( tablePtr->Name, typeList[i], DNS_QUERY_NO_WIRE_QUERY | 32768, // Undocumented flags NULL, &dnsQueryResultPtr, NULL ); if (dnsStatus == ERROR_SUCCESS) { PDNS_RECORD dnsRecordPtr = dnsQueryResultPtr; while (dnsRecordPtr) { if (!RecordSetContains(root, dnsRecordPtr)) { PDNS_RECORD temp = root; root = DnsRecordCopy(dnsRecordPtr); root->pNext = temp; } dnsRecordPtr = dnsRecordPtr->pNext; } DnsRecordListFree(dnsQueryResultPtr, DnsFreeRecordList); } } tablePtr = tablePtr->Next; } CleanupExit: if (dnsCacheDataTable) DnsRecordListFree(dnsCacheDataTable, DnsFreeRecordList); return root; }
/** * Issues the DNS request to discover the sFlow service settings * (collector addresses and ports, sampling rates and polling intervals). * The DNS request is configured to bypass the DNS cache and go straight * to the wire to avoid using stale entries. * If the request succeeds, updates the min TTL in HSP *sp, parses the response, * and returns the number of records returned, populating HSPSFlowSettings *settings * with the parsed result. * If the request fails, returns -1. * char *dname contains the DNS query (fully qualified) * WORD dtype the DNS query type (SRV for collectors or TEXT for sampling rates * and polling intervals) * Note that we are using the DnsQuery function to make the DNS request. * This function does not take into account the system DNS search path, so the * DNS query must be fully qualified (ie include the domain to search). */ static int dnsSD_Request(HSP *sp, HSPSFlowSettings *settings, char *dname, WORD rtype) { PDNS_RECORD pDnsRecord; DNS_FREE_TYPE dnsFreeType; dnsFreeType = DnsFreeRecordListDeep; DNS_STATUS status = DnsQuery(dname, rtype, DNS_QUERY_WIRE_ONLY, NULL, &pDnsRecord, NULL); if (status) { //fail logErr(LOG_ERR, status, "dnsSD_Request: DNSQuery(%s, %u) failed error=%u", dname, rtype, status); return -1; } else { //process results and free int answerCount = 0; PDNS_RECORD nextRecord = pDnsRecord; while (nextRecord != NULL) { //update the minimum ttl DWORD ttl = nextRecord->dwTtl; if (sp->DNSSD_ttl == 0 || ttl < sp->DNSSD_ttl) { sp->DNSSD_ttl = ttl; } switch(rtype) { case DNS_TYPE_TEXT: if (nextRecord->wType == DNS_TYPE_TEXT) { answerCount++; DWORD stringCount = nextRecord->Data.TXT.dwStringCount; for (DWORD i = 0; i < stringCount; i++) { if (LOG_INFO <= debug) { myLog(LOG_INFO, "dnsDS_Request: DNS_TYPE_TEXT %s", nextRecord->Data.TXT.pStringArray[i]); } dnsSD_parseTxt(settings, nextRecord->Data.TXT.pStringArray[i]); } } break; case DNS_TYPE_SRV: if (nextRecord->wType == DNS_TYPE_SRV) { answerCount++; if (LOG_INFO <= debug) { myLog(LOG_INFO, "dnsDS_Request: DNS_TYPE_SRV %s %u", nextRecord->Data.SRV.pNameTarget, nextRecord->Data.SRV.wPort); } insertCollector(settings, nextRecord->Data.SRV.pNameTarget, nextRecord->Data.SRV.wPort); } break; default: DnsRecordListFree(pDnsRecord, dnsFreeType); myLog(LOG_ERR, "dnsDS_Request: unsupported query type %u", rtype); return -1; } nextRecord = nextRecord->pNext; } DnsRecordListFree(pDnsRecord, dnsFreeType); return answerCount; } }
int getrrs(const char *label, int rrtype, void gotrec(unsigned int num, int type, const char *record)) { DNS_STATUS status; /* Return value of DnsQuery_A() function */ PDNS_RECORD pResult, pRec; /* Pointer to DNS_RECORD structure */ unsigned int rrnum = 0, i; uint16_t type; status = DnsQuery(label, /* Pointer to OwnerName */ rrtype, /* Type of the record to be queried */ DNS_QUERY_STANDARD, /* Standard Query */ NULL, /* Contains DNS server IP address */ &pResult, /* Resource record that contains the response */ NULL); /* Reserved for future use */ if (status) return -1; else { for (pRec = pResult; pRec; pRec = pRec->pNext) { rrnum++; type = pRec->wType; if (rrtype != type && rrtype != ns_t_any) continue; switch (type) { case ns_t_txt: for (i=0; i < pRec->Data.TXT.dwStringCount; i++) { gotrec(rrnum, type, pRec->Data.TXT.pStringArray[i]); } break; case ns_t_a: gotrec(rrnum, type, (const char *)&pRec->Data.A.IpAddress); break; case ns_t_aaaa: gotrec(rrnum, type, (const char *)&pRec->Data.AAAA.Ip6Address); break; case ns_t_mx: gotrec(rrnum, type, pRec->Data.MX.pNameExchange); break; case ns_t_ns: gotrec(rrnum, type, pRec->Data.NS.pNameHost); break; } } } /* Free memory allocated for DNS records. */ DnsRecordListFree(pResult, DnsFreeRecordListDeep); return 0; }
int CSmtpClient::ResolveSmtpServerName(LPCTSTR szEmailAddress, std::map<WORD, CString>& host_list) { // This methods takes an E-mail address and resolve the domain name(s) // associated with this address. DNS_RECORD *apResult = NULL; // Convert to CString CString sEmailAddress = szEmailAddress; // Crop server name part from the E-mail address CString sServer; sServer = sEmailAddress.Mid(sEmailAddress.Find('@')+1); // Add a message to log CString sStatusMsg; sStatusMsg.Format(_T("Quering MX record of domain %s"), sServer); m_scn->SetProgress(sStatusMsg, 2); // Resolve the domain name(s) of the SMTP servers associated with // the E-mail address. Use MX record of DNS. int r = DnsQuery(sServer, DNS_TYPE_MX, DNS_QUERY_STANDARD, NULL, (PDNS_RECORD*)&apResult, NULL); PDNS_RECORD pRecOrig = apResult; // Check result if(r==0) { // Walk through returned DNS records while(apResult!=NULL) { // Look for MX record if(apResult->wType==DNS_TYPE_MX) { // Save domain name to our list CString sServerName = CString(apResult->Data.MX.pNameExchange); host_list[apResult->Data.MX.wPreference] = sServerName; } // Next record apResult = apResult->pNext; } // Free resources DnsRecordListFree(pRecOrig, DnsFreeRecordList); // Done return 0; } // Failed to resolve the address sStatusMsg.Format(_T("DNS query failed with code %d"), r); m_scn->SetProgress(sStatusMsg, 2); return 1; }
int main( int argc, char **argv ) { PDNS_RECORD QueryReply, AddrResponse; DWORD Addr; assert (DnsQuery ("www.reactos.com", DNS_TYPE_A, DNS_QUERY_STANDARD, NULL, &QueryReply, NULL) == ERROR_SUCCESS); AddrResponse = QueryReply; while( AddrResponse ) { if( AddrResponse->wType == DNS_TYPE_A ) { Addr = ntohl( AddrResponse->Data.A.IpAddress ); printf( "www.reactos.com == %d.%d.%d.%d\n", (int)(Addr >> 24) & 0xff, (int)(Addr >> 16) & 0xff, (int)(Addr >> 8) & 0xff, (int)Addr & 0xff ); } AddrResponse = AddrResponse->pNext; }
void DNS::IPToHostname(LPWSTR ip, std::wstring *hostname) { PDNS_RECORD dnsInfo; DWORD ret; WCHAR *token; WCHAR *context; std::wstring address; std::vector<LPWSTR> octets; LPWSTR tmpString = new WCHAR[lstrlen(ip)+1]; ZeroMemory(tmpString, lstrlen(ip)+1); lstrcpy(tmpString, ip); hostname->clear(); // Gotta flip the IP around for reverse DNS lookups. token = wcstok_s(tmpString, L".", &context); while(token != NULL) { octets.push_back(token); token = wcstok_s(NULL, L".", &context); } address.append(octets[3]); address.append(L"."); address.append(octets[2]); address.append(L"."); address.append(octets[1]); address.append(L"."); address.append(octets[0]); address.append(L".in-addr.arpa"); if((ret = DnsQuery((PWCHAR)address.c_str(), DNS_TYPE_PTR, DNS_QUERY_STANDARD, NULL, &dnsInfo, NULL)) != 0) { Util::Error(ret, L"DnsQuery()"); wprintf(L"ret = %x\n", ret); } else { hostname->append(dnsInfo->Data.PTR.pNameHost); DnsRecordListFree(dnsInfo); } delete(tmpString); }
int main( int argc, char **argv ) { PDNS_RECORD QueryReply, AddrResponse; DWORD Addr; assert (DnsValidateName( "||||", DnsNameDomain ) == DNS_ERROR_INVALID_NAME_CHAR); assert (DnsValidateName( "a.b.c", DnsNameDomainLabel ) == DNS_ERROR_INVALID_NAME); assert (DnsValidateName( "1234", DnsNameDomainLabel ) == ERROR_SUCCESS); assert (DnsValidateName( "fubar", DnsNameDomain ) == ERROR_SUCCESS); assert (DnsQuery ("www.reactos.com", DNS_TYPE_A, DNS_QUERY_STANDARD, NULL, &QueryReply, NULL) == ERROR_SUCCESS); AddrResponse = QueryReply; while( AddrResponse ) { if( AddrResponse->wType == DNS_TYPE_A ) { Addr = ntohl( AddrResponse->Data.A.IpAddress ); printf( "www.reactos.com == %d.%d.%d.%d\n", (int)(Addr >> 24) & 0xff, (int)(Addr >> 16) & 0xff, (int)(Addr >> 8) & 0xff, (int)Addr & 0xff ); } AddrResponse = AddrResponse->pNext; }
int srv_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { char *srv_name; size_t srv_name_size; char tgt_port[6]; #ifdef WIN32 PDNS_RECORD resp, entry; char *tgt_name; #else char tgt_name[BINKD_FQDNLEN + 1]; unsigned char resp[SRVGAI_DNSRESPLEN]; ns_msg nsb; ns_rr rrb; int rlen, i, rrlen; const unsigned char *p; struct in_addr dummy_addr; #endif int rc; struct addrinfo *ai, **ai_last = res; /* we need sensible information for all parameters */ if (!node || (node && !*node) || !service || (service && !*service) || !hints || !res) return getaddrinfo(node, service, hints, res); /* only domain names are supported */ if (hints->ai_flags & AI_NUMERICHOST) return getaddrinfo(node, service, hints, res); /* detect IP addresses */ if ((hints->ai_family == AF_INET || hints->ai_family == AF_UNSPEC) && #ifdef WIN32 inet_addr(node) != INADDR_NONE #else inet_aton(node, &dummy_addr) != 0 #endif ) return getaddrinfo(node, service, hints, res); #ifdef AF_INET6 if ((hints->ai_family == AF_INET6 || hints->ai_family == AF_UNSPEC) && strchr(node, ':')) return getaddrinfo(node, service, hints, res); #endif /* only named services are supported */ if ((hints->ai_flags & AI_NUMERICSERV) || *service == '0' || atoi(service) > 0) return getaddrinfo(node, service, hints, res); /* only TCP and UDP are supported */ if (hints->ai_socktype != SOCK_STREAM && hints->ai_socktype != SOCK_DGRAM) return getaddrinfo(node, service, hints, res); /* _ <service> ._ tcp . <node> \0 */ srv_name_size = 1 + strlen(service) + 2 + 3 + 1 + strlen(node) + 1; srv_name = malloc(srv_name_size); if (!srv_name) return EAI_MEMORY; /* construct domain name for SRV query */ snprintf(srv_name, srv_name_size, "_%s._%s.%s", service, hints->ai_socktype == SOCK_STREAM ? "tcp" : "udp", node); #ifdef WIN32 rc = DnsQuery(srv_name, DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &resp, NULL); #else rlen = res_search(srv_name, ns_c_in, ns_t_srv, resp, sizeof(resp)); #endif free(srv_name); /* fallback if DNS query does not return a single entry */ #ifdef WIN32 if (rc != ERROR_SUCCESS) #else if (rlen < 1) #endif return getaddrinfo(node, service, hints, res); #ifndef WIN32 /* fallback in case we cannot parse the response */ if (ns_initparse(resp, rlen, &nsb) < 0) return getaddrinfo(node, service, hints, res); #endif /* iterate through result set -- might be incomplete */ #ifdef WIN32 for (entry = resp; entry != NULL; entry = entry->pNext) { switch (entry->wType) { case DNS_TYPE_SRV: snprintf(tgt_port, sizeof(tgt_port), "%d", entry->Data.SRV.wPort); tgt_name = entry->Data.SRV.pNameTarget; #else for (i = 0; i < ns_msg_count(nsb, ns_s_an); i++) { rc = ns_parserr(&nsb, ns_s_an, i, &rrb); if (rc < 0) continue; if (ns_rr_class(rrb) != ns_c_in) continue; switch (ns_rr_type(rrb)) { case ns_t_srv: rrlen = ns_rr_rdlen(rrb); if (rrlen < 8) /* 2+2+2 and at least 2 for host */ break; /* extract host and port */ p = ns_rr_rdata(rrb); rc = dn_expand(resp, resp+rlen, p+6, tgt_name, sizeof(tgt_name)); if (rc < 2) break; snprintf(tgt_port, sizeof(tgt_port), "%u", (unsigned int)p[4] << 8 | (unsigned int)p[5]); #endif /* resolve and add to end of list */ if (getaddrinfo(tgt_name, tgt_port, hints, ai_last) != 0) break; /* get end of list */ for (ai=*ai_last; ai != NULL; ai = ai->ai_next) ai_last = &(ai->ai_next); break; default: /* someone stupid might use CNAME */ break; } } #ifdef WIN32 /* free result set */ DnsRecordListFree(resp, DnsFreeRecordList); #endif /* fallback in case no resolution via SRV is possible */ if (ai_last == res) return getaddrinfo(node, service, hints, res); return 0; }
int eXosip_get_naptr(char *domain, char *protocol, char *srv_record, int max_length) { char zone[1024]; PDNS_RECORD answer, tmp; /* answer buffer from nameserver */ int n; char tr[100]; memset(srv_record, 0, max_length); if (domain == NULL || protocol == NULL) return OSIP_BADPARAMETER; if (strlen(domain) + strlen(protocol) > 1000) return OSIP_BADPARAMETER; if (strlen(protocol) >= 100) return OSIP_BADPARAMETER; snprintf(tr, 100, protocol); osip_tolower(tr); snprintf(zone, 1024, "%s", domain); OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "About to ask for '%s NAPTR'\n", zone)); if (DnsQuery(zone, DNS_TYPE_NAPTR, DNS_QUERY_STANDARD, NULL, &answer, NULL) != 0) { return OSIP_UNKNOWN_HOST; } n = 0; for (tmp = answer; tmp != NULL; tmp = tmp->pNext) { char *buf = (char *) &tmp->Data; int len; OSVERSIONINFOEX ovi; typedef struct { unsigned short order; unsigned short pref; char flag[256]; char service[1024]; char regexp[1024]; char replacement[1024]; } osip_naptr_t; osip_naptr_t anaptr; if (tmp->wType != DNS_TYPE_NAPTR) continue; memset(&anaptr, 0, sizeof(osip_naptr_t)); memset(&ovi, 0, sizeof(ovi)); ovi.dwOSVersionInfoSize = sizeof(ovi); GetVersionEx((LPOSVERSIONINFO) & ovi); /* Minimum: client: Windows 2000 Professional */ /* Minimum: server: Windows 2000 Server */ OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "check OS support for NAPTR: %i %i %i\n", ovi.dwMajorVersion, ovi.dwMinorVersion, ovi.dwBuildNumber)); if (ovi.dwMajorVersion > 5) { #if (_WIN32_WINNT >= 0x0600) /* RUN only on Vista? */ /* compile starting from SDK 6.0A? even on XP... */ anaptr.order = tmp->Data.NAPTR.wOrder; anaptr.pref = tmp->Data.NAPTR.wPreference; strncpy(anaptr.flag, tmp->Data.NAPTR.pFlags, sizeof(anaptr.flag) - 1); strncpy(anaptr.service, tmp->Data.NAPTR.pService, sizeof(anaptr.service) - 1); strncpy(anaptr.regexp, tmp->Data.NAPTR.pRegularExpression, sizeof(anaptr.regexp) - 1); strncpy(anaptr.replacement, tmp->Data.NAPTR.pReplacement, sizeof(anaptr.replacement) - 1); #endif } else { memcpy((void *) &anaptr.order, buf, 2); anaptr.order = ntohs(anaptr.order); /* ((unsigned short)buf[0] << 8) | ((unsigned short)buf[1]); */ buf += sizeof(unsigned short); memcpy((void *) &anaptr.pref, buf, 2); anaptr.pref = ntohs(anaptr.pref); /* ((unsigned short)buf[0] << 8) | ((unsigned short)buf[1]); */ buf += sizeof(unsigned short); len = *buf; if (len < 0 || len > 255) break; buf++; strncpy(anaptr.flag, buf, len); anaptr.flag[len] = '\0'; buf += len; len = *buf; if (len < 0 || len > 1023) break; buf++; strncpy(anaptr.service, buf, len); anaptr.service[len] = '\0'; buf += len; len = *buf; if (len < 0 || len > 1023) break; buf++; strncpy(anaptr.regexp, buf, len); anaptr.regexp[len] = '\0'; buf += len; len = _eX_dn_expand((char *) &tmp->Data, ((char *) &tmp->Data) + tmp->wDataLength, buf, anaptr.replacement, 1024 - 1); if (len < 0) break; buf += len; } OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "NAPTR %s ->%i/%i/%s/%s/%s/%s\n", zone, anaptr.order, anaptr.pref, anaptr.flag, anaptr.service, anaptr.regexp, anaptr.replacement)); if (osip_strncasecmp(tr, "udp", 4) == 0 && osip_strncasecmp(anaptr.service, "SIP+D2U", 8) == 0) { snprintf(srv_record, max_length, "%s", anaptr.replacement); DnsRecordListFree(answer, DnsFreeRecordList); return OSIP_SUCCESS; } else if (osip_strncasecmp(tr, "tcp", 4) == 0 && osip_strncasecmp(anaptr.service, "SIP+D2T", 8) == 0) { snprintf(srv_record, max_length, "%s", anaptr.replacement); DnsRecordListFree(answer, DnsFreeRecordList); return OSIP_SUCCESS; } else if (osip_strncasecmp(tr, "udp-tls", 8) == 0 && osip_strncasecmp(anaptr.service, "SIPS+D2U", 9) == 0) { snprintf(srv_record, max_length, "%s", anaptr.replacement); DnsRecordListFree(answer, DnsFreeRecordList); return OSIP_SUCCESS; } else if (osip_strncasecmp(tr, "tls", 4) == 0 && osip_strncasecmp(anaptr.service, "SIPS+D2T", 9) == 0) { snprintf(srv_record, max_length, "%s", anaptr.replacement); DnsRecordListFree(answer, DnsFreeRecordList); return OSIP_SUCCESS; } else if (osip_strncasecmp(tr, "sctp", 5) == 0 && osip_strncasecmp(anaptr.service, "SIP+D2S", 8) == 0) { snprintf(srv_record, max_length, "%s", anaptr.replacement); DnsRecordListFree(answer, DnsFreeRecordList); return OSIP_SUCCESS; } n++; } DnsRecordListFree(answer, DnsFreeRecordList); if (n == 0) return OSIP_UNKNOWN_HOST; OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "protocol: %s is not supported by domain %s\n", protocol, domain)); return OSIP_SUCCESS; }
//------------------------------------------------------------------------------ DWORD WINAPI Scan_dns(LPVOID lParam) { unsigned int local_id = (unsigned int)lParam; //check if local or not :) if (!LOCAL_SCAN || WINE_OS) { h_thread_test[local_id] = 0; check_treeview(htrv_test, H_tests[local_id], TRV_STATE_UNCHECK);//db_scan return 0; } //init if(!SQLITE_FULL_SPEED)sqlite3_exec(db_scan,"BEGIN TRANSACTION;", NULL, NULL, NULL); sqlite3 *db = (sqlite3 *)db_scan; unsigned int session_id = current_session_id; //make file directory char file[MAX_PATH]=""; char ip[IPV6_SIZE_MAX],name[MAX_PATH]; snprintf(file,MAX_PATH,"%s\\WINDOWS\\system32\\drivers\\etc\\hosts",getenv("SYSTEMDRIVE")); #ifdef CMD_LINE_ONLY_NO_DB printf("\"DNS\";\"file\";\"ip\";\"name\";\"last_file_update\";\"malware_check\";\"session_id\";\r\n"); #endif // CMD_LINE_ONLY_NO_DB //open host file and read all hosts HANDLE Hfic = CreateFile(file,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,0); if (Hfic != INVALID_HANDLE_VALUE) { DWORD taille_fic = GetFileSize(Hfic,NULL); if (taille_fic != INVALID_FILE_SIZE) { char *buffer = (char *) HeapAlloc(GetProcessHeap(), 0, taille_fic+1); if (buffer != NULL) { //get last update char last_file_update[DATE_SIZE_MAX]=""; FILETIME LastWriteTime; if(GetFileTime(Hfic,NULL,NULL,&LastWriteTime))filetimeToString_GMT(LastWriteTime, last_file_update, DATE_SIZE_MAX); //read data line by line DWORD copiee; char lines[MAX_PATH]; if (ReadFile(Hfic, buffer, taille_fic,&copiee,0)) { char *r = buffer; char *s,*c; while (*r) { //read line memset(lines,0,MAX_PATH); strncpy(lines,r,MAX_PATH); s = lines; while (*s && *s != '\r')s++; *s = 0; r = r+strlen(lines)+2; //comment or not :) if (lines[0]!='#' && strlen(lines) > 8) { //get IP strncpy(ip,lines,IPV6_SIZE_MAX); c = ip; while (*c && *c != ' ' && *c!= '\t' && (*c == '.' || *c == ':' || (*c<='9' && *c>='0')))c++; if (*c) { *c = 0; //get name c = lines+strlen(ip); while (*c && (*c == ' ' || *c == '\t'))c++; memset(name,0,MAX_PATH); strncpy(name,c,MAX_PATH); addHosttoDB(file, ip, name, last_file_update,session_id,db); } } } } HeapFree(GetProcessHeap(), 0, buffer); } } CloseHandle(Hfic); } //get cache HMODULE hDLL = LoadLibrary( "DNSAPI.DLL" ); if (!hDLL) return 0; //function //typedef int(*DNS_GET_CACHE_DATA_TABLE)(PDNS_RECORD*); typedef int(WINAPI *DNS_GET_CACHE_DATA_TABLE)(PDNS_RECORD); DNS_GET_CACHE_DATA_TABLE DnsGetCacheDataTable = (DNS_GET_CACHE_DATA_TABLE)GetProcAddress(hDLL,"DnsGetCacheDataTable"); if (DnsGetCacheDataTable != NULL) { PDNS_RECORD pcache = NULL; DNS_RECORD* dnsRecords = NULL, *dnsr; IN_ADDR ipAddress; char last_file_update[DATE_SIZE_MAX]=""; if (DnsGetCacheDataTable(&pcache) == TRUE) { PDNS_RECORD cache = pcache; while (cache) { memset(name,0,MAX_PATH); snprintf(name,MAX_PATH,"%S",cache->pName); if (name[0] != 0) { //get IP + TTL if(DnsQuery(name,DNS_TYPE_A,0,NULL,&dnsRecords,NULL) == ERROR_SUCCESS) { dnsr = dnsRecords; while (dnsr != NULL) { ipAddress.S_un.S_addr = dnsr->Data.A.IpAddress; if (inet_ntoa(ipAddress) != NULL) { snprintf(ip,IP_SIZE_MAX,"%s",inet_ntoa(ipAddress)); snprintf(last_file_update,DATE_SIZE_MAX,"%lu (s)",dnsr->dwTtl); addHosttoDB("", ip, name, last_file_update,session_id,db); } dnsr = dnsr->pNext; } //free DnsRecordListFree(dnsRecords,DnsFreeRecordList); } } cache = cache->pNext; } } } FreeLibrary(hDLL); if(!SQLITE_FULL_SPEED)sqlite3_exec(db_scan,"END TRANSACTION;", NULL, NULL, NULL); check_treeview(htrv_test, H_tests[local_id], TRV_STATE_UNCHECK);//db_scan h_thread_test[local_id] = 0; return 0; }
BOOL CHwSMTP::SendSpeedEmail ( LPCTSTR lpszAddrFrom, LPCTSTR lpszAddrTo, LPCTSTR lpszSubject, LPCTSTR lpszBody, LPCTSTR lpszCharSet, CStringArray *pStrAryAttach, LPCTSTR pStrAryCC, UINT nSmtpSrvPort, LPCTSTR pSend ) { BOOL ret=true; CString To; To += GET_SAFE_STRING(lpszAddrTo); To += _T(";"); To += GET_SAFE_STRING(pStrAryCC); std::map<CString,std::vector<CString>> Address; int start = 0; while( start >= 0 ) { CString one= To.Tokenize(_T(";"),start); one=one.Trim(); if(one.IsEmpty()) continue; CString addr; addr = GetServerAddress(one); if(addr.IsEmpty()) continue; Address[addr].push_back(one); } std::map<CString,std::vector<CString>>::iterator itr1 = Address.begin(); for( ; itr1 != Address.end(); ++itr1 ) { PDNS_RECORD pDnsRecord; PDNS_RECORD pNext; DnsQuery(itr1->first , DNS_TYPE_MX,DNS_QUERY_STANDARD, NULL, //Contains DNS server IP address. &pDnsRecord, //Resource record that contains the response. NULL ); CString to; to.Empty(); for(int i=0;i<itr1->second.size();i++) { to+=itr1->second[i]; to+=_T(";"); } if(to.IsEmpty()) continue; pNext=pDnsRecord; while(pNext) { if(pNext->wType == DNS_TYPE_MX) if(SendEmail(pNext->Data.MX.pNameExchange,NULL,NULL,false, lpszAddrFrom,to,lpszSubject,lpszBody,lpszCharSet,pStrAryAttach,pStrAryCC, 25,pSend,lpszAddrTo)) break; pNext=pNext->pNext; } if(pNext == NULL) ret = false; //SendEmail(itr1.first,NULL,NULL,false,lpszAddrFrom,,lpszFromname); DnsRecordListFree(pDnsRecord,DnsFreeRecordList); } return ret; }
const char* conTCPObjectConnect(Linker::SimObject *obj, S32 argc, const char *argv[]) { if (sRunningTCPObjects.count(obj->mId) >= 1) TCPObject_Disconnect(sRunningTCPObjects[obj->mId].get()); DX::TCPObject *operand = new DX::TCPObject((unsigned int)obj); // Copy the hostname over char *desired_hostname = (char*)malloc(strlen(argv[2]) + 1); memcpy(desired_hostname, argv[2], strlen(argv[2]) + 1); // Create the connection info ConnectionInformation *connection = new ConnectionInformation; connection->target_hostname = desired_hostname; connection->buffer_length = 0; connection->is_connected = false; connection->socket = 0; // Hack: Store the Ptr to our connection information struct in the old unused state value operand->state = (unsigned int)connection; //ConnectionInformation *connection = (ConnectionInformation*)parameters; char *target_hostname = strlwr(connection->target_hostname); // Is it an IP we got? if (strstr(target_hostname, "ip:")) target_hostname += 3; // Chop off the 'ip:' segment // Did we get a port #? unsigned int desired_port = 0; char *port_delineator = strstr(target_hostname, ":"); if (port_delineator) { port_delineator[0] = 0x00; // NULL Terminate the IP Segment port_delineator += 1; desired_port = atoi(port_delineator); } else { Con::errorf(0, "No Port"); operand->CallMethod("onConnectFailed", 1, S32ToCharPtr(1)); return "NO_PORT"; } // Perform a DNS Lookup wchar_t hostname_dns[128]; std::mbstowcs(hostname_dns, target_hostname, strlen(target_hostname) + 1); PDNS_RECORD dns_record; if (DnsQuery(hostname_dns, DNS_TYPE_A, DNS_QUERY_BYPASS_CACHE, NULL, &dns_record, NULL)) { Con::errorf(0, "DNS Resolution Failed"); operand->CallMethod("onDNSFailed", 0); return "FAILED_DNS"; } IN_ADDR result_address; result_address.S_un.S_addr = dns_record->Data.A.IpAddress; DNS_FREE_TYPE freetype; DnsRecordListFree(dns_record, freetype); target_hostname = inet_ntoa(result_address); SOCKADDR_IN target_host; target_host.sin_family = AF_INET; target_host.sin_port = htons(desired_port); target_host.sin_addr.s_addr = inet_addr(target_hostname); Con::errorf(0, "Target %s on port %u SimID %u", target_hostname, desired_port, operand->identifier); // Create the Socket connection->socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (connection->socket == INVALID_SOCKET) { Con::errorf(0, "Failed to create Socket!"); operand->CallMethod("onConnectFailed", 2, S32ToCharPtr(2), S32ToCharPtr(WSAGetLastError())); return "FAILED_SOCKET_CREATION"; } // Set Blocking Mode (a non-zero for imode = non-blocking) u_long imode = 1; ioctlsocket(connection->socket, FIONBIO, &imode); sRunningTCPObjects[obj->mId] = std::unique_ptr<DX::TCPObject>(operand); // Attempt the Connection connect(connection->socket, (SOCKADDR*)&target_host, sizeof(target_host)); if (getsockopt(connection->socket, SOL_SOCKET, SO_ERROR, NULL, NULL) < 0) { operand->CallMethod("onConnectFailed", 2, S32ToCharPtr(3), S32ToCharPtr(WSAGetLastError())); return "CANNOT_CONNECT"; } else { operand->CallMethod("onConnected", 0); return "SUCCESS"; } return "UNKNOWN_ERROR"; }
static int dns_query(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result, int short_answer) { #if defined(HAVE_RES_QUERY) || defined(_WINDOWS) size_t offset = 0; int res, type, retrans, retry, i, ret = SYSINFO_RET_FAIL; char ip[MAX_STRING_LEN], zone[MAX_STRING_LEN], tmp[MAX_STRING_LEN], buffer[MAX_STRING_LEN]; struct in_addr inaddr; #ifndef _WINDOWS int saved_nscount, saved_retrans, saved_retry; struct sockaddr_in saved_ns; #endif typedef struct { char *name; int type; } resolv_querytype_t; static const resolv_querytype_t qt[] = { {"ANY", T_ANY}, {"A", T_A}, {"NS", T_NS}, {"MD", T_MD}, {"MF", T_MF}, {"CNAME", T_CNAME}, {"SOA", T_SOA}, {"MB", T_MB}, {"MG", T_MG}, {"MR", T_MR}, {"NULL", T_NULL}, #ifndef _WINDOWS {"WKS", T_WKS}, #endif {"PTR", T_PTR}, {"HINFO", T_HINFO}, {"MINFO", T_MINFO}, {"MX", T_MX}, {"TXT", T_TXT}, {"SRV", T_SRV}, {NULL} }; #ifdef _WINDOWS PDNS_RECORD pQueryResults, pDnsRecord; LPTSTR wzone; char tmp2[MAX_STRING_LEN]; #else char *name; unsigned char *msg_end, *msg_ptr, *p; int num_answers, num_query, q_type, q_class, q_len, value, c, n; struct servent *s; HEADER *hp; struct protoent *pr; #if PACKETSZ > 1024 unsigned char buf[PACKETSZ]; #else unsigned char buf[1024]; #endif typedef union { HEADER h; #if defined(NS_PACKETSZ) unsigned char buffer[NS_PACKETSZ]; #elif defined(PACKETSZ) unsigned char buffer[PACKETSZ]; #else unsigned char buffer[512]; #endif } answer_t; answer_t answer; #endif /* _WINDOWS */ *buffer = '\0'; if (5 < num_param(param)) return SYSINFO_RET_FAIL; if (0 != get_param(param, 1, ip, sizeof(ip))) *ip = '\0'; if (0 != get_param(param, 2, zone, sizeof(zone)) || '\0' == *zone) strscpy(zone, "zabbix.com"); if (0 != get_param(param, 3, tmp, sizeof(tmp)) || '\0' == *tmp) type = T_SOA; else { for (i = 0; NULL != qt[i].name; i++) { #ifdef _WINDOWS if (0 == lstrcmpiA(qt[i].name, tmp)) #else if (0 == strcasecmp(qt[i].name, tmp)) #endif { type = qt[i].type; break; } } if (NULL == qt[i].name) return SYSINFO_RET_FAIL; } if (0 != get_param(param, 4, tmp, sizeof(tmp)) || '\0' == *tmp) retrans = 1; else retrans = atoi(tmp); if (0 != get_param(param, 5, tmp, sizeof(tmp)) || '\0' == *tmp) retry = 2; else retry = atoi(tmp); #ifdef _WINDOWS wzone = zbx_utf8_to_unicode(zone); res = DnsQuery(wzone, type, DNS_QUERY_STANDARD, NULL, &pQueryResults, NULL); zbx_free(wzone); if (1 == short_answer) { SET_UI64_RESULT(result, DNS_RCODE_NOERROR != res ? 0 : 1); ret = SYSINFO_RET_OK; goto clean; } if (DNS_RCODE_NOERROR != res) return SYSINFO_RET_FAIL; pDnsRecord = pQueryResults; while (NULL != pDnsRecord) { if (DnsSectionAnswer != pDnsRecord->Flags.S.Section) { pDnsRecord = pDnsRecord->pNext; continue; } if (NULL == pDnsRecord->pName) goto clean; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%-20s", zbx_unicode_to_utf8_static(pDnsRecord->pName, tmp, sizeof(tmp))); offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %-8s", decode_type(pDnsRecord->wType)); switch (pDnsRecord->wType) { case T_A: inaddr.s_addr = pDnsRecord->Data.A.IpAddress; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", inet_ntoa(inaddr)); break; case T_NS: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.NS.pNameHost, tmp, sizeof(tmp))); break; case T_MD: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MD.pNameHost, tmp, sizeof(tmp))); break; case T_MF: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MF.pNameHost, tmp, sizeof(tmp))); break; case T_CNAME: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.CNAME.pNameHost, tmp, sizeof(tmp))); break; case T_SOA: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s %s %lu %lu %lu %lu %lu", zbx_unicode_to_utf8_static(pDnsRecord->Data.SOA.pNamePrimaryServer, tmp, sizeof(tmp)), zbx_unicode_to_utf8_static(pDnsRecord->Data.SOA.pNameAdministrator, tmp2, sizeof(tmp2)), pDnsRecord->Data.SOA.dwSerialNo, pDnsRecord->Data.SOA.dwRefresh, pDnsRecord->Data.SOA.dwRetry, pDnsRecord->Data.SOA.dwExpire, pDnsRecord->Data.SOA.dwDefaultTtl); break; case T_MB: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MB.pNameHost, tmp, sizeof(tmp))); break; case T_MG: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MG.pNameHost, tmp, sizeof(tmp))); break; case T_MR: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MR.pNameHost, tmp, sizeof(tmp))); break; case T_NULL: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " len:%lu", pDnsRecord->Data.Null.dwByteCount); break; case T_PTR: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.PTR.pNameHost, tmp, sizeof(tmp))); break; case T_HINFO: for (i = 0; i < (int)(pDnsRecord->Data.HINFO.dwStringCount); i++) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"%s\"", zbx_unicode_to_utf8_static(pDnsRecord->Data.HINFO.pStringArray[i], tmp, sizeof(tmp))); break; case T_MINFO: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MINFO.pNameMailbox, tmp, sizeof(tmp)), zbx_unicode_to_utf8_static(pDnsRecord->Data.MINFO.pNameErrorsMailbox, tmp2, sizeof(tmp2))); break; case T_MX: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %hu %s", pDnsRecord->Data.MX.wPreference, zbx_unicode_to_utf8_static(pDnsRecord->Data.MX.pNameExchange, tmp, sizeof(tmp))); break; case T_TXT: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \""); for (i = 0; i < (int)(pDnsRecord->Data.TXT.dwStringCount); i++) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%s ", zbx_unicode_to_utf8_static(pDnsRecord->Data.TXT.pStringArray[i], tmp, sizeof(tmp))); if (0 < i) offset -= 1; /* remove the trailing space */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\""); break; case T_SRV: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %hu %hu %hu %s", pDnsRecord->Data.SRV.wPriority, pDnsRecord->Data.SRV.wWeight, pDnsRecord->Data.SRV.wPort, zbx_unicode_to_utf8_static(pDnsRecord->Data.SRV.pNameTarget, tmp, sizeof(tmp))); break; default: break; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\n"); pDnsRecord = pDnsRecord->pNext; } #else /* not _WINDOWS */ if (-1 == res_init()) /* initialize always, settings might have changed */ return SYSINFO_RET_FAIL; if (-1 == (res = res_mkquery(QUERY, zone, C_IN, type, NULL, 0, NULL, buf, sizeof(buf)))) return SYSINFO_RET_FAIL; if ('\0' != *ip) { if (0 == inet_aton(ip, &inaddr)) return SYSINFO_RET_FAIL; memcpy(&saved_ns, &(_res.nsaddr_list[0]), sizeof(struct sockaddr_in)); saved_nscount = _res.nscount; _res.nsaddr_list[0].sin_addr = inaddr; _res.nsaddr_list[0].sin_family = AF_INET; _res.nsaddr_list[0].sin_port = htons(ZBX_DEFAULT_DNS_PORT); _res.nscount = 1; } saved_retrans = _res.retrans; saved_retry = _res.retry; _res.retrans = retrans; _res.retry = retry; res = res_send(buf, res, answer.buffer, sizeof(answer.buffer)); _res.retrans = saved_retrans; _res.retry = saved_retry; if ('\0' != *ip) { memcpy(&(_res.nsaddr_list[0]), &saved_ns, sizeof(struct sockaddr_in)); _res.nscount = saved_nscount; } hp = (HEADER *)answer.buffer; if (1 == short_answer) { SET_UI64_RESULT(result, NOERROR != hp->rcode || 0 == ntohs(hp->ancount) || -1 == res ? 0 : 1); return SYSINFO_RET_OK; } if (NOERROR != hp->rcode || 0 == ntohs(hp->ancount) || -1 == res) return SYSINFO_RET_FAIL; msg_end = answer.buffer + res; num_answers = ntohs(answer.h.ancount); num_query = ntohs(answer.h.qdcount); msg_ptr = answer.buffer + HFIXEDSZ; /* skipping query records */ for (; 0 < num_query && msg_ptr < msg_end; num_query--) msg_ptr += dn_skipname(msg_ptr, msg_end) + QFIXEDSZ; for (; 0 < num_answers && msg_ptr < msg_end; num_answers--) { if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) return SYSINFO_RET_FAIL; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%-20s", name); GETSHORT(q_type, msg_ptr); GETSHORT(q_class, msg_ptr); msg_ptr += INT32SZ; /* skipping TTL */ GETSHORT(q_len, msg_ptr); offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %-8s", decode_type(q_type)); switch (q_type) { case T_A: switch (q_class) { case C_IN: case C_HS: memcpy(&inaddr, msg_ptr, INADDRSZ); offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", inet_ntoa(inaddr)); break; default: ; } msg_ptr += q_len; break; case T_NS: case T_CNAME: case T_MB: case T_MD: case T_MF: case T_MG: case T_MR: case T_PTR: if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) return SYSINFO_RET_FAIL; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); break; case T_MX: GETSHORT(value, msg_ptr); /* preference */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* exchange */ return SYSINFO_RET_FAIL; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); break; case T_SOA: if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* source host */ return SYSINFO_RET_FAIL; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* administrator */ return SYSINFO_RET_FAIL; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); GETLONG(value, msg_ptr); /* serial number */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETLONG(value, msg_ptr); /* refresh time */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETLONG(value, msg_ptr); /* retry time */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETLONG(value, msg_ptr); /* expire time */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETLONG(value, msg_ptr); /* minimum TTL */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); break; case T_NULL: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " len:%d", q_len); msg_ptr += q_len; break; case T_WKS: if (INT32SZ + 1 > q_len) return SYSINFO_RET_FAIL; p = msg_ptr + q_len; memcpy(&inaddr, msg_ptr, INADDRSZ); msg_ptr += INT32SZ; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", inet_ntoa(inaddr)); if (NULL != (pr = getprotobynumber(*msg_ptr))) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", pr->p_name); else offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", (int)*msg_ptr); msg_ptr++; n = 0; while (msg_ptr < p) { c = *msg_ptr++; do { if (0 != (c & 0200)) { s = getservbyport((int)htons(n), pr ? pr->p_name : NULL); if (NULL != s) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", s->s_name); else offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " #%d", n); } c <<= 1; } while (0 != (++n & 07)); } break; case T_HINFO: p = msg_ptr + q_len; c = *msg_ptr++; if (0 != c) { offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"%.*s\"", c, msg_ptr); msg_ptr += c; } if (msg_ptr < p) { c = *msg_ptr++; if (0 != c) { offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"%.*s\"", c, msg_ptr); msg_ptr += c; } } break; case T_MINFO: if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* mailbox responsible for mailing lists */ return SYSINFO_RET_FAIL; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* mailbox for error messages */ return SYSINFO_RET_FAIL; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); break; case T_TXT: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \""); p = msg_ptr + q_len; while (msg_ptr < p) { for (c = *msg_ptr++; 0 < c && msg_ptr < p; c--) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%c", *msg_ptr++); } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\""); break; case T_SRV: GETSHORT(value, msg_ptr); /* priority */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETSHORT(value, msg_ptr); /* weight */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETSHORT(value, msg_ptr); /* port */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* target */ return SYSINFO_RET_FAIL; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); break; default: msg_ptr += q_len; break; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\n"); } #endif /* _WINDOWS */ if (0 != offset) buffer[--offset] = '\0'; SET_TEXT_RESULT(result, zbx_strdup(NULL, buffer)); ret = SYSINFO_RET_OK; #ifdef _WINDOWS clean: if (DNS_RCODE_NOERROR == res) DnsRecordListFree(pQueryResults, DnsFreeRecordList); #endif return ret; #else /* both HAVE_RES_QUERY and _WINDOWS not defined */ return SYSINFO_RET_FAIL; #endif /* defined(HAVE_RES_QUERY) || defined(_WINDOWS) */ }
/* we always return a null-terminated string which has been malloc'ed. The string * is always in the tag=value form. If a temporary or permanent error occurs, * the string will be exactly "e=perm;" or "e=temp;". * Note that it never returns NULL. */ char *dns_text(char *dn) { // added by nhatier for compilation under MSVC #ifdef _MSC_VER DNS_RECORD * l_Records = NULL; DNS_STATUS l_Result = DnsQuery(dn, DNS_TYPE_TEXT, DNS_QUERY_STANDARD, NULL, &l_Records, NULL); if (l_Result == ERROR_SUCCESS) { if (l_Records->wType == DNS_TYPE_TEXT) { unsigned int i; char buf[4096]; buf[0] = 0; for (i = 0; i < l_Records->Data.TXT.dwStringCount; i++) { strcat(buf, l_Records->Data.TXT.pStringArray[i]); } DnsRecordListFree(l_Records, DnsFreeRecordList); return dk_strdup(buf); } else { DnsRecordListFree(l_Records, DnsFreeRecordList); return dk_strdup("e=perm;"); } } else if (l_Result == DNS_ERROR_RECORD_TIMED_OUT) { DnsRecordListFree(l_Records, DnsFreeRecordList); return dk_strdup("e=temp;"); } else { DnsRecordListFree(l_Records, DnsFreeRecordList); return dk_strdup("e=perm;"); } #else //end added by nhatier u_char response[PACKETSZ+1]; /* response */ int responselen; /* buffer length */ int i, rc; /* misc variables */ int ancount, qdcount; /* answer count and query count */ u_short type, rdlength; /* fields of records returned */ u_char *eom, *cp; u_char buf[PACKETSZ+1]; /* we're storing a TXT record here, not just a DNAME */ u_char *bufptr; responselen = res_query(dn, C_IN, T_TXT, response, sizeof(response)); if (responselen < 0){ if (h_errno == TRY_AGAIN) return dk_strdup("e=temp;"); else return dk_strdup("e=perm;"); } qdcount = getshort( response + 4); /* http://crynwr.com/rfc1035/rfc1035.html#4.1.1. */ ancount = getshort( response + 6); eom = response + responselen; cp = response + HFIXEDSZ; while( qdcount-- > 0 && cp < eom ) { rc = dn_expand( response, eom, cp, (char *)buf, MAXDNAME ); if( rc < 0 ) { return dk_strdup("e=perm;"); } cp += rc + QFIXEDSZ; } while( ancount-- > 0 && cp < eom ) { rc = dn_expand( response, eom, cp, (char *)buf, MAXDNAME ); if( rc < 0 ) { return dk_strdup("e=perm;"); } cp += rc; if (cp + RRFIXEDSZ >= eom) return dk_strdup("e=perm;"); type = getshort(cp + 0); /* http://crynwr.com/rfc1035/rfc1035.html#4.1.3. */ rdlength = getshort(cp + 8); cp += RRFIXEDSZ; if( type != T_TXT ) { cp += rdlength; continue; } bufptr = buf; while (rdlength && cp < eom) { int cnt; cnt = *cp++; /* http://crynwr.com/rfc1035/rfc1035.html#3.3.14. */ if( bufptr-buf + cnt + 1 >= PACKETSZ ) return dk_strdup("e=perm;"); if (cp + cnt > eom) return dk_strdup("e=perm;"); memcpy( bufptr, cp, cnt); rdlength -= cnt + 1; bufptr += cnt; cp += cnt; *bufptr = '\0'; } return (char *) dk_strdup( buf ); } return dk_strdup("e=perm;"); #endif }
void PlatformDomainNameServiceQuery::runBlocking() { if (!serviceValid) { emitError(); return; } SWIFT_LOG(debug) << "Querying " << service << std::endl; std::vector<DomainNameServiceQuery::Result> records; #if defined(SWIFTEN_PLATFORM_WINDOWS) DNS_RECORD* responses; // FIXME: This conversion doesn't work if unicode is deffed above if (DnsQuery(service.c_str(), DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &responses, NULL) != ERROR_SUCCESS) { emitError(); return; } DNS_RECORD* currentEntry = responses; while (currentEntry) { if (currentEntry->wType == DNS_TYPE_SRV) { DomainNameServiceQuery::Result record; record.priority = currentEntry->Data.SRV.wPriority; record.weight = currentEntry->Data.SRV.wWeight; record.port = currentEntry->Data.SRV.wPort; // The pNameTarget is actually a PCWSTR, so I would have expected this // conversion to not work at all, but it does. // Actually, it doesn't. Fix this and remove explicit cast // Remove unicode undef above as well record.hostname = std::string((const char*) currentEntry->Data.SRV.pNameTarget); records.push_back(record); } currentEntry = currentEntry->pNext; } DnsRecordListFree(responses, DnsFreeRecordList); #else // Make sure we reinitialize the domain list every time res_init(); ByteArray response; response.resize(NS_PACKETSZ); int responseLength = res_query(const_cast<char*>(service.c_str()), ns_c_in, ns_t_srv, reinterpret_cast<u_char*>(vecptr(response)), response.size()); if (responseLength == -1) { SWIFT_LOG(debug) << "Error" << std::endl; emitError(); return; } // Parse header HEADER* header = reinterpret_cast<HEADER*>(vecptr(response)); unsigned char* messageStart = vecptr(response); unsigned char* messageEnd = messageStart + responseLength; unsigned char* currentEntry = messageStart + NS_HFIXEDSZ; // Skip over the queries int queriesCount = ntohs(header->qdcount); while (queriesCount > 0) { int entryLength = dn_skipname(currentEntry, messageEnd); if (entryLength < 0) { emitError(); return; } currentEntry += entryLength + NS_QFIXEDSZ; queriesCount--; } // Process the SRV answers int answersCount = ntohs(header->ancount); while (answersCount > 0) { DomainNameServiceQuery::Result record; int entryLength = dn_skipname(currentEntry, messageEnd); currentEntry += entryLength; currentEntry += NS_RRFIXEDSZ; // Priority if (currentEntry + 2 >= messageEnd) { emitError(); return; } record.priority = boost::numeric_cast<int>(ns_get16(currentEntry)); currentEntry += 2; // Weight if (currentEntry + 2 >= messageEnd) { emitError(); return; } record.weight = boost::numeric_cast<int>(ns_get16(currentEntry)); currentEntry += 2; // Port if (currentEntry + 2 >= messageEnd) { emitError(); return; } record.port = boost::numeric_cast<int>(ns_get16(currentEntry)); currentEntry += 2; // Hostname if (currentEntry >= messageEnd) { emitError(); return; } ByteArray entry; entry.resize(NS_MAXDNAME); entryLength = dn_expand(messageStart, messageEnd, currentEntry, reinterpret_cast<char*>(vecptr(entry)), entry.size()); if (entryLength < 0) { emitError(); return; } record.hostname = std::string(reinterpret_cast<const char*>(vecptr(entry))); records.push_back(record); currentEntry += entryLength; answersCount--; } #endif BoostRandomGenerator generator; DomainNameServiceQuery::sortResults(records, generator); //std::cout << "Sending out " << records.size() << " SRV results " << std::endl; eventLoop->postEvent(boost::bind(boost::ref(onResult), records), shared_from_this()); }
bool DNSResolver::Resolve_(const String &sSearchFor, std::vector<String> &vecFoundNames, WORD wType, int iRecursion) { if (iRecursion > 10) { String sMessage = Formatter::Format("Too many recursions during query. Query: {0}, Type: {1}", sSearchFor, wType); ErrorManager::Instance()->ReportError(ErrorManager::Low, 4401, "DNSResolver::Resolve_", sMessage); return false; } PDNS_RECORD pDnsRecord = NULL; PIP4_ARRAY pSrvList = NULL; DWORD fOptions = DNS_QUERY_STANDARD; DNS_STATUS nDnsStatus = DnsQuery(sSearchFor, wType, fOptions, NULL, &pDnsRecord, NULL); PDNS_RECORD pDnsRecordsToDelete = pDnsRecord; if (nDnsStatus != 0) { if (pDnsRecordsToDelete) _FreeDNSRecord(pDnsRecordsToDelete); bool bDNSError = IsDNSError_(nDnsStatus); if (bDNSError) { String sMessage; sMessage.Format(_T("DNS - Query failure. Query: %s, Type: %d, DnsQuery return value: %d."), sSearchFor.c_str(), wType, nDnsStatus); LOG_TCPIP(sMessage); return false; } return true; } std::vector<DnsRecordWithPreference> foundDnsRecordsWithPreference; do { switch (pDnsRecord->wType) { case DNS_TYPE_A: { SOCKADDR_IN addr; memset(&addr, 0, sizeof addr); addr.sin_family = AF_INET; addr.sin_addr = *((in_addr*)&(pDnsRecord->Data.AAAA.Ip6Address)); char buf[128]; DWORD bufSize = sizeof(buf); if (WSAAddressToStringA((sockaddr*)&addr, sizeof addr, NULL, buf, &bufSize) == 0) { DnsRecordWithPreference rec(0, buf); foundDnsRecordsWithPreference.push_back(rec); } break; } case DNS_TYPE_AAAA: { SOCKADDR_IN6 addr; memset(&addr, 0, sizeof addr); addr.sin6_family = AF_INET6; addr.sin6_addr = *((in_addr6*)&(pDnsRecord->Data.AAAA.Ip6Address)); char buf[128]; DWORD bufSize = sizeof(buf); if (WSAAddressToStringA((sockaddr*)&addr, sizeof addr, NULL, buf, &bufSize) == 0) { DnsRecordWithPreference rec(0, buf); foundDnsRecordsWithPreference.push_back(rec); } break; } case DNS_TYPE_CNAME: { String sDomainName = pDnsRecord->Data.CNAME.pNameHost; if (!Resolve_(sDomainName, vecFoundNames, wType, iRecursion+1)) return false; break; } case DNS_TYPE_MX: { String sName = pDnsRecord->pName; bool bNameMatches = (sName.CompareNoCase(sSearchFor) == 0); if (pDnsRecord->Flags.S.Section == DNSREC_ANSWER && bNameMatches) { DnsRecordWithPreference rec(pDnsRecord->Data.MX.wPreference, pDnsRecord->Data.MX.pNameExchange); foundDnsRecordsWithPreference.push_back(rec); } break; } case DNS_TYPE_TEXT: { AnsiString retVal; for (u_int i = 0; i < pDnsRecord->Data.TXT.dwStringCount; i++) retVal += pDnsRecord->Data.TXT.pStringArray[i]; DnsRecordWithPreference rec (0, retVal); foundDnsRecordsWithPreference.push_back(rec); break; } case DNS_TYPE_PTR: { AnsiString retVal; retVal = pDnsRecord->Data.PTR.pNameHost; DnsRecordWithPreference rec(0, retVal); foundDnsRecordsWithPreference.push_back(rec); break; } default: { ErrorManager::Instance()->ReportError(ErrorManager::Medium, 5036, "DNSResolver::Resolve_", Formatter::Format("Queried for {0} but received type {1}", wType, pDnsRecord->wType)); break; } } pDnsRecord = pDnsRecord->pNext; } while (pDnsRecord != nullptr); std::sort(foundDnsRecordsWithPreference.begin(), foundDnsRecordsWithPreference.end(), SortDnsRecordWithPreference); for (DnsRecordWithPreference item : foundDnsRecordsWithPreference) { vecFoundNames.push_back(item.Value); } _FreeDNSRecord(pDnsRecordsToDelete); pDnsRecordsToDelete = 0; return true; }
static int dns_query(AGENT_REQUEST *request, AGENT_RESULT *result, int short_answer) { #if defined(HAVE_RES_QUERY) || defined(_WINDOWS) size_t offset = 0; int res, type, retrans, retry, use_tcp, i, ret = SYSINFO_RET_FAIL, ip_type = AF_INET; char *ip, zone[MAX_STRING_LEN], buffer[MAX_STRING_LEN], *zone_str, *param, tmp[MAX_STRING_LEN]; struct in_addr inaddr; struct in6_addr in6addr; #ifndef _WINDOWS #if defined(HAVE_RES_NINIT) && !defined(_AIX) /* It seems that on some AIX systems with no updates installed res_ninit() can */ /* corrupt stack (see ZBX-14559). Use res_init() on AIX. */ struct __res_state res_state_local; #else /* thread-unsafe resolver API */ int saved_retrans, saved_retry, saved_nscount = 0; unsigned long saved_options; struct sockaddr_in saved_ns; # if defined(HAVE_RES_U_EXT) /* thread-unsafe resolver API /Linux/ */ int save_nssocks, saved_nscount6; # endif #endif #if defined(HAVE_RES_EXT_EXT) /* AIX */ union res_sockaddr_union saved_ns6; #elif defined(HAVE_RES_U_EXT_EXT) /* BSD */ struct sockaddr_in6 saved_ns6; #else struct sockaddr_in6 *saved_ns6; #endif struct sockaddr_in6 sockaddrin6; struct addrinfo hint, *hres = NULL; #endif typedef struct { const char *name; int type; } resolv_querytype_t; static const resolv_querytype_t qt[] = { {"ANY", T_ANY}, {"A", T_A}, {"AAAA", T_AAAA}, {"NS", T_NS}, {"MD", T_MD}, {"MF", T_MF}, {"CNAME", T_CNAME}, {"SOA", T_SOA}, {"MB", T_MB}, {"MG", T_MG}, {"MR", T_MR}, {"NULL", T_NULL}, #ifndef _WINDOWS {"WKS", T_WKS}, #endif {"PTR", T_PTR}, {"HINFO", T_HINFO}, {"MINFO", T_MINFO}, {"MX", T_MX}, {"TXT", T_TXT}, {"SRV", T_SRV}, {NULL} }; #ifdef _WINDOWS PDNS_RECORD pQueryResults, pDnsRecord; wchar_t *wzone; char tmp2[MAX_STRING_LEN]; DWORD options; #else char *name; unsigned char *msg_end, *msg_ptr, *p; int num_answers, num_query, q_type, q_class, q_len, value, c, n; struct servent *s; HEADER *hp; struct protoent *pr; #if PACKETSZ > 1024 unsigned char buf[PACKETSZ]; #else unsigned char buf[1024]; #endif typedef union { HEADER h; #if defined(NS_PACKETSZ) unsigned char buffer[NS_PACKETSZ]; #elif defined(PACKETSZ) unsigned char buffer[PACKETSZ]; #else unsigned char buffer[512]; #endif } answer_t; answer_t answer; #endif /* _WINDOWS */ zbx_vector_str_t answers; *buffer = '\0'; if (6 < request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); return SYSINFO_RET_FAIL; } ip = get_rparam(request, 0); zone_str = get_rparam(request, 1); #ifndef _WINDOWS memset(&hint, '\0', sizeof(hint)); hint.ai_family = PF_UNSPEC; hint.ai_flags = AI_NUMERICHOST; if (NULL != ip && '\0' != *ip && 0 == getaddrinfo(ip, NULL, &hint, &hres) && AF_INET6 == hres->ai_family) ip_type = hres->ai_family; if (NULL != hres) freeaddrinfo(hres); #endif if (NULL == zone_str || '\0' == *zone_str) strscpy(zone, "zabbix.com"); else strscpy(zone, zone_str); param = get_rparam(request, 2); if (NULL == param || '\0' == *param) type = T_SOA; else { for (i = 0; NULL != qt[i].name; i++) { if (0 == strcasecmp(qt[i].name, param)) { type = qt[i].type; break; } } if (NULL == qt[i].name) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); return SYSINFO_RET_FAIL; } } param = get_rparam(request, 3); if (NULL == param || '\0' == *param) retrans = 1; else if (SUCCEED != is_uint31(param, &retrans) || 0 == retrans) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid fourth parameter.")); return SYSINFO_RET_FAIL; } param = get_rparam(request, 4); if (NULL == param || '\0' == *param) retry = 2; else if (SUCCEED != is_uint31(param, &retry) || 0 == retry) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid fifth parameter.")); return SYSINFO_RET_FAIL; } param = get_rparam(request, 5); if (NULL == param || '\0' == *param || 0 == strcmp(param, "udp")) use_tcp = 0; else if (0 == strcmp(param, "tcp")) use_tcp = 1; else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid sixth parameter.")); return SYSINFO_RET_FAIL; } #ifdef _WINDOWS options = DNS_QUERY_STANDARD | DNS_QUERY_BYPASS_CACHE; if (0 != use_tcp) options |= DNS_QUERY_USE_TCP_ONLY; wzone = zbx_utf8_to_unicode(zone); res = DnsQuery(wzone, type, options, NULL, &pQueryResults, NULL); zbx_free(wzone); if (1 == short_answer) { SET_UI64_RESULT(result, DNS_RCODE_NOERROR != res ? 0 : 1); ret = SYSINFO_RET_OK; goto clean_dns; } if (DNS_RCODE_NOERROR != res) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot perform DNS query: [%d]", res)); return SYSINFO_RET_FAIL; } pDnsRecord = pQueryResults; zbx_vector_str_create(&answers); while (NULL != pDnsRecord) { if (DnsSectionAnswer != pDnsRecord->Flags.S.Section) { pDnsRecord = pDnsRecord->pNext; continue; } if (NULL == pDnsRecord->pName) goto clean; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%-20s", zbx_unicode_to_utf8_static(pDnsRecord->pName, tmp, sizeof(tmp))); offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %-8s", decode_type(pDnsRecord->wType)); switch (pDnsRecord->wType) { case T_A: inaddr.s_addr = pDnsRecord->Data.A.IpAddress; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", inet_ntoa(inaddr)); break; case T_AAAA: memcpy(&in6addr.s6_addr, &(pDnsRecord->Data.AAAA.Ip6Address), sizeof(in6addr.s6_addr)); offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_inet_ntop(AF_INET6, &in6addr, tmp, sizeof(tmp))); break; case T_NS: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.NS.pNameHost, tmp, sizeof(tmp))); break; case T_MD: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MD.pNameHost, tmp, sizeof(tmp))); break; case T_MF: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MF.pNameHost, tmp, sizeof(tmp))); break; case T_CNAME: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.CNAME.pNameHost, tmp, sizeof(tmp))); break; case T_SOA: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s %s %lu %lu %lu %lu %lu", zbx_unicode_to_utf8_static(pDnsRecord->Data.SOA.pNamePrimaryServer, tmp, sizeof(tmp)), zbx_unicode_to_utf8_static(pDnsRecord->Data.SOA.pNameAdministrator, tmp2, sizeof(tmp2)), pDnsRecord->Data.SOA.dwSerialNo, pDnsRecord->Data.SOA.dwRefresh, pDnsRecord->Data.SOA.dwRetry, pDnsRecord->Data.SOA.dwExpire, pDnsRecord->Data.SOA.dwDefaultTtl); break; case T_MB: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MB.pNameHost, tmp, sizeof(tmp))); break; case T_MG: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MG.pNameHost, tmp, sizeof(tmp))); break; case T_MR: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MR.pNameHost, tmp, sizeof(tmp))); break; case T_NULL: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " len:%lu", pDnsRecord->Data.Null.dwByteCount); break; case T_PTR: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.PTR.pNameHost, tmp, sizeof(tmp))); break; case T_HINFO: for (i = 0; i < (int)(pDnsRecord->Data.HINFO.dwStringCount); i++) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"%s\"", zbx_unicode_to_utf8_static(pDnsRecord->Data.HINFO.pStringArray[i], tmp, sizeof(tmp))); break; case T_MINFO: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MINFO.pNameMailbox, tmp, sizeof(tmp)), zbx_unicode_to_utf8_static(pDnsRecord->Data.MINFO.pNameErrorsMailbox, tmp2, sizeof(tmp2))); break; case T_MX: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %hu %s", pDnsRecord->Data.MX.wPreference, zbx_unicode_to_utf8_static(pDnsRecord->Data.MX.pNameExchange, tmp, sizeof(tmp))); break; case T_TXT: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \""); for (i = 0; i < (int)(pDnsRecord->Data.TXT.dwStringCount); i++) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%s ", zbx_unicode_to_utf8_static(pDnsRecord->Data.TXT.pStringArray[i], tmp, sizeof(tmp))); if (0 < i) offset -= 1; /* remove the trailing space */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\""); break; case T_SRV: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %hu %hu %hu %s", pDnsRecord->Data.SRV.wPriority, pDnsRecord->Data.SRV.wWeight, pDnsRecord->Data.SRV.wPort, zbx_unicode_to_utf8_static(pDnsRecord->Data.SRV.pNameTarget, tmp, sizeof(tmp))); break; default: break; } zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\n"); pDnsRecord = pDnsRecord->pNext; zbx_vector_str_append(&answers, zbx_strdup(NULL, buffer)); offset = 0; *buffer = '\0'; } #else /* not _WINDOWS */ #if defined(HAVE_RES_NINIT) && !defined(_AIX) memset(&res_state_local, 0, sizeof(res_state_local)); if (-1 == res_ninit(&res_state_local)) /* initialize always, settings might have changed */ #else if (-1 == res_init()) /* initialize always, settings might have changed */ #endif { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot initialize DNS subsystem: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } #if defined(HAVE_RES_NINIT) && !defined(_AIX) if (-1 == (res = res_nmkquery(&res_state_local, QUERY, zone, C_IN, type, NULL, 0, NULL, buf, sizeof(buf)))) #else if (-1 == (res = res_mkquery(QUERY, zone, C_IN, type, NULL, 0, NULL, buf, sizeof(buf)))) #endif { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot create DNS query: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } if (NULL != ip && '\0' != *ip && AF_INET == ip_type) { if (0 == inet_aton(ip, &inaddr)) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid IP address.")); return SYSINFO_RET_FAIL; } #if defined(HAVE_RES_NINIT) && !defined(_AIX) res_state_local.nsaddr_list[0].sin_addr = inaddr; res_state_local.nsaddr_list[0].sin_family = AF_INET; res_state_local.nsaddr_list[0].sin_port = htons(ZBX_DEFAULT_DNS_PORT); res_state_local.nscount = 1; #else /* thread-unsafe resolver API */ memcpy(&saved_ns, &(_res.nsaddr_list[0]), sizeof(struct sockaddr_in)); saved_nscount = _res.nscount; _res.nsaddr_list[0].sin_addr = inaddr; _res.nsaddr_list[0].sin_family = AF_INET; _res.nsaddr_list[0].sin_port = htons(ZBX_DEFAULT_DNS_PORT); _res.nscount = 1; #endif } else if (NULL != ip && '\0' != *ip && AF_INET6 == ip_type) { if (0 == inet_pton(ip_type, ip, &in6addr)) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid IPv6 address.")); return SYSINFO_RET_FAIL; } memset(&sockaddrin6, '\0', sizeof(sockaddrin6)); #if defined(HAVE_RES_SIN6_LEN) sockaddrin6.sin6_len = sizeof(sockaddrin6); #endif sockaddrin6.sin6_family = AF_INET6; sockaddrin6.sin6_addr = in6addr; sockaddrin6.sin6_port = htons(ZBX_DEFAULT_DNS_PORT); #if defined(HAVE_RES_NINIT) && !defined(_AIX) && (defined(HAVE_RES_U_EXT) || defined(HAVE_RES_U_EXT_EXT)) memset(&res_state_local.nsaddr_list[0], '\0', sizeof(res_state_local.nsaddr_list[0])); # ifdef HAVE_RES_U_EXT /* Linux */ saved_ns6 = res_state_local._u._ext.nsaddrs[0]; res_state_local._u._ext.nsaddrs[0] = &sockaddrin6; res_state_local._u._ext.nssocks[0] = -1; res_state_local._u._ext.nscount6 = 1; /* CentOS */ # elif HAVE_RES_U_EXT_EXT /* BSD */ if (NULL != res_state_local._u._ext.ext) memcpy(res_state_local._u._ext.ext, &sockaddrin6, sizeof(sockaddrin6)); res_state_local.nsaddr_list[0].sin_port = htons(ZBX_DEFAULT_DNS_PORT); # endif res_state_local.nscount = 1; #else memcpy(&saved_ns, &(_res.nsaddr_list[0]), sizeof(struct sockaddr_in)); saved_nscount = _res.nscount; # if defined(HAVE_RES_U_EXT) || defined(HAVE_RES_U_EXT_EXT) || defined(HAVE_RES_EXT_EXT) memset(&_res.nsaddr_list[0], '\0', sizeof(_res.nsaddr_list[0])); _res.nscount = 1; # endif # if defined(HAVE_RES_U_EXT) /* thread-unsafe resolver API /Linux/ */ saved_nscount6 = _res._u._ext.nscount6; saved_ns6 = _res._u._ext.nsaddrs[0]; save_nssocks = _res._u._ext.nssocks[0]; _res._u._ext.nsaddrs[0] = &sockaddrin6; _res._u._ext.nssocks[0] = -1; _res._u._ext.nscount6 = 1; # elif defined(HAVE_RES_U_EXT_EXT) /* thread-unsafe resolver API /BSD/ */ memcpy(&saved_ns6, _res._u._ext.ext, sizeof(saved_ns6)); _res.nsaddr_list[0].sin_port = htons(ZBX_DEFAULT_DNS_PORT); if (NULL != _res._u._ext.ext) memcpy(_res._u._ext.ext, &sockaddrin6, sizeof(sockaddrin6)); # elif defined(HAVE_RES_EXT_EXT) /* thread-unsafe resolver API /AIX/ */ memcpy(&saved_ns6, &(_res._ext.ext.nsaddrs[0]), sizeof(saved_ns6)); memcpy(&_res._ext.ext.nsaddrs[0], &sockaddrin6, sizeof(sockaddrin6)); # endif /* #if defined(HAVE_RES_U_EXT) */ #endif /* #if defined(HAVE_RES_NINIT) && !defined(_AIX) && (defined(HAVE_RES_U_EXT) || defined(HAVE_RES_U_EXT_EXT)) */ } #if defined(HAVE_RES_NINIT) && !defined(_AIX) && (defined(HAVE_RES_U_EXT) || defined(HAVE_RES_U_EXT_EXT)) if (0 != use_tcp) res_state_local.options |= RES_USEVC; res_state_local.retrans = retrans; res_state_local.retry = retry; res = res_nsend(&res_state_local, buf, res, answer.buffer, sizeof(answer.buffer)); # ifdef HAVE_RES_U_EXT /* Linux */ if (NULL != ip && '\0' != *ip && AF_INET6 == ip_type) res_state_local._u._ext.nsaddrs[0] = saved_ns6; # endif # ifdef HAVE_RES_NDESTROY res_ndestroy(&res_state_local); # else res_nclose(&res_state_local); # endif #else /* thread-unsafe resolver API */ saved_options = _res.options; saved_retrans = _res.retrans; saved_retry = _res.retry; if (0 != use_tcp) _res.options |= RES_USEVC; _res.retrans = retrans; _res.retry = retry; res = res_send(buf, res, answer.buffer, sizeof(answer.buffer)); _res.options = saved_options; _res.retrans = saved_retrans; _res.retry = saved_retry; if (NULL != ip && '\0' != *ip) { if (AF_INET6 == ip_type) { # if defined(HAVE_RES_U_EXT) /* Linux */ _res._u._ext.nsaddrs[0] = saved_ns6; _res._u._ext.nssocks[0] = save_nssocks; _res._u._ext.nscount6 = saved_nscount6; # elif defined(HAVE_RES_U_EXT_EXT) /* BSD */ if (NULL != _res._u._ext.ext) memcpy(_res._u._ext.ext, &saved_ns6, sizeof(saved_ns6)); # elif defined(HAVE_RES_EXT_EXT) /* AIX */ memcpy(&_res._ext.ext.nsaddrs[0], &saved_ns6, sizeof(saved_ns6)); # endif } memcpy(&(_res.nsaddr_list[0]), &saved_ns, sizeof(struct sockaddr_in)); _res.nscount = saved_nscount; } #endif hp = (HEADER *)answer.buffer; if (1 == short_answer) { SET_UI64_RESULT(result, NOERROR != hp->rcode || 0 == ntohs(hp->ancount) || -1 == res ? 0 : 1); return SYSINFO_RET_OK; } if (NOERROR != hp->rcode || 0 == ntohs(hp->ancount) || -1 == res) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot perform DNS query.")); return SYSINFO_RET_FAIL; } msg_end = answer.buffer + res; num_answers = ntohs(answer.h.ancount); num_query = ntohs(answer.h.qdcount); msg_ptr = answer.buffer + HFIXEDSZ; zbx_vector_str_create(&answers); /* skipping query records */ for (; 0 < num_query && msg_ptr < msg_end; num_query--) msg_ptr += dn_skipname(msg_ptr, msg_end) + QFIXEDSZ; for (; 0 < num_answers && msg_ptr < msg_end; num_answers--) { if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); ret = SYSINFO_RET_FAIL; goto clean; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%-20s", name); GETSHORT(q_type, msg_ptr); GETSHORT(q_class, msg_ptr); msg_ptr += INT32SZ; /* skipping TTL */ GETSHORT(q_len, msg_ptr); offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %-8s", decode_type(q_type)); switch (q_type) { case T_A: switch (q_class) { case C_IN: case C_HS: memcpy(&inaddr, msg_ptr, INADDRSZ); offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", inet_ntoa(inaddr)); break; default: ; } msg_ptr += q_len; break; case T_AAAA: switch (q_class) { case C_IN: case C_HS: memcpy(&in6addr, msg_ptr, IN6ADDRSZ); offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", inet_ntop(AF_INET6, &in6addr, tmp, sizeof(tmp))); break; default: ; } msg_ptr += q_len; break; case T_NS: case T_CNAME: case T_MB: case T_MD: case T_MF: case T_MG: case T_MR: case T_PTR: if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); break; case T_MX: GETSHORT(value, msg_ptr); /* preference */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* exchange */ { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); break; case T_SOA: if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* source host */ { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* administrator */ { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); GETLONG(value, msg_ptr); /* serial number */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETLONG(value, msg_ptr); /* refresh time */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETLONG(value, msg_ptr); /* retry time */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETLONG(value, msg_ptr); /* expire time */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETLONG(value, msg_ptr); /* minimum TTL */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); break; case T_NULL: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " len:%d", q_len); msg_ptr += q_len; break; case T_WKS: if (INT32SZ + 1 > q_len) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } p = msg_ptr + q_len; memcpy(&inaddr, msg_ptr, INADDRSZ); msg_ptr += INT32SZ; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", inet_ntoa(inaddr)); if (NULL != (pr = getprotobynumber(*msg_ptr))) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", pr->p_name); else offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", (int)*msg_ptr); msg_ptr++; n = 0; while (msg_ptr < p) { c = *msg_ptr++; do { if (0 != (c & 0200)) { s = getservbyport((int)htons(n), pr ? pr->p_name : NULL); if (NULL != s) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", s->s_name); else offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " #%d", n); } c <<= 1; } while (0 != (++n & 07)); } break; case T_HINFO: p = msg_ptr + q_len; c = *msg_ptr++; if (0 != c) { offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"%.*s\"", c, msg_ptr); msg_ptr += c; } if (msg_ptr < p) { c = *msg_ptr++; if (0 != c) { offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"%.*s\"", c, msg_ptr); msg_ptr += c; } } break; case T_MINFO: if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* mailbox responsible for mailing lists */ { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* mailbox for error messages */ { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); break; case T_TXT: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \""); p = msg_ptr + q_len; while (msg_ptr < p) { for (c = *msg_ptr++; 0 < c && msg_ptr < p; c--) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%c", *msg_ptr++); } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\""); break; case T_SRV: GETSHORT(value, msg_ptr); /* priority */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETSHORT(value, msg_ptr); /* weight */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETSHORT(value, msg_ptr); /* port */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* target */ { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); break; default: msg_ptr += q_len; break; } zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\n"); zbx_vector_str_append(&answers, zbx_strdup(NULL, buffer)); offset = 0; *buffer = '\0'; } #endif /* _WINDOWS */ zbx_vector_str_sort(&answers, ZBX_DEFAULT_STR_COMPARE_FUNC); for (i = 0; i < answers.values_num; i++) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%s", answers.values[i]); if (0 != offset) buffer[--offset] = '\0'; SET_TEXT_RESULT(result, zbx_strdup(NULL, buffer)); ret = SYSINFO_RET_OK; clean: zbx_vector_str_clear_ext(&answers, zbx_str_free); zbx_vector_str_destroy(&answers); #ifdef _WINDOWS clean_dns: if (DNS_RCODE_NOERROR == res) DnsRecordListFree(pQueryResults, DnsFreeRecordList); #endif return ret; #else /* both HAVE_RES_QUERY and _WINDOWS not defined */ return SYSINFO_RET_FAIL; #endif /* defined(HAVE_RES_QUERY) || defined(_WINDOWS) */ }
int eXosip_get_srv_record(struct osip_srv_record *record, char *domain, char *protocol) { char zone[1024]; PDNS_RECORD answer, tmp; /* answer buffer from nameserver */ int n; char tr[100]; memset(zone, 0, sizeof(zone)); memset(record, 0, sizeof(struct osip_srv_record)); if (domain == NULL || protocol == NULL) return OSIP_BADPARAMETER; if (eXosip.dns_capabilities <= 0) return OSIP_UNKNOWN_HOST; /* disabled */ if (strlen(domain) + strlen(protocol) > 1000) return OSIP_BADPARAMETER; if (strlen(protocol) >= 100) return OSIP_BADPARAMETER; snprintf(tr, 100, protocol); osip_tolower(tr); if (eXosip.dns_capabilities >= 2) n = eXosip_get_naptr(domain, protocol, zone, sizeof(zone) - 1); else n = -1; /* avoid NAPTR */ if (n == OSIP_SUCCESS && zone[0] == '\0') { /* protocol is not listed in NAPTR answer: not supported */ return OSIP_UNKNOWN_HOST; } if (n != OSIP_SUCCESS) { if (osip_strcasecmp(tr, "TLS") == 0) snprintf(zone, sizeof(zone) - 1, "_sips._tcp.%s", domain); else if (osip_strcasecmp(tr, "DTLS") == 0) snprintf(zone, sizeof(zone) - 1, "_sips._udp.%s", domain); else snprintf(zone, sizeof(zone) - 1, "_sip._%s.%s", tr, domain); OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "Using locally generated SRV record %s\n", zone)); } OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "About to ask for '%s IN SRV'\n", zone)); if (DnsQuery(zone, DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &answer, NULL) != 0) { return OSIP_UNKNOWN_HOST; } n = 0; for (tmp = answer; tmp != NULL; tmp = tmp->pNext) { struct osip_srv_entry *srventry; DNS_SRV_DATA *data; if (tmp->wType != DNS_TYPE_SRV) continue; srventry = &record->srventry[n]; data = &tmp->Data.SRV; snprintf(srventry->srv, sizeof(srventry->srv), "%s", data->pNameTarget); srventry->priority = data->wPriority; srventry->weight = data->wWeight; if (srventry->weight) srventry->rweight = 1 + rand() % (10000 * srventry->weight); else srventry->rweight = 0; srventry->port = data->wPort; OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "SRV record %s IN SRV -> %s:%i/%i/%i/%i\n", zone, srventry->srv, srventry->port, srventry->priority, srventry->weight, srventry->rweight)); n++; if (n == 10) break; } DnsRecordListFree(answer, DnsFreeRecordList); if (n == 0) return OSIP_UNKNOWN_HOST; osip_srv_record_sort(record, n); snprintf(record->name, sizeof(record->name), "%s", domain); return OSIP_SUCCESS; }