ntopng/include/HostAlert.h
Ivan Nardi 8ee8b740ea
First batch of make cppcheck clean up (#10878)
Rework the `cppcheck:` recipe so it is usable in practice:
  - `--enable=all` -> `--enable=warning,performance,portability`
    (drops the `style`/`information`/`unusedFunction` groups, which produced
    hundreds of opinion-level hits)
  - drop `--force` (was re-analyzing every file once per #ifdef combination;
    single files took 40+ min). Analyzes the default build config only.
  - add `-j $(shell nproc)` + `--cppcheck-build-dir=.cppcheck-build` for
    parallelism and incremental caching; `mkdir -p` the cache dir in the recipe
  - suppress checks that are noise for this codebase:
      * useInitializationList  - micro perf, POD members
      * duplInheritedMember    - intentional non-virtual name shadowing
        (operator[], swap, enqueue, incUses, lua, ...)
      * noCopyConstructor / noOperatorEq - the flagged classes
        (NetworkInterface, Ntop, Flow, ...) are non-copyable by design and
        always held by pointer; the fix cppcheck suggests (add operator=)
        is meaningless for them
  - .gitignore: ignore the new .cppcheck-build/ cache directory

FlowAlertsLoader::registerRisk (src/FlowAlertsLoader.cpp)
  Missing `else`: `alert_to_risk[alert_type.id] = risk` was executed even when
  `alert_type.id >= MAX_DEFINED_FLOW_ALERT_TYPE` -> out-of-bounds array write.
  The sibling registerAlert() already had the `else`.

Uninitialized ndpi_protocol structs (src/NetworkInterface.cpp x6,
src/LuaEngineInterface.cpp x1)
  Local `ndpi_protocol` values were only partially initialized (proto.* set,
  but breed/fpc/state/category/custom_category_userdata left indeterminate)
  and then passed by value to get_ndpi_full_proto_name() /
  get_ndpi_proto_category(). Added `memset(&x, 0, sizeof(x))` at each
  declaration, matching the existing convention elsewhere in the tree.

Uninitialized locals
  - src/ParserInterface.cpp: `src2dst_direction` was read on the
    `flow == NULL` path (getFlow() not called). Initialize to a defined value;
    the value is not otherwise observable on that path.
  - include/Bitmap.h (toHexString): if `buf_len <= 0` the first loop never
    runs and `strlen(buf)` reads uninitialized memory; also `strlen(buf) - 2`
    underflows (unsigned) when the string is shorter than 2 bytes. Null-
    terminate up front and hoist strlen into a `size_t`, iterate with
    `pos + 2 < len`.

src/NetworkInterface.cpp incNumHosts()/decNumHosts()
  `if (isShuttingDown() || (!host->isUnicastHost())) return;` - the second
  term is always false, the function already returned on `!isUnicastHost()`
  a few lines above. Dropped it.

include/NetworkInterface.h getActiveFlowsStats()
  Declaration and definition disagreed on the first two parameter *names*
  (`stats, status_stats` vs `ndpi_stats, stats`); types matched. Renamed the
  header params to match the implementation.

No behavioural change; each argument was already non-negative.

  - Interface id (`get_id()` returns int; kept int because 3 call sites test
    `== -1`) formatted with %u in redis-key macros -> cast the argument
    `(u_int)` at the call site:
      include/AutonomousSystem.h, include/Country.h,
      include/ObservationPoint.h, include/VLAN.h,
      src/BroadcastDomains.cpp (x2), src/HostPools.cpp, src/LocalHost.cpp,
      src/LuaEngineInterface.cpp (x3), src/NetworkInterface.cpp (x2),
      src/SyslogParserInterface.cpp
  - src/HTTPserver.cpp: `%d` with get_http_port()/get_https_port() (u_int)
    -> `%u`; the scanf-width builder `"%%%u[^|]..."` fed `int` macros -> `%d`
  - src/Flow.cpp: `"%u.%u.%u.%u"` with `int` octets from a `%d` sscanf -> `%d`;
    `%u` (arg 13) with get_protocol_category() enum -> cast `(u_int)`
  - src/MacManufacturers.cpp: `int _mac[3]` scanned with `%02x`
    (wants `unsigned int*`) -> declare `u_int _mac[3]`
  - src/StatsManager.cpp: `%lu` with `static_cast<long int>(key)` epoch values
    -> `%ld` (respects the explicit signed cast)
  - src/Trace.cpp: `"%s.%u"` with loop `int i` / `i + 1` -> `%d`
  - src/Prefs.cpp: `%u` in usage() help text fed CONST_DEFAULT_* /
    MAX_NUM_* / CLICKHOUSE_MAX_* int macros -> cast `(u_int)`

std::string / std::vector parameters taken by value, changed to `const &`
(declaration and definition kept in sync; none are virtual or overrides, so
callers are source-compatible):

  - AggregatedFlowsStats::setInfoKey
  - Flow::setL7JSON
  - CustomFlowLuaScriptAlert::setAlertMessage
  - CustomHostLuaScriptAlert::setAlertMessage, ctor (_msg)
  - ScanRealtimeAlert ctor (_alerts, std::vector)
  - CustomHostLuaScript::allocAlert (_msg)
  - OtherAlertableEntity::getAlertCachedValue / setAlertCacheValue /
    triggerAlert / releaseAlert (key, value)
  - HostAlert::init and HostAlert(HostCheckID, ...) ctor (_check_name)
  - Ntop::luaFlowCheckInfo / luaHostCheckInfo (check_name)
  - Ntop::incBlacklisHits (listname)
  - Ntop::setLuaCache (key, val)
2026-09-01 08:36:01 +02:00

132 lines
4.5 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 _HOST_ALERT_H_
#define _HOST_ALERT_H_
#include "ntop_includes.h"
class HostCheck;
class HostAlert {
private:
Host* host;
bool released; /* to be released */
bool last_released_for_host; /* there no other engaged alert at the time this
has been released */
bool expiring; /* engaged, under re-evaluation */
HostCheckID check_id;
std::string check_name;
u_int64_t rowid; /* row id used by engaged alert in the in-memory table */
time_t engage_time;
time_t release_time;
time_t timeout_time; /* used by alerts with no C++ Check to automatically
disengage */
risk_percentage
cli_pctg; /* The fraction of total risk that goes to the client */
bool is_attacker, is_victim; /* Whether the host of this alert is considered
to be an attacker o a victim */
/*
Adds to the passed `serializer` (generated with `getAlertSerializer`)
information specific to this alert
*/
virtual ndpi_serializer* getAlertJSON(ndpi_serializer* serializer) {
return serializer;
}
void init(HostCheckID _check_id, const std::string &_check_name, Host* h,
risk_percentage _cli_pctg);
public:
HostAlert(HostCheckID check_id, const std::string &check_name, Host* h,
risk_percentage _cli_pctg);
HostAlert(HostCheck* c, Host* h, risk_percentage _cli_pctg);
virtual ~HostAlert();
inline u_int8_t getCliScore() const {
return (cli_pctg * getAlertScore()) / 100;
}
inline u_int8_t getSrvScore() const {
return (getAlertScore() - getCliScore());
}
/*
An alert is assumed to be client if the client score is positive and greater
than the server score. Similarly, it is assumed to be server when the server
score is positive and greater than the client score.
*/
inline bool isClient() const {
return getCliScore() > 0 && getCliScore() > getSrvScore();
}
inline bool isServer() const {
return getSrvScore() > 0 && getSrvScore() > getCliScore();
}
inline void setAttacker() { is_attacker = true; }
inline void setVictim() { is_victim = true; }
inline bool isAttacker() const { return is_attacker; }
inline bool isVictim() const { return is_victim; }
virtual HostAlertType getAlertType() const = 0;
virtual u_int8_t getAlertScore() const { return SCORE_LEVEL_NOTICE; };
/* Alert automatically released when the condition is no longer satisfied. */
virtual bool hasAutoRelease() { return true; }
inline Host* getHost() const { return (host); }
inline HostCheckID getCheckType() const { return (check_id); }
inline std::string getCheckName() const { return (check_name); }
inline void setEngaged(u_int64_t _rowid) {
expiring = released = false;
rowid = _rowid;
}
inline void setExpiring() { expiring = true; }
inline bool isExpired() { return expiring; }
inline void setTimeout(time_t t) { timeout_time = t; }
inline time_t getTimeout() { return timeout_time; }
inline void release() {
released = true;
release_time = time(NULL);
}
inline bool isReleased() { return released; }
inline void setLastReleased() { last_released_for_host = true; }
inline bool isLastReleased() { return last_released_for_host; }
inline time_t getEngageTime() { return engage_time; }
inline time_t getReleaseTime() { return release_time; }
inline u_int32_t getRowID() { return rowid; }
inline bool equals(HostAlertType type) {
return getAlertType().id == type.id;
}
virtual bool autoAck() const { return false; };
/* Generates the JSON alert serializer with base information and per-check
* information gathered with `getAlertJSON`. NOTE: memory must be freed by the
* caller. */
ndpi_serializer* getSerializedAlert();
};
#endif /* _HOST_ALERT_H_ */