1 
2 /***************************************************************************
3  * nmap_dns.cc -- Handles parallel reverse DNS resolution for target IPs   *
4  *                                                                         *
5  ***********************IMPORTANT NMAP LICENSE TERMS************************
6  *                                                                         *
7  * The Nmap Security Scanner is (C) 1996-2020 Insecure.Com LLC ("The Nmap  *
8  * Project"). Nmap is also a registered trademark of the Nmap Project.     *
9  *                                                                         *
10  * This program is distributed under the terms of the Nmap Public Source   *
11  * License (NPSL). The exact license text applying to a particular Nmap    *
12  * release or source code control revision is contained in the LICENSE     *
13  * file distributed with that version of Nmap or source code control       *
14  * revision. More Nmap copyright/legal information is available from       *
15  * https://nmap.org/book/man-legal.html, and further information on the    *
16  * NPSL license itself can be found at https://nmap.org/npsl. This header  *
17  * summarizes some key points from the Nmap license, but is no substitute  *
18  * for the actual license text.                                            *
19  *                                                                         *
20  * Nmap is generally free for end users to download and use themselves,    *
21  * including commercial use. It is available from https://nmap.org.        *
22  *                                                                         *
23  * The Nmap license generally prohibits companies from using and           *
24  * redistributing Nmap in commercial products, but we sell a special Nmap  *
25  * OEM Edition with a more permissive license and special features for     *
26  * this purpose. See https://nmap.org/oem                                  *
27  *                                                                         *
28  * If you have received a written Nmap license agreement or contract       *
29  * stating terms other than these (such as an Nmap OEM license), you may   *
30  * choose to use and redistribute Nmap under those terms instead.          *
31  *                                                                         *
32  * The official Nmap Windows builds include the Npcap software             *
33  * (https://npcap.org) for packet capture and transmission. It is under    *
34  * separate license terms which forbid redistribution without special      *
35  * permission. So the official Nmap Windows builds may not be              *
36  * redistributed without special permission (such as an Nmap OEM           *
37  * license).                                                               *
38  *                                                                         *
39  * Source is provided to this software because we believe users have a     *
40  * right to know exactly what a program is going to do before they run it. *
41  * This also allows you to audit the software for security holes.          *
42  *                                                                         *
43  * Source code also allows you to port Nmap to new platforms, fix bugs,    *
44  * and add new features.  You are highly encouraged to submit your         *
45  * changes as a Github PR or by email to the dev@nmap.org mailing list     *
46  * for possible incorporation into the main distribution. Unless you       *
47  * specify otherwise, it is understood that you are offering us very       *
48  * broad rights to use your submissions as described in the Nmap Public    *
49  * Source License Contributor Agreement. This is important because we      *
50  * fund the project by selling licenses with various terms, and also       *
51  * because the inability to relicense code has caused devastating          *
52  * problems for other Free Software projects (such as KDE and NASM).       *
53  *                                                                         *
54  * The free version of Nmap is distributed in the hope that it will be     *
55  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of  *
56  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Warranties,        *
57  * indemnification and commercial support are all available through the    *
58  * Npcap OEM program--see https://nmap.org/oem.                            *
59  *                                                                         *
60  ***************************************************************************/
61 
62 // mass_rdns - Parallel Asynchronous Reverse DNS Resolution
63 //
64 // One of Nmap's features is to perform reverse DNS queries
65 // on large number of IP addresses. Nmap supports 2 different
66 // methods of accomplishing this:
67 //
68 // System Resolver (specified using --system-dns):
69 // Performs sequential getnameinfo() calls on all the IPs.
70 // As reliable as your system resolver, almost guaranteed
71 // to be portable, but intolerably slow for scans of hundreds
72 // or more because the result from each query needs to be
73 // received before the next one can be sent.
74 //
75 // Mass/Async DNS (default):
76 // Attempts to resolve host names in parallel using a set
77 // of DNS servers. DNS servers are found here:
78 //
79 //    --dns-servers <serv1[,serv2],...>   (all platforms - overrides everything else)
80 //
81 //    /etc/resolv.conf   (only on unix)
82 //
83 //    These registry keys:   (only on windows)
84 //
85 //      HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
86 //      HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
87 //      HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\*\NameServer
88 //      HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\*\DhcpNameServer
89 //
90 //
91 // Also, most systems maintain a file "/etc/hosts" that contains
92 // IP to hostname mappings. We also try to consult these files. Here
93 // is where we look for the files:
94 //
95 // Unix: /etc/hosts
96 //
97 // Windows:
98 //   for 95/98/Me: WINDOWS_DIR\hosts
99 //   for NT/2000/XP Pro: WINDOWS_DIR\system32\drivers\etc\hosts
100 //   for XP Home: WINDOWS_DIR\system32\drivers\etc\hosts
101 //     --see http://accs-net.com/hosts/how_to_use_hosts.html
102 //
103 //
104 // Created by Doug Hoyte <doug at hcsw.org> http://www.hcsw.org
105 // DNS Caching and aging added by Eddie Bell ejlbell@gmail.com 2007
106 // IPv6 and improved DNS cache by Gioacchino Mazzurco <gmazzurco89@gmail.com> 2015
107 
108 
109 // TODO:
110 //
111 // * Tune performance parameters
112 //
113 // * Figure out best way to estimate completion time
114 //   and display it in a ScanProgressMeter
115 
116 #ifdef WIN32
117 #include "nmap_winconfig.h"
118 /* Need DnetName2PcapName */
119 #include "libnetutil/netutil.h"
120 #endif
121 
122 #include "nmap.h"
123 #include "NmapOps.h"
124 #include "nmap_dns.h"
125 #include "nsock.h"
126 #include "nmap_error.h"
127 #include "nmap_tty.h"
128 #include "tcpip.h"
129 #include "timing.h"
130 #include "Target.h"
131 
132 #include <stdlib.h>
133 #include <limits.h>
134 #include <list>
135 #include <vector>
136 
137 extern NmapOps o;
138 
139 
140 
141 //------------------- Performance Parameters ---------------------
142 
143 // Algorithm:
144 //
145 // A batch of num_targets hosts is passed to nmap_mass_rdns():
146 //   void nmap_mass_rdns(Target **targets, int num_targets)
147 //
148 // mass_dns sends out CAPACITY_MIN of these hosts to the DNS
149 // servers detected, alternating in sequence.
150 
151 // When a request is fulfilled (either a resolved domain, NXDomain,
152 // or confirmed ServFail) CAPACITY_UP_STEP is added to the current
153 // capacity of the server the request was found by.
154 
155 // When a request times out and retries on the same server,
156 // the server's capacity is scaled by CAPACITY_MINOR_DOWN_STEP.
157 
158 // When a request times out and moves to the next server in
159 // sequence, the server's capacity is scaled by CAPACITY_MAJOR_DOWN_STEP.
160 
161 // mass_dns tries to maintain the current number of "outstanding
162 // queries" on each server to that of its current capacity. The
163 // packet is dropped if it cycles through all specified DNS
164 // servers.
165 
166 
167 // Since multiple DNS servers can be specified, different sequences
168 // of timers are maintained. These are the various retransmission
169 // intervals for each server before we move on to the next DNS server:
170 
171 // In milliseconds
172 // Each row MUST be terminated with -1
173 static int read_timeouts[][4] = {
174   { 4000, 4000, 5000, -1 }, // 1 server
175   { 2500, 4000,   -1, -1 }, // 2 servers
176   { 2500, 3000,   -1, -1 }, // 3+ servers
177 };
178 
179 #define CAPACITY_MIN 10
180 #define CAPACITY_MAX 200
181 #define CAPACITY_UP_STEP 2
182 #define CAPACITY_MINOR_DOWN_SCALE 0.9
183 #define CAPACITY_MAJOR_DOWN_SCALE 0.7
184 
185 // Each request will try to resolve on at most this many servers:
186 #define SERVERS_TO_TRY 3
187 
188 
189 //------------------- Other Parameters ---------------------
190 
191 // How often to display a short debugging summary if debugging is
192 // specified. Lower numbers means it's displayed more often.
193 #define SUMMARY_DELAY 50
194 
195 // Minimum debugging level to display packet trace
196 #define TRACE_DEBUG_LEVEL 4
197 
198 // The amount of time we wait for nsock_write() to complete before
199 // retransmission. This should almost never happen. (in milliseconds)
200 #define WRITE_TIMEOUT 100
201 
202 
203 //------------------- Internal Structures ---------------------
204 
205 struct dns_server;
206 struct request;
207 typedef struct sockaddr_storage sockaddr_storage;
208 
209 struct dns_server {
210   std::string hostname;
211   sockaddr_storage addr;
212   size_t addr_len;
213   nsock_iod nsd;
214   int connected;
215   int reqs_on_wire;
216   int capacity;
217   int write_busy;
218   std::list<request *> to_process;
219   std::list<request *> in_process;
220 };
221 
222 struct request {
223   Target *targ;
224   struct timeval timeout;
225   int tries;
226   int servers_tried;
227   dns_server *first_server;
228   dns_server *curr_server;
229   u16 id;
230 };
231 
232 /*keeps record of a request going through a particular DNS server
233 helps in attaining faster lookup based on ID */
234 struct info{
235   dns_server *server;
236   request *tpreq;
237 };
238 
239 class HostElem
240 {
241 public:
HostElem(const std::string & name_,const sockaddr_storage & ip)242   HostElem(const std::string & name_, const sockaddr_storage & ip) :
243     name(name_), addr(ip), cache_hits(0) {}
~HostElem()244   ~HostElem() {}
245 
246   /* Ages entries and return true with a cache hit of 0 (the least used) */
isTimeToClean(HostElem he)247   static bool isTimeToClean(HostElem he)
248   {
249     if(he.cache_hits)
250     {
251       he.cache_hits >>= 1;
252       return false;
253     }
254 
255     return true;
256   }
257 
258   const std::string name;
259   const sockaddr_storage addr;
260   u8 cache_hits;
261 };
262 
263 class HostCacheLine : public std::list<HostElem>{};
264 
265 class HostCache
266 {
267 public:
268   //            TODO: avoid hardcode this constant
HostCache()269   HostCache() : lines_count(256), hash_mask(lines_count-1),
270     hosts_storage(new HostCacheLine[lines_count]), elements_count(0)
271   {}
~HostCache()272   ~HostCache()
273   {
274     delete[] hosts_storage;
275   }
276 
hash(sockaddr_storage ip)277   u32 hash(sockaddr_storage ip)
278   {
279     u32 ret = 0;
280 
281     switch (ip.ss_family)
282     {
283       case AF_INET:
284       {
285         u8 * ipv4 = (u8 *) &((const struct sockaddr_in *) &ip)->sin_addr;
286         // Shuffle bytes a little so we avoid awful performances in commons
287         // usages patterns like 10.0.1-255.1 and lines_count 256
288         ret = ipv4[0] + (ipv4[1]<<3) + (ipv4[2]<<5) + (ipv4[3]<<7);
289         break;
290       }
291       case AF_INET6:
292       {
293         const struct sockaddr_in6 * sa6 = (const struct sockaddr_in6 *) &ip;
294         u32 * ipv6 = (u32 *) sa6->sin6_addr.s6_addr;
295         ret = ipv6[0] + ipv6[1] + ipv6[2] + ipv6[3];
296         break;
297       }
298     }
299 
300     return ret & hash_mask;
301   }
302 
303   /* Add to the dns cache. If there are too many entries
304    * we age and remove the least frequently used ones to
305    * make more space. */
add(const sockaddr_storage & ip,const std::string & hname)306   bool add( const sockaddr_storage & ip, const std::string & hname)
307   {
308     std::string discard;
309     if(lookup(ip, discard)) return false;
310 
311     if(elements_count >= lines_count) prune();
312 
313     HostElem he(hname, ip);
314     hosts_storage[hash(ip)].push_back(he);
315     ++elements_count;
316     return true;
317   }
318 
prune()319   u32 prune()
320   {
321     u32 original_count = elements_count;
322     for(u32 i = 0; i < lines_count; ++i)
323     {
324       std::list<HostElem>::iterator it = find_if(hosts_storage[i].begin(),
325                                                  hosts_storage[i].end(),
326                                                  HostElem::isTimeToClean);
327       while ( it != hosts_storage[i].end() )
328       {
329         it = hosts_storage[i].erase(it);
330         assert(elements_count > 0);
331         --elements_count;
332       }
333     }
334 
335     return original_count - elements_count;
336   }
337 
338   /* Search for a hostname in the cache and increment
339    * its cache hit counter if found */
lookup(const sockaddr_storage & ip,std::string & name)340   bool lookup(const sockaddr_storage & ip, std::string & name)
341   {
342     std::list<HostElem>::iterator hostI;
343     u32 ip_hash = hash(ip);
344     for( hostI = hosts_storage[ip_hash].begin();
345          hostI != hosts_storage[ip_hash].end();
346          ++hostI)
347     {
348       if (sockaddr_storage_equal(&hostI->addr, &ip))
349       {
350         if(hostI->cache_hits < UCHAR_MAX)
351           hostI->cache_hits++;
352         name = hostI->name;
353         return true;
354       }
355     }
356     return false;
357   }
358 
359 protected:
360   const u32 lines_count;
361   const u32 hash_mask;
362   HostCacheLine * const hosts_storage;
363   u32 elements_count;
364 };
365 
366 //------------------- Globals ---------------------
367 
368 u16 DNS::Factory::progressiveId = get_random_u16();
369 static std::list<dns_server> servs;
370 static std::list<request *> new_reqs;
371 static std::list<request *> deferred_reqs;
372 static std::map<u16, info> records;
373 static int total_reqs;
374 static nsock_pool dnspool=NULL;
375 
376 /* The DNS cache, not just for entries from /etc/hosts. */
377 static HostCache host_cache;
378 
379 static int stat_actual, stat_ok, stat_nx, stat_sf, stat_trans, stat_dropped, stat_cname;
380 static struct timeval starttv;
381 static int read_timeout_index;
382 
383 static int firstrun=1;
384 static ScanProgressMeter *SPM;
385 
386 
387 //------------------- Prototypes and macros ---------------------
388 static void read_evt_handler(nsock_pool, nsock_event, void *);
389 static void put_dns_packet_on_wire(request *req);
390 
391 #define ACTION_FINISHED 0
392 #define ACTION_SYSTEM_RESOLVE 1
393 #define ACTION_TIMEOUT 2
394 
395 //------------------- Misc code ---------------------
396 
output_summary()397 static void output_summary() {
398   int tp = stat_ok + stat_nx + stat_dropped;
399   struct timeval now;
400 
401   memcpy(&now, nsock_gettimeofday(), sizeof(struct timeval));
402 
403   if (o.debugging && (tp%SUMMARY_DELAY == 0))
404     log_write(LOG_STDOUT, "mass_rdns: %.2fs %d/%d [#: %lu, OK: %d, NX: %d, DR: %d, SF: %d, TR: %d]\n",
405                     TIMEVAL_MSEC_SUBTRACT(now, starttv) / 1000.0,
406                     tp, stat_actual,
407                     (unsigned long) servs.size(), stat_ok, stat_nx, stat_dropped, stat_sf, stat_trans);
408 }
409 
check_capacities(dns_server * tpserv)410 static void check_capacities(dns_server *tpserv) {
411   if (tpserv->capacity < CAPACITY_MIN) tpserv->capacity = CAPACITY_MIN;
412   if (tpserv->capacity > CAPACITY_MAX) tpserv->capacity = CAPACITY_MAX;
413   if (o.debugging >= TRACE_DEBUG_LEVEL) log_write(LOG_STDOUT, "CAPACITY <%s> = %d\n", tpserv->hostname.c_str(), tpserv->capacity);
414 }
415 
416 // Closes all nsis created in connect_dns_servers()
close_dns_servers()417 static void close_dns_servers() {
418   std::list<dns_server>::iterator serverI;
419 
420   for(serverI = servs.begin(); serverI != servs.end(); serverI++) {
421     if (serverI->connected) {
422       nsock_iod_delete(serverI->nsd, NSOCK_PENDING_SILENT);
423       serverI->connected = 0;
424       serverI->to_process.clear();
425       serverI->in_process.clear();
426     }
427   }
428 }
429 
430 
431 // Puts as many packets on the line as capacity will allow
do_possible_writes()432 static void do_possible_writes() {
433   std::list<dns_server>::iterator servI;
434   request *tpreq;
435 
436   for(servI = servs.begin(); servI != servs.end(); servI++) {
437     if (servI->write_busy == 0 && servI->reqs_on_wire < servI->capacity) {
438       tpreq = NULL;
439       if (!servI->to_process.empty()) {
440         tpreq = servI->to_process.front();
441         servI->to_process.pop_front();
442       } else if (!new_reqs.empty()) {
443         tpreq = new_reqs.front();
444         assert(tpreq != NULL);
445         tpreq->first_server = tpreq->curr_server = &*servI;
446         new_reqs.pop_front();
447       }
448 
449       if (tpreq) {
450         if (o.debugging >= TRACE_DEBUG_LEVEL)
451            log_write(LOG_STDOUT, "mass_rdns: TRANSMITTING for <%s> (server <%s>)\n", tpreq->targ->targetipstr() , servI->hostname.c_str());
452         stat_trans++;
453         put_dns_packet_on_wire(tpreq);
454       }
455     }
456   }
457 }
458 
459 // nsock write handler
write_evt_handler(nsock_pool nsp,nsock_event evt,void * req_v)460 static void write_evt_handler(nsock_pool nsp, nsock_event evt, void *req_v) {
461   info record;
462   request *req = (request *) req_v;
463 
464   req->curr_server->write_busy = 0;
465 
466   req->curr_server->in_process.push_front(req);
467   record.tpreq = req;
468   record.server = req->curr_server;
469   records[req->id] = record;
470 
471   do_possible_writes();
472 }
473 
474 // Takes a DNS request structure and actually puts it on the wire
475 // (calls nsock_write()). Does various other tasks like recording
476 // the time for the timeout.
put_dns_packet_on_wire(request * req)477 static void put_dns_packet_on_wire(request *req) {
478   const size_t maxlen = 512;
479   u8 packet[maxlen];
480   size_t plen=0;
481 
482   struct timeval now, timeout;
483 
484   req->id = DNS::Factory::progressiveId;
485   req->curr_server->write_busy = 1;
486   req->curr_server->reqs_on_wire++;
487 
488   plen = DNS::Factory::buildReverseRequest(*req->targ->TargetSockAddr(), packet, maxlen);
489 
490   memcpy(&now, nsock_gettimeofday(), sizeof(struct timeval));
491   TIMEVAL_MSEC_ADD(timeout, now, read_timeouts[read_timeout_index][req->tries]);
492   memcpy(&req->timeout, &timeout, sizeof(struct timeval));
493 
494   req->tries++;
495 
496   nsock_write(dnspool, req->curr_server->nsd, write_evt_handler, WRITE_TIMEOUT, req, reinterpret_cast<const char *>(packet), plen);
497 }
498 
499 // Processes DNS packets that have timed out
500 // Returns time until next read timeout
deal_with_timedout_reads()501 static int deal_with_timedout_reads() {
502   std::list<dns_server>::iterator servI;
503   std::list<dns_server>::iterator servItemp;
504   std::list<request *>::iterator reqI;
505   std::list<request *>::iterator nextI;
506   std::map<u16, info>::iterator infoI;
507   request *tpreq;
508   struct timeval now;
509   int tp, min_timeout = INT_MAX;
510 
511   memcpy(&now, nsock_gettimeofday(), sizeof(struct timeval));
512 
513   if (keyWasPressed())
514     SPM->printStats((double) (stat_ok + stat_nx + stat_dropped) / stat_actual, &now);
515 
516   for(servI = servs.begin(); servI != servs.end(); servI++) {
517     nextI = servI->in_process.begin();
518     if (nextI == servI->in_process.end()) continue;
519 
520     do {
521       reqI = nextI++;
522       tpreq = *reqI;
523 
524       tp = TIMEVAL_MSEC_SUBTRACT(tpreq->timeout, now);
525       if (tp > 0 && tp < min_timeout) min_timeout = tp;
526 
527       if (tp <= 0) {
528         servI->capacity = (int) (servI->capacity * CAPACITY_MINOR_DOWN_SCALE);
529         check_capacities(&*servI);
530         servI->in_process.erase(reqI);
531         std::map<u16, info>::iterator it = records.find(tpreq->id);
532         if ( it != records.end() )
533           records.erase(it);
534         servI->reqs_on_wire--;
535 
536         // If we've tried this server enough times, move to the next one
537         if (read_timeouts[read_timeout_index][tpreq->tries] == -1) {
538           servI->capacity = (int) (servI->capacity * CAPACITY_MAJOR_DOWN_SCALE);
539           check_capacities(&*servI);
540 
541           servItemp = servI;
542           servItemp++;
543 
544           if (servItemp == servs.end()) servItemp = servs.begin();
545 
546           tpreq->curr_server = &*servItemp;
547           tpreq->tries = 0;
548           tpreq->servers_tried++;
549 
550           if (tpreq->curr_server == tpreq->first_server || tpreq->servers_tried == SERVERS_TO_TRY) {
551             // Either give up on the IP
552             // or, for maximum reliability, put the server back into processing
553             // Note it's possible that this will never terminate.
554             // FIXME: Find a good compromise
555 
556             // **** We've already tried all servers... give up
557             if (o.debugging >= TRACE_DEBUG_LEVEL) log_write(LOG_STDOUT, "mass_rdns: *DR*OPPING <%s>\n", tpreq->targ->targetipstr());
558 
559             output_summary();
560             stat_dropped++;
561             total_reqs--;
562             infoI = records.find(tpreq->id);
563             if ( infoI != records.end() )
564               records.erase(infoI);
565             delete tpreq;
566 
567             // **** OR We start at the back of this server's queue
568             //servItemp->to_process.push_back(tpreq);
569           } else {
570             servItemp->to_process.push_back(tpreq);
571           }
572         } else {
573           servI->to_process.push_back(tpreq);
574         }
575 
576     }
577 
578     } while (nextI != servI->in_process.end());
579 
580   }
581 
582   if (min_timeout > 500) return 500;
583   else return min_timeout;
584 
585 }
586 
587 // After processing a DNS response, we search through the IPs we're
588 // looking for and update their results as necessary.
589 // Returns non-zero if this matches a query we're looking for
process_result(const sockaddr_storage & ip,const std::string & result,int action,u16 id)590 static int process_result(const sockaddr_storage &ip, const std::string &result, int action, u16 id)
591 {
592   request *tpreq;
593   std::map<u16, info>::iterator infoI;
594   dns_server *server;
595 
596   infoI = records.find(id);
597 
598   if( infoI != records.end() ){
599 
600     tpreq = infoI->second.tpreq;
601     server = infoI->second.server;
602 
603     if( !result.empty() && !sockaddr_storage_equal(&ip, tpreq->targ->TargetSockAddr()) )
604       return 0;
605 
606     if (action == ACTION_SYSTEM_RESOLVE || action == ACTION_FINISHED)
607     {
608       server->capacity += CAPACITY_UP_STEP;
609       check_capacities(&*server);
610 
611       if(!result.empty())
612       {
613         tpreq->targ->setHostName(result.c_str());
614         host_cache.add(* tpreq->targ->TargetSockAddr(), result);
615       }
616 
617       records.erase(infoI);
618       server->in_process.remove(tpreq);
619       server->reqs_on_wire--;
620 
621       total_reqs--;
622 
623       if (action == ACTION_SYSTEM_RESOLVE) deferred_reqs.push_back(tpreq);
624       if (action == ACTION_FINISHED) delete tpreq;
625     }
626     else
627     {
628       memcpy(&tpreq->timeout, nsock_gettimeofday(), sizeof(struct timeval));
629       deal_with_timedout_reads();
630     }
631 
632     do_possible_writes();
633 
634     // Close DNS servers if we're all done so that we kill
635     // all events and return from nsock_loop immediateley
636     if (total_reqs == 0)
637       close_dns_servers();
638     return 1;
639   }
640   return 0;
641 }
642 
643 // Nsock read handler. One nsock read for each DNS server exists at each
644 // time. This function uses various helper functions as defined above.
read_evt_handler(nsock_pool nsp,nsock_event evt,void *)645 static void read_evt_handler(nsock_pool nsp, nsock_event evt, void *) {
646   u8 *buf;
647   int buflen;
648 
649   if (total_reqs >= 1)
650     nsock_read(nsp, nse_iod(evt), read_evt_handler, -1, NULL);
651 
652   if (nse_type(evt) != NSE_TYPE_READ || nse_status(evt) != NSE_STATUS_SUCCESS) {
653     if (o.debugging)
654       log_write(LOG_STDOUT, "mass_dns: warning: got a %s:%s in %s()\n",
655         nse_type2str(nse_type(evt)),
656         nse_status2str(nse_status(evt)), __func__);
657     return;
658   }
659 
660   buf = (unsigned char *) nse_readbuf(evt, &buflen);
661 
662   DNS::Packet p;
663   size_t readed_bytes = p.parseFromBuffer(buf, buflen);
664   if(readed_bytes < DNS::DATA) return;
665 
666   // We should have 1+ queries:
667   u16 &f = p.flags;
668   if(p.queries.empty() || !DNS_HAS_FLAG(f, DNS::RESPONSE) ||
669      !DNS_HAS_FLAG(f, DNS::OP_STANDARD_QUERY) ||
670      (f & DNS::ZERO) || DNS_HAS_ERR(f, DNS::ERR_FORMAT) ||
671      DNS_HAS_ERR(f, DNS::ERR_NOT_IMPLEMENTED) || DNS_HAS_ERR(f, DNS::ERR_REFUSED))
672     return;
673 
674   if (DNS_HAS_ERR(f, DNS::ERR_NAME))
675   {
676     sockaddr_storage discard;
677     if(process_result(discard, "", ACTION_FINISHED, p.id))
678     {
679       if (o.debugging >= TRACE_DEBUG_LEVEL)
680         log_write(LOG_STDOUT, "mass_rdns: NXDOMAIN <id = %d>\n", p.id);
681       output_summary();
682       stat_nx++;
683     }
684 
685     return;
686   }
687 
688   if (DNS_HAS_ERR(f, DNS::ERR_SERVFAIL))
689   {
690     sockaddr_storage discard;
691     if (process_result(discard, "", ACTION_TIMEOUT, p.id))
692     {
693       if (o.debugging >= TRACE_DEBUG_LEVEL)
694         log_write(LOG_STDOUT, "mass_rdns: SERVFAIL <id = %d>\n", p.id);
695       stat_sf++;
696     }
697 
698     return;
699   }
700 
701   bool processing_successful = false;
702 
703   sockaddr_storage ip;
704   ip.ss_family = AF_UNSPEC;
705   std::string alias;
706 
707   for(std::list<DNS::Answer>::const_iterator it = p.answers.begin();
708       it != p.answers.end() && !processing_successful; ++it )
709   {
710     const DNS::Answer &a = *it;
711     if(a.record_class == DNS::CLASS_IN)
712     {
713       switch(a.record_type)
714       {
715         case DNS::PTR:
716         {
717           DNS::PTR_Record * ptr = static_cast<DNS::PTR_Record *>(a.record);
718 
719           if(
720             // If CNAME answer filled in ip with a matching alias
721             (ip.ss_family != AF_UNSPEC && a.name == alias )
722             // Or if we can get an IP from reversing the .arpa PTR address
723             || DNS::Factory::ptrToIp(a.name, ip))
724           {
725             if ((processing_successful = process_result(ip, ptr->value, ACTION_FINISHED, p.id)))
726             {
727               if (o.debugging >= TRACE_DEBUG_LEVEL)
728               {
729                 char ipstr[INET6_ADDRSTRLEN];
730                 sockaddr_storage_iptop(&ip, ipstr);
731                 log_write(LOG_STDOUT, "mass_rdns: OK MATCHED <%s> to <%s>\n",
732                           ipstr,
733                           ptr->value.c_str());
734               }
735               output_summary();
736               stat_ok++;
737             }
738           }
739           break;
740         }
741         case DNS::CNAME:
742         {
743           if(DNS::Factory::ptrToIp(a.name, ip))
744           {
745             DNS::CNAME_Record * cname = static_cast<DNS::CNAME_Record *>(a.record);
746             alias = cname->value;
747             if (o.debugging >= TRACE_DEBUG_LEVEL)
748             {
749               char ipstr[INET6_ADDRSTRLEN];
750               sockaddr_storage_iptop(&ip, ipstr);
751               log_write(LOG_STDOUT, "mass_rdns: CNAME found for <%s> to <%s>\n", ipstr, alias.c_str());
752             }
753           }
754           break;
755         }
756         default:
757           break;
758       }
759     }
760   }
761 
762   if (!processing_successful) {
763     if (DNS_HAS_FLAG(f, DNS::TRUNCATED)) {
764       // TODO: TCP fallback, or only use system resolver if user didn't specify --dns-servers
765       process_result(ip, "", ACTION_SYSTEM_RESOLVE, p.id);
766     }
767     else if (!alias.empty()) {
768       if (o.debugging >= TRACE_DEBUG_LEVEL)
769       {
770         char ipstr[INET6_ADDRSTRLEN];
771         sockaddr_storage_iptop(&ip, ipstr);
772         log_write(LOG_STDOUT, "mass_rdns: CNAME for <%s> not processed.\n", ipstr);
773       }
774       // TODO: Send a PTR request for alias instead. Meanwhile, we'll just fall
775       // back to using system resolver. Alternative: report the canonical name
776       // (alias), but that's not very useful.
777       process_result(ip, "", ACTION_SYSTEM_RESOLVE, p.id);
778     }
779     else {
780       if (o.debugging >= TRACE_DEBUG_LEVEL) {
781         log_write(LOG_STDOUT, "mass_rdns: Unable to process the response\n");
782       }
783     }
784   }
785 }
786 
787 
788 // nsock connect handler - Empty because it doesn't really need to do anything...
connect_evt_handler(nsock_pool,nsock_event,void *)789 static void connect_evt_handler(nsock_pool, nsock_event, void *) {}
790 
791 
792 // Adds DNS servers to the dns_server list. They can be separated by
793 // commas or spaces - NOTE this doesn't actually do any connecting!
add_dns_server(char * ipaddrs)794 static void add_dns_server(char *ipaddrs) {
795   std::list<dns_server>::iterator servI;
796   char *hostname;
797   struct sockaddr_storage addr;
798   size_t addr_len = sizeof(addr);
799 
800   for (hostname = strtok(ipaddrs, " ,"); hostname != NULL; hostname = strtok(NULL, " ,")) {
801 
802     if (resolve(hostname, 0, (struct sockaddr_storage *) &addr, &addr_len,
803       o.spoofsource ? o.af() : PF_UNSPEC) != 0)
804       continue;
805 
806     for(servI = servs.begin(); servI != servs.end(); servI++) {
807       // Already added!
808       if (memcmp(&addr, &servI->addr, sizeof(addr)) == 0) break;
809     }
810 
811     // If it hasn't already been added, add it!
812     if (servI == servs.end()) {
813       dns_server tpserv;
814 
815       tpserv.hostname = hostname;
816       memcpy(&tpserv.addr, &addr, sizeof(addr));
817       tpserv.addr_len = addr_len;
818 
819       servs.push_front(tpserv);
820 
821       if (o.debugging) log_write(LOG_STDOUT, "mass_rdns: Using DNS server %s\n", hostname);
822     }
823 
824   }
825 
826 }
827 
828 // Creates a new nsi for each DNS server
connect_dns_servers()829 static void connect_dns_servers() {
830   std::list<dns_server>::iterator serverI;
831   for(serverI = servs.begin(); serverI != servs.end(); serverI++) {
832     serverI->nsd = nsock_iod_new(dnspool, NULL);
833     if (o.spoofsource) {
834       struct sockaddr_storage ss;
835       size_t sslen;
836       o.SourceSockAddr(&ss, &sslen);
837       nsock_iod_set_localaddr(serverI->nsd, &ss, sslen);
838     }
839     if (o.ipoptionslen)
840       nsock_iod_set_ipoptions(serverI->nsd, o.ipoptions, o.ipoptionslen);
841     serverI->reqs_on_wire = 0;
842     serverI->capacity = CAPACITY_MIN;
843     serverI->write_busy = 0;
844 
845     nsock_connect_udp(dnspool, serverI->nsd, connect_evt_handler, NULL, (struct sockaddr *) &serverI->addr, serverI->addr_len, 53);
846     nsock_read(dnspool, serverI->nsd, read_evt_handler, -1, NULL);
847     serverI->connected = 1;
848   }
849 
850 }
851 
852 
853 #ifdef WIN32
interface_is_known_by_guid(const char * guid)854 static bool interface_is_known_by_guid(const char *guid) {
855   struct interface_info *iflist;
856   int i, n;
857 
858   iflist = getinterfaces(&n, NULL, 0);
859   if (iflist == NULL)
860     return false;
861 
862   for (i = 0; i < n; i++) {
863     char pcap_name[1024];
864     char *pcap_guid;
865 
866     if (!DnetName2PcapName(iflist[i].devname, pcap_name, sizeof(pcap_name)))
867       continue;
868     pcap_guid = strchr(pcap_name, '{');
869     if (pcap_guid == NULL)
870       continue;
871     if (strcasecmp(guid, pcap_guid) == 0)
872       return true;
873   }
874 
875   return false;
876 }
877 
878 // Reads the Windows registry and adds all the nameservers found via the
879 // add_dns_server() function.
win32_read_registry()880 void win32_read_registry() {
881   HKEY hKey;
882   HKEY hKey2;
883   char keybasebuf[2048];
884   char buf[2048], keyname[2048], *p;
885   DWORD sz, i;
886 
887   Snprintf(keybasebuf, sizeof(keybasebuf), "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters");
888   if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keybasebuf,
889                     0, KEY_READ, &hKey) != ERROR_SUCCESS) {
890     if (firstrun) error("mass_dns: warning: Error opening registry to read DNS servers. Try using --system-dns or specify valid servers with --dns-servers");
891     return;
892   }
893 
894   sz = sizeof(buf);
895   if (RegQueryValueEx(hKey, "NameServer", NULL, NULL, (LPBYTE) buf, (LPDWORD) &sz) == ERROR_SUCCESS)
896     add_dns_server(buf);
897 
898   sz = sizeof(buf);
899   if (RegQueryValueEx(hKey, "DhcpNameServer", NULL, NULL, (LPBYTE) buf, (LPDWORD) &sz) == ERROR_SUCCESS)
900     add_dns_server(buf);
901 
902   RegCloseKey(hKey);
903 
904   Snprintf(keybasebuf, sizeof(keybasebuf), "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces");
905   if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keybasebuf,
906                     0, KEY_ENUMERATE_SUB_KEYS, &hKey) == ERROR_SUCCESS) {
907 
908     for (i=0; sz = sizeof(buf), RegEnumKeyEx(hKey, i, buf, &sz, NULL, NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS; i++) {
909 
910       // If we don't have pcap, interface_is_known_by_guid will crash. Just use any servers we can find.
911       if (o.have_pcap && !interface_is_known_by_guid(buf)) {
912         if (o.debugging > 1)
913           log_write(LOG_PLAIN, "Interface %s is not known; ignoring its nameservers.\n", buf);
914         continue;
915       }
916 
917       Snprintf(keyname, sizeof(keyname), "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%s", buf);
918 
919       if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname,
920                         0, KEY_READ, &hKey2) == ERROR_SUCCESS) {
921 
922         sz = sizeof(buf);
923         if (RegQueryValueEx(hKey2, "DhcpNameServer", NULL, NULL, (LPBYTE) buf, (LPDWORD) &sz) == ERROR_SUCCESS)
924           add_dns_server(buf);
925 
926         sz = sizeof(buf);
927         if (RegQueryValueEx(hKey2, "NameServer", NULL, NULL, (LPBYTE) buf, (LPDWORD) &sz) == ERROR_SUCCESS)
928           add_dns_server(buf);
929 
930         RegCloseKey(hKey2);
931       }
932     }
933 
934     RegCloseKey(hKey);
935 
936   }
937 
938 }
939 #endif // WIN32
940 
941 
942 
943 // Parses /etc/resolv.conf (unix) and adds all the nameservers found via the
944 // add_dns_server() function.
parse_resolvdotconf()945 static void parse_resolvdotconf() {
946   FILE *fp;
947   char buf[2048], *tp;
948   char fmt[32];
949   char ipaddr[INET6_ADDRSTRLEN+1];
950 
951   fp = fopen("/etc/resolv.conf", "r");
952   if (fp == NULL) {
953     if (firstrun) error("mass_dns: warning: Unable to open /etc/resolv.conf. Try using --system-dns or specify valid servers with --dns-servers");
954     return;
955   }
956 
957   Snprintf(fmt, sizeof(fmt), "nameserver %%%us", INET6_ADDRSTRLEN);
958 
959   while (fgets(buf, sizeof(buf), fp)) {
960     tp = buf;
961 
962     // Clip off comments #, \r, \n
963     while (*tp != '\r' && *tp != '\n' && *tp != '#' && *tp) tp++;
964     *tp = '\0';
965 
966     tp = buf;
967     // Skip any leading whitespace
968     while (*tp == ' ' || *tp == '\t') tp++;
969 
970     if (sscanf(tp, fmt, ipaddr) == 1) add_dns_server(ipaddr);
971   }
972 
973   fclose(fp);
974 }
975 
976 
parse_etchosts(const char * fname)977 static void parse_etchosts(const char *fname) {
978   FILE *fp;
979   char buf[2048], hname[256], ipaddrstr[INET6_ADDRSTRLEN+1], *tp;
980   sockaddr_storage ia;
981 
982   fp = fopen(fname, "r");
983   if (fp == NULL) return; // silently is OK
984 
985   while (fgets(buf, sizeof(buf), fp)) {
986     tp = buf;
987 
988     // Clip off comments #, \r, \n
989     while (*tp != '\r' && *tp != '\n' && *tp != '#' && *tp) tp++;
990     *tp = '\0';
991 
992     tp = buf;
993     // Skip any leading whitespace
994     while (*tp == ' ' || *tp == '\t') tp++;
995 
996     std::stringstream pattern;
997     pattern << "%" << INET6_ADDRSTRLEN << "s %255s";
998     if (sscanf(tp, pattern.str().c_str(), ipaddrstr, hname) == 2)
999       if (sockaddr_storage_inet_pton(ipaddrstr, &ia))
1000       {
1001         const std::string hname_ = hname;
1002         host_cache.add(ia, hname_);
1003       }
1004   }
1005 
1006   fclose(fp);
1007 }
1008 
etchosts_init(void)1009 static void etchosts_init(void) {
1010   static int initialized = 0;
1011   if (initialized) return;
1012   initialized = 1;
1013 
1014 #ifdef WIN32
1015   char windows_dir[1024];
1016   char tpbuf[2048];
1017   int has_backslash;
1018 
1019   if (!GetWindowsDirectory(windows_dir, sizeof(windows_dir)))
1020     fatal("Failed to determine your windows directory");
1021 
1022   // If it has a backslash it's C:\, otherwise something like C:\WINNT
1023   has_backslash = (windows_dir[strlen(windows_dir)-1] == '\\');
1024 
1025   // Windows 95/98/Me:
1026   Snprintf(tpbuf, sizeof(tpbuf), "%s%shosts", windows_dir, has_backslash ? "" : "\\");
1027   parse_etchosts(tpbuf);
1028 
1029   // Windows NT/2000/XP/2K3:
1030   Snprintf(tpbuf, sizeof(tpbuf), "%s%ssystem32\\drivers\\etc\\hosts", windows_dir, has_backslash ? "" : "\\");
1031   parse_etchosts(tpbuf);
1032 
1033 #else
1034   parse_etchosts("/etc/hosts");
1035 #endif // WIN32
1036 }
1037 
1038 /* Initialize the global servs list of DNS servers. If the --dns-servers option
1039  * was given, use the listed servers; otherwise get the list from resolv.conf or
1040  * the Windows registry. If o.mass_dns is false, the list of servers is empty.
1041  * This function caches the results from the first time it is run. */
init_servs(void)1042 static void init_servs(void) {
1043   static bool initialized = false;
1044 
1045   if (initialized)
1046     return;
1047 
1048   initialized = true;
1049 
1050   if (!o.mass_dns)
1051     return;
1052 
1053   if (o.dns_servers) {
1054     add_dns_server(o.dns_servers);
1055   } else {
1056 #ifndef WIN32
1057     parse_resolvdotconf();
1058 #else
1059     win32_read_registry();
1060 #endif
1061   }
1062 }
1063 
1064 //------------------- Main loops ---------------------
1065 
1066 
1067 // Actual main loop
nmap_mass_rdns_core(Target ** targets,int num_targets)1068 static void nmap_mass_rdns_core(Target **targets, int num_targets) {
1069 
1070   Target **hostI;
1071   std::list<request *>::iterator reqI;
1072   request *tpreq;
1073   int timeout;
1074   const char *tpname;
1075   int i;
1076   char spmobuf[1024];
1077 
1078   // If necessary, set up the dns server list
1079   init_servs();
1080 
1081   if (servs.size() == 0 && firstrun) error("mass_dns: warning: Unable to "
1082                                            "determine any DNS servers. Reverse"
1083                                            " DNS is disabled. Try using "
1084                                            "--system-dns or specify valid "
1085                                            "servers with --dns-servers");
1086 
1087 
1088   // If necessary, read /etc/hosts and put entries into the hashtable
1089   etchosts_init();
1090 
1091 
1092   total_reqs = 0;
1093 
1094   // Set up the request structure
1095   for(hostI = targets; hostI < targets+num_targets; hostI++)
1096   {
1097     if (!((*hostI)->flags & HOST_UP) && !o.always_resolve) continue;
1098 
1099     // See if it's cached
1100     std::string res;
1101     if (host_cache.lookup(*(*hostI)->TargetSockAddr(), res)) {
1102       tpname = res.c_str();
1103       (*hostI)->setHostName(tpname);
1104       continue;
1105     }
1106 
1107     tpreq = new request;
1108     tpreq->targ = *hostI;
1109     tpreq->tries = 0;
1110     tpreq->servers_tried = 0;
1111 
1112     new_reqs.push_back(tpreq);
1113 
1114     stat_actual++;
1115     total_reqs++;
1116   }
1117 
1118   if (total_reqs == 0 || servs.size() == 0) return;
1119 
1120   // And finally, do it!
1121 
1122   if ((dnspool = nsock_pool_new(NULL)) == NULL)
1123     fatal("Unable to create nsock pool in %s()", __func__);
1124 
1125   nmap_set_nsock_logger();
1126   nmap_adjust_loglevel(o.packetTrace());
1127 
1128   nsock_pool_set_device(dnspool, o.device);
1129 
1130   if (o.proxy_chain)
1131     nsock_pool_set_proxychain(dnspool, o.proxy_chain);
1132 
1133   connect_dns_servers();
1134 
1135   deferred_reqs.clear();
1136 
1137   read_timeout_index = MIN(sizeof(read_timeouts)/sizeof(read_timeouts[0]), servs.size()) - 1;
1138 
1139   Snprintf(spmobuf, sizeof(spmobuf), "Parallel DNS resolution of %d host%s.", stat_actual, stat_actual-1 ? "s" : "");
1140   SPM = new ScanProgressMeter(spmobuf);
1141 
1142   while (total_reqs > 0) {
1143     timeout = deal_with_timedout_reads();
1144 
1145     do_possible_writes();
1146 
1147     if (total_reqs <= 0) break;
1148 
1149     /* Because this can change with runtime interaction */
1150     nmap_adjust_loglevel(o.packetTrace());
1151 
1152     nsock_loop(dnspool, timeout);
1153   }
1154 
1155   SPM->endTask(NULL, NULL);
1156   delete SPM;
1157 
1158   close_dns_servers();
1159 
1160   nsock_pool_delete(dnspool);
1161 
1162   if (deferred_reqs.size() && o.debugging)
1163     log_write(LOG_STDOUT, "Performing system-dns for %d domain names that were deferred\n", (int) deferred_reqs.size());
1164 
1165   if (deferred_reqs.size()) {
1166     Snprintf(spmobuf, sizeof(spmobuf), "System DNS resolution of %u host%s.", (unsigned) deferred_reqs.size(), deferred_reqs.size()-1 ? "s" : "");
1167     SPM = new ScanProgressMeter(spmobuf);
1168 
1169     for(i=0, reqI = deferred_reqs.begin(); reqI != deferred_reqs.end(); reqI++, i++) {
1170       struct sockaddr_storage ss;
1171       size_t sslen;
1172       char hostname[FQDN_LEN + 1] = "";
1173 
1174       if (keyWasPressed())
1175         SPM->printStats((double) i / deferred_reqs.size(), NULL);
1176 
1177       tpreq = *reqI;
1178 
1179       if (tpreq->targ->TargetSockAddr(&ss, &sslen) != 0)
1180         fatal("Failed to get target socket address.");
1181 
1182       if (getnameinfo((struct sockaddr *)&ss, sslen, hostname,
1183                       sizeof(hostname), NULL, 0, NI_NAMEREQD) == 0) {
1184         stat_ok++;
1185         stat_cname++;
1186         tpreq->targ->setHostName(hostname);
1187       }
1188 
1189       delete tpreq;
1190 
1191     }
1192 
1193     SPM->endTask(NULL, NULL);
1194     delete SPM;
1195   }
1196 
1197   deferred_reqs.clear();
1198 
1199 }
1200 
nmap_system_rdns_core(Target ** targets,int num_targets)1201 static void nmap_system_rdns_core(Target **targets, int num_targets) {
1202   Target **hostI;
1203   Target *currenths;
1204   struct sockaddr_storage ss;
1205   size_t sslen;
1206   char hostname[FQDN_LEN + 1] = "";
1207   char spmobuf[1024];
1208   int i;
1209 
1210   for(hostI = targets; hostI < targets+num_targets; hostI++) {
1211     currenths = *hostI;
1212 
1213     if (((currenths->flags & HOST_UP) || o.always_resolve) && !o.noresolve) stat_actual++;
1214   }
1215 
1216   Snprintf(spmobuf, sizeof(spmobuf), "System DNS resolution of %d host%s.", stat_actual, stat_actual-1 ? "s" : "");
1217   SPM = new ScanProgressMeter(spmobuf);
1218 
1219   for(i=0, hostI = targets; hostI < targets+num_targets; hostI++, i++) {
1220     currenths = *hostI;
1221 
1222     if (keyWasPressed())
1223       SPM->printStats((double) i / stat_actual, NULL);
1224 
1225     if (((currenths->flags & HOST_UP) || o.always_resolve) && !o.noresolve) {
1226       if (currenths->TargetSockAddr(&ss, &sslen) != 0)
1227         fatal("Failed to get target socket address.");
1228       if (getnameinfo((struct sockaddr *)&ss, sslen, hostname,
1229                       sizeof(hostname), NULL, 0, NI_NAMEREQD) == 0) {
1230         stat_ok++;
1231         currenths->setHostName(hostname);
1232       }
1233     }
1234   }
1235 
1236   SPM->endTask(NULL, NULL);
1237   delete SPM;
1238 }
1239 
1240 
1241 // Publicly available function. Basically just a wrapper so we
1242 // can record time information, restart statistics, etc.
nmap_mass_rdns(Target ** targets,int num_targets)1243 void nmap_mass_rdns(Target **targets, int num_targets) {
1244 
1245   struct timeval now;
1246 
1247   gettimeofday(&starttv, NULL);
1248 
1249   stat_actual = stat_ok = stat_nx = stat_sf = stat_trans = stat_dropped = stat_cname = 0;
1250 
1251   if (o.mass_dns)
1252     nmap_mass_rdns_core(targets, num_targets);
1253   else
1254     nmap_system_rdns_core(targets, num_targets);
1255 
1256   gettimeofday(&now, NULL);
1257 
1258   if (stat_actual > 0) {
1259     if (o.debugging || o.verbose >= 3) {
1260       if (o.mass_dns) {
1261         // #:  Number of DNS servers used
1262         // OK: Number of fully reverse resolved queries
1263         // NX: Number of confirmations of 'No such reverse domain eXists'
1264         // DR: Dropped IPs (no valid responses were received)
1265         // SF: Number of IPs that got 'Server Failure's
1266         // TR: Total number of transmissions necessary. The number of domains is ideal, higher is worse
1267         log_write(LOG_STDOUT, "DNS resolution of %d IPs took %.2fs. Mode: Async [#: %lu, OK: %d, NX: %d, DR: %d, SF: %d, TR: %d, CN: %d]\n",
1268                   stat_actual, TIMEVAL_MSEC_SUBTRACT(now, starttv) / 1000.0,
1269                   (unsigned long) servs.size(), stat_ok, stat_nx, stat_dropped, stat_sf, stat_trans, stat_cname);
1270       } else {
1271         log_write(LOG_STDOUT, "DNS resolution of %d IPs took %.2fs. Mode: System [OK: %d, ??: %d]\n",
1272                   stat_actual, TIMEVAL_MSEC_SUBTRACT(now, starttv) / 1000.0,
1273                   stat_ok, stat_actual - stat_ok);
1274       }
1275     }
1276   }
1277 
1278   firstrun=0;
1279 }
1280 
1281 
1282 // Returns a list of known DNS servers
get_dns_servers()1283 std::list<std::string> get_dns_servers() {
1284   init_servs();
1285 
1286   // If the user said --system-dns (!o.mass_dns), we should never return a list
1287   // of servers.
1288   assert(o.mass_dns || servs.empty());
1289 
1290   std::list<dns_server>::iterator servI;
1291   std::list<std::string> serverList;
1292   for(servI = servs.begin(); servI != servs.end(); servI++) {
1293     serverList.push_back(inet_socktop((struct sockaddr_storage *) &servI->addr));
1294   }
1295   return serverList;
1296 }
1297 
ipToPtr(const sockaddr_storage & ip,std::string & ptr)1298 bool DNS::Factory::ipToPtr(const sockaddr_storage &ip, std::string &ptr)
1299 {
1300   switch (ip.ss_family) {
1301     case AF_INET:
1302     {
1303       ptr.clear();
1304       char ipv4_c[INET_ADDRSTRLEN];
1305       if(!sockaddr_storage_iptop(&ip, ipv4_c)) return false;
1306 
1307       std::string ipv4 = ipv4_c;
1308       std::string octet;
1309       std::string::const_reverse_iterator crend = ipv4.rend();
1310       for (std::string::const_reverse_iterator c=ipv4.rbegin(); c != crend; ++c)
1311         if((*c)=='.')
1312         {
1313           ptr += octet + ".";
1314           octet.clear();
1315         }
1316         else
1317           octet = (*c) + octet;
1318 
1319       ptr += octet + IPV4_PTR_DOMAIN;
1320 
1321       break;
1322     }
1323     case AF_INET6:
1324     {
1325       ptr.clear();
1326       const struct sockaddr_in6 &s6 = (const struct sockaddr_in6 &) ip;
1327       const u8 * ipv6 = s6.sin6_addr.s6_addr;
1328       for (short i=15; i>=0; --i)
1329       {
1330         char tmp[3];
1331         sprintf(tmp, "%02x", ipv6[i]);
1332         ptr += '.';
1333         ptr += tmp[1];
1334         ptr += '.';
1335         ptr += tmp[0];
1336       }
1337       ptr.erase(ptr.begin());
1338       ptr += IPV6_PTR_DOMAIN;
1339       break;
1340     }
1341     default:
1342       return false;
1343   }
1344   return true;
1345 }
1346 
ptrToIp(const std::string & ptr,sockaddr_storage & ip)1347 bool DNS::Factory::ptrToIp(const std::string &ptr, sockaddr_storage &ip)
1348 {
1349   const char *cptr = ptr.c_str();
1350   const char *p = NULL;
1351 
1352   memset(&ip, 0, sizeof(sockaddr_storage));
1353 
1354   // Check whether the name ends with the IPv4 PTR domain
1355   if (NULL != (p = strcasestr(cptr + ptr.length() + 1 - sizeof(C_IPV4_PTR_DOMAIN), C_IPV4_PTR_DOMAIN)))
1356   {
1357     struct sockaddr_in *ip4 = (struct sockaddr_in *)&ip;
1358     u8 place_value[] = {1, 10, 100};
1359     u8 *v = (u8 *) &(ip4->sin_addr.s_addr);
1360     size_t place = 0;
1361     size_t i = 0;
1362 
1363     p--;
1364     while (i < sizeof(ip4->sin_addr.s_addr))
1365     {
1366       if (*p == '.')
1367       {
1368         place = 0;
1369         p--;
1370         i++;
1371       }
1372       if (p < cptr)
1373       {
1374         break;
1375       }
1376       u8 n = *p;
1377       if (n >= '0' && n <= '9') { // 0-9
1378         n -= 0x30;
1379       }
1380       else { // invalid
1381         return false;
1382       }
1383       v[i] += n * place_value[place];
1384       place++;
1385       p--;
1386     }
1387     ip.ss_family = AF_INET;
1388   }
1389   // If not, check IPv6
1390   else if (NULL != (p = strcasestr(cptr + ptr.length() + 1 - sizeof(C_IPV6_PTR_DOMAIN), C_IPV6_PTR_DOMAIN)))
1391   {
1392     struct sockaddr_in6 *ip6 = (struct sockaddr_in6 *)&ip;
1393     u8 alt = 0;
1394     size_t i=0;
1395 
1396     p--;
1397     while (i < sizeof(ip6->sin6_addr.s6_addr))
1398     {
1399       if (*p == '.')
1400       {
1401         p--;
1402       }
1403       if (p < cptr)
1404       {
1405         break;
1406       }
1407       u8 n = *p;
1408       // First subtract base regardless of underflow:
1409       if (n < 0x3A) { // 0-9
1410         n -= 0x30;
1411       }
1412       else if (n < 0x47) { // A-F
1413         n -= 0x37;
1414       }
1415       else if (n < 0x67) { // a-f
1416         n -= 0x57;
1417       }
1418       else { // invalid
1419         return false;
1420       }
1421       // Now catch any of the underflow conditions above:
1422       if (n > 0xf) { // invalid
1423         return false;
1424       }
1425       if (alt == 0) { // high nibble
1426         ip6->sin6_addr.s6_addr[i] += n << 4;
1427         alt = 1;
1428       }
1429       else { // low nibble
1430         ip6->sin6_addr.s6_addr[i] += n;
1431         alt = 0;
1432         i++;
1433       }
1434       p--;
1435     }
1436     ip.ss_family = AF_INET6;
1437   }
1438   return true;
1439 }
1440 
buildSimpleRequest(const std::string & name,RECORD_TYPE rt,u8 * buf,size_t maxlen)1441 size_t DNS::Factory::buildSimpleRequest(const std::string &name, RECORD_TYPE rt, u8 *buf, size_t maxlen)
1442 {
1443   size_t ret=0 , tmp=0;
1444   DNS_CHECK_ACCUMLATE(ret, tmp, putUnsignedShort(progressiveId++, buf, ID, maxlen)); // Postincrement inmportant here
1445   DNS_CHECK_ACCUMLATE(ret, tmp, putUnsignedShort(OP_STANDARD_QUERY | RECURSION_DESIRED, buf, FLAGS_OFFSET, maxlen));
1446   DNS_CHECK_ACCUMLATE(ret, tmp, putUnsignedShort(1, buf, QDCOUNT, maxlen));
1447   DNS_CHECK_ACCUMLATE(ret, tmp, putUnsignedShort(0, buf, ANCOUNT, maxlen));
1448   DNS_CHECK_ACCUMLATE(ret, tmp, putUnsignedShort(0, buf, NSCOUNT, maxlen));
1449   DNS_CHECK_ACCUMLATE(ret, tmp, putUnsignedShort(0, buf, ARCOUNT, maxlen));
1450   DNS_CHECK_ACCUMLATE(ret, tmp, putDomainName(name, buf, DATA, maxlen));
1451   DNS_CHECK_ACCUMLATE(ret, tmp, putUnsignedShort(rt, buf, ret, maxlen));
1452   DNS_CHECK_ACCUMLATE(ret, tmp, putUnsignedShort(CLASS_IN, buf, ret, maxlen));
1453 
1454   return ret;
1455 }
1456 
buildReverseRequest(const sockaddr_storage & ip,u8 * buf,size_t maxlen)1457 size_t DNS::Factory::buildReverseRequest(const sockaddr_storage &ip, u8 *buf, size_t maxlen)
1458 {
1459   std::string name;
1460   if(ipToPtr(ip,name))
1461     return buildSimpleRequest(name, PTR, buf, maxlen);
1462   return 0;
1463 }
1464 
putUnsignedShort(u16 num,u8 * buf,size_t offset,size_t maxlen)1465 size_t DNS::Factory::putUnsignedShort(u16 num, u8 *buf, size_t offset, size_t maxlen)
1466 {
1467   size_t max_access = offset+1;
1468   if(buf && (maxlen > max_access))
1469   {
1470     buf[offset] = (num >> 8) & 0xFF;
1471     buf[max_access] = num & 0xFF;
1472     return 2;
1473   }
1474 
1475   return 0;
1476 }
1477 
putDomainName(const std::string & name,u8 * buf,size_t offset,size_t maxlen)1478 size_t DNS::Factory::putDomainName(const std::string &name, u8 *buf, size_t offset, size_t maxlen)
1479 {
1480   size_t ret=0;
1481   if( !( buf && (maxlen > (offset + name.length() + 1))) ) return ret;
1482 
1483   std::string namew = name + ".";
1484   std::string accumulator;
1485   for (std::string::const_iterator c=namew.begin(); c != namew.end(); ++c)
1486   {
1487     if((*c)=='.')
1488     {
1489       u8 length = accumulator.length();
1490       *(buf+offset+ret) = length;
1491       ret += 1;
1492 
1493       memcpy(buf+offset+ret, accumulator.c_str(), length);
1494       ret += length;
1495       accumulator.clear();
1496     }
1497     else
1498       accumulator += (*c);
1499   }
1500 
1501   *(buf+offset+ret) = 0;
1502   ret += 1;
1503 
1504   return ret;
1505 }
1506 
parseUnsignedShort(u16 & num,const u8 * buf,size_t offset,size_t maxlen)1507 size_t DNS::Factory::parseUnsignedShort(u16 &num, const u8 *buf, size_t offset, size_t maxlen)
1508 {
1509   size_t max_access = offset+1;
1510   if(buf && (maxlen > max_access))
1511   {
1512     const u8 * n = buf + offset;
1513     num = n[1] + (n[0]<<8);
1514     return 2;
1515   }
1516 
1517   return 0;
1518 }
1519 
parseUnsignedInt(u32 & num,const u8 * buf,size_t offset,size_t maxlen)1520 size_t DNS::Factory::parseUnsignedInt(u32 &num, const u8 *buf, size_t offset, size_t maxlen)
1521 {
1522   size_t max_access = offset+3;
1523   if(buf && (maxlen > max_access))
1524   {
1525     const u8 * n = buf + offset;
1526     num = n[3] + (n[2]<<8) + (n[1]<<16) + (n[0]<<24);
1527     return 4;
1528   }
1529 
1530   return 0;
1531 }
1532 
parseDomainName(std::string & name,const u8 * buf,size_t offset,size_t maxlen)1533 size_t DNS::Factory::parseDomainName(std::string &name, const u8 *buf, size_t offset, size_t maxlen)
1534 {
1535   size_t tmp, ret = 0;
1536 
1537   name.clear();
1538   while(u8 label_length = buf[offset+ret++]) // Postincrement important here
1539   {
1540     if((label_length & COMPRESSED_NAME) == COMPRESSED_NAME)
1541     {
1542       --ret; // The byte it's part of the pointer, wasn't really consumed yet
1543       u16 real_offset;
1544       DNS_CHECK_ACCUMLATE(ret, tmp, parseUnsignedShort(real_offset, buf, offset+ret, maxlen));
1545       real_offset -= COMPRESSED_NAME<<8;
1546       if( real_offset < offset)
1547       {
1548         std::string val;
1549         DNS_CHECK_ACCUMLATE(tmp, tmp, parseDomainName(val, buf, real_offset, maxlen));
1550         name+=val;
1551         return ret;
1552       }
1553       else return 0;
1554     }
1555 
1556     for(u8 i=0; i<label_length; ++i)
1557     {
1558       size_t index = offset+ret++;  // Postincrement important here
1559       DNS_CHECK_UPPER_BOUND(index, maxlen);
1560       name += buf[index];
1561     }
1562     name += '.';
1563   }
1564 
1565   std::string::iterator it = name.end()-1;
1566   if( *it == '.') name.erase(it);
1567 
1568   return ret;
1569 }
1570 
parseFromBuffer(const u8 * buf,size_t offset,size_t maxlen)1571 size_t DNS::A_Record::parseFromBuffer(const u8 *buf, size_t offset, size_t maxlen)
1572 {
1573   size_t tmp, ret = 0;
1574   u32 num;
1575   DNS_CHECK_ACCUMLATE(ret, tmp, Factory::parseUnsignedInt(num, buf, offset, maxlen));
1576 
1577   memset(&value, 0, sizeof(value));
1578   struct sockaddr_in * ip4addr = (sockaddr_in *) &value;
1579   ip4addr->sin_family = AF_INET;
1580   ip4addr->sin_addr.s_addr = htonl(num);
1581 
1582   return ret;
1583 }
1584 
parseFromBuffer(const u8 * buf,size_t offset,size_t maxlen)1585 size_t DNS::Query::parseFromBuffer(const u8 *buf, size_t offset, size_t maxlen)
1586 {
1587   size_t ret=0;
1588 
1589   if (buf && ((maxlen - offset) > 5))
1590   {
1591     size_t tmp=0;
1592     DNS_CHECK_ACCUMLATE(ret, tmp, Factory::parseDomainName(name, buf, offset+ret, maxlen));
1593     DNS_CHECK_ACCUMLATE(ret, tmp, Factory::parseUnsignedShort(record_type, buf, offset+ret, maxlen));
1594     DNS_CHECK_ACCUMLATE(ret, tmp, Factory::parseUnsignedShort(record_class, buf, offset+ret, maxlen));
1595   }
1596 
1597   return ret;
1598 }
1599 
parseFromBuffer(const u8 * buf,size_t offset,size_t maxlen)1600 size_t DNS::Answer::parseFromBuffer(const u8 *buf, size_t offset, size_t maxlen)
1601 {
1602   size_t ret=0;
1603 
1604   if (buf && ((maxlen - offset) > 7))
1605   {
1606     size_t tmp;
1607     DNS_CHECK_ACCUMLATE(ret, tmp, Factory::parseDomainName(name, buf, offset+ret, maxlen));
1608     DNS_CHECK_ACCUMLATE(ret, tmp, Factory::parseUnsignedShort(record_type, buf, offset+ret, maxlen));
1609     DNS_CHECK_ACCUMLATE(ret, tmp, Factory::parseUnsignedShort(record_class, buf, offset+ret, maxlen));
1610     DNS_CHECK_ACCUMLATE(ret, tmp, Factory::parseUnsignedInt(ttl, buf, offset+ret, maxlen));
1611     DNS_CHECK_ACCUMLATE(ret, tmp, Factory::parseUnsignedShort(length, buf, offset+ret, maxlen));
1612 
1613     DNS_CHECK_UPPER_BOUND(offset+ret+length, maxlen);
1614 
1615     switch(record_type)
1616     {
1617     case A:
1618     {
1619       record = new A_Record();
1620       break;
1621     }
1622     case CNAME:
1623     {
1624       record = new CNAME_Record();
1625       break;
1626     }
1627     case PTR:
1628     {
1629       record = new PTR_Record();
1630       break;
1631     }
1632     default:
1633       return 0;
1634     }
1635 
1636     DNS_CHECK_ACCUMLATE(ret, tmp, record->parseFromBuffer(buf, offset+ret, maxlen));
1637   }
1638 
1639   return ret;
1640 }
1641 
operator =(const Answer & r)1642 DNS::Answer& DNS::Answer::operator=(const Answer &r)
1643 {
1644   name = r.name;
1645   record_type = r.record_type;
1646   record_class = r.record_class;
1647   ttl = r.ttl;
1648   length = r.length;
1649   record = r.record->clone();
1650   return *this;
1651 }
1652 
parseFromBuffer(const u8 * buf,size_t maxlen)1653 size_t DNS::Packet::parseFromBuffer(const u8 *buf, size_t maxlen)
1654 {
1655   if( !buf || maxlen < DATA) return 0;
1656 
1657   size_t tmp, ret = 0;
1658   DNS_CHECK_ACCUMLATE(ret, tmp, Factory::parseUnsignedShort(id, buf, ID, maxlen));
1659   DNS_CHECK_ACCUMLATE(ret, tmp, Factory::parseUnsignedShort(flags, buf, FLAGS_OFFSET, maxlen));
1660 
1661   u16 queries_counter, answers_counter, authorities_counter, additionals_counter;
1662   DNS_CHECK_ACCUMLATE(ret, tmp, Factory::parseUnsignedShort(queries_counter, buf, QDCOUNT, maxlen));
1663   DNS_CHECK_ACCUMLATE(ret, tmp, Factory::parseUnsignedShort(answers_counter, buf, ANCOUNT, maxlen));
1664   DNS_CHECK_ACCUMLATE(ret, tmp, Factory::parseUnsignedShort(authorities_counter, buf, NSCOUNT, maxlen));
1665   DNS_CHECK_ACCUMLATE(ret, tmp, Factory::parseUnsignedShort(additionals_counter, buf, ARCOUNT, maxlen));
1666 
1667   queries.clear();
1668   for(u16 i=0; i<queries_counter; ++i)
1669   {
1670     Query q;
1671     DNS_CHECK_ACCUMLATE(ret, tmp, q.parseFromBuffer(buf, ret, maxlen));
1672     queries.push_back(q);
1673   }
1674 
1675   answers.clear();
1676   for(u16 i=0; i<answers_counter; ++i)
1677   {
1678     Answer a;
1679     DNS_CHECK_ACCUMLATE(ret, tmp, a.parseFromBuffer(buf, ret, maxlen));
1680     answers.push_back(a);
1681   };
1682 
1683   return ret;
1684 }
1685