aboutsummaryrefslogtreecommitdiffstats
path: root/src/fnettrace
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@protonmail.com>2023-07-16 11:32:00 -0400
committerLibravatar netblue30 <netblue30@protonmail.com>2023-07-16 11:32:00 -0400
commitf3e428e6fab326c993e17eeae1c223dcb5f8dc2b (patch)
treea750e0b86041ae5df4ab2acb817af23648c2a568 /src/fnettrace
parentMerge branch 'master' of ssh://github.com/netblue30/firejail (diff)
downloadfirejail-f3e428e6fab326c993e17eeae1c223dcb5f8dc2b.tar.gz
firejail-f3e428e6fab326c993e17eeae1c223dcb5f8dc2b.tar.zst
firejail-f3e428e6fab326c993e17eeae1c223dcb5f8dc2b.zip
feature: stats support for --nettrace
Diffstat (limited to 'src/fnettrace')
-rw-r--r--src/fnettrace/fnettrace.h5
-rw-r--r--src/fnettrace/main.c56
-rw-r--r--src/fnettrace/radix.c27
-rw-r--r--src/fnettrace/radix.h2
-rw-r--r--src/fnettrace/static-ip-map.txt14
-rw-r--r--src/fnettrace/terminal.c52
6 files changed, 140 insertions, 16 deletions
diff --git a/src/fnettrace/fnettrace.h b/src/fnettrace/fnettrace.h
index 629b8ce5b..b1a2f5b6c 100644
--- a/src/fnettrace/fnettrace.h
+++ b/src/fnettrace/fnettrace.h
@@ -70,4 +70,9 @@ char* retrieve_hostname(uint32_t ip);
70// tail.c 70// tail.c
71void tail(const char *logfile); 71void tail(const char *logfile);
72 72
73// terminal.c
74void terminal_handler(int s);
75void terminal_set(void);
76void terminal_restore(void);
77
73#endif 78#endif
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;
29static int arg_tail = 0; 29static int arg_tail = 0;
30static char *arg_log = NULL; 30static char *arg_log = NULL;
31 31
32uint32_t stats_pkts = 0;
33uint32_t stats_icmp = 0;
34uint32_t stats_dns = 0;
35
36
32typedef struct hnode_t { 37typedef 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
442void 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
436static void run_trace(void) { 450static 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
537static char *filter_start = 575static 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
diff --git a/src/fnettrace/radix.c b/src/fnettrace/radix.c
index f0ac4c094..322ee2643 100644
--- a/src/fnettrace/radix.c
+++ b/src/fnettrace/radix.c
@@ -151,12 +151,22 @@ RNode *radix_longest_prefix_match(uint32_t ip) {
151} 151}
152 152
153static uint32_t sum; 153static uint32_t sum;
154static void print(RNode *ptr, int level) { 154static void print(RNode *ptr, int level, int pkts) {
155 if (!ptr) 155 if (!ptr)
156 return; 156 return;
157 if (ptr->name) { 157 if (ptr->name) {
158 printf("%d.%d.%d.%d/%d ", PRINT_IP(sum << (32 - level)), level); 158 if (pkts) {
159 printf("%s\n", ptr->name); 159 if (ptr->pkts) {
160 printf(" %d.%d.%d.%d/%d ", PRINT_IP(sum << (32 - level)), level);
161 printf("%s", ptr->name);
162 printf(" (%u)\n", ptr->pkts);
163 }
164 }
165 else {
166 printf("%d.%d.%d.%d/%d ", PRINT_IP(sum << (32 - level)), level);
167 printf("%s", ptr->name);
168 printf("\n");
169 }
160 } 170 }
161 171
162 if (ptr->zero == NULL && ptr->one == NULL) 172 if (ptr->zero == NULL && ptr->one == NULL)
@@ -164,22 +174,21 @@ static void print(RNode *ptr, int level) {
164 174
165 level++; 175 level++;
166 sum <<= 1; 176 sum <<= 1;
167 print(ptr->zero, level); 177 print(ptr->zero, level, pkts);
168 sum++; 178 sum++;
169 print(ptr->one, level); 179 print(ptr->one, level, pkts);
170 sum--; 180 sum--;
171 sum >>= 1; 181 sum >>= 1;
172} 182}
173 183
174void radix_print(void) { 184void radix_print(int pkts) {
175 if (!head) 185 if (!head)
176 return; 186 return;
177 printf("\n");
178 sum = 0; 187 sum = 0;
179 print(head->zero, 1); 188 print(head->zero, 1, pkts);
180 assert(sum == 0); 189 assert(sum == 0);
181 sum = 1; 190 sum = 1;
182 print(head->one, 1); 191 print(head->one, 1, pkts);
183 assert(sum == 1); 192 assert(sum == 1);
184} 193}
185 194
diff --git a/src/fnettrace/radix.h b/src/fnettrace/radix.h
index 60a64f18f..358524723 100644
--- a/src/fnettrace/radix.h
+++ b/src/fnettrace/radix.h
@@ -30,7 +30,7 @@ typedef struct rnode_t {
30extern int radix_nodes; 30extern int radix_nodes;
31RNode *radix_longest_prefix_match(uint32_t ip); 31RNode *radix_longest_prefix_match(uint32_t ip);
32RNode*radix_add(uint32_t ip, uint32_t mask, char *name); 32RNode*radix_add(uint32_t ip, uint32_t mask, char *name);
33void radix_print(void); 33void radix_print(int pkts);
34void radix_squash(void); 34void radix_squash(void);
35 35
36#endif 36#endif
diff --git a/src/fnettrace/static-ip-map.txt b/src/fnettrace/static-ip-map.txt
index 52eb307d8..756658562 100644
--- a/src/fnettrace/static-ip-map.txt
+++ b/src/fnettrace/static-ip-map.txt
@@ -202,6 +202,7 @@
202199.9.248.0/21 Twitch 202199.9.248.0/21 Twitch
203199.16.156.0/22 Twitter 203199.16.156.0/22 Twitter
204199.59.148.0/22 Twitter 204199.59.148.0/22 Twitter
205199.168.96.24/29 BitChute
205205.185.194.0/24 Steam 206205.185.194.0/24 Steam
206205.196.6.0/24 Steam 207205.196.6.0/24 Steam
207207.45.72.0/22 Netflix 208207.45.72.0/22 Netflix
@@ -212,6 +213,19 @@
212208.80.152.0/22 Wikipedia 213208.80.152.0/22 Wikipedia
213209.140.128.0/18 eBay 214209.140.128.0/18 eBay
214 215
216# Imperva
217199.83.128.0/21 Imperva
218198.143.32.0/19 Imperva
219149.126.72.0/21 Imperva
220103.28.248.0/22 Imperva
22145.64.64.0/22 Imperva
222185.11.124.0/22 Imperva
223192.230.64.0/18 Imperva
224107.154.0.0/16 Imperva
22545.60.0.0/16 Imperva
22645.223.0.0/16 Imperva
227131.125.128.0/17 Imperva
228
215# Level 3 229# Level 3
21666.114.192.0/18 Level 3 23066.114.192.0/18 Level 3
21766.147.128.0/18 Level 3 23166.147.128.0/18 Level 3
diff --git a/src/fnettrace/terminal.c b/src/fnettrace/terminal.c
new file mode 100644
index 000000000..0ca307bad
--- /dev/null
+++ b/src/fnettrace/terminal.c
@@ -0,0 +1,52 @@
1/*
2 * Copyright (C) 2014-2023 Firejail Authors
3 *
4 * This file is part of firejail project
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 2 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 along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "fnettrace.h"
21#include <termios.h>
22
23static struct termios tlocal; // startup terminal setting
24static struct termios twait; // no wait on key press
25static int tset = 0;
26
27void terminal_restore(void) {
28 if (tset)
29 tcsetattr(0, TCSANOW, &tlocal);
30}
31
32void terminal_handler(int s) {
33 // Remove unused parameter warning
34 (void)s;
35 terminal_restore();
36 _exit(0);
37}
38
39void terminal_set(void) {
40 if (tset == 0) {
41 tcgetattr(0, &twait); // get current terminal attributes; 0 is the file descriptor for stdin
42 memcpy(&tlocal, &twait, sizeof(tlocal));
43 twait.c_lflag &= ~ICANON; // disable canonical mode
44 twait.c_lflag &= ~ECHO; // no echo
45 twait.c_cc[VMIN] = 1; // wait until at least one keystroke available
46 twait.c_cc[VTIME] = 0; // no timeout
47 tset = 1;
48 }
49 tcsetattr(0, TCSANOW, &twait);
50}
51
52