1
2 /***************************************************************************
3 * Target.cc -- The Target class encapsulates much of the information Nmap *
4 * has about a host. Results (such as ping, OS scan, etc) are stored in *
5 * this class as they are determined. *
6 * *
7 ***********************IMPORTANT NMAP LICENSE TERMS************************
8 * *
9 * The Nmap Security Scanner is (C) 1996-2020 Insecure.Com LLC ("The Nmap *
10 * Project"). Nmap is also a registered trademark of the Nmap Project. *
11 * *
12 * This program is distributed under the terms of the Nmap Public Source *
13 * License (NPSL). The exact license text applying to a particular Nmap *
14 * release or source code control revision is contained in the LICENSE *
15 * file distributed with that version of Nmap or source code control *
16 * revision. More Nmap copyright/legal information is available from *
17 * https://nmap.org/book/man-legal.html, and further information on the *
18 * NPSL license itself can be found at https://nmap.org/npsl. This header *
19 * summarizes some key points from the Nmap license, but is no substitute *
20 * for the actual license text. *
21 * *
22 * Nmap is generally free for end users to download and use themselves, *
23 * including commercial use. It is available from https://nmap.org. *
24 * *
25 * The Nmap license generally prohibits companies from using and *
26 * redistributing Nmap in commercial products, but we sell a special Nmap *
27 * OEM Edition with a more permissive license and special features for *
28 * this purpose. See https://nmap.org/oem *
29 * *
30 * If you have received a written Nmap license agreement or contract *
31 * stating terms other than these (such as an Nmap OEM license), you may *
32 * choose to use and redistribute Nmap under those terms instead. *
33 * *
34 * The official Nmap Windows builds include the Npcap software *
35 * (https://npcap.org) for packet capture and transmission. It is under *
36 * separate license terms which forbid redistribution without special *
37 * permission. So the official Nmap Windows builds may not be *
38 * redistributed without special permission (such as an Nmap OEM *
39 * license). *
40 * *
41 * Source is provided to this software because we believe users have a *
42 * right to know exactly what a program is going to do before they run it. *
43 * This also allows you to audit the software for security holes. *
44 * *
45 * Source code also allows you to port Nmap to new platforms, fix bugs, *
46 * and add new features. You are highly encouraged to submit your *
47 * changes as a Github PR or by email to the dev@nmap.org mailing list *
48 * for possible incorporation into the main distribution. Unless you *
49 * specify otherwise, it is understood that you are offering us very *
50 * broad rights to use your submissions as described in the Nmap Public *
51 * Source License Contributor Agreement. This is important because we *
52 * fund the project by selling licenses with various terms, and also *
53 * because the inability to relicense code has caused devastating *
54 * problems for other Free Software projects (such as KDE and NASM). *
55 * *
56 * The free version of Nmap is distributed in the hope that it will be *
57 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of *
58 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Warranties, *
59 * indemnification and commercial support are all available through the *
60 * Npcap OEM program--see https://nmap.org/oem. *
61 * *
62 ***************************************************************************/
63
64 /* $Id: Target.cc 38078 2020-10-02 16:12:22Z dmiller $ */
65
66 #ifdef WIN32
67 #include "nmap_winconfig.h"
68 #endif
69
70 #include "Target.h"
71 #include "FingerPrintResults.h" /* for ~FingerPrintResults() */
72 #include <dnet.h>
73 #include "nbase.h"
74 #include "NmapOps.h"
75 #include "nmap.h"
76 #include "nmap_error.h"
77
78 extern NmapOps o;
79
Target()80 Target::Target() {
81 Initialize();
82 }
83
Initialize()84 void Target::Initialize() {
85 hostname = NULL;
86 targetname = NULL;
87 memset(&seq, 0, sizeof(seq));
88 distance = -1;
89 distance_calculation_method = DIST_METHOD_NONE;
90 FPR = NULL;
91 osscan_flag = OS_NOTPERF;
92 weird_responses = flags = 0;
93 traceroute_probespec.type = PS_NONE;
94 memset(&to, 0, sizeof(to));
95 memset(&targetsock, 0, sizeof(targetsock));
96 memset(&sourcesock, 0, sizeof(sourcesock));
97 memset(&nexthopsock, 0, sizeof(nexthopsock));
98 targetsocklen = sourcesocklen = nexthopsocklen = 0;
99 directly_connected = -1;
100 targetipstring[0] = '\0';
101 sourceipstring[0] = '\0';
102 nameIPBuf = NULL;
103 memset(&MACaddress, 0, sizeof(MACaddress));
104 memset(&SrcMACaddress, 0, sizeof(SrcMACaddress));
105 memset(&NextHopMACaddress, 0, sizeof(NextHopMACaddress));
106 MACaddress_set = SrcMACaddress_set = NextHopMACaddress_set = false;
107 htn.msecs_used = 0;
108 htn.toclock_running = false;
109 htn.host_start = htn.host_end = 0;
110 interface_type = devt_other;
111 devname[0] = '\0';
112 devfullname[0] = '\0';
113 mtu = 0;
114 state_reason_init(&reason);
115 memset(&pingprobe, 0, sizeof(pingprobe));
116 pingprobe_state = PORT_UNKNOWN;
117 }
118
119
deviceName() const120 const char * Target::deviceName() const {
121 return (devname[0] != '\0')? devname : NULL;
122 }
123
deviceFullName() const124 const char * Target::deviceFullName() const {
125 return (devfullname[0] != '\0')? devfullname : NULL;
126 }
127
Recycle()128 void Target::Recycle() {
129 FreeInternal();
130 Initialize();
131 }
132
~Target()133 Target::~Target() {
134 FreeInternal();
135 #ifndef NOLUA
136 while (!scriptResults.empty()) {
137 scriptResults.front().clear();
138 scriptResults.pop_front();
139 }
140 #endif
141 }
142
FreeInternal()143 void Target::FreeInternal() {
144 /* Free the DNS name if we resolved one */
145 if (hostname)
146 free(hostname);
147
148 if (targetname)
149 free(targetname);
150
151 if (nameIPBuf) {
152 free(nameIPBuf);
153 nameIPBuf = NULL;
154 }
155
156 if (FPR) delete FPR;
157 }
158
159 /* Creates a "presentation" formatted string out of the IPv4/IPv6 address.
160 Called when the IP changes */
GenerateTargetIPString()161 void Target::GenerateTargetIPString() {
162 struct sockaddr_in *sin = (struct sockaddr_in *) &targetsock;
163 #if HAVE_IPV6
164 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &targetsock;
165 #endif
166
167 if (inet_ntop(sin->sin_family, (sin->sin_family == AF_INET)?
168 (char *) &sin->sin_addr :
169 #if HAVE_IPV6
170 (char *) &sin6->sin6_addr,
171 #else
172 (char *) NULL,
173 #endif
174 targetipstring, sizeof(targetipstring)) == NULL) {
175 fatal("Failed to convert target address to presentation format!?! Error: %s", strerror(socket_errno()));
176 }
177 }
178
179 /* Creates a "presentation" formatted string out of the IPv4/IPv6 address.
180 Called when the IP changes */
GenerateSourceIPString()181 void Target::GenerateSourceIPString() {
182 struct sockaddr_in *sin = (struct sockaddr_in *) &sourcesock;
183 #if HAVE_IPV6
184 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &sourcesock;
185 #endif
186
187 if (inet_ntop(sin->sin_family, (sin->sin_family == AF_INET)?
188 (char *) &sin->sin_addr :
189 #if HAVE_IPV6
190 (char *) &sin6->sin6_addr,
191 #else
192 (char *) NULL,
193 #endif
194 sourceipstring, sizeof(sourceipstring)) == NULL) {
195 fatal("Failed to convert source address to presentation format!?! Error: %s", strerror(socket_errno()));
196 }
197 }
198
199 /* Returns the address family of the destination address. */
af() const200 int Target::af() const {
201 return targetsock.ss_family;
202 }
203
204 /* Fills a sockaddr_storage with the AF_INET or AF_INET6 address
205 information of the target. This is a preferred way to get the
206 address since it is portable for IPv6 hosts. Returns 0 for
207 success. ss_len must be provided. It is not examined, but is set
208 to the size of the sockaddr copied in. */
TargetSockAddr(struct sockaddr_storage * ss,size_t * ss_len) const209 int Target::TargetSockAddr(struct sockaddr_storage *ss, size_t *ss_len) const {
210 assert(ss);
211 assert(ss_len);
212 if (targetsocklen <= 0)
213 return 1;
214 assert(targetsocklen <= sizeof(*ss));
215 memcpy(ss, &targetsock, targetsocklen);
216 *ss_len = targetsocklen;
217 return 0;
218 }
219
TargetSockAddr() const220 const struct sockaddr_storage *Target::TargetSockAddr() const {
221 return &targetsock;
222 }
223
224 /* Note that it is OK to pass in a sockaddr_in or sockaddr_in6 casted
225 to sockaddr_storage */
setTargetSockAddr(const struct sockaddr_storage * ss,size_t ss_len)226 void Target::setTargetSockAddr(const struct sockaddr_storage *ss, size_t ss_len) {
227
228 assert(ss_len > 0 && ss_len <= sizeof(*ss));
229 if (targetsocklen > 0) {
230 /* We had an old target sock, so we better blow away the hostname as
231 this one may be new. */
232 setHostName(NULL);
233 setTargetName(NULL);
234 }
235 memcpy(&targetsock, ss, ss_len);
236 targetsocklen = ss_len;
237 GenerateTargetIPString();
238 /* The ports array needs to know a name too */
239 ports.setIdStr(targetipstr());
240 }
241
242 // Returns IPv4 host address or {0} if unavailable.
v4host() const243 struct in_addr Target::v4host() const {
244 const struct in_addr *addy = v4hostip();
245 struct in_addr in;
246 if (addy) return *addy;
247 in.s_addr = 0;
248 return in;
249 }
250
251 // Returns IPv4 host address or NULL if unavailable.
v4hostip() const252 const struct in_addr *Target::v4hostip() const {
253 struct sockaddr_in *sin = (struct sockaddr_in *) &targetsock;
254 if (sin->sin_family == AF_INET) {
255 return &(sin->sin_addr);
256 }
257 return NULL;
258 }
259
v6hostip() const260 const struct in6_addr *Target::v6hostip() const {
261 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &targetsock;
262 if (sin6->sin6_family == AF_INET6) {
263 return &(sin6->sin6_addr);
264 }
265 return NULL;
266 }
267
268 /* The source address used to reach the target */
SourceSockAddr(struct sockaddr_storage * ss,size_t * ss_len) const269 int Target::SourceSockAddr(struct sockaddr_storage *ss, size_t *ss_len) const {
270 if (sourcesocklen <= 0)
271 return 1;
272 assert(sourcesocklen <= sizeof(*ss));
273 if (ss)
274 memcpy(ss, &sourcesock, sourcesocklen);
275 if (ss_len)
276 *ss_len = sourcesocklen;
277 return 0;
278 }
279
SourceSockAddr() const280 const struct sockaddr_storage *Target::SourceSockAddr() const {
281 return &sourcesock;
282 }
283
284 /* Note that it is OK to pass in a sockaddr_in or sockaddr_in6 casted
285 to sockaddr_storage */
setSourceSockAddr(const struct sockaddr_storage * ss,size_t ss_len)286 void Target::setSourceSockAddr(const struct sockaddr_storage *ss, size_t ss_len) {
287 assert(ss_len > 0 && ss_len <= sizeof(*ss));
288 memcpy(&sourcesock, ss, ss_len);
289 sourcesocklen = ss_len;
290 GenerateSourceIPString();
291 }
292
293 // Returns IPv4 host address or {0} if unavailable.
source() const294 struct sockaddr_storage Target::source() const {
295 return sourcesock;
296 }
297
298 // Returns IPv4 host address or NULL if unavailable.
v4sourceip() const299 const struct in_addr *Target::v4sourceip() const {
300 struct sockaddr_in *sin = (struct sockaddr_in *) &sourcesock;
301 if (sin->sin_family == AF_INET) {
302 return &(sin->sin_addr);
303 }
304 return NULL;
305 }
306
307 // Returns IPv6 host address or NULL if unavailable.
v6sourceip() const308 const struct in6_addr *Target::v6sourceip() const {
309 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &sourcesock;
310 if (sin6->sin6_family == AF_INET6) {
311 return &(sin6->sin6_addr);
312 }
313 return NULL;
314 }
315
316 /* You can set to NULL to erase a name or if it failed to resolve -- or
317 just don't call this if it fails to resolve */
setHostName(const char * name)318 void Target::setHostName(const char *name) {
319 char *p;
320 if (hostname) {
321 free(hostname);
322 hostname = NULL;
323 }
324 if (name) {
325 p = hostname = strdup(name);
326 while (*p) {
327 // I think only a-z A-Z 0-9 . and - are allowed, but I'll be a little more
328 // generous.
329 if (!isalnum((int) (unsigned char) *p) && !strchr(".-+=:_~*", *p)) {
330 log_write(LOG_STDOUT, "Illegal character(s) in hostname -- replacing with '*'\n");
331 *p = '*';
332 }
333 p++;
334 }
335 }
336 }
337
setTargetName(const char * name)338 void Target::setTargetName(const char *name) {
339 if (targetname) {
340 free(targetname);
341 targetname = NULL;
342 }
343 if (name) {
344 targetname = strdup(name);
345 }
346 }
347
348 /* Generates a printable string consisting of the host's IP
349 address and hostname (if available). Eg "www.insecure.org
350 (64.71.184.53)" or "fe80::202:e3ff:fe14:1102". The name is
351 written into the buffer provided, which is also returned. Results
352 that do not fit in buflen will be truncated. */
NameIP(char * buf,size_t buflen) const353 const char *Target::NameIP(char *buf, size_t buflen) const {
354 assert(buf);
355 assert(buflen > 8);
356 if (targetname)
357 Snprintf(buf, buflen, "%s (%s)", targetname, targetipstring);
358 else if (hostname)
359 Snprintf(buf, buflen, "%s (%s)", hostname, targetipstring);
360 else
361 Strncpy(buf, targetipstring, buflen);
362 return buf;
363 }
364
365 /* This next version returns a static buffer -- so no concurrency */
NameIP() const366 const char *Target::NameIP() const {
367 /* Add 3 characters for the hostname and IP string, hence we allocate
368 (FQDN_LEN + INET6_ADDRSTRLEN + 4) octets, with octet for the null terminator */
369 if (!nameIPBuf) nameIPBuf = (char *) safe_malloc(FQDN_LEN + INET6_ADDRSTRLEN + 4);
370 return NameIP(nameIPBuf, FQDN_LEN + INET6_ADDRSTRLEN + 4);
371 }
372
373 /* Returns the next hop for sending packets to this host. Returns true if
374 next_hop was filled in. It might be false, for example, if
375 next_hop has never been set */
nextHop(struct sockaddr_storage * next_hop,size_t * next_hop_len)376 bool Target::nextHop(struct sockaddr_storage *next_hop, size_t *next_hop_len) {
377 if (nexthopsocklen <= 0)
378 return false;
379 assert(nexthopsocklen <= sizeof(*next_hop));
380 if (next_hop)
381 memcpy(next_hop, &nexthopsock, nexthopsocklen);
382 if (next_hop_len)
383 *next_hop_len = nexthopsocklen;
384 return true;
385 }
386
387 /* If the host is directly connected on a network, set and retrieve
388 that information here. directlyConnected() will abort if it hasn't
389 been set yet. */
setDirectlyConnected(bool connected)390 void Target::setDirectlyConnected(bool connected) {
391 directly_connected = connected? 1 : 0;
392 }
393
directlyConnectedOrUnset() const394 int Target::directlyConnectedOrUnset() const {
395 return directly_connected;
396 }
397
directlyConnected() const398 bool Target::directlyConnected() const {
399 assert(directly_connected == 0 || directly_connected == 1);
400 return directly_connected;
401 }
402
403 /* Note that it is OK to pass in a sockaddr_in or sockaddr_in6 casted
404 to sockaddr_storage */
setNextHop(struct sockaddr_storage * next_hop,size_t next_hop_len)405 void Target::setNextHop(struct sockaddr_storage *next_hop, size_t next_hop_len) {
406 assert(next_hop_len > 0 && next_hop_len <= sizeof(nexthopsock));
407 memcpy(&nexthopsock, next_hop, next_hop_len);
408 nexthopsocklen = next_hop_len;
409 }
410
411 /* Set MTU (to correspond with devname) */
setMTU(int devmtu)412 void Target::setMTU(int devmtu) {
413 mtu = devmtu;
414 }
415
416 /* Get MTU (to correspond with devname) */
MTU(void)417 int Target::MTU(void) {
418 return mtu;
419 }
420
421 /* Starts the timeout clock for the host running (e.g. you are
422 beginning a scan). If you do not have the current time handy,
423 you can pass in NULL. When done, call stopTimeOutClock (it will
424 also automatically be stopped of timedOut() returns true) */
startTimeOutClock(const struct timeval * now)425 void Target::startTimeOutClock(const struct timeval *now) {
426 assert(htn.toclock_running == false);
427 htn.toclock_running = true;
428 if (now) htn.toclock_start = *now;
429 else gettimeofday(&htn.toclock_start, NULL);
430 if (!htn.host_start) htn.host_start = htn.toclock_start.tv_sec;
431 }
432 /* The complement to startTimeOutClock. */
stopTimeOutClock(const struct timeval * now)433 void Target::stopTimeOutClock(const struct timeval *now) {
434 struct timeval tv;
435 assert(htn.toclock_running == true);
436 htn.toclock_running = false;
437 if (now) tv = *now;
438 else gettimeofday(&tv, NULL);
439 htn.msecs_used += TIMEVAL_MSEC_SUBTRACT(tv, htn.toclock_start);
440 htn.host_end = tv.tv_sec;
441 }
442 /* Returns whether the host is timedout. If the timeoutclock is
443 running, counts elapsed time for that. Pass NULL if you don't have the
444 current time handy. You might as well also pass NULL if the
445 clock is not running, as the func won't need the time. */
timedOut(const struct timeval * now)446 bool Target::timedOut(const struct timeval *now) {
447 unsigned long used = htn.msecs_used;
448 struct timeval tv;
449
450 if (!o.host_timeout) return false;
451 if (htn.toclock_running) {
452 if (now) tv = *now;
453 else gettimeofday(&tv, NULL);
454 used += TIMEVAL_MSEC_SUBTRACT(tv, htn.toclock_start);
455 }
456
457 return (used > o.host_timeout);
458 }
459
460
461 /* Returns zero if MAC address set successfully */
setMACAddress(const u8 * addy)462 int Target::setMACAddress(const u8 *addy) {
463 if (!addy) return 1;
464 memcpy(MACaddress, addy, 6);
465 MACaddress_set = 1;
466 return 0;
467 }
468
setSrcMACAddress(const u8 * addy)469 int Target::setSrcMACAddress(const u8 *addy) {
470 if (!addy) return 1;
471 memcpy(SrcMACaddress, addy, 6);
472 SrcMACaddress_set = 1;
473 return 0;
474 }
475
setNextHopMACAddress(const u8 * addy)476 int Target::setNextHopMACAddress(const u8 *addy) {
477 if (!addy) return 1;
478 memcpy(NextHopMACaddress, addy, 6);
479 NextHopMACaddress_set = 1;
480 return 0;
481 }
482
483 /* Set the device names so that they can be returned by deviceName()
484 and deviceFullName(). The normal name may not include alias
485 qualifier, while the full name may include it (e.g. "eth1:1"). If
486 these are non-null, they will overwrite the stored version */
setDeviceNames(const char * name,const char * fullname)487 void Target::setDeviceNames(const char *name, const char *fullname) {
488 if (name) Strncpy(devname, name, sizeof(devname));
489 if (fullname) Strncpy(devfullname, fullname, sizeof(devfullname));
490 }
491
492 /* Returns the 6-byte long MAC address, or NULL if none has been set */
MACAddress() const493 const u8 *Target::MACAddress() const {
494 return (MACaddress_set)? MACaddress : NULL;
495 }
496
SrcMACAddress() const497 const u8 *Target::SrcMACAddress() const {
498 return (SrcMACaddress_set)? SrcMACaddress : NULL;
499 }
500
NextHopMACAddress() const501 const u8 *Target::NextHopMACAddress() const {
502 return (NextHopMACaddress_set)? NextHopMACaddress : NULL;
503 }
504
osscanPerformed(void)505 int Target::osscanPerformed(void) {
506 return osscan_flag;
507 }
508
osscanSetFlag(int flag)509 void Target::osscanSetFlag(int flag) {
510 if(osscan_flag == OS_PERF_UNREL)
511 return;
512 else
513 osscan_flag = flag;
514 }
515