/src/ntopng/include/Utils.h
Line | Count | Source |
1 | | /* |
2 | | * |
3 | | * (C) 2013-26 - ntop.org |
4 | | * |
5 | | * |
6 | | * This program is free software; you can redistribute it and/or modify |
7 | | * it under the terms of the GNU General Public License as published by |
8 | | * the Free Software Foundation; either version 3 of the License, or |
9 | | * (at your option) any later version. |
10 | | * |
11 | | * This program is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU General Public License |
17 | | * along with this program; if not, write to the Free Software Foundation, |
18 | | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
19 | | * |
20 | | */ |
21 | | |
22 | | #ifndef _UTILS_H_ |
23 | | #define _UTILS_H_ |
24 | | |
25 | | #include "ntop_includes.h" |
26 | | |
27 | | typedef unsigned long long ticks; |
28 | | |
29 | | #ifdef WIN32 |
30 | | #define _usleep(a) win_usleep(a) |
31 | | #else |
32 | 4 | #define _usleep(a) usleep(a) |
33 | | #endif |
34 | | |
35 | | /* ******************************* */ |
36 | | |
37 | | class Utils { |
38 | | private: |
39 | | static bool validInterfaceName(const char* name); |
40 | | static bool validInterfaceDescription(const char* description); |
41 | | static bool validInterface(const pcap_if_t* pcap_if); |
42 | | |
43 | | public: |
44 | 7.40k | static inline bool isEmptyString(const char* s) { return (!s || !s[0]); } |
45 | | static char* toLowerResolvedNames(const char* const name); |
46 | | static char* jsonLabel(int label, const char* label_str, char* buf, |
47 | | u_int buf_len); |
48 | | static char* formatTraffic(float numBits, bool bits, char* buf, |
49 | | u_int buf_len); |
50 | | static char* formatPackets(float numPkts, char* buf, u_int buf_len); |
51 | | static const char* edition2name(NtopngEdition ntopng_edition); |
52 | | static char* l4proto2name(u_int8_t proto); |
53 | | static u_int8_t l4name2proto(const char* name); |
54 | | static u_int8_t queryname2type(const char* name); |
55 | | static bool isIPAddress(const char* ip); |
56 | | static void splitAddressAndVlan(char* addr, u_int16_t* vlan_id); |
57 | | static const bool isIpEmpty(ipAddress addr); |
58 | | #ifdef __linux__ |
59 | | static int setAffinityMask(char* cores_list, cpu_set_t* mask); |
60 | | static int setThreadAffinityWithMask(pthread_t thread, cpu_set_t* mask); |
61 | | #endif |
62 | | static int setThreadAffinity(pthread_t thread, int core_id); |
63 | | static void setThreadName(const char* name); |
64 | | static char* trim(char* s); |
65 | | static u_int32_t hashString(const char* s, |
66 | | u_int32_t len = 0 /* automatically computed */); |
67 | | static float timeval2ms(const struct timeval* tv); |
68 | | #ifdef PROFILING |
69 | | static u_int64_t getTimeNsec(); |
70 | | #endif |
71 | | static float msTimevalDiff(const struct timeval* end, |
72 | | const struct timeval* begin); |
73 | | static u_int32_t usecTimevalDiff(const struct timeval* end, |
74 | | const struct timeval* begin); |
75 | | /* Returns the difference new_value - cur_value and then stores new_value in |
76 | | * *cur_value */ |
77 | | template <typename T> |
78 | | static inline T uintDiff(T* cur_value, T new_value) { |
79 | | T res = new_value > *cur_value ? new_value - *cur_value : 0; |
80 | | *cur_value = new_value; |
81 | | return res; |
82 | | }; |
83 | | static size_t file_write(const char* path, const char* content, |
84 | | size_t content_len); |
85 | | static size_t file_read(const char* path, char** content); |
86 | | static bool file_exists(const char* path); |
87 | | static bool dir_exists(const char* path); |
88 | | static int8_t num_files_in_dir(const char* dir); |
89 | | static bool mkdir_tree(char* const path); |
90 | | static int mkdir(const char* pathname, mode_t mode); |
91 | | static void lua_getpaths_recursively(lua_State* vm, const char* path, |
92 | | const char* filename); |
93 | | static int remove_recursively(const char* path); |
94 | | static const char* trend2str(ValueTrend t); |
95 | | static int dropPrivileges(); |
96 | | static char* base64_encode(unsigned char const* bytes_to_encode, |
97 | | ssize_t in_len); |
98 | | static std::string base64_decode(std::string const& encoded_string); |
99 | | static double pearsonValueCorrelation(activity_bitmap* x, activity_bitmap* y); |
100 | | static double JaccardSimilarity(activity_bitmap* x, activity_bitmap* y); |
101 | | static int ifname2id(const char* name); |
102 | | static char* stringtolower(char* str); |
103 | | static std::string list2JsonArray(const char* s); |
104 | | static char* sanitizeHostName(char* str); |
105 | | static char* urlDecode(const char* src, char* dst, u_int dst_len); |
106 | | static bool isValidUTF8(const u_char* param, size_t length); |
107 | | static bool purifyHTTPparam(char* const param, bool strict, bool allowURL, |
108 | | bool allowDots); |
109 | | static char* stripHTML(const char* str); |
110 | | static bool sendTCPData(char* host, int port, char* data, int timeout); |
111 | | static bool sendUDPData(char* host, int port, char* data); |
112 | | static bool postHTTPJsonData(char* bearer_token, char* username, |
113 | | char* password, char* url, char* json, |
114 | | int connect_timeout, int max_duration_timeout, |
115 | | HTTPTranferStats* stats); |
116 | | static bool postHTTPJsonData(char* bearer_token, char* username, |
117 | | char* password, char* url, char* json, |
118 | | int connect_timeout, int max_duration_timeout, |
119 | | HTTPTranferStats* stats, char* return_data, |
120 | | int return_data_size, int* response_code); |
121 | | static bool sendMail(lua_State* vm, char* from, char* to, char* cc, |
122 | | char* message, char* smtp_server, char* username, |
123 | | char* password, bool use_proxy, bool verbose); |
124 | | static bool postHTTPTextFile(lua_State* vm, char* username, char* password, |
125 | | char* url, char* path, int connect_timeout, |
126 | | int max_duration_timeout, |
127 | | HTTPTranferStats* stats); |
128 | | static bool httpGetPostPutPatch(lua_State* vm, char* url, HttpMethod method, |
129 | | const HttpGetPostOptions& opts = {}); |
130 | | static long httpGet(const char* url, const char* username, |
131 | | const char* password, const char* user_header_token, |
132 | | int connect_timeout, int max_duration_timeout, |
133 | | char* const resp, const u_int resp_len); |
134 | | static bool progressCanContinue(ProgressState* progressState); |
135 | | static char* urlEncode(const char* url); |
136 | | static ticks getticks(); |
137 | | static ticks gettickspersec(); |
138 | | static char* getURL(char* url, char* buf, u_int buf_len); |
139 | | static bool discardOldFilesExceeding(const char* path, |
140 | | const unsigned long max_size); |
141 | | static u_int64_t macaddr_int(const u_int8_t* mac); |
142 | | static char* ifname2devname(const char* ifname, char* devname, |
143 | | int devname_size); |
144 | | static void readMac(const char* ifname, dump_mac_t mac_addr); |
145 | | static u_int32_t readIPv4(char* ifname); |
146 | | static bool readIPv6(char* ifname, struct in6_addr* sin); |
147 | | static u_int32_t getMaxIfSpeed(const char* ifname); |
148 | | static u_int16_t getIfMTU(const char* ifname); |
149 | | static int ethtoolGet(const char* ifname, int cmd, uint32_t* v); |
150 | | static int ethtoolSet(const char* ifname, int cmd, uint32_t v); |
151 | | static int disableOffloads(const char* ifname); |
152 | | static bool isGoodNameToCategorize(char* name); |
153 | | static char* get2ndLevelDomain(char* _domainname); |
154 | | static char* tokenizer(char* arg, int c, char** data); |
155 | | static in_addr_t inet_addr(const char* cp); |
156 | | static char* intoaV4(unsigned int addr, char* buf, u_short bufLen); |
157 | | static char* intoaV6(struct ndpi_in6_addr ipv6, char* buf, u_short bufLen); |
158 | | static u_int64_t timeval2usec(const struct timeval* tv); |
159 | | static void xor_encdec(u_char* data, int data_len, u_char* key); |
160 | | static bool isPrintableChar(u_char c); |
161 | | static char* formatMacAddress(const u_int8_t* const mac, char* buf, |
162 | | u_int buf_len); |
163 | | static char* formatMac(const u_int8_t* const mac, char* buf, u_int buf_len); |
164 | | static u_int64_t encodeMacTo64(u_int8_t mac[6]); |
165 | | static void decode64ToMac(u_int64_t mac64, u_int8_t mac[6] /* out */); |
166 | | static void parseMac(u_int8_t* mac, const char* symMac); |
167 | | static u_int32_t macHash(const u_int8_t* const mac); |
168 | | static bool isEmptyMac(const u_int8_t* const mac); |
169 | | static bool isSpecialMac(u_int8_t* mac); |
170 | 0 | inline static bool isBroadMulticastMac(const u_int8_t* mac) { |
171 | 0 | return (isBroadcastMac(mac) || isMulticastMac(mac)); |
172 | 0 | } |
173 | | static bool isBroadcastMac(const u_int8_t* mac); |
174 | | static bool isMulticastMac(const u_int8_t* mac); |
175 | | static int numberOfSetBits(u_int32_t i); |
176 | | static void initRedis(Redis** r, const char* redis_host, |
177 | | const char* redis_password, u_int16_t redis_port, |
178 | | u_int8_t _redis_db_id, bool giveup_on_failure, |
179 | | const char* tls_ca_cert = NULL, |
180 | | const char* tls_cert = NULL, |
181 | | const char* tls_key = NULL, |
182 | | bool tls_skip_verify = false); |
183 | | static json_object* cloneJSONSimple(json_object* src); |
184 | | |
185 | | /* ScriptPeriodicity */ |
186 | | static const char* periodicityToScriptName(ScriptPeriodicity p); |
187 | | static int periodicityToSeconds(ScriptPeriodicity p); |
188 | | |
189 | | /* eBPF-related */ |
190 | | static int tcpStateStr2State(const char* state_str); |
191 | | static const char* tcpState2StateStr(int state); |
192 | | static eBPFEventType eBPFEventStr2Event(const char* event_str); |
193 | | static const char* eBPFEvent2EventStr(eBPFEventType event); |
194 | | |
195 | | static bool str2DetailsLevel(const char* details, DetailsLevel* out); |
196 | | static u_int32_t roundTime(u_int32_t now, u_int32_t rounder, |
197 | | int32_t offset_from_utc); |
198 | | static bool isCriticalNetworkProtocol(u_int16_t protocol_id); |
199 | | static u_int32_t stringHash(const char* s); |
200 | | static const char* policySource2Str(L7PolicySource_t policy_source); |
201 | | static const char* captureDirection2Str(pcap_direction_t dir); |
202 | | static bool readInterfaceStats(const char* ifname, ProtoStats* in_stats, |
203 | | ProtoStats* out_stats); |
204 | | static bool shouldResolveHost(const char* host_ip); |
205 | | static bool mg_write_retry(struct mg_connection* conn, u_char* b, int len); |
206 | | static bool parseAuthenticatorJson(HTTPAuthenticator* auth, char* content); |
207 | | static void freeAuthenticator(HTTPAuthenticator* auth); |
208 | | static DetailsLevel bool2DetailsLevel(bool max, bool higher, |
209 | | bool normal = false); |
210 | | |
211 | | /* Patricia Tree */ |
212 | | static ndpi_patricia_node_t* add_to_ptree(ndpi_patricia_tree_t* tree, |
213 | | int family, void* addr, int bits); |
214 | | static ndpi_patricia_node_t* ptree_match(ndpi_patricia_tree_t* tree, |
215 | | int family, const void* const addr, |
216 | | int bits); |
217 | | static ndpi_patricia_node_t* ptree_add_rule(ndpi_patricia_tree_t* ptree, |
218 | | const char* line); |
219 | | static bool ptree_prefix_print(ndpi_prefix_t* prefix, char* buffer, |
220 | | size_t bufsize); |
221 | | |
222 | | static inline void update_ewma(u_int32_t sample, u_int32_t* ewma, |
223 | 172 | u_int8_t alpha_percent) { |
224 | 172 | if (alpha_percent > 100) alpha_percent = 100; |
225 | 172 | if (!ewma) return; |
226 | 172 | (*ewma) = (alpha_percent * sample + (100 - alpha_percent) * (*ewma)) / 100; |
227 | 172 | } |
228 | 0 | static inline u_int64_t toUs(const struct timeval* t) { |
229 | 0 | return (((u_int64_t)t->tv_sec) * 1000000 + ((u_int64_t)t->tv_usec)); |
230 | 0 | }; |
231 | | static void replacestr(char* line, const char* search, const char* replace); |
232 | | static u_int32_t getHostManagementIPv4Address(); |
233 | | static bool isInterfaceUp(char* ifname); |
234 | | static bool maskHost(bool isLocalIP); |
235 | | static char* getInterfaceDescription(char* ifname, char* buf, int buf_len); |
236 | | static int bindSockToDevice(int sock, int family, const char* devicename); |
237 | | static bool execCmd(char* cmd, std::string* out); |
238 | | static void maximizeSocketBuffer(int sock_fd, bool rx_buffer, |
239 | | u_int max_buf_mb); |
240 | | static u_int32_t parsetime(char* str); |
241 | | static time_t str2epoch(const char* str); |
242 | | static u_int64_t mac2int(const u_int8_t* mac); |
243 | | static u_int8_t* int2mac(u_int64_t mac, u_int8_t* buf); |
244 | | static void listInterfaces(lua_State* vm); |
245 | | static bool validInterface(const ntop_if_t* ntop_if); |
246 | | static void containerInfoLua(lua_State* vm, const ContainerInfo* const cont); |
247 | | static char* ntop_lookupdev(char* ifname_out, int ifname_size); |
248 | | static int get_ifindex(const char* ifname); |
249 | | static char* get_real_name(const char* ifname_alias, ntop_if_t* devlist); |
250 | | static char* get_real_name(const char* ifname_alias); |
251 | | /** |
252 | | * @brief Return all the available interfaces |
253 | | * @details Return all the available interfaces, unifying data from PF_RING |
254 | | * and pcap, and excluding invalid interfaces Interfaces are returned as a |
255 | | * linked-list in the **alldevsp parameter. |
256 | | * |
257 | | * @return returns 0 on success and -1 on failure |
258 | | */ |
259 | | static int ntop_findalldevs(ntop_if_t** alldevsp); |
260 | | /** |
261 | | * @brief Free data returned with `Utils::ntop_findalldevs` |
262 | | * @details Frees data allocated during the call to `Utils::ntop_findalldevs` |
263 | | * |
264 | | * @return void |
265 | | */ |
266 | | static void ntop_freealldevs(ntop_if_t* alldevs); |
267 | | |
268 | | /* System Host Montoring and Diagnose Functions */ |
269 | | static bool getCPULoad(cpu_load_stats* out); |
270 | | static void luaMeminfo(lua_State* vm); |
271 | | static int retainWriteCapabilities(); |
272 | | static int gainWriteCapabilities(); |
273 | | static int dropWriteCapabilities(); |
274 | | static u_int32_t findInterfaceGatewayIPv4(const char* ifname); |
275 | | |
276 | | /* Data Format */ |
277 | | static char* formatTraffic(float numBits, bool bits, char* buf); |
278 | | static char* formatPackets(float numPkts, char* buf); |
279 | | |
280 | | /* Pcap files utiles */ |
281 | | static void init_pcap_header(struct pcap_file_header* const h, int linktype, |
282 | | int snaplen, bool nsec = false); |
283 | | |
284 | | /* Bitmap functions */ |
285 | | static bool bitmapIsSet(u_int64_t bitmap, u_int8_t v); |
286 | | static u_int64_t bitmapSet(u_int64_t bitmap, u_int8_t v); |
287 | | static u_int64_t bitmapClear(u_int64_t bitmap, u_int8_t v); |
288 | | static int bitmapGetNext(u_int64_t bitmap, u_int8_t start); |
289 | | |
290 | 0 | static inline u_int64_t bitmapOr(u_int64_t bitmap1, u_int64_t bitmap2) { |
291 | 0 | return (bitmap1 | bitmap2); |
292 | 0 | } |
293 | | |
294 | | static ndpi_os getOSFromFingerprint(const char* fingerprint, |
295 | | const char* manuf, DeviceType devtype); |
296 | | static DeviceType getDeviceTypeFromOsDetail(const char* os_detail, |
297 | | ndpi_os* hint); |
298 | | static ndpi_os OShint2ndpi_os(ndpi_os os); |
299 | | static u_int32_t pow2(u_int32_t v); |
300 | | static int exec(const char* command); |
301 | | #ifdef __linux__ |
302 | | static void deferredExec(const char* command); |
303 | | #endif |
304 | | static void tlv2lua(lua_State* vm, ndpi_serializer* serializer); |
305 | | static void tlv2serializer(ndpi_serializer* tvl_serializer, |
306 | | ndpi_serializer* serializer); |
307 | | static char* getCountry(char* buf, u_int buf_len, IpAddress* ip); |
308 | | static u_int16_t countryCode2U16(const char* country_code); |
309 | | static char* countryU162Code(u_int16_t country_u16, char* country_code, |
310 | | size_t country_code_size); |
311 | | static bool isNumber(const char* s, unsigned int s_len, bool* is_float); |
312 | | static bool isPingSupported(); |
313 | | static ScoreCategory mapAlertToScoreCategory(AlertCategory check_category); |
314 | | /* Map alert score to AlertLevel */ |
315 | | static AlertLevel mapScoreToSeverity(u_int32_t score); |
316 | | /* Map AlertLevel to score */ |
317 | | static u_int8_t mapSeverityToScore(AlertLevel alert_level); |
318 | | /* |
319 | | Maps an AlertLevel into the corresponding AlertLevelGroup. Alert level |
320 | | groups are used to 'compress' alert levels into a reduced number of |
321 | | (grouped) levels. |
322 | | */ |
323 | | static AlertLevelGroup mapAlertLevelToGroup(AlertLevel alert_level); |
324 | | static bool hasExtension(const char* path, const char* ext); |
325 | | #ifndef WIN32 |
326 | | static int mapSyslogFacilityTextToValue(const char* facility_text); |
327 | | #endif |
328 | | static void buildSqliteAllowedNetworksFilters(lua_State* vm); |
329 | | static void make_session_key(char* buf, u_int buf_len); |
330 | | static const char* get_state_label(ThreadedActivityState ta_state); |
331 | | static bool endsWith(const char* base, const char* str); |
332 | | static int openSocket(int domain, int type, int protocol, const char* label); |
333 | | static void closeSocket(int socket); |
334 | | static int pollSocket(int sock, int timeout /* msec */); |
335 | | static int pollSockets(int socks[], u_int num, int timeout /* msec */); |
336 | | static const char** getMessagingTopics(); |
337 | | static char* toHex(char* in, u_int in_len, char* out, u_int out_len); |
338 | | static bool fromHex(char* in, u_int in_len, char* out, u_int out_len); |
339 | | |
340 | | static void swap8(u_int8_t* a, u_int8_t* b); |
341 | | static void swap16(u_int16_t* a, u_int16_t* b); |
342 | | static void swap32(u_int32_t* a, u_int32_t* b); |
343 | | static void swap64(u_int64_t* a, u_int64_t* b); |
344 | | static void swapfloat(float* a, float* b); |
345 | | static void swapLen(void* a, void* b, u_int len); |
346 | | static char* createRandomString(char* buf, size_t buf_len); |
347 | | static IpAddress* parseHostString(char* host_ip, |
348 | | u_int16_t* vlan_id /* out */); |
349 | | static bool nwInterfaceExists(char* if_name); |
350 | | static bool readModbusDeviceInfo(char* ip_address, u_int8_t timeout_sec, |
351 | | lua_State* vm); |
352 | | static bool readEthernetIPDeviceInfo(char* ip_address, u_int8_t timeout_sec, |
353 | | lua_State* vm); |
354 | | static const char* OS2Str(ndpi_os os); |
355 | | static const char* learningMode2str(OSLearningMode mode); |
356 | | static const char* deviceType2str(DeviceType devtype); |
357 | | static bool checkNetworkList(char* network_list, char* rsp, |
358 | | bool (*callback)(char*, char*, void* user_data), |
359 | | void* user_data); |
360 | | |
361 | | static DeviceType osType2deviceType(ndpi_os t); |
362 | | static bool setProcessLimit(int resource, u_int32_t upper_limit); |
363 | | |
364 | | /* Increment the counter up to 255 without wrapping */ |
365 | 25.8k | static void inc8bitNoOverflow(u_int8_t* v) { |
366 | 25.8k | if (*v < 0xFF) (*v)++; |
367 | 25.8k | } |
368 | | static void flushHTTPBuffer(lua_State *vm); |
369 | | static void convertIPv4ToIPv6(u_int32_t ipv4_addr /* in */, |
370 | | struct ndpi_in6_addr *ipv6_addr /* out */); |
371 | | static void setIPv4Address(struct ndpi_in6_addr *out_addr, u_int32_t ipv4); |
372 | | static bool parseIPv4v6Address(const char *ip_str, struct ndpi_in6_addr *out_addr); |
373 | | static bool isNullAddress(struct ndpi_in6_addr *ip); |
374 | | }; |
375 | | |
376 | | #endif /* _UTILS_H_ */ |