/src/PcapPlusPlus/Common++/header/SystemUtils.h
Line | Count | Source (jump to first uncovered line) |
1 | | #pragma once |
2 | | |
3 | | #include "DeprecationUtils.h" |
4 | | |
5 | | #include <cstdint> |
6 | | #include <string> |
7 | | #include <vector> |
8 | | #include <ctime> |
9 | | |
10 | | /// @file |
11 | | |
12 | | // @todo Change to constexpr when C++17 is minimum supported version |
13 | | enum : uint8_t |
14 | | { |
15 | | MAX_NUM_OF_CORES = 32 |
16 | | }; |
17 | | |
18 | | #ifdef _MSC_VER |
19 | | int gettimeofday(struct timeval* tp, struct timezone* tzp); |
20 | | #endif |
21 | | |
22 | | /// @namespace pcpp |
23 | | /// @brief The main namespace for the PcapPlusPlus lib |
24 | | namespace pcpp |
25 | | { |
26 | | |
27 | | /// @struct SystemCore |
28 | | /// Represents data of 1 CPU core. Current implementation supports up to 32 cores |
29 | | struct SystemCore |
30 | | { |
31 | | |
32 | | /// Core position in a 32-bit mask. For each core this attribute holds a 4B integer where only 1 bit is set, |
33 | | /// according to the core ID. For example: |
34 | | /// - In core #0 the right-most bit will be set (meaning the number 0x01); |
35 | | /// - in core #5 the 5th right-most bit will be set (meaning the number 0x20) |
36 | | uint32_t Mask; |
37 | | |
38 | | /// Core ID - a value between 0 and 31 |
39 | | uint8_t Id; |
40 | | |
41 | | /// Overload of the comparison operator |
42 | | /// @return true if 2 addresses are equal. False otherwise |
43 | | bool operator==(const SystemCore& other) const |
44 | 0 | { |
45 | 0 | return Id == other.Id; |
46 | 0 | } |
47 | | }; |
48 | | |
49 | | /// @struct SystemCores |
50 | | /// Contains static representation to all 32 cores and a static array to map core ID (integer) to a SystemCore |
51 | | /// struct |
52 | | struct SystemCores |
53 | | { |
54 | | /// Static representation of core #0 |
55 | | static const SystemCore Core0; |
56 | | /// Static representation of core #1 |
57 | | static const SystemCore Core1; |
58 | | /// Static representation of core #2 |
59 | | static const SystemCore Core2; |
60 | | /// Static representation of core #3 |
61 | | static const SystemCore Core3; |
62 | | /// Static representation of core #4 |
63 | | static const SystemCore Core4; |
64 | | /// Static representation of core #5 |
65 | | static const SystemCore Core5; |
66 | | /// Static representation of core #6 |
67 | | static const SystemCore Core6; |
68 | | /// Static representation of core #7 |
69 | | static const SystemCore Core7; |
70 | | /// Static representation of core #8 |
71 | | static const SystemCore Core8; |
72 | | /// Static representation of core #9 |
73 | | static const SystemCore Core9; |
74 | | /// Static representation of core #10 |
75 | | static const SystemCore Core10; |
76 | | /// Static representation of core #11 |
77 | | static const SystemCore Core11; |
78 | | /// Static representation of core #12 |
79 | | static const SystemCore Core12; |
80 | | /// Static representation of core #13 |
81 | | static const SystemCore Core13; |
82 | | /// Static representation of core #14 |
83 | | static const SystemCore Core14; |
84 | | /// Static representation of core #15 |
85 | | static const SystemCore Core15; |
86 | | /// Static representation of core #16 |
87 | | static const SystemCore Core16; |
88 | | /// Static representation of core #17 |
89 | | static const SystemCore Core17; |
90 | | /// Static representation of core #18 |
91 | | static const SystemCore Core18; |
92 | | /// Static representation of core #19 |
93 | | static const SystemCore Core19; |
94 | | /// Static representation of core #20 |
95 | | static const SystemCore Core20; |
96 | | /// Static representation of core #21 |
97 | | static const SystemCore Core21; |
98 | | /// Static representation of core #22 |
99 | | static const SystemCore Core22; |
100 | | /// Static representation of core #23 |
101 | | static const SystemCore Core23; |
102 | | /// Static representation of core #24 |
103 | | static const SystemCore Core24; |
104 | | /// Static representation of core #25 |
105 | | static const SystemCore Core25; |
106 | | /// Static representation of core #26 |
107 | | static const SystemCore Core26; |
108 | | /// Static representation of core #27 |
109 | | static const SystemCore Core27; |
110 | | /// Static representation of core #28 |
111 | | static const SystemCore Core28; |
112 | | /// Static representation of core #29 |
113 | | static const SystemCore Core29; |
114 | | /// Static representation of core #30 |
115 | | static const SystemCore Core30; |
116 | | /// Static representation of core #31 |
117 | | static const SystemCore Core31; |
118 | | /// A static array for mapping core ID (integer) to the corresponding static SystemCore representation |
119 | | static const SystemCore IdToSystemCore[MAX_NUM_OF_CORES]; |
120 | | }; |
121 | | |
122 | | using CoreMask = uint32_t; |
123 | | |
124 | | /// Get total number of cores on device |
125 | | /// @return Total number of CPU cores on device |
126 | | int getNumOfCores(); |
127 | | |
128 | | /// Create a core mask for all cores available on machine |
129 | | /// @return A core mask for all cores available on machine |
130 | | CoreMask getCoreMaskForAllMachineCores(); |
131 | | |
132 | | /// Create a core mask from a vector of system cores |
133 | | /// @param[in] cores A vector of SystemCore instances |
134 | | /// @return A core mask representing these cores |
135 | | CoreMask createCoreMaskFromCoreVector(const std::vector<SystemCore>& cores); |
136 | | |
137 | | /// Create a core mask from a vector of core IDs |
138 | | /// @param[in] coreIds A vector of core IDs |
139 | | /// @return A core mask representing these cores |
140 | | CoreMask createCoreMaskFromCoreIds(const std::vector<int>& coreIds); |
141 | | |
142 | | /// Convert a core mask into a vector of its appropriate system cores |
143 | | /// @param[in] coreMask The input core mask |
144 | | /// @param[out] resultVec The vector that will contain the system cores |
145 | | void createCoreVectorFromCoreMask(CoreMask coreMask, std::vector<SystemCore>& resultVec); |
146 | | |
147 | | /// Execute a shell command and return its output |
148 | | /// @param[in] command The command to run |
149 | | /// @return The output of the command (both stdout and stderr) |
150 | | /// @throws std::runtime_error Error executing the command. |
151 | | std::string executeShellCommand(const std::string& command); |
152 | | |
153 | | /// Check if a directory exists |
154 | | /// @param[in] dirPath Full path of the directory to search |
155 | | /// @return True if directory exists, false otherwise |
156 | | bool directoryExists(const std::string& dirPath); |
157 | | |
158 | | /// Retrieve a system-wide real-time accurate clock. It's actually a multi-platform version of clock_gettime() which |
159 | | /// is fully supported only on Linux |
160 | | /// @param[out] sec The second portion of the time |
161 | | /// @param[out] nsec The nanosecond portion of the time |
162 | | /// @return 0 for success, or -1 for failure |
163 | | int clockGetTime(long& sec, long& nsec); |
164 | | |
165 | | /// Convert std::tm to time_t in UTC time, ignoring local timezone |
166 | | /// @param[in] tm The time to convert |
167 | | /// @return A time_t object representing the input time |
168 | | /// @throws std::runtime_error if a conversion error occurs |
169 | | time_t mkUtcTime(std::tm& tm); |
170 | | |
171 | | /// A multi-platform version of the popular sleep method. This method simply runs the right sleep method, according |
172 | | /// to the platform it is running on. |
173 | | /// @param[in] seconds Number of seconds to sleep |
174 | | /// @deprecated Please use std::this_thread::sleep_for(). It is a standard C++ (since C++11) method which is already |
175 | | /// cross-platform |
176 | | PCPP_DEPRECATED("Please use std::this_thread::sleep_for(std::chrono::seconds(seconds)) instead") |
177 | | void multiPlatformSleep(uint32_t seconds); |
178 | | |
179 | | /// A multi-platform version of sleep in milliseconds resolution. This method simply runs the right sleep method, |
180 | | /// according to the platform it is running on. |
181 | | /// @param[in] milliseconds Number of milliseconds to sleep |
182 | | /// @deprecated Please use std::this_thread::sleep_for(). It is a standard C++ (since C++11) method which is already |
183 | | /// cross-platform |
184 | | PCPP_DEPRECATED("Please use std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds)) instead") |
185 | | void multiPlatformMSleep(uint32_t milliseconds); |
186 | | |
187 | | /// A multi-platform version of `htons` which convert host to network byte order |
188 | | /// @param[in] host Value in host byte order |
189 | | /// @return Value in network byte order |
190 | | uint16_t hostToNet16(uint16_t host); |
191 | | |
192 | | /// A multi-platform version of `ntohs` which convert network to host byte order |
193 | | /// @param[in] net Value in network byte order |
194 | | /// @return Value in host byte order |
195 | | uint16_t netToHost16(uint16_t net); |
196 | | |
197 | | /// A multi-platform version of `htonl` which convert host to network byte order |
198 | | /// @param[in] host Value in host byte order |
199 | | /// @return Value in network byte order |
200 | | uint32_t hostToNet32(uint32_t host); |
201 | | |
202 | | /// A multi-platform version of `ntohl` which convert network to host byte order |
203 | | /// @param[in] net Value in network byte order |
204 | | /// @return Value in host byte order |
205 | | uint32_t netToHost32(uint32_t net); |
206 | | |
207 | | /// @class AppName |
208 | | /// This class extracts the application name from the current running executable and stores it for usage of the |
209 | | /// application throughout its runtime. This class should be initialized once in the beginning of the main() method |
210 | | /// using AppName#init() and from then on the app name could be retrieved using AppName#get() |
211 | | class AppName |
212 | | { |
213 | | private: |
214 | | static std::string m_AppName; |
215 | | |
216 | | public: |
217 | | /// Static init method which should be called once at the beginning of the main method. |
218 | | /// @param[in] argc The argc param from main() |
219 | | /// @param[in] argv The argv param from main() |
220 | | // cppcheck-suppress constParameter |
221 | | static void init(int argc, char* argv[]) |
222 | 0 | { |
223 | 0 | if (argc == 0) |
224 | 0 | { |
225 | 0 | m_AppName.clear(); |
226 | 0 | return; |
227 | 0 | } |
228 | 0 |
|
229 | 0 | m_AppName = argv[0]; |
230 | 0 |
|
231 | 0 | // remove Linux/Unix path |
232 | 0 | size_t lastPos = m_AppName.rfind('/'); |
233 | 0 | if (lastPos != std::string::npos) |
234 | 0 | { |
235 | 0 | m_AppName = m_AppName.substr(lastPos + 1); |
236 | 0 | } |
237 | 0 |
|
238 | 0 | // remove Windows path |
239 | 0 | lastPos = m_AppName.rfind('\\'); |
240 | 0 | if (lastPos != std::string::npos) |
241 | 0 | { |
242 | 0 | m_AppName = m_AppName.substr(lastPos + 1); |
243 | 0 | } |
244 | 0 |
|
245 | 0 | // remove file extension |
246 | 0 | lastPos = m_AppName.rfind('.'); |
247 | 0 | if (lastPos != std::string::npos) |
248 | 0 | { |
249 | 0 | m_AppName.resize(lastPos); |
250 | 0 | } |
251 | 0 | } |
252 | | |
253 | | /// @return The app name as extracted from the current running executable |
254 | | static const std::string& get() |
255 | 0 | { |
256 | 0 | return m_AppName; |
257 | 0 | } |
258 | | }; |
259 | | |
260 | | /// @class ApplicationEventHandler |
261 | | /// A singleton class that provides callbacks for events that occur during application life-cycle such as ctrl+c |
262 | | /// pressed, application closed, killed, etc. |
263 | | class ApplicationEventHandler |
264 | | { |
265 | | public: |
266 | | /// @typedef EventHandlerCallback |
267 | | /// The callback to be invoked when the event occurs |
268 | | /// @param[in] cookie A pointer the the cookie provided by the user in ApplicationEventHandler c'tor |
269 | | using EventHandlerCallback = void (*)(void*); |
270 | | |
271 | | /// As ApplicationEventHandler is a singleton, this is the static getter to retrieve its instance |
272 | | /// @return The singleton instance of ApplicationEventHandler |
273 | | static ApplicationEventHandler& getInstance() |
274 | 0 | { |
275 | 0 | static ApplicationEventHandler instance; |
276 | 0 | return instance; |
277 | 0 | } |
278 | | |
279 | | /// Register for an application-interrupted event, meaning ctrl+c was pressed |
280 | | /// @param[in] handler The callback to be activated when the event occurs |
281 | | /// @param[in] cookie A pointer to a user provided object. This object will be transferred to the |
282 | | /// EventHandlerCallback callback. This cookie is very useful for transferring objects that give context to the |
283 | | /// event callback |
284 | | void onApplicationInterrupted(EventHandlerCallback handler, void* cookie); |
285 | | |
286 | | private: |
287 | | EventHandlerCallback m_ApplicationInterruptedHandler; |
288 | | void* m_ApplicationInterruptedCookie; |
289 | | |
290 | | // private c'tor |
291 | | ApplicationEventHandler(); |
292 | | |
293 | | #if defined(_WIN32) |
294 | | static int handlerRoutine(unsigned long fdwCtrlType); |
295 | | #else |
296 | | static void handlerRoutine(int signum); |
297 | | #endif |
298 | | }; |
299 | | |
300 | | } // namespace pcpp |