diff options
author | netblue30 <netblue30@protonmail.com> | 2023-07-16 11:32:00 -0400 |
---|---|---|
committer | netblue30 <netblue30@protonmail.com> | 2023-07-16 11:32:00 -0400 |
commit | f3e428e6fab326c993e17eeae1c223dcb5f8dc2b (patch) | |
tree | a750e0b86041ae5df4ab2acb817af23648c2a568 /src | |
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')
-rw-r--r-- | src/firejail/netfilter.c | 2 | ||||
-rw-r--r-- | src/fnettrace/fnettrace.h | 5 | ||||
-rw-r--r-- | src/fnettrace/main.c | 56 | ||||
-rw-r--r-- | src/fnettrace/radix.c | 27 | ||||
-rw-r--r-- | src/fnettrace/radix.h | 2 | ||||
-rw-r--r-- | src/fnettrace/static-ip-map.txt | 14 | ||||
-rw-r--r-- | src/fnettrace/terminal.c | 52 |
7 files changed, 141 insertions, 17 deletions
diff --git a/src/firejail/netfilter.c b/src/firejail/netfilter.c index 32fdd6218..458fb0dd1 100644 --- a/src/firejail/netfilter.c +++ b/src/firejail/netfilter.c | |||
@@ -108,7 +108,7 @@ void netfilter_trace(pid_t pid, const char *cmd) { | |||
108 | arg[3] = NULL; | 108 | arg[3] = NULL; |
109 | 109 | ||
110 | clearenv(); | 110 | clearenv(); |
111 | sbox_exec_v(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, arg); | 111 | sbox_exec_v(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP | SBOX_ALLOW_STDIN, arg); |
112 | // it will never get here!! | 112 | // it will never get here!! |
113 | } | 113 | } |
114 | 114 | ||
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 |
71 | void tail(const char *logfile); | 71 | void tail(const char *logfile); |
72 | 72 | ||
73 | // terminal.c | ||
74 | void terminal_handler(int s); | ||
75 | void terminal_set(void); | ||
76 | void 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; | |||
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 | ||
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 | ||
153 | static uint32_t sum; | 153 | static uint32_t sum; |
154 | static void print(RNode *ptr, int level) { | 154 | static 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 | ||
174 | void radix_print(void) { | 184 | void 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 { | |||
30 | extern int radix_nodes; | 30 | extern int radix_nodes; |
31 | RNode *radix_longest_prefix_match(uint32_t ip); | 31 | RNode *radix_longest_prefix_match(uint32_t ip); |
32 | RNode*radix_add(uint32_t ip, uint32_t mask, char *name); | 32 | RNode*radix_add(uint32_t ip, uint32_t mask, char *name); |
33 | void radix_print(void); | 33 | void radix_print(int pkts); |
34 | void radix_squash(void); | 34 | void 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 @@ | |||
202 | 199.9.248.0/21 Twitch | 202 | 199.9.248.0/21 Twitch |
203 | 199.16.156.0/22 Twitter | 203 | 199.16.156.0/22 Twitter |
204 | 199.59.148.0/22 Twitter | 204 | 199.59.148.0/22 Twitter |
205 | 199.168.96.24/29 BitChute | ||
205 | 205.185.194.0/24 Steam | 206 | 205.185.194.0/24 Steam |
206 | 205.196.6.0/24 Steam | 207 | 205.196.6.0/24 Steam |
207 | 207.45.72.0/22 Netflix | 208 | 207.45.72.0/22 Netflix |
@@ -212,6 +213,19 @@ | |||
212 | 208.80.152.0/22 Wikipedia | 213 | 208.80.152.0/22 Wikipedia |
213 | 209.140.128.0/18 eBay | 214 | 209.140.128.0/18 eBay |
214 | 215 | ||
216 | # Imperva | ||
217 | 199.83.128.0/21 Imperva | ||
218 | 198.143.32.0/19 Imperva | ||
219 | 149.126.72.0/21 Imperva | ||
220 | 103.28.248.0/22 Imperva | ||
221 | 45.64.64.0/22 Imperva | ||
222 | 185.11.124.0/22 Imperva | ||
223 | 192.230.64.0/18 Imperva | ||
224 | 107.154.0.0/16 Imperva | ||
225 | 45.60.0.0/16 Imperva | ||
226 | 45.223.0.0/16 Imperva | ||
227 | 131.125.128.0/17 Imperva | ||
228 | |||
215 | # Level 3 | 229 | # Level 3 |
216 | 66.114.192.0/18 Level 3 | 230 | 66.114.192.0/18 Level 3 |
217 | 66.147.128.0/18 Level 3 | 231 | 66.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 | |||
23 | static struct termios tlocal; // startup terminal setting | ||
24 | static struct termios twait; // no wait on key press | ||
25 | static int tset = 0; | ||
26 | |||
27 | void terminal_restore(void) { | ||
28 | if (tset) | ||
29 | tcsetattr(0, TCSANOW, &tlocal); | ||
30 | } | ||
31 | |||
32 | void terminal_handler(int s) { | ||
33 | // Remove unused parameter warning | ||
34 | (void)s; | ||
35 | terminal_restore(); | ||
36 | _exit(0); | ||
37 | } | ||
38 | |||
39 | void 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 | |||