#ifdef WIN32
#include "nmap_winconfig.h"
#endif
#include "Target.h"
#include "FingerPrintResults.h"
#include <dnet.h>
#include "nbase.h"
#include "NmapOps.h"
#include "nmap.h"
#include "nmap_error.h"
extern NmapOps o;
Target::Target() {
hostname = NULL;
targetname = NULL;
memset(&seq, 0, sizeof(seq));
distance = -1;
distance_calculation_method = DIST_METHOD_NONE;
FPR = NULL;
osscan_flag = OS_NOTPERF;
weird_responses = flags = 0;
traceroute_probespec.type = PS_NONE;
memset(&to, 0, sizeof(to));
memset(&targetsock, 0, sizeof(targetsock));
memset(&sourcesock, 0, sizeof(sourcesock));
memset(&nexthopsock, 0, sizeof(nexthopsock));
targetsocklen = sourcesocklen = nexthopsocklen = 0;
directly_connected = -1;
targetipstring[0] = '\0';
sourceipstring[0] = '\0';
nameIPBuf = NULL;
memset(&MACaddress, 0, sizeof(MACaddress));
memset(&SrcMACaddress, 0, sizeof(SrcMACaddress));
memset(&NextHopMACaddress, 0, sizeof(NextHopMACaddress));
MACaddress_set = SrcMACaddress_set = NextHopMACaddress_set = false;
htn.msecs_used = 0;
htn.toclock_running = false;
htn.host_start = htn.host_end = 0;
interface_type = devt_other;
devname[0] = '\0';
devfullname[0] = '\0';
mtu = 0;
state_reason_init(&reason);
memset(&pingprobe, 0, sizeof(pingprobe));
pingprobe_state = PORT_UNKNOWN;
}
const char * Target::deviceName() const {
return (devname[0] != '\0')? devname : NULL;
}
const char * Target::deviceFullName() const {
return (devfullname[0] != '\0')? devfullname : NULL;
}
Target::~Target() {
FreeInternal();
#ifndef NOLUA
for (ScriptResults::iterator it = scriptResults.begin();
it != scriptResults.end(); it++) {
delete (*it);
}
#endif
}
void Target::FreeInternal() {
if (hostname)
free(hostname);
if (targetname)
free(targetname);
if (nameIPBuf) {
free(nameIPBuf);
nameIPBuf = NULL;
}
if (FPR) delete FPR;
for (std::vector<EarlySvcResponse *>::iterator it=earlySvcResponses.begin();
it != earlySvcResponses.end(); it++) {
free(*it);
}
earlySvcResponses.clear();
}
void Target::GenerateTargetIPString() {
struct sockaddr_in *sin = (struct sockaddr_in *) &targetsock;
#if HAVE_IPV6
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &targetsock;
#endif
if (inet_ntop(sin->sin_family, (sin->sin_family == AF_INET)?
(char *) &sin->sin_addr :
#if HAVE_IPV6
(char *) &sin6->sin6_addr,
#else
(char *) NULL,
#endif
targetipstring, sizeof(targetipstring)) == NULL) {
fatal("Failed to convert target address to presentation format!?! Error: %s", strerror(socket_errno()));
}
}
void Target::GenerateSourceIPString() {
struct sockaddr_in *sin = (struct sockaddr_in *) &sourcesock;
#if HAVE_IPV6
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &sourcesock;
#endif
if (inet_ntop(sin->sin_family, (sin->sin_family == AF_INET)?
(char *) &sin->sin_addr :
#if HAVE_IPV6
(char *) &sin6->sin6_addr,
#else
(char *) NULL,
#endif
sourceipstring, sizeof(sourceipstring)) == NULL) {
fatal("Failed to convert source address to presentation format!?! Error: %s", strerror(socket_errno()));
}
}
int Target::af() const {
return targetsock.ss_family;
}
int Target::TargetSockAddr(struct sockaddr_storage *ss, size_t *ss_len) const {
assert(ss);
assert(ss_len);
if (targetsocklen <= 0)
return 1;
assert(targetsocklen <= sizeof(*ss));
memcpy(ss, &targetsock, targetsocklen);
*ss_len = targetsocklen;
return 0;
}
const struct sockaddr_storage *Target::TargetSockAddr() const {
return &targetsock;
}
void Target::setTargetSockAddr(const struct sockaddr_storage *ss, size_t ss_len) {
assert(ss_len > 0 && ss_len <= sizeof(*ss));
if (targetsocklen > 0) {
setHostName(NULL);
setTargetName(NULL);
}
memcpy(&targetsock, ss, ss_len);
targetsocklen = ss_len;
GenerateTargetIPString();
ports.setIdStr(targetipstr());
}
struct in_addr Target::v4host() const {
const struct in_addr *addy = v4hostip();
struct in_addr in;
if (addy) return *addy;
in.s_addr = 0;
return in;
}
const struct in_addr *Target::v4hostip() const {
struct sockaddr_in *sin = (struct sockaddr_in *) &targetsock;
if (sin->sin_family == AF_INET) {
return &(sin->sin_addr);
}
return NULL;
}
const struct in6_addr *Target::v6hostip() const {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &targetsock;
if (sin6->sin6_family == AF_INET6) {
return &(sin6->sin6_addr);
}
return NULL;
}
int Target::SourceSockAddr(struct sockaddr_storage *ss, size_t *ss_len) const {
if (sourcesocklen <= 0)
return 1;
assert(sourcesocklen <= sizeof(*ss));
if (ss)
memcpy(ss, &sourcesock, sourcesocklen);
if (ss_len)
*ss_len = sourcesocklen;
return 0;
}
const struct sockaddr_storage *Target::SourceSockAddr() const {
return &sourcesock;
}
void Target::setSourceSockAddr(const struct sockaddr_storage *ss, size_t ss_len) {
assert(ss_len > 0 && ss_len <= sizeof(*ss));
memcpy(&sourcesock, ss, ss_len);
sourcesocklen = ss_len;
GenerateSourceIPString();
}
struct sockaddr_storage Target::source() const {
return sourcesock;
}
const struct in_addr *Target::v4sourceip() const {
struct sockaddr_in *sin = (struct sockaddr_in *) &sourcesock;
if (sin->sin_family == AF_INET) {
return &(sin->sin_addr);
}
return NULL;
}
const struct in6_addr *Target::v6sourceip() const {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &sourcesock;
if (sin6->sin6_family == AF_INET6) {
return &(sin6->sin6_addr);
}
return NULL;
}
void Target::setHostName(const char *name) {
char *p;
if (hostname) {
free(hostname);
hostname = NULL;
}
if (name) {
p = hostname = strdup(name);
while (*p) {
if (!isalnum((int) (unsigned char) *p) && !strchr(".-+=:_~*", *p)) {
log_write(LOG_STDOUT, "Illegal character(s) in hostname -- replacing with '*'\n");
*p = '*';
}
p++;
}
}
}
void Target::setTargetName(const char *name) {
if (targetname) {
free(targetname);
targetname = NULL;
}
if (name) {
targetname = strdup(name);
}
}
const char *Target::NameIP(char *buf, size_t buflen) const {
assert(buf);
assert(buflen > 8);
if (targetname)
Snprintf(buf, buflen, "%s (%s)", targetname, targetipstring);
else if (hostname)
Snprintf(buf, buflen, "%s (%s)", hostname, targetipstring);
else
Strncpy(buf, targetipstring, buflen);
return buf;
}
const char *Target::NameIP() const {
if (!nameIPBuf) nameIPBuf = (char *) safe_malloc(FQDN_LEN + INET6_ADDRSTRLEN + 4);
return NameIP(nameIPBuf, FQDN_LEN + INET6_ADDRSTRLEN + 4);
}
bool Target::nextHop(struct sockaddr_storage *next_hop, size_t *next_hop_len) const {
if (nexthopsocklen <= 0)
return false;
assert(nexthopsocklen <= sizeof(*next_hop));
if (next_hop)
memcpy(next_hop, &nexthopsock, nexthopsocklen);
if (next_hop_len)
*next_hop_len = nexthopsocklen;
return true;
}
void Target::setDirectlyConnected(bool connected) {
directly_connected = connected? 1 : 0;
}
int Target::directlyConnectedOrUnset() const {
return directly_connected;
}
bool Target::directlyConnected() const {
assert(directly_connected == 0 || directly_connected == 1);
return directly_connected;
}
void Target::setNextHop(const struct sockaddr_storage *next_hop, size_t next_hop_len) {
assert(next_hop_len > 0 && next_hop_len <= sizeof(nexthopsock));
memcpy(&nexthopsock, next_hop, next_hop_len);
nexthopsocklen = next_hop_len;
}
void Target::setMTU(int devmtu) {
mtu = devmtu;
}
int Target::MTU(void) const {
return mtu;
}
void Target::startTimeOutClock(const struct timeval *now) {
assert(htn.toclock_running == false);
htn.toclock_running = true;
if (now) htn.toclock_start = *now;
else gettimeofday(&htn.toclock_start, NULL);
if (!htn.host_start) htn.host_start = htn.toclock_start.tv_sec;
}
void Target::stopTimeOutClock(const struct timeval *now) {
struct timeval tv;
assert(htn.toclock_running == true);
htn.toclock_running = false;
if (now) tv = *now;
else gettimeofday(&tv, NULL);
htn.msecs_used += TIMEVAL_MSEC_SUBTRACT(tv, htn.toclock_start);
htn.host_end = tv.tv_sec;
}
bool Target::timedOut(const struct timeval *now) const {
unsigned long used = htn.msecs_used;
struct timeval tv;
if (!o.host_timeout) return false;
if (htn.toclock_running) {
if (now) tv = *now;
else gettimeofday(&tv, NULL);
used += TIMEVAL_MSEC_SUBTRACT(tv, htn.toclock_start);
}
return (used > o.host_timeout);
}
int Target::setMACAddress(const u8 *addy) {
if (!addy) return 1;
memcpy(MACaddress, addy, 6);
MACaddress_set = 1;
return 0;
}
int Target::setSrcMACAddress(const u8 *addy) {
if (!addy) return 1;
memcpy(SrcMACaddress, addy, 6);
SrcMACaddress_set = 1;
return 0;
}
int Target::setNextHopMACAddress(const u8 *addy) {
if (!addy) return 1;
memcpy(NextHopMACaddress, addy, 6);
NextHopMACaddress_set = 1;
return 0;
}
void Target::setDeviceNames(const char *name, const char *fullname) {
if (name) Strncpy(devname, name, sizeof(devname));
if (fullname) Strncpy(devfullname, fullname, sizeof(devfullname));
}
const u8 *Target::MACAddress() const {
return (MACaddress_set)? MACaddress : NULL;
}
const u8 *Target::SrcMACAddress() const {
return (SrcMACaddress_set)? SrcMACaddress : NULL;
}
const u8 *Target::NextHopMACAddress() const {
return (NextHopMACaddress_set)? NextHopMACaddress : NULL;
}
int Target::osscanPerformed(void) const {
return osscan_flag;
}
void Target::osscanSetFlag(int flag) {
if(osscan_flag == OS_PERF_UNREL)
return;
else
osscan_flag = flag;
}