diff --git a/include/Flow.h b/include/Flow.h
index b812c55944c5..d3660738db7f 100644
--- a/include/Flow.h
+++ b/include/Flow.h
@@ -78,6 +78,8 @@ class Flow : public GenericHashEntry {
} predominant_alert_info;
char *json_protocol_info, *riskInfo, *end_reason;
+ char *wlan_ssid;
+ u_int8_t wtp_mac_address[6];
/* Calculate the entropy on the first MAX_ENTROPY_BYTES bytes */
struct {
@@ -1330,6 +1332,9 @@ inline float get_goodput_bytes_thpt() const { return (goodput_bytes_thpt); };
void setFlowRiskName(char *r);
char *getFlowRiskName();
void getJSONRiskInfo(ndpi_serializer *serializer);
+ void setWLANInfo(char *wlan_ssid, u_int8_t *wtp_mac_address);
+ char *getWLANSSID() { return (wlan_ssid); };
+ u_int8_t *getWTPMACAddress() { return (wtp_mac_address); };
inline FlowTrafficStats *getTrafficStats() { return (&stats); };
inline char *get_custom_category_file() const {
diff --git a/include/ParsedFlow.h b/include/ParsedFlow.h
index 765eb188e1ee..11f56a0b1105 100644
--- a/include/ParsedFlow.h
+++ b/include/ParsedFlow.h
@@ -53,6 +53,8 @@ class ParsedFlow : public ParsedFlowCore, public ParsedeBPF {
ndpi_risk ndpi_flow_risk_bitmap;
char *ndpi_flow_risk_name;
FlowSource flow_source;
+ char *wlan_ssid;
+ u_int8_t wtp_mac_address[6];
public:
ParsedFlow();
@@ -132,6 +134,9 @@ class ParsedFlow : public ParsedFlowCore, public ParsedeBPF {
inline void setPreNATDstPort(u_int16_t v) { dst_port_pre_nat = v; };
inline void setPostNATSrcPort(u_int16_t v) { src_port_post_nat = v; };
inline void setPostNATDstPort(u_int16_t v) { dst_port_post_nat = v; };
+ inline void setWLANSSID(const char *str) { if(wlan_ssid != NULL) free(wlan_ssid); if(str) { wlan_ssid = strdup(str);} else wlan_ssid = NULL; }
+ inline void setWTPMACAddress(const char *str) { Utils::parseMac(wtp_mac_address, str); }
+
/* ****** */
inline char* getL7Info(bool setToNULL = false) { char *r = l7_info; if(setToNULL) l7_info = NULL; return(r); }
inline char* getHTTPurl(bool setToNULL = false) { char *r = http_url; if(setToNULL) http_url = NULL; return(r); }
@@ -149,6 +154,9 @@ class ParsedFlow : public ParsedFlowCore, public ParsedeBPF {
inline char* getSMTPMailFrom(bool setToNull = false) { char *r = smtp_mail_from; if(setToNull) smtp_mail_from = NULL; return(r); }
inline char* getDHCPClientName(bool setToNull = false) { char *r = dhcp_client_name; if(setToNull) dhcp_client_name = NULL; return(r); }
inline char* getSIPCallId(bool setToNull = false) { char *r = sip_call_id; if(setToNull) sip_call_id = NULL; return(r); }
+ inline char* getWLANSSID(bool setToNull = false) { char *r = wlan_ssid; if(setToNull) wlan_ssid = NULL; return(r); }
+ inline u_int8_t *getWTPMACAddress() { return wtp_mac_address; }
+
inline u_int32_t getPreNATSrcIp() { return src_ip_addr_pre_nat; };
inline u_int32_t getPreNATDstIp() { return dst_ip_addr_pre_nat; };
inline u_int32_t getPostNATSrcIp() { return src_ip_addr_post_nat; };
diff --git a/scripts/lua/flow_details.lua b/scripts/lua/flow_details.lua
index 104741c0ef30..628fa1f71403 100644
--- a/scripts/lua/flow_details.lua
+++ b/scripts/lua/flow_details.lua
@@ -2010,6 +2010,19 @@ else
end
end
+ if flow.wlan then
+ if flow.wlan.ssid then
+ print("
" .. getFlowKey('WLAN_SSID') .. " | ")
+ print("" .. flow.wlan["ssid"] .. " | ")
+ print("
\n")
+ end
+ if flow.wlan.wtp_mac_address then
+ print("" .. getFlowKey('WTP_MAC_ADDRESS') .. " | ")
+ print("" .. flow.wlan["wtp_mac_address"] .. " | ")
+ print("
\n")
+ end
+ end
+
if (flow.flow_payload ~= nil) then
local idx
diff --git a/src/Flow.cpp b/src/Flow.cpp
index 8a8e70ad6134..da3df1719da5 100644
--- a/src/Flow.cpp
+++ b/src/Flow.cpp
@@ -103,6 +103,8 @@ Flow::Flow(NetworkInterface *_iface,
ndpiFlowRiskName = NULL;
viewFlowStats = NULL, suspicious_dga_domain = NULL;
flow_payload = NULL, flow_payload_len = 0;
+ wlan_ssid = NULL;
+ memset(wtp_mac_address, 0, sizeof(wtp_mac_address));
last_db_dump.partial = NULL;
last_db_dump.first_seen = last_db_dump.last_seen = 0;
@@ -422,6 +424,7 @@ Flow::~Flow() {
if (riskInfo) free(riskInfo);
if (end_reason) free(end_reason);
+ if (wlan_ssid) free(wlan_ssid);
if (viewFlowStats) delete (viewFlowStats);
if (periodic_stats_update_partial) delete (periodic_stats_update_partial);
if (last_db_dump.partial) delete (last_db_dump.partial);
@@ -3004,6 +3007,20 @@ void Flow::lua(lua_State *vm, AddressTree *ptree, DetailsLevel details_level,
if (end_reason)
lua_push_str_table_entry(vm, "flow_end_reason", getEndReason());
+ if (wlan_ssid) {
+ char mac_buf[20];
+
+ lua_newtable(vm);
+
+ lua_push_str_table_entry(vm, "ssid", wlan_ssid);
+ lua_push_str_table_entry(vm, "wtp_mac_address",
+ Utils::formatMac(wtp_mac_address, mac_buf, sizeof(mac_buf)));
+
+ lua_pushstring(vm, "wlan");
+ lua_insert(vm, -2);
+ lua_settable(vm, -3);
+ }
+
if (isSMTP()
/* Discard SMTP connections that become TLS as the SMTP part is not populated */
&& (!isSMTPS())) {
@@ -3961,6 +3978,19 @@ void Flow::formatGenericFlow(json_object *my_object) {
sizeof(jsonbuf)),
json_object_new_string(end_reason));
+ if (wlan_ssid) {
+ char mac_buf[20];
+ json_object_object_add(my_object,
+ Utils::jsonLabel(WLAN_SSID, "WLAN_SSID", jsonbuf,
+ sizeof(jsonbuf)),
+ json_object_new_string(wlan_ssid));
+ json_object_object_add(my_object,
+ Utils::jsonLabel(WTP_MAC_ADDRESS, "WTP_MAC_ADDRESS", jsonbuf,
+ sizeof(jsonbuf)),
+ json_object_new_string(Utils::formatMac(wtp_mac_address, mac_buf,
+ sizeof(mac_buf))));
+ }
+
if (protocol == IPPROTO_TCP) {
json_object_object_add(my_object,
Utils::jsonLabel(TCP_FLAGS, "TCP_FLAGS", jsonbuf, sizeof(jsonbuf)),
@@ -8290,6 +8320,16 @@ char *Flow::getEndReason() { return (end_reason); }
/* *************************************** */
+void Flow::setWLANInfo(char *_wlan_ssid, u_int8_t *_wtp_mac_address) {
+ if (_wlan_ssid) {
+ if (wlan_ssid) free(wlan_ssid);
+ wlan_ssid = strdup(_wlan_ssid);
+ }
+ memcpy(wtp_mac_address, _wtp_mac_address, 6);
+}
+
+/* *************************************** */
+
void Flow::setSMTPMailFrom(char *r) {
if (!r) return;
diff --git a/src/ParsedFlow.cpp b/src/ParsedFlow.cpp
index 05fcba31cc75..63cc78f7595f 100644
--- a/src/ParsedFlow.cpp
+++ b/src/ParsedFlow.cpp
@@ -53,6 +53,8 @@ ParsedFlow::ParsedFlow() : ParsedFlowCore(), ParsedeBPF() {
src_ip_addr_pre_nat = dst_ip_addr_pre_nat =
src_ip_addr_post_nat = dst_ip_addr_post_nat = 0;
memset(&custom_app, 0, sizeof(custom_app));
+ wlan_ssid = NULL;
+ memset(&wtp_mac_address, 0, sizeof(wtp_mac_address));
has_parsed_ebpf = false;
}
@@ -150,6 +152,13 @@ ParsedFlow::ParsedFlow(const ParsedFlow &pf) : ParsedFlowCore(pf), ParsedeBPF(pf
else
sip_call_id = NULL;
+ if(pf.wlan_ssid)
+ wlan_ssid = strdup(pf.wlan_ssid);
+ else
+ wlan_ssid = NULL;
+
+ memcpy(&wtp_mac_address, &pf.wtp_mac_address, sizeof(wtp_mac_address));
+
tls_cipher = pf.tls_cipher;
tls_unsafe_cipher = pf.tls_unsafe_cipher;
ndpi_flow_risk_bitmap = pf.ndpi_flow_risk_bitmap;
@@ -322,6 +331,7 @@ void ParsedFlow::freeMemory() {
if (smtp_mail_from) { free(smtp_mail_from); smtp_mail_from = NULL; }
if (dhcp_client_name) { free(dhcp_client_name); dhcp_client_name = NULL; }
if (sip_call_id) { free(sip_call_id); sip_call_id = NULL; }
+ if (wlan_ssid) { free(wlan_ssid); wlan_ssid = NULL; }
}
/* *************************************** */
diff --git a/src/ParserInterface.cpp b/src/ParserInterface.cpp
index 2677ac6c5a44..61a6e7716021 100644
--- a/src/ParserInterface.cpp
+++ b/src/ParserInterface.cpp
@@ -360,6 +360,9 @@ bool ParserInterface::processFlow(ParsedFlow *zflow) {
flow->setTOS(zflow->src_tos, true), flow->setTOS(zflow->dst_tos, false);
flow->setRtt();
+ if (zflow->getWLANSSID())
+ flow->setWLANInfo(zflow->getWLANSSID(), zflow->getWTPMACAddress());
+
if(zflow->getSIPCallId())
flow->setSIPCallId(zflow->getSIPCallId());
diff --git a/src/ZMQParserInterface.cpp b/src/ZMQParserInterface.cpp
index 5ca345851cae..937d1994d1ab 100644
--- a/src/ZMQParserInterface.cpp
+++ b/src/ZMQParserInterface.cpp
@@ -76,11 +76,6 @@ ZMQParserInterface::ZMQParserInterface(const char *endpoint,
addMapping("IPV6_DST_ADDR", IPV6_DST_ADDR);
addMapping("IP_PROTOCOL_VERSION", IP_PROTOCOL_VERSION);
addMapping("PROTOCOL", PROTOCOL);
- addMapping("L7_PROTO", L7_PROTO, NTOP_PEN);
- addMapping("L7_PROTO_NAME", L7_PROTO_NAME, NTOP_PEN);
- addMapping("L7_INFO", L7_INFO, NTOP_PEN);
- addMapping("L7_CONFIDENCE", L7_CONFIDENCE, NTOP_PEN);
- addMapping("L7_ERROR_CODE", L7_ERROR_CODE, NTOP_PEN);
addMapping("IN_BYTES", IN_BYTES);
addMapping("IN_PKTS", IN_PKTS);
addMapping("OUT_BYTES", OUT_BYTES);
@@ -90,8 +85,6 @@ ZMQParserInterface::ZMQParserInterface(const char *endpoint,
addMapping("EXPORTER_IPV4_ADDRESS", EXPORTER_IPV4_ADDRESS);
addMapping("EXPORTER_IPV6_ADDRESS", EXPORTER_IPV6_ADDRESS);
addMapping("TOTAL_FLOWS_EXP", TOTAL_FLOWS_EXP);
- addMapping("NPROBE_IPV4_ADDRESS", NPROBE_IPV4_ADDRESS, NTOP_PEN);
- addMapping("NPROBE_INSTANCE_NAME", NPROBE_INSTANCE_NAME, NTOP_PEN);
addMapping("TCP_FLAGS", TCP_FLAGS);
addMapping("INITIATOR_PKTS", INITIATOR_PKTS);
addMapping("INITIATOR_OCTETS", INITIATOR_OCTETS);
@@ -113,6 +106,17 @@ ZMQParserInterface::ZMQParserInterface(const char *endpoint,
addMapping("BGP_NEXT_ADJACENT_ASN", BGP_NEXT_ADJACENT_ASN);
addMapping("BGP_PREV_ADJACENT_ASN", BGP_PREV_ADJACENT_ASN);
addMapping("FLOW_END_REASON", FLOW_END_REASON);
+ addMapping("WLAN_SSID", WLAN_SSID);
+ addMapping("WTP_MAC_ADDRESS", WTP_MAC_ADDRESS);
+
+ /* ntop IEs */
+ addMapping("L7_PROTO", L7_PROTO, NTOP_PEN);
+ addMapping("L7_PROTO_NAME", L7_PROTO_NAME, NTOP_PEN);
+ addMapping("L7_INFO", L7_INFO, NTOP_PEN);
+ addMapping("L7_CONFIDENCE", L7_CONFIDENCE, NTOP_PEN);
+ addMapping("L7_ERROR_CODE", L7_ERROR_CODE, NTOP_PEN);
+ addMapping("NPROBE_IPV4_ADDRESS", NPROBE_IPV4_ADDRESS, NTOP_PEN);
+ addMapping("NPROBE_INSTANCE_NAME", NPROBE_INSTANCE_NAME, NTOP_PEN);
addMapping("OOORDER_IN_PKTS", OOORDER_IN_PKTS, NTOP_PEN);
addMapping("OOORDER_OUT_PKTS", OOORDER_OUT_PKTS, NTOP_PEN);
addMapping("RETRANSMITTED_IN_PKTS", RETRANSMITTED_IN_PKTS, NTOP_PEN);
@@ -896,6 +900,12 @@ bool ZMQParserInterface::parsePENZeroField(ParsedFlow *const flow,
case BGP_PREV_ADJACENT_ASN:
flow->prev_adjacent_as = value->int_num;
break;
+ case WLAN_SSID:
+ if (value->string) flow->setWLANSSID(value->string);
+ break;
+ case WTP_MAC_ADDRESS:
+ if (value->string) flow->setWTPMACAddress(value->string);
+ break;
default:
ntop->getTrace()->traceEvent(TRACE_INFO,
"Skipping no-PEN flow fieldId %u", field);
@@ -1454,6 +1464,18 @@ bool ZMQParserInterface::matchPENZeroField(ParsedFlow *const flow,
else
return (flow->prev_adjacent_as == value->int_num);
+ case WLAN_SSID:
+ if (value->string) {
+ if (flow->getWLANSSID())
+ return (!strcmp(value->string, flow->getWLANSSID()));
+ }
+
+ case WTP_MAC_ADDRESS: {
+ u_int8_t mac[6];
+ Utils::parseMac(mac, value->string);
+ return (memcmp(flow->getWTPMACAddress(), mac, sizeof(mac)) == 0);
+ }
+
default:
ntop->getTrace()->traceEvent(TRACE_INFO,
"Skipping no-PEN flow fieldId %u", field);