1 //-----------------------------------------------------------------------------
2 //
3 //	DNSImpl.cpp
4 //
5 //	Unix DNS Lookup Routines.
6 //
7 //	Copyright (c) 2016 Justin Hammond <justin@dynam.ac>
8 //
9 //	SOFTWARE NOTICE AND LICENSE
10 //
11 //	This file is part of OpenZWave.
12 //
13 //	OpenZWave is free software: you can redistribute it and/or modify
14 //	it under the terms of the GNU Lesser General Public License as published
15 //	by the Free Software Foundation, either version 3 of the License,
16 //	or (at your option) any later version.
17 //
18 //	OpenZWave is distributed in the hope that it will be useful,
19 //	but WITHOUT ANY WARRANTY; without even the implied warranty of
20 //	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 //	GNU Lesser General Public License for more details.
22 //
23 //	You should have received a copy of the GNU Lesser General Public License
24 //	along with OpenZWave.  If not, see <http://www.gnu.org/licenses/>.
25 //
26 //-----------------------------------------------------------------------------
27 
28 #include <netinet/in.h>
29 #include <arpa/nameser.h>
30 #include <resolv.h>
31 #include <string.h>
32 #include <netdb.h>
33 
34 #include "DNSImpl.h"
35 
36 namespace OpenZWave
37 {
38 	namespace Internal
39 	{
40 		namespace Platform
41 		{
42 
DNSImpl()43 			DNSImpl::DNSImpl() :
44 					status(DNSError_None)
45 			{
46 				res_init();
47 			}
48 
~DNSImpl()49 			DNSImpl::~DNSImpl()
50 			{
51 
52 			}
53 
LookupTxT(string lookup,string & result)54 			bool DNSImpl::LookupTxT(string lookup, string &result)
55 			{
56 
57 				int response;
58 				unsigned char query_buffer[1024];
59 				ns_msg nsMsg;
60 				ns_rr rr;
61 				const unsigned char *p, *start;
62 				unsigned char l;
63 				int rrlen;
64 
65 				char outb[1025];
66 
67 #ifdef __APPLE_CC__
68 				response = res_query(lookup.c_str(), ns_c_in, ns_t_txt, query_buffer, sizeof(query_buffer));
69 #else
70 				response= res_query(lookup.c_str(), C_IN, ns_t_txt, query_buffer, sizeof(query_buffer));
71 #endif
72 				if (response < 0)
73 				{
74 					Log::Write(LogLevel_Warning, "Error looking up txt Record: %s - %s", lookup.c_str(), hstrerror(h_errno));
75 					switch (h_errno)
76 					{
77 						case HOST_NOT_FOUND:
78 							status = DNSError_NotFound;
79 							break;
80 						case NO_DATA:
81 							status = DNSError_NotFound;
82 							break;
83 						case NO_RECOVERY:
84 							status = DNSError_InternalError;
85 							break;
86 						case TRY_AGAIN:
87 							status = DNSError_InternalError;
88 							break;
89 						default:
90 							status = DNSError_InternalError;
91 							break;
92 
93 					}
94 					return false;
95 				}
96 
97 				ns_initparse(query_buffer, response, &nsMsg);
98 
99 				ns_parserr(&nsMsg, ns_s_an, 0, &rr);
100 
101 				p = start = ns_rr_rdata(rr);
102 				rrlen = ns_rr_rdlen(rr);
103 				if (rrlen > 1024)
104 				{
105 					status = DNSError_InternalError;
106 					return false;
107 				}
108 				while (p < start + rrlen)
109 				{
110 					l = *p;
111 					p++;
112 					if (p + l > start + rrlen)
113 					{
114 						break;
115 					}
116 					memcpy(outb, p, l);
117 					outb[l] = 0;
118 					p += l;
119 				}
120 				result = outb;
121 				status = DNSError_None;
122 				return true;
123 			}
124 		} // namespace Platform
125 	} // namespace Internal
126 } // namespace OpenZWave
127