ntopng/include/Mac.h
2026-03-16 12:40:56 +01:00

240 lines
7.8 KiB
C++

/*
*
* (C) 2013-26 - ntop.org
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef _MAC_H_
#define _MAC_H_
#include "ntop_includes.h"
class Mac : public GenericHashEntry {
private:
Mutex m;
u_int8_t mac[6];
u_int16_t host_pool_id;
u_int32_t bridge_seen_iface_id; /* != 0 for bridge interfaces only */
bool special_mac, lockDeviceTypeChanges, broadcast_mac, asset_map_updated,
empty_mac;
bool stats_reset_requested, data_delete_requested;
const char* manuf;
MacStats *stats, *stats_shadow;
time_t last_stats_reset;
ndpi_os device_os; /* This is the OS hint has observed via MAC address */
#ifdef HAVE_NEDGE
u_int32_t last_counter_reset;
std::vector<std::string> events;
#endif
struct {
char* dhcp; /* Extracted from DHCP dissection */
} names;
char* dhcpv4_fingerprint;
char* model;
char* ssid;
bool source_mac;
DeviceType device_type;
#ifdef NTOPNG_PRO
time_t captive_portal_notified;
#endif
/* END Mac data: */
void checkDeviceTypeFromManufacturer();
void readDHCPCache();
void freeMacData();
void deleteMacData();
bool statsResetRequested();
void checkStatsReset();
void dumpToRedis();
void guessDeviceType();
public:
Mac(NetworkInterface* _iface, u_int8_t _mac[6]);
~Mac();
inline u_int32_t getNumHosts() { return getUses(); }
void setDeviceType(DeviceType devtype);
inline void incUses() {
GenericHashEntry::incUses();
if (getUses() > CONST_MAX_NUM_HOST_USES) {
setDeviceType(device_networking);
lockDeviceTypeChanges = true;
}
}
inline void decUses() { GenericHashEntry::decUses(); }
inline bool isSpecialMac() { return (special_mac); }
inline bool isEmptyMac() { return (empty_mac); }
inline bool isSourceMac() { return (source_mac); }
inline void setSourceMac() {
if (!source_mac && !special_mac) {
source_mac = true;
iface->incNumL2Devices();
}
}
#ifdef HAVE_NEDGE
MacLocation locate();
#endif
inline u_int32_t key() { return (Utils::macHash(mac)); }
inline const u_int8_t* const get_mac() const { return (mac); }
u_int64_t get_mac64();
inline const char* get_manufacturer() { return manuf ? manuf : NULL; }
bool isNull() const;
bool equal(const u_int8_t _mac[6]);
bool equal(const Mac* m) {
return ((memcmp(mac, m->mac, 6) == 0) ? true : false);
};
inline void set(u_int8_t* macval) { memcpy(mac, macval, 6); };
#ifdef NTOPNG_PRO
inline time_t getNotifiedTime() { return captive_portal_notified; };
inline void setNotifiedTime() { captive_portal_notified = time(NULL); };
#endif
inline void setSeenIface(u_int32_t idx) {
bridge_seen_iface_id = idx;
setSourceMac();
}
inline u_int32_t getSeenIface() { return (bridge_seen_iface_id); }
void setDeviceOS(ndpi_os _os);
inline ndpi_os getDeviceOS() { return (device_os); }
inline void forceDeviceType(DeviceType devtype) {
/* Called when a user, from the GUI, wants to change the device type and
* specify a custom type */
device_type = devtype;
/* If the user specifies a custom type, then we want ntopng to stop guessing
other types for the same device */
if (!lockDeviceTypeChanges) lockDeviceTypeChanges = true;
}
inline DeviceType getDeviceType() { return (device_type); }
char* getDHCPName(char* const buf, ssize_t buf_size);
inline char* getDHCPNamePtr() { return (names.dhcp); }
char* getDHCPNameNotLowerCase(char* const buf, ssize_t buf_size);
void set_hash_entry_state_idle();
void lua(lua_State* vm, bool show_details, bool asListElement);
virtual char* get_string_key(char* buf, u_int buf_len) const {
return (Utils::formatMac(mac, buf, buf_len));
};
inline int16_t findAddress(AddressTree* ptree) {
return ptree ? ptree->findMac(mac) : -1;
};
inline char* print(char* str, u_int str_len) {
return (Utils::formatMac(mac, str, str_len));
};
void updateHostPool(bool isInlineCall, bool firstUpdate = false);
void inlineSetModel(const char* m);
void setDHCPFingerprint(const char* f);
void inlineSetSSID(const char* s);
void inlineSetDHCPName(const char* dhcp_name);
inline u_int16_t get_host_pool() { return (host_pool_id); }
inline void requestStatsReset() { stats_reset_requested = true; };
inline void requestDataReset() {
data_delete_requested = true;
requestStatsReset();
};
void checkDataReset();
inline void incSentStats(time_t t, u_int64_t num_pkts, u_int64_t num_bytes) {
if (first_seen == 0) first_seen = t;
if (stats && (num_pkts != 0)) stats->incSentStats(t, num_pkts, num_bytes);
last_seen = t;
}
bool is_hash_entry_state_idle_transition_ready();
inline void incnDPIStats(time_t when, ndpi_protocol_category_t ndpi_category,
u_int64_t sent_packets, u_int64_t sent_bytes,
u_int64_t sent_goodput_bytes, u_int64_t rcvd_packets,
u_int64_t rcvd_bytes, u_int64_t rcvd_goodput_bytes) {
if (stats != NULL)
stats->incnDPIStats(when, ndpi_category, sent_packets, sent_bytes,
sent_goodput_bytes, rcvd_packets, rcvd_bytes,
rcvd_goodput_bytes);
}
inline void incRcvdStats(time_t t, u_int64_t num_pkts, u_int64_t num_bytes) {
if (stats && (num_pkts != 0)) stats->incRcvdStats(t, num_pkts, num_bytes);
}
char* getSerializationKey(char* buf, u_int bufsize,
bool short_format = false);
inline u_int64_t getNumSentArp() { return (stats->getNumSentArp()); }
inline u_int64_t getNumRcvdArp() { return (stats->getNumRcvdArp()); }
inline void incNumDroppedFlows() {
if (stats != NULL) stats->incNumDroppedFlows();
}
inline void incSentArpRequests() {
if (stats != NULL) stats->incSentArpRequests();
}
inline void incSentArpReplies() {
if (stats != NULL) stats->incSentArpReplies();
}
inline void incRcvdArpRequests() {
if (stats != NULL) stats->incRcvdArpRequests();
}
inline void incRcvdArpReplies() {
if (stats != NULL) stats->incRcvdArpReplies();
}
void periodic_stats_update(const struct timeval* tv, bool force_update);
inline u_int64_t getNumBytes() { return (stats->getNumBytes()); }
inline float getBytesThpt() { return (stats->getBytesThpt()); }
inline bool isMulticast() { return Utils::isMulticastMac(mac); }
inline u_int64_t getNumPktsSent() {
return stats ? stats->getNumPktsSent() : 0;
}
inline u_int64_t getNumPktsRcvd() {
return stats ? stats->getNumPktsRcvd() : 0;
}
inline u_int64_t getNumBytesSent() {
return stats ? stats->getNumBytesSent() : 0;
}
inline u_int64_t getNumBytesRcvd() {
return stats ? stats->getNumBytesRcvd() : 0;
}
inline bool isBroadcast() { return (broadcast_mac); }
inline void incNumDHCPRequests() { stats->incNumDHCPRequests(); }
inline void incNumDHCPReplies() { stats->incNumDHCPReplies(); }
inline bool isAssetUpdated() { return (asset_map_updated); }
#ifdef NTOPNG_PRO
void dumpAssetMac(ndpi_serializer* serializer);
void dumpAssetInfo(ndpi_serializer* serializer);
void dumpMacInfo(bool add_last_seen);
void analyzeDevice();
#endif
inline char* getDHCPfingerprint() { return (dhcpv4_fingerprint); }
#ifdef HAVE_NEDGE
void logMacEvent(char* msg);
#endif
};
#endif /* _MAC_H_ */