diff --git a/include/Flow.h b/include/Flow.h
index 60816281a0..c5f362751a 100644
--- a/include/Flow.h
+++ b/include/Flow.h
@@ -40,7 +40,6 @@ typedef struct {
u_int16_t cli2srv_window, srv2cli_window;
struct timeval synTime, synAckTime, ackTime; /* network Latency (3-way handshake) */
float clientRTT3WH, serverRTT3WH; /* Computed at 3WH (msec) */
-
time_t last_network_issues; /* last time retr/ooo/lost has been observed */
struct {
@@ -97,6 +96,7 @@ private:
#ifdef NTOPNG_PRO
FlowUDP *udp;
#endif
+ u_int32_t flow_key;
FlowCollectionInfo *collection;
/* Data collected from nProbe */
@@ -419,7 +419,8 @@ private:
void updateUDPHostServices(bool src2dst_direction);
void updateServerName(Host *h);
void allocateCollection();
-
+ void computeKey();
+
public:
Flow(NetworkInterface *_iface, int32_t iface_idx,
u_int16_t _vlanId,
@@ -967,7 +968,7 @@ public:
static char *printTCPflags(u_int8_t flags, char *const buf, u_int buf_len);
char *print(char *buf, u_int buf_len, bool full_report = true) const;
- u_int32_t key();
+ inline u_int32_t key() { return(flow_key); }
static u_int32_t key(Host *cli, u_int16_t cli_port, Host *srv,
u_int16_t srv_port, u_int16_t vlan_id,
u_int16_t _observation_point_id, u_int16_t protocol);
diff --git a/scripts/lua/flow_details.lua b/scripts/lua/flow_details.lua
index ad60062e47..12c3051c09 100644
--- a/scripts/lua/flow_details.lua
+++ b/scripts/lua/flow_details.lua
@@ -826,14 +826,13 @@ else
print("
| \n")
end
- print(
- "| " .. i18n("client") .. " " .. i18n("server") ..
- ": " .. formatPackets(flow["cli2srv.packets"]) .. " / " ..
- bytesToSize(flow["cli2srv.bytes"]) .. " | " ..
- i18n("client") .. " " .. i18n("server") ..
- ": " .. formatPackets(flow["srv2cli.packets"]) .. " / " ..
- bytesToSize(flow["srv2cli.bytes"]) .. " |
\n")
-
+ print("| " .. i18n("client") .. " " .. i18n("server") ..
+ ": " .. formatPackets(flow["cli2srv.packets"]) .. " / " ..
+ bytesToSize(flow["cli2srv.bytes"]) .. " | " ..
+ i18n("client") .. " " .. i18n("server") ..
+ ": " .. formatPackets(flow["srv2cli.packets"]) .. " / " ..
+ bytesToSize(flow["srv2cli.bytes"]) .. " |
\n")
+
print("| ")
cli2srv = round((flow["cli2srv.bytes"] * 100) / flow["bytes"], 0)
diff --git a/scripts/lua/mac_details.lua b/scripts/lua/mac_details.lua
index 0e58a557a0..f7f4fcfdb1 100644
--- a/scripts/lua/mac_details.lua
+++ b/scripts/lua/mac_details.lua
@@ -102,7 +102,7 @@ end
local mac_info = interface.getMacInfo(mac)
--- tprint(mac_info)
+-- tprint(mac_info.dhcp_fingerprint)
local only_historical = (mac_info == nil) and (page == "historical")
local serialize_by_mac = ntop.getPref(string.format("ntopng.prefs.ifid_" .. ifId .. ".serialize_local_broadcast_hosts_as_macs")) == "1"
@@ -245,9 +245,11 @@ if((page == "overview") or (page == nil)) then
print(" | |
\n")
end
- if(mac_info.fingerprint ~= "") then
- print("| DHCP Fingerprint "..''
- .." | "..mac_info.fingerprint.." |
\n")
+ if((mac_info.dhcp_fingerprint ~= nil) and (mac_info.dhcp_fingerprint ~= "")) then
+ print("| DHCP Fingerprint "..''
+ .." | "..mac_info.dhcp_fingerprint)
+ print_copy_button('dhcp_fingerprint', mac_info.dhcp_fingerprint)
+ print(" |
\n")
end
if have_nedge then
diff --git a/scripts/lua/modules/flow_utils.lua b/scripts/lua/modules/flow_utils.lua
index 5206e14fdc..e715fdc5be 100644
--- a/scripts/lua/modules/flow_utils.lua
+++ b/scripts/lua/modules/flow_utils.lua
@@ -666,16 +666,10 @@ local function formatFlowHost(flow, cli_or_srv, historical_bounds, hyperlink_suf
host_name = host_name .. format_utils.formatFullAddressCategory(host)
- local mac
- if (host == nil) then
- mac = nil
- else
- mac = host["mac"]
- end
+ local mac
+ mac = flow[cli_or_srv..".mac"]
- return
- hostinfo2detailshref(flow2hostinfo(flow, cli_or_srv), hyperlink_params, host_name, tooltip, true --[[ perform link existance checks --]] ),
- mac
+ return hostinfo2detailshref(flow2hostinfo(flow, cli_or_srv), hyperlink_params, host_name, tooltip, true --[[ perform link existance checks --]] ), mac
end
function formatFlowPort(flow, cli_or_srv, port, historical_bounds)
diff --git a/src/Flow.cpp b/src/Flow.cpp
index caf8ee8509..cef3e31014 100644
--- a/src/Flow.cpp
+++ b/src/Flow.cpp
@@ -315,6 +315,7 @@ Flow::Flow(NetworkInterface *_iface,
break;
}
+ computeKey();
deferredInitialization();
}
@@ -2740,7 +2741,8 @@ bool Flow::equal(const Mac *_src_pkt_mac, const Mac *_dst_pkt_mac,
bool *src2srv_direction) const {
const IpAddress *cli_ip = get_cli_ip_addr(), *srv_ip = get_srv_ip_addr();
const Mac *src_mac, *dst_mac;
-
+ bool useMacAddressInFlowKey = ntop->getPrefs()->useMacAddressInFlowKey();
+
#if 0
if(ntohs(_cli_port) == 17446) {
char buf1[64],buf2[64],buf3[64],buf4[64];
@@ -2784,7 +2786,11 @@ bool Flow::equal(const Mac *_src_pkt_mac, const Mac *_dst_pkt_mac,
return (false);
/* Check if MAC address needs to be used in flow key */
- if(ntop->getPrefs()->useMacAddressInFlowKey()) {
+ if((cli_ip->key() == 0) && (srv_ip->key() == 0xFFFFFFFF)) {
+ useMacAddressInFlowKey = true;
+ }
+
+ if(useMacAddressInFlowKey) {
if(cli_host && src_mac) {
Mac *cli_mac = cli_host->getMac();
@@ -2920,7 +2926,7 @@ void Flow::lua(lua_State *vm, AddressTree *ptree,
u_char community_id[200];
char buf[64];
Mac *cli_mac = get_cli_host() ? get_cli_host()->getMac() : NULL;
-
+
if(ptree) {
if(src_ip) src_match = src_ip->match(ptree);
if(dst_ip) dst_match = dst_ip->match(ptree);
@@ -3372,7 +3378,7 @@ void Flow::clearRisks() {
/* *************************************** */
-u_int32_t Flow::key() {
+void Flow::computeKey() {
u_int32_t k = cli_port + srv_port + vlanId + protocol + privateFlowId;
#ifdef MAKE_OBSERVATION_POINT_KEY
@@ -3383,7 +3389,16 @@ u_int32_t Flow::key() {
if(get_srv_ip_addr()) k += get_srv_ip_addr()->key();
if(icmp_info) k += icmp_info->key();
- return (k);
+ if(get_cli_ip_addr() && get_srv_ip_addr()) {
+ if((get_cli_ip_addr()->key() == 0) && (get_srv_ip_addr()->key() == 0xFFFFFFFF)) {
+ /* Add the MAC address of the source host (dst_mac is not necessary as it's FF:FF:FF:FF:FF:FF) */
+ Mac *cli_mac = get_cli_host()->getMac();
+
+ if(cli_mac != NULL) k += cli_mac->key();
+ }
+ }
+
+ flow_key = k;
}
/* *************************************** */
@@ -7383,8 +7398,7 @@ void Flow::lua_get_ip(lua_State *vm, bool client) const {
mask_host ? 0 : h->key());
if(h->isProtocolServer())
- lua_push_bool_table_entry(
- vm, client ? "cli.protocol_server" : "srv.protocol_server", true);
+ lua_push_bool_table_entry(vm, client ? "cli.protocol_server" : "srv.protocol_server", true);
} else if(h_ip) {
/* Host hasn't been instantiated but we still have the ip address (e.g, in
* viewed interfaces) */
@@ -7410,11 +7424,14 @@ void Flow::lua_get_mac(lua_State *vm, bool client) const {
Host *h = client ? get_cli_host() : get_srv_host();
if(h) {
- lua_push_str_table_entry(vm, client ? "cli.mac" : "srv.mac",
- Utils::formatMac(h->get_mac(), buf, sizeof(buf)));
- lua_push_bool_table_entry(
- vm, client ? "cli.serialize_by_mac" : "srv.serialize_by_mac",
- h->serializeByMac());
+ Mac *m = h->getMac();
+
+ if(m != NULL) {
+ lua_push_str_table_entry(vm, client ? "cli.mac" : "srv.mac",
+ m->print(buf, sizeof(buf)));
+ lua_push_bool_table_entry(vm, client ? "cli.serialize_by_mac" : "srv.serialize_by_mac",
+ h->serializeByMac());
+ }
}
}
diff --git a/src/FlowHash.cpp b/src/FlowHash.cpp
index cd0dcabdee..a45514d38b 100644
--- a/src/FlowHash.cpp
+++ b/src/FlowHash.cpp
@@ -33,34 +33,40 @@ FlowHash::FlowHash(NetworkInterface *_iface, u_int _num_hashes,
static u_int16_t max_num_loops = 0;
-Flow *FlowHash::find(Mac *src_mac, Mac *dst_mac, IpAddress *src_ip,
+Flow* FlowHash::find(Mac *src_mac, Mac *dst_mac, IpAddress *src_ip,
IpAddress *dst_ip, u_int16_t src_port, u_int16_t dst_port,
u_int16_t vlanId, u_int16_t observation_point_id,
u_int32_t private_flow_id, u_int8_t protocol,
const ICMPinfo *const icmp_info, bool *src2dst_direction,
bool is_inline_call, Flow **unswapped_flow) {
- u_int32_t hash = ((src_ip->key() +
- dst_ip->key() +
- (icmp_info ? icmp_info->key() : 0) +
- private_flow_id +
- src_port +
- dst_port +
- vlanId +
- protocol) %
- num_hashes);
- Flow *head = (Flow *)table[hash];
+ u_int32_t hash;
+ Flow *head;
u_int16_t num_loops = 0;
+ hash = src_ip->key() + dst_ip->key() +
+ (icmp_info ? icmp_info->key() : 0) +
+ private_flow_id +
+ src_port + dst_port + vlanId + protocol;
+
+ if((src_ip->key() == 0) && (dst_ip->key() == 0xFFFFFFFF)) {
+ /* Add the MAC address of the source host (dst_mac is not necessary as it's FF:FF:FF:FF:FF:FF) */
+ if(src_mac != NULL) hash += src_mac->key();
+ }
+
+ hash %= num_hashes;
+
+ head = (Flow *)table[hash];
+
*unswapped_flow = NULL;
#if 0
ntop->getTrace()->traceEvent(TRACE_NORMAL, "[%s] %u:%u / %u:%u [icmp key: %u]"
- "[priv flow id: %u][vlan: %u][protocol: %u]"
- "[hash: %u][head: 0x%x]",
- iface->get_name(),
- src_ip->key(), ntohs(src_port), dst_ip->key(), ntohs(dst_port),
- icmp_info ? icmp_info->key() : 0,
- private_flow_id, vlanId, protocol, hash, head);
+ "[priv flow id: %u][vlan: %u][protocol: %u]"
+ "[hash: %u][head: 0x%x]",
+ iface->get_name(),
+ src_ip->key(), ntohs(src_port), dst_ip->key(), ntohs(dst_port),
+ icmp_info ? icmp_info->key() : 0,
+ private_flow_id, vlanId, protocol, hash, head);
#endif
if (!head) return (NULL);
diff --git a/src/HostHash.cpp b/src/HostHash.cpp
index 75b951533a..151857dc3e 100644
--- a/src/HostHash.cpp
+++ b/src/HostHash.cpp
@@ -33,13 +33,20 @@ HostHash::HostHash(NetworkInterface *_iface, u_int _num_hashes,
/* ************************************ */
-Host *HostHash::get(u_int16_t vlanId, IpAddress *key, Mac *mac,
+Host* HostHash::get(u_int16_t vlanId, IpAddress *key, Mac *mac,
bool is_inline_call, u_int16_t observation_point_id) {
- u_int32_t hash = (key->key() % num_hashes);
+ u_int32_t hash = key->key();
- /* Check if MAC address needs to be used in host key */
- if (ntop->getPrefs()->useMacAddressInFlowKey() == false) mac = NULL;
+ if((hash == 0 /* 0.0.0.0 */) && (mac != NULL))
+ hash += mac->key();
+ else {
+ /* Check if MAC address needs to be used in host key */
+ if (ntop->getPrefs()->useMacAddressInFlowKey() == false)
+ mac = NULL;
+ }
+ hash %= num_hashes;
+
if (table[hash] == NULL) {
return (NULL);
} else {