Fix MDNS/Netbios names mixed with host labels

Addresses #3677
This commit is contained in:
emanuele-f 2020-05-08 12:12:52 +02:00
parent dc15a27ab6
commit 898811ff6f
4 changed files with 78 additions and 61 deletions

View file

@ -46,13 +46,14 @@ class Host : public GenericHashEntry, public AlertableEntity {
/* Host data: update Host::deleteHostData when adding new fields */
struct {
char * mdns, * mdns_txt;
char * resolved; /* The name as resolved by ntopng DNS requests */
char *mdns /* name from a MDNS reply of any type */,
*mdns_txt /* name from a TXT MDNS reply after "nm=" field (most accurate) */,
*mdns_info /* name from a TXT MDNS reply */;
char *resolved; /* The name as resolved by ntopng DNS requests */
char *netbios; /* The Netbios name */
} names;
char *mdns_info;
char *ssdpLocation;
bool host_label_set;
bool prefs_loaded;
MudRecording mud_pref;
/* END Host data: */
@ -179,6 +180,8 @@ class Host : public GenericHashEntry, public AlertableEntity {
char * getResolvedName(char * const buf, ssize_t buf_len);
char * getMDNSName(char * const buf, ssize_t buf_len);
char * getMDNSTXTName(char * const buf, ssize_t buf_len);
char * getMDNSInfo(char * const buf, ssize_t buf_len);
char * getNetbiosName(char * const buf, ssize_t buf_len);
#ifdef NTOPNG_PRO
inline TrafficShaper *get_ingress_shaper(ndpi_protocol ndpiProtocol) { return(get_shaper(ndpiProtocol, true)); }
inline TrafficShaper *get_egress_shaper(ndpi_protocol ndpiProtocol) { return(get_shaper(ndpiProtocol, false)); }
@ -255,9 +258,7 @@ class Host : public GenericHashEntry, public AlertableEntity {
void lua_get_geoloc(lua_State *vm);
void resolveHostName();
void set_host_label(char *label_name, bool ignoreIfPresent);
char *get_host_label(char * const buf, ssize_t buf_size);
inline bool is_label_set() { return(host_label_set); };
inline int compare(Host *h) { return(ip.compare(&h->ip)); };
inline bool equal(IpAddress *_ip) { return(_ip && ip.equal(_ip)); };
void incStats(u_int32_t when, u_int8_t l4_proto,
@ -346,6 +347,7 @@ class Host : public GenericHashEntry, public AlertableEntity {
void housekeepAlerts(ScriptPeriodicity p);
virtual void inlineSetOSDetail(const char *detail) { }
virtual const char* getOSDetail(char * const buf, ssize_t buf_len);
void offlineSetNetbiosName(const char * const n);
void offlineSetSSDPLocation(const char * const url);
void offlineSetMDNSInfo(char * const s);
void offlineSetMDNSName(const char * const n);

View file

@ -1350,7 +1350,7 @@ void Flow::hosts_periodic_stats_update(NetworkInterface *iface, Host *cli_host,
break;
case NDPI_PROTOCOL_NETBIOS:
if(cli_host) {
if(protos.netbios.name) cli_host->set_host_label(protos.netbios.name, true);
if(protos.netbios.name) cli_host->offlineSetNetbiosName(protos.netbios.name);
}
break;
case NDPI_PROTOCOL_IP_ICMP:

View file

@ -132,34 +132,6 @@ void Host::housekeepAlerts(ScriptPeriodicity p) {
/* *************************************** */
void Host::set_host_label(char *label_name, bool ignoreIfPresent) {
if(label_name) {
char buf[64], buf1[64], *host = ip.print(buf, sizeof(buf));
host_label_set = true;
if(ignoreIfPresent
&& (!ntop->getRedis()->hashGet((char*)HOST_LABEL_NAMES, host, buf1, (u_int)sizeof(buf1)) /* Found into redis */
&& (buf1[0] != '\0') /* Not empty */ ))
return;
else
ntop->getRedis()->hashSet((char*)HOST_LABEL_NAMES, host, label_name);
}
}
/* *************************************** */
char *Host::get_host_label(char * const buf, ssize_t buf_size) {
char ip_buf[64], *host = ip.print(ip_buf, sizeof(ip_buf));
if(ntop->getRedis()->hashGet((char*)HOST_LABEL_NAMES, host, buf, buf_size) != 0)
buf[0] = '\0';
return buf;
}
/* *************************************** */
void Host::initialize(Mac *_mac, u_int16_t _vlanId, bool init_all) {
char buf[64];
@ -189,8 +161,7 @@ void Host::initialize(Mac *_mac, u_int16_t _vlanId, bool init_all) {
active_alerted_flows = 0;
flow_alert_counter = NULL;
nextResolveAttempt = 0, mdns_info = NULL;
host_label_set = false;
nextResolveAttempt = 0;
vlan_id = _vlanId % MAX_NUM_VLAN,
memset(&names, 0, sizeof(names));
asn = 0, asname = NULL;
@ -364,6 +335,9 @@ void Host::lua_get_names(lua_State * const vm, char * const buf, ssize_t buf_siz
getResolvedName(buf, buf_size);
if(buf[0]) lua_push_str_table_entry(vm, "resolved", buf);
getNetbiosName(buf, buf_size);
if(buf[0]) lua_push_str_table_entry(vm, "netbios", buf);
if(isBroadcastDomainHost() && cur_mac) {
cur_mac->getDHCPName(buf, buf_size);
if(buf[0]) lua_push_str_table_entry(vm, "dhcp", buf);
@ -660,7 +634,7 @@ void Host::lua(lua_State* vm, AddressTree *ptree,
the actual, original interface the host is associated to. */
lua_push_uint64_table_entry(vm, "ifid", iface->get_id());
if(!mask_host)
luaStrTableEntryLocked(vm, "info", mdns_info); /* locked to protect against data-reset changes */
luaStrTableEntryLocked(vm, "info", names.mdns_info); /* locked to protect against data-reset changes */
lua_get_names(vm, buf, sizeof(buf));
@ -741,6 +715,7 @@ char* Host::get_name(char *buf, u_int buf_len, bool force_resolution_if_not_foun
num_resolve_attempts++;
/* Most relevant names goes first */
if(isBroadcastDomainHost()) {
Mac *cur_mac = getMac(); /* Cache it as it can change */
if (cur_mac) {
@ -750,16 +725,24 @@ char* Host::get_name(char *buf, u_int buf_len, bool force_resolution_if_not_foun
}
}
getMDNSName(name_buf, sizeof(name_buf));
if(strlen(name_buf))
getMDNSTXTName(name_buf, sizeof(name_buf));
if(name_buf[0])
goto out;
getMDNSTXTName(name_buf, sizeof(name_buf));
if(strlen(name_buf))
getMDNSName(name_buf, sizeof(name_buf));
if(name_buf[0])
goto out;
getMDNSInfo(name_buf, sizeof(name_buf));
if(name_buf[0])
goto out;
getNetbiosName(name_buf, sizeof(name_buf));
if(name_buf[0])
goto out;
getResolvedName(name_buf, sizeof(name_buf));
if(strlen(name_buf))
if(name_buf[0])
goto out;
if(!skip_resolution) {
@ -780,6 +763,21 @@ char* Host::get_name(char *buf, u_int buf_len, bool force_resolution_if_not_foun
/* ***************************************** */
/* Retrieve the host label. This should only be used to store persistent
* information from C. In lua use hostinfo2label instead. */
char * Host::get_host_label(char * const buf, ssize_t buf_len) {
/* Try to get a label first */
char ip_buf[64], *host = ip.print(ip_buf, sizeof(ip_buf));
if(ntop->getRedis()->hashGet((char*)HOST_LABEL_NAMES, host, buf, buf_len) != 0)
/* Not found, use the internal names instead */
get_name(buf, buf_len, false /* don't resolve */);
return buf;
}
/* ***************************************** */
char * Host::getResolvedName(char * const buf, ssize_t buf_len) {
if(buf && buf_len) {
m.lock(__FILE__, __LINE__);
@ -817,6 +815,30 @@ char * Host::getMDNSTXTName(char * const buf, ssize_t buf_len) {
/* ***************************************** */
char * Host::getMDNSInfo(char * const buf, ssize_t buf_len) {
if(buf && buf_len) {
m.lock(__FILE__, __LINE__);
snprintf(buf, buf_len, "%s", names.mdns_info ? names.mdns_info : "");
m.unlock(__FILE__, __LINE__);
}
return buf;
}
/* ***************************************** */
char * Host::getNetbiosName(char * const buf, ssize_t buf_len) {
if(buf && buf_len) {
m.lock(__FILE__, __LINE__);
snprintf(buf, buf_len, "%s", names.netbios ? names.netbios : "");
m.unlock(__FILE__, __LINE__);
}
return buf;
}
/* ***************************************** */
const char * Host::getOSDetail(char * const buf, ssize_t buf_len) {
if(buf && buf_len)
buf[0] = '\0';
@ -1217,7 +1239,7 @@ void Host::offlineSetMDNSInfo(char * const str) {
NULL
};
if(mdns_info || !str)
if(names.mdns_info || !str)
return; /* Already set */
if(strstr(str, ".ip6.arpa"))
@ -1234,8 +1256,7 @@ void Host::offlineSetMDNSInfo(char * const str) {
}
/* Time to set the actual info */
mdns_info = cur_info;
set_host_label(mdns_info, true);
names.mdns_info = cur_info;
}
return;
@ -1266,6 +1287,13 @@ void Host::offlineSetMDNSTXTName(const char * const mdns_n_txt) {
/* *************************************** */
void Host::offlineSetNetbiosName(const char * const netbios_n) {
if(!names.netbios && netbios_n && (names.netbios = strdup(netbios_n)))
;
}
/* *************************************** */
void Host::setResolvedName(const char * const resolved_name) {
/* This is NOT set inline, so we must lock. */
if(resolved_name) {
@ -1390,11 +1418,12 @@ void Host::checkBroadcastDomain() {
/* *************************************** */
void Host::freeHostNames() {
if(mdns_info) { free(mdns_info); mdns_info = NULL; }
if(ssdpLocation) { free(ssdpLocation); ssdpLocation = NULL; }
if(names.mdns) { free(names.mdns); names.mdns = NULL; }
if(names.mdns_info){ free(names.mdns_info); names.mdns_info = NULL; }
if(names.mdns_txt) { free(names.mdns_txt); names.mdns_txt = NULL; }
if(names.resolved) { free(names.resolved); names.resolved = NULL; }
if(names.netbios) { free(names.netbios); names.netbios = NULL; }
}
/* *************************************** */
@ -1418,7 +1447,6 @@ void Host::checkNameReset() {
void Host::deleteHostData() {
resetHostNames();
host_label_set = false;
first_seen = last_seen;
}

View file

@ -2745,20 +2745,7 @@ static int ntop_get_resolved_address(lua_State* vm) {
else
snprintf(value, sizeof(value), "%s", tmp);
#if 0
if(!strcmp(value, key)) {
char rsp[64];
if((ntop->getRedis()->hashGet((char*)HOST_LABEL_NAMES, key, rsp, sizeof(rsp)) == 0)
&& (rsp[0] !='\0'))
lua_pushfstring(vm, "%s", rsp);
else
lua_pushfstring(vm, "%s", value);
} else
lua_pushfstring(vm, "%s", value);
#else
lua_pushfstring(vm, "%s", value);
#endif
return(CONST_LUA_OK);
}