diff options
author | netblue30 <netblue30@protonmail.com> | 2022-01-09 22:20:35 -0500 |
---|---|---|
committer | netblue30 <netblue30@protonmail.com> | 2022-01-09 22:20:35 -0500 |
commit | 55b986d253fcae830d4a5daeaee6b1a784bebef0 (patch) | |
tree | a85eb60ecba674771e5dc35dbc39b5ccf5ea400d /src/fnettrace/main.c | |
parent | Merge branch 'master' of ssh://github.com/netblue30/firejail (diff) | |
download | firejail-55b986d253fcae830d4a5daeaee6b1a784bebef0.tar.gz firejail-55b986d253fcae830d4a5daeaee6b1a784bebef0.tar.zst firejail-55b986d253fcae830d4a5daeaee6b1a784bebef0.zip |
nettrace
Diffstat (limited to 'src/fnettrace/main.c')
-rw-r--r-- | src/fnettrace/main.c | 112 |
1 files changed, 82 insertions, 30 deletions
diff --git a/src/fnettrace/main.c b/src/fnettrace/main.c index 804a9cd80..40025590e 100644 --- a/src/fnettrace/main.c +++ b/src/fnettrace/main.c | |||
@@ -46,8 +46,6 @@ HNode *htable[HMAX] = {NULL}; | |||
46 | // display linked list | 46 | // display linked list |
47 | HNode *dlist = NULL; | 47 | HNode *dlist = NULL; |
48 | 48 | ||
49 | static unsigned bwmax = 0; // max bytes received in a display interval | ||
50 | |||
51 | static void hnode_add(uint32_t ip_src, uint32_t ip_dst, uint8_t protocol, uint16_t port_src, uint32_t bytes) { | 49 | static void hnode_add(uint32_t ip_src, uint32_t ip_dst, uint8_t protocol, uint16_t port_src, uint32_t bytes) { |
52 | uint8_t h = hash(ip_src); | 50 | uint8_t h = hash(ip_src); |
53 | 51 | ||
@@ -151,7 +149,7 @@ static char *print_bw(unsigned units) { | |||
151 | units = DISPLAY_BW_UNITS ; | 149 | units = DISPLAY_BW_UNITS ; |
152 | 150 | ||
153 | if (bw_line[units] == NULL) { | 151 | if (bw_line[units] == NULL) { |
154 | char *ptr = malloc(DISPLAY_BW_UNITS + 1); | 152 | char *ptr = malloc(DISPLAY_BW_UNITS + 2); |
155 | if (!ptr) | 153 | if (!ptr) |
156 | errExit("malloc"); | 154 | errExit("malloc"); |
157 | bw_line[units] = ptr; | 155 | bw_line[units] = ptr; |
@@ -159,12 +157,44 @@ static char *print_bw(unsigned units) { | |||
159 | unsigned i; | 157 | unsigned i; |
160 | for (i = 0; i < DISPLAY_BW_UNITS; i++, ptr++) | 158 | for (i = 0; i < DISPLAY_BW_UNITS; i++, ptr++) |
161 | sprintf(ptr, "%s", (i < units)? "*": " "); | 159 | sprintf(ptr, "%s", (i < units)? "*": " "); |
160 | sprintf(ptr, "%s", " "); | ||
162 | } | 161 | } |
163 | 162 | ||
164 | return bw_line[units]; | 163 | return bw_line[units]; |
165 | } | 164 | } |
166 | 165 | ||
167 | static void hnode_print(void) { | 166 | #define LINE_MAX 200 |
167 | static inline void adjust_line(char *str, int len, int cols) { | ||
168 | if (len > LINE_MAX) // functions such as snprintf truncate the string, and return the length of the untruncated string | ||
169 | len = LINE_MAX; | ||
170 | if (cols > 4 && len > cols) { | ||
171 | str[cols] = '\0'; | ||
172 | str[cols- 1] = '\n'; | ||
173 | } | ||
174 | } | ||
175 | |||
176 | #define BWMAX_CNT 8 | ||
177 | static unsigned adjust_bandwidth(unsigned bw) { | ||
178 | static unsigned array[BWMAX_CNT] = {0}; | ||
179 | static int instance = 0; | ||
180 | |||
181 | array[instance] = bw; | ||
182 | int i; | ||
183 | unsigned sum = 0; | ||
184 | unsigned max = 0; | ||
185 | for ( i = 0; i < BWMAX_CNT; i++) { | ||
186 | sum += array[i]; | ||
187 | max = (max > array[i])? max: array[i]; | ||
188 | } | ||
189 | sum /= BWMAX_CNT; | ||
190 | |||
191 | if (++instance >= BWMAX_CNT) | ||
192 | instance = 0; | ||
193 | |||
194 | return (max < (sum / 2))? sum: max; | ||
195 | } | ||
196 | |||
197 | static void hnode_print(unsigned bw) { | ||
168 | assert(!arg_netfilter); | 198 | assert(!arg_netfilter); |
169 | ansi_clrscr(); | 199 | ansi_clrscr(); |
170 | 200 | ||
@@ -178,38 +208,47 @@ static void hnode_print(void) { | |||
178 | 208 | ||
179 | // get terminal size | 209 | // get terminal size |
180 | struct winsize sz; | 210 | struct winsize sz; |
181 | int col = 80; | 211 | int cols = 80; |
182 | if (isatty(STDIN_FILENO)) { | 212 | if (isatty(STDIN_FILENO)) { |
183 | if (!ioctl(0, TIOCGWINSZ, &sz)) | 213 | if (!ioctl(0, TIOCGWINSZ, &sz)) |
184 | col = sz.ws_col; | 214 | cols = sz.ws_col; |
185 | } | 215 | } |
186 | #define LINE_MAX 200 | 216 | if (cols > LINE_MAX) |
217 | cols = LINE_MAX; | ||
187 | char line[LINE_MAX + 1]; | 218 | char line[LINE_MAX + 1]; |
188 | if (col > LINE_MAX) | 219 | |
189 | col = LINE_MAX; | 220 | // print stats line |
221 | bw = adjust_bandwidth(bw); | ||
222 | char stats[31]; | ||
223 | if (bw > (1024 * 1024 * DISPLAY_INTERVAL)) | ||
224 | sprintf(stats, "%d MB/s ", bw / (1024 * 1024 * DISPLAY_INTERVAL)); | ||
225 | else | ||
226 | sprintf(stats, "%d KB/s ", bw / (1024 * DISPLAY_INTERVAL)); | ||
227 | int len = snprintf(line, LINE_MAX, "%32s geoip %d, IP database %d\n", stats, geoip_calls, radix_nodes); | ||
228 | adjust_line(line, len, cols); | ||
229 | printf("%s", line); | ||
190 | 230 | ||
191 | HNode *ptr = dlist; | 231 | HNode *ptr = dlist; |
192 | HNode *prev = NULL; | 232 | HNode *prev = NULL; |
233 | int row = 0; | ||
193 | while (ptr) { | 234 | while (ptr) { |
194 | HNode *next = ptr->dnext; | 235 | HNode *next = ptr->dnext; |
195 | if (--ptr->ttl > 0) { | 236 | if (--ptr->ttl > 0) { |
196 | char bytes[11]; | 237 | char bytes[11]; |
197 | if (ptr->bytes > (DISPLAY_INTERVAL * 1024 * 1024 * 2)) // > 2 MB/second | 238 | if (ptr->bytes > (DISPLAY_INTERVAL * 1024 * 1024 * 2)) // > 2 MB/second |
198 | sprintf(bytes, "%u MB/s", | 239 | snprintf(bytes, 11, "%u MB/s", |
199 | (unsigned) (ptr->bytes / (DISPLAY_INTERVAL * 1024* 1024))); | 240 | (unsigned) (ptr->bytes / (DISPLAY_INTERVAL * 1024* 1024))); |
200 | else if (ptr->bytes > (DISPLAY_INTERVAL * 1024 * 2)) // > 2 KB/second | 241 | else if (ptr->bytes > (DISPLAY_INTERVAL * 1024 * 2)) // > 2 KB/second |
201 | sprintf(bytes, "%u KB/s", | 242 | snprintf(bytes, 11, "%u KB/s", |
202 | (unsigned) (ptr->bytes / (DISPLAY_INTERVAL * 1024))); | 243 | (unsigned) (ptr->bytes / (DISPLAY_INTERVAL * 1024))); |
203 | else | 244 | else |
204 | sprintf(bytes, "%u B/s", (unsigned) (ptr->bytes / DISPLAY_INTERVAL)); | 245 | snprintf(bytes, 11, "%u B/s", (unsigned) (ptr->bytes / DISPLAY_INTERVAL)); |
205 | 246 | ||
206 | char *hostname = ptr->hostname; | 247 | char *hostname = ptr->hostname; |
207 | if (!hostname) | 248 | if (!hostname) |
208 | hostname = radix_find_last(ptr->ip_src); | 249 | hostname = radix_find_last(ptr->ip_src); |
209 | |||
210 | if (!hostname) | 250 | if (!hostname) |
211 | hostname = retrieve_hostname(ptr->ip_src); | 251 | hostname = retrieve_hostname(ptr->ip_src); |
212 | |||
213 | if (!hostname) | 252 | if (!hostname) |
214 | hostname = " "; | 253 | hostname = " "; |
215 | else { | 254 | else { |
@@ -218,16 +257,30 @@ static void hnode_print(void) { | |||
218 | errExit("strdup"); | 257 | errExit("strdup"); |
219 | } | 258 | } |
220 | 259 | ||
221 | unsigned bwunit = bwmax / DISPLAY_BW_UNITS; | 260 | unsigned bwunit = bw / DISPLAY_BW_UNITS; |
222 | unsigned units = ptr->bytes / bwunit; | 261 | char *bwline; |
223 | char *bwline = print_bw(units); | 262 | if (bwunit == 0) |
263 | bwline = print_bw(0); | ||
264 | else | ||
265 | bwline = print_bw(ptr->bytes / bwunit); | ||
266 | |||
267 | char *protocol = ""; | ||
268 | if (ptr->port_src == 80) | ||
269 | protocol = "(HTTP)"; | ||
270 | else if (ptr->port_src == 853) | ||
271 | protocol = "(DoT)"; | ||
272 | else if (ptr->protocol == 0x11) | ||
273 | protocol = "(UDP)"; | ||
274 | /* | ||
275 | else (ptr->port_src == 443) | ||
276 | protocol = "SSL"; | ||
277 | else if (ptr->port_src == 53) | ||
278 | protocol = "DNS"; | ||
279 | */ | ||
224 | 280 | ||
225 | sprintf(line, "%10s %s %d.%d.%d.%d:%u %s\n", bytes, bwline, PRINT_IP(ptr->ip_src), ptr->port_src, hostname); | 281 | len = snprintf(line, LINE_MAX, "%10s %s %d.%d.%d.%d:%u%s %s\n", |
226 | int len = strlen(line); | 282 | bytes, bwline, PRINT_IP(ptr->ip_src), ptr->port_src, protocol, hostname); |
227 | if (col > 4 && len > col) { | 283 | adjust_line(line, len, cols); |
228 | line[col] = '\0'; | ||
229 | line[col - 1] = '\n'; | ||
230 | } | ||
231 | printf("%s", line); | 284 | printf("%s", line); |
232 | 285 | ||
233 | if (ptr->bytes) | 286 | if (ptr->bytes) |
@@ -246,6 +299,7 @@ static void hnode_print(void) { | |||
246 | 299 | ||
247 | ptr = next; | 300 | ptr = next; |
248 | } | 301 | } |
302 | |||
249 | } | 303 | } |
250 | 304 | ||
251 | static void run_trace(void) { | 305 | static void run_trace(void) { |
@@ -262,18 +316,16 @@ static void run_trace(void) { | |||
262 | unsigned last_print_traces = 0; | 316 | unsigned last_print_traces = 0; |
263 | unsigned last_print_remaining = 0; | 317 | unsigned last_print_remaining = 0; |
264 | unsigned char buf[MAX_BUF_SIZE]; | 318 | unsigned char buf[MAX_BUF_SIZE]; |
265 | unsigned bwcurrent = 0; | 319 | unsigned bw = 0; // bandwidth calculations |
266 | while (1) { | 320 | while (1) { |
267 | unsigned end = time(NULL); | 321 | unsigned end = time(NULL); |
268 | if (arg_netfilter && end - start >= NETLOCK_INTERVAL) | 322 | if (arg_netfilter && end - start >= NETLOCK_INTERVAL) |
269 | break; | 323 | break; |
270 | if (end % DISPLAY_INTERVAL == 1 && last_print_traces != end) { // first print after 1 second | 324 | if (end % DISPLAY_INTERVAL == 1 && last_print_traces != end) { // first print after 1 second |
271 | if (bwcurrent > bwmax) | ||
272 | bwmax = bwcurrent; | ||
273 | if (!arg_netfilter) | 325 | if (!arg_netfilter) |
274 | hnode_print(); | 326 | hnode_print(bw); |
275 | last_print_traces = end; | 327 | last_print_traces = end; |
276 | bwcurrent = 0; | 328 | bw = 0; |
277 | } | 329 | } |
278 | if (arg_netfilter && last_print_remaining != end) { | 330 | if (arg_netfilter && last_print_remaining != end) { |
279 | logprintf("."); | 331 | logprintf("."); |
@@ -300,7 +352,7 @@ static void run_trace(void) { | |||
300 | 352 | ||
301 | unsigned bytes = recvfrom(sock, buf, MAX_BUF_SIZE, 0, NULL, NULL); | 353 | unsigned bytes = recvfrom(sock, buf, MAX_BUF_SIZE, 0, NULL, NULL); |
302 | if (bytes >= 20) { // size of IP header | 354 | if (bytes >= 20) { // size of IP header |
303 | bwcurrent += bytes + 14; // assume a 14 byte Ethernet layer | 355 | bw += bytes + 14; // assume a 14 byte Ethernet layer |
304 | // filter out loopback traffic | 356 | // filter out loopback traffic |
305 | if (buf[12] != 127) { | 357 | if (buf[12] != 127) { |
306 | uint32_t ip_src; | 358 | uint32_t ip_src; |
@@ -486,8 +538,8 @@ static void usage(void) { | |||
486 | printf("Options:\n"); | 538 | printf("Options:\n"); |
487 | printf(" --build=filename - compact list of addresses\n"); | 539 | printf(" --build=filename - compact list of addresses\n"); |
488 | printf(" --help, -? - this help screen\n"); | 540 | printf(" --help, -? - this help screen\n"); |
541 | printf(" --log=filename - netlocker logfile\n"); | ||
489 | printf(" --netfilter - build the firewall rules and commit them.\n"); | 542 | printf(" --netfilter - build the firewall rules and commit them.\n"); |
490 | printf(" --log=filename - logfile\n"); | ||
491 | printf("\n"); | 543 | printf("\n"); |
492 | } | 544 | } |
493 | 545 | ||