diff options
author | 2023-07-16 11:32:00 -0400 | |
---|---|---|
committer | 2023-07-16 11:32:00 -0400 | |
commit | f3e428e6fab326c993e17eeae1c223dcb5f8dc2b (patch) | |
tree | a750e0b86041ae5df4ab2acb817af23648c2a568 /src/fnettrace/main.c | |
parent | Merge branch 'master' of ssh://github.com/netblue30/firejail (diff) | |
download | firejail-f3e428e6fab326c993e17eeae1c223dcb5f8dc2b.tar.gz firejail-f3e428e6fab326c993e17eeae1c223dcb5f8dc2b.tar.zst firejail-f3e428e6fab326c993e17eeae1c223dcb5f8dc2b.zip |
feature: stats support for --nettrace
Diffstat (limited to 'src/fnettrace/main.c')
-rw-r--r-- | src/fnettrace/main.c | 56 |
1 files changed, 50 insertions, 6 deletions
diff --git a/src/fnettrace/main.c b/src/fnettrace/main.c index 136a16e6d..932afff61 100644 --- a/src/fnettrace/main.c +++ b/src/fnettrace/main.c | |||
@@ -29,6 +29,11 @@ static int arg_netfilter = 0; | |||
29 | static int arg_tail = 0; | 29 | static int arg_tail = 0; |
30 | static char *arg_log = NULL; | 30 | static char *arg_log = NULL; |
31 | 31 | ||
32 | uint32_t stats_pkts = 0; | ||
33 | uint32_t stats_icmp = 0; | ||
34 | uint32_t stats_dns = 0; | ||
35 | |||
36 | |||
32 | typedef struct hnode_t { | 37 | typedef struct hnode_t { |
33 | struct hnode_t *hnext; // used for hash table and unused linked list | 38 | struct hnode_t *hnext; // used for hash table and unused linked list |
34 | struct hnode_t *dnext; // used to display streams on the screen | 39 | struct hnode_t *dnext; // used to display streams on the screen |
@@ -331,7 +336,7 @@ static void hnode_print(unsigned bw) { | |||
331 | else | 336 | else |
332 | sprintf(stats, "%u KB/s ", bw / (1024 * DISPLAY_INTERVAL)); | 337 | sprintf(stats, "%u KB/s ", bw / (1024 * DISPLAY_INTERVAL)); |
333 | // int len = snprintf(line, LINE_MAX, "%32s geoip %d, IP database %d\n", stats, geoip_calls, radix_nodes); | 338 | // int len = snprintf(line, LINE_MAX, "%32s geoip %d, IP database %d\n", stats, geoip_calls, radix_nodes); |
334 | int len = snprintf(line, LINE_MAX, "%32s address:port (protocol) host (packets)\n", stats); | 339 | int len = snprintf(line, LINE_MAX, "%32s address:port (protocol) network (packets)\n", stats); |
335 | adjust_line(line, len, cols); | 340 | adjust_line(line, len, cols); |
336 | printf("%s", line); | 341 | printf("%s", line); |
337 | 342 | ||
@@ -418,6 +423,7 @@ static void hnode_print(unsigned bw) { | |||
418 | 423 | ||
419 | ptr = next; | 424 | ptr = next; |
420 | } | 425 | } |
426 | printf("press any key to access stats\n"); | ||
421 | 427 | ||
422 | #ifdef DEBUG | 428 | #ifdef DEBUG |
423 | { | 429 | { |
@@ -432,6 +438,14 @@ static void hnode_print(unsigned bw) { | |||
432 | #endif | 438 | #endif |
433 | } | 439 | } |
434 | 440 | ||
441 | |||
442 | void print_stats(void) { | ||
443 | printf("\nIP table: %d entries, %d unknown\n", radix_nodes, geoip_calls); | ||
444 | printf(" address network (packets)\n"); | ||
445 | radix_print(1); | ||
446 | printf("Packets: %u total, ICMP %u, DNS %u\n", stats_pkts, stats_icmp, stats_dns); | ||
447 | } | ||
448 | |||
435 | // trace rx traffic coming in | 449 | // trace rx traffic coming in |
436 | static void run_trace(void) { | 450 | static void run_trace(void) { |
437 | if (arg_netfilter) | 451 | if (arg_netfilter) |
@@ -449,6 +463,7 @@ static void run_trace(void) { | |||
449 | unsigned last_print_remaining = 0; | 463 | unsigned last_print_remaining = 0; |
450 | unsigned char buf[MAX_BUF_SIZE]; | 464 | unsigned char buf[MAX_BUF_SIZE]; |
451 | unsigned bw = 0; // bandwidth calculations | 465 | unsigned bw = 0; // bandwidth calculations |
466 | |||
452 | while (1) { | 467 | while (1) { |
453 | unsigned end = time(NULL); | 468 | unsigned end = time(NULL); |
454 | if (arg_netfilter && end - start >= NETLOCK_INTERVAL) | 469 | if (arg_netfilter && end - start >= NETLOCK_INTERVAL) |
@@ -470,6 +485,8 @@ static void run_trace(void) { | |||
470 | FD_SET(s1, &rfds); | 485 | FD_SET(s1, &rfds); |
471 | FD_SET(s2, &rfds); | 486 | FD_SET(s2, &rfds); |
472 | FD_SET(s3, &rfds); | 487 | FD_SET(s3, &rfds); |
488 | if (!arg_netfilter) | ||
489 | FD_SET(0, &rfds); | ||
473 | int maxfd = (s1 > s2) ? s1 : s2; | 490 | int maxfd = (s1 > s2) ? s1 : s2; |
474 | maxfd = (s3 > maxfd) ? s3 : maxfd; | 491 | maxfd = (s3 > maxfd) ? s3 : maxfd; |
475 | maxfd++; | 492 | maxfd++; |
@@ -484,9 +501,20 @@ static void run_trace(void) { | |||
484 | else if (rv == 0) | 501 | else if (rv == 0) |
485 | continue; | 502 | continue; |
486 | 503 | ||
487 | int icmp = 0; | 504 | |
505 | // rx tcp traffic by default | ||
488 | int sock = s1; | 506 | int sock = s1; |
489 | if (FD_ISSET(s2, &rfds)) | 507 | int icmp = 0; |
508 | |||
509 | if (FD_ISSET(0, &rfds)) { | ||
510 | getchar(); | ||
511 | print_stats(); | ||
512 | printf("press any key to continue..."); | ||
513 | fflush(0); | ||
514 | getchar(); | ||
515 | continue; | ||
516 | } | ||
517 | else if (FD_ISSET(s2, &rfds)) | ||
490 | sock = s2; | 518 | sock = s2; |
491 | else if (FD_ISSET(s3, &rfds)) { | 519 | else if (FD_ISSET(s3, &rfds)) { |
492 | sock = s3; | 520 | sock = s3; |
@@ -516,22 +544,32 @@ static void run_trace(void) { | |||
516 | ip_src = ntohl(ip_src); | 544 | ip_src = ntohl(ip_src); |
517 | 545 | ||
518 | uint8_t hlen = (buf[0] & 0x0f) * 4; | 546 | uint8_t hlen = (buf[0] & 0x0f) * 4; |
547 | uint16_t port_src = 0; | ||
519 | if (icmp) | 548 | if (icmp) |
520 | hnode_add(ip_src, 0, 0, bytes + 14); | 549 | hnode_add(ip_src, 0, 0, bytes + 14); |
521 | else { | 550 | else { |
522 | uint16_t port_src; | ||
523 | memcpy(&port_src, buf + hlen, 2); | 551 | memcpy(&port_src, buf + hlen, 2); |
524 | port_src = ntohs(port_src); | 552 | port_src = ntohs(port_src); |
525 | 553 | ||
526 | uint8_t protocol = buf[9]; | 554 | uint8_t protocol = buf[9]; |
527 | hnode_add(ip_src, protocol, port_src, bytes + 14); | 555 | hnode_add(ip_src, protocol, port_src, bytes + 14); |
528 | } | 556 | } |
557 | |||
558 | // stats | ||
559 | stats_pkts++; | ||
560 | if (icmp) | ||
561 | stats_icmp++; | ||
562 | if (port_src == 53) | ||
563 | stats_dns++; | ||
564 | |||
529 | } | 565 | } |
530 | } | 566 | } |
531 | } | 567 | } |
532 | 568 | ||
533 | close(s1); | 569 | close(s1); |
534 | close(s2); | 570 | close(s2); |
571 | close(s3); | ||
572 | print_stats(); | ||
535 | } | 573 | } |
536 | 574 | ||
537 | static char *filter_start = | 575 | static char *filter_start = |
@@ -733,7 +771,7 @@ int main(int argc, char **argv) { | |||
733 | else if (strcmp(argv[i], "--print-map") == 0) { | 771 | else if (strcmp(argv[i], "--print-map") == 0) { |
734 | char *fname = "static-ip-map.txt"; | 772 | char *fname = "static-ip-map.txt"; |
735 | load_hostnames(fname); | 773 | load_hostnames(fname); |
736 | radix_print(); | 774 | radix_print(0); |
737 | return 0; | 775 | return 0; |
738 | } | 776 | } |
739 | else if (strncmp(argv[i], "--squash-map=", 13) == 0) { | 777 | else if (strncmp(argv[i], "--squash-map=", 13) == 0) { |
@@ -755,7 +793,7 @@ int main(int argc, char **argv) { | |||
755 | printf("# License GPLv2\n"); | 793 | printf("# License GPLv2\n"); |
756 | printf("#\n"); | 794 | printf("#\n"); |
757 | 795 | ||
758 | radix_print(); | 796 | radix_print(0); |
759 | printf("\n#\n#\n# input %d, output %d\n#\n#\n", in, radix_nodes); | 797 | printf("\n#\n#\n# input %d, output %d\n#\n#\n", in, radix_nodes); |
760 | fprintf(stderr, "static ip map: input %d, output %d\n", in, radix_nodes); | 798 | fprintf(stderr, "static ip map: input %d, output %d\n", in, radix_nodes); |
761 | return 0; | 799 | return 0; |
@@ -790,6 +828,12 @@ int main(int argc, char **argv) { | |||
790 | return 1; | 828 | return 1; |
791 | } | 829 | } |
792 | 830 | ||
831 | terminal_set(); | ||
832 | // handle CTRL-C | ||
833 | signal (SIGINT, terminal_handler); | ||
834 | signal (SIGTERM, terminal_handler); | ||
835 | atexit(terminal_restore); | ||
836 | |||
793 | // kill the process if the parent died | 837 | // kill the process if the parent died |
794 | prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); | 838 | prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); |
795 | 839 | ||