aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@protonmail.com>2022-09-27 12:12:43 -0400
committerLibravatar netblue30 <netblue30@protonmail.com>2022-09-27 12:12:43 -0400
commit1ac8ca3c6f6ea6a2002fba05e402e0eb3f47acd8 (patch)
treef6b64766fa975a9005fa58d47777e690d5baae42 /src
parentMerge branch 'master' of ssh://github.com/netblue30/firejail (diff)
downloadfirejail-1ac8ca3c6f6ea6a2002fba05e402e0eb3f47acd8.tar.gz
firejail-1ac8ca3c6f6ea6a2002fba05e402e0eb3f47acd8.tar.zst
firejail-1ac8ca3c6f6ea6a2002fba05e402e0eb3f47acd8.zip
ICMP support in --nettrace
Diffstat (limited to 'src')
-rw-r--r--src/fnettrace/main.c136
-rw-r--r--src/fnettrace/static-ip-map9
2 files changed, 89 insertions, 56 deletions
diff --git a/src/fnettrace/main.c b/src/fnettrace/main.c
index f5e9bea65..da5ac02c6 100644
--- a/src/fnettrace/main.c
+++ b/src/fnettrace/main.c
@@ -74,7 +74,7 @@ void hfree(HNode *ptr) {
74 hnode_unused = ptr; 74 hnode_unused = ptr;
75} 75}
76 76
77 77// using protocol 0 and port 0 for ICMP
78static void hnode_add(uint32_t ip_src, uint8_t protocol, uint16_t port_src, uint32_t bytes) { 78static void hnode_add(uint32_t ip_src, uint8_t protocol, uint16_t port_src, uint32_t bytes) {
79 uint8_t h = hash(ip_src); 79 uint8_t h = hash(ip_src);
80 80
@@ -183,7 +183,7 @@ static char *print_bw(unsigned units) {
183 183
184 unsigned i; 184 unsigned i;
185 for (i = 0; i < DISPLAY_BW_UNITS; i++, ptr++) 185 for (i = 0; i < DISPLAY_BW_UNITS; i++, ptr++)
186 sprintf(ptr, "%s", (i < units)? "*": " "); 186 sprintf(ptr, "%s", (i < units) ? "*" : " ");
187 sprintf(ptr, "%s", " "); 187 sprintf(ptr, "%s", " ");
188 } 188 }
189 189
@@ -196,7 +196,7 @@ static inline void adjust_line(char *str, int len, int cols) {
196 len = LINE_MAX; 196 len = LINE_MAX;
197 if (cols > 4 && len > cols) { 197 if (cols > 4 && len > cols) {
198 str[cols] = '\0'; 198 str[cols] = '\0';
199 str[cols- 1] = '\n'; 199 str[cols - 1] = '\n';
200 } 200 }
201} 201}
202 202
@@ -211,18 +211,44 @@ static unsigned adjust_bandwidth(unsigned bw) {
211 unsigned max = 0; 211 unsigned max = 0;
212 for ( i = 0; i < BWMAX_CNT; i++) { 212 for ( i = 0; i < BWMAX_CNT; i++) {
213 sum += array[i]; 213 sum += array[i];
214 max = (max > array[i])? max: array[i]; 214 max = (max > array[i]) ? max : array[i];
215 } 215 }
216 sum /= BWMAX_CNT; 216 sum /= BWMAX_CNT;
217 217
218 if (++instance >= BWMAX_CNT) 218 if (++instance >= BWMAX_CNT)
219 instance = 0; 219 instance = 0;
220 220
221 return (max < (sum / 2))? sum: max; 221 return (max < (sum / 2)) ? sum : max;
222} 222}
223 223
224typedef struct port_type_t {
225 uint16_t port;
226 char *service;
227} PortType;
228static PortType ports[] = {
229 {20, "(FTP)"},
230 {21, "(FTP)"},
231 {22, "(SSH)"},
232 {23, "(telnet)"},
233 {25, "(SMTP)"},
234 {43, "(WHOIS)"},
235 {67, "(DHCP)"},
236 {68, "(DHCP)"},
237 {69, "(TFTP)"},
238 {80, "(HTTP)"},
239 {109, "(POP2)"},
240 {110, "(POP3)"},
241 {113, "(IRC)"},
242 {123, "(NTP)"},
243 {161, "(SNP)"},
244 {162, "(SNP)"},
245 {194, "(IRC)"},
246 {0, NULL},
247};
248
249
224static inline const char *common_port(uint16_t port) { 250static inline const char *common_port(uint16_t port) {
225 if (port > 194) { 251 if (port >= 6660 && port <= 9150) {
226 if (port >= 6660 && port <= 6669) 252 if (port >= 6660 && port <= 6669)
227 return "(IRC)"; 253 return "(IRC)";
228 else if (port == 6679) 254 else if (port == 6679)
@@ -244,44 +270,23 @@ static inline const char *common_port(uint16_t port) {
244 return NULL; 270 return NULL;
245 } 271 }
246 272
247 if (port == 20 || port == 21) 273 if (port <= 194) {
248 return "(FTP)"; 274 PortType *ptr =&ports[0];
249 else if (port == 22) 275 while(ptr->service != NULL) {
250 return "(SSH)"; 276 if (ptr->port == port)
251 else if (port == 23) 277 return ptr->service;
252 return "(telnet)"; 278 ptr++;
253 else if (port == 25) 279 }
254 return "(SMTP)"; 280 }
255 else if (port == 43)
256 return "(WHOIS)";
257 else if (port == 67)
258 return "(DHCP)";
259 else if (port == 69)
260 return "(TFTP)";
261 else if (port == 80)
262 return "(HTTP)";
263 else if (port == 109)
264 return "(POP2)";
265 else if (port == 110)
266 return "(POP3)";
267 else if (port == 113)
268 return "(IRC)";
269 else if (port == 123)
270 return "(NTP)";
271 else if (port == 161)
272 return "(SNMP)";
273 else if (port == 162)
274 return "(SNMP)";
275 else if (port == 194)
276 return "(IRC)";
277 281
278 return NULL; 282 return NULL;
279} 283}
280 284
281 285
286
282static void hnode_print(unsigned bw) { 287static void hnode_print(unsigned bw) {
283 assert(!arg_netfilter); 288 assert(!arg_netfilter);
284 bw = (bw < 1024 * DISPLAY_INTERVAL)? 1024 * DISPLAY_INTERVAL: bw; 289 bw = (bw < 1024 * DISPLAY_INTERVAL) ? 1024 * DISPLAY_INTERVAL : bw;
285#ifdef DEBUG 290#ifdef DEBUG
286 printf("*********************\n"); 291 printf("*********************\n");
287 debug_dlist(); 292 debug_dlist();
@@ -322,10 +327,10 @@ static void hnode_print(unsigned bw) {
322 char bytes[11]; 327 char bytes[11];
323 if (ptr->bytes > (DISPLAY_INTERVAL * 1024 * 1024 * 2)) // > 2 MB/second 328 if (ptr->bytes > (DISPLAY_INTERVAL * 1024 * 1024 * 2)) // > 2 MB/second
324 snprintf(bytes, 11, "%u MB/s", 329 snprintf(bytes, 11, "%u MB/s",
325 (unsigned) (ptr->bytes / (DISPLAY_INTERVAL * 1024* 1024))); 330 (unsigned) (ptr->bytes / (DISPLAY_INTERVAL * 1024 * 1024)));
326 else if (ptr->bytes > (DISPLAY_INTERVAL * 1024 * 2)) // > 2 KB/second 331 else if (ptr->bytes > (DISPLAY_INTERVAL * 1024 * 2)) // > 2 KB/second
327 snprintf(bytes, 11, "%u KB/s", 332 snprintf(bytes, 11, "%u KB/s",
328 (unsigned) (ptr->bytes / (DISPLAY_INTERVAL * 1024))); 333 (unsigned) (ptr->bytes / (DISPLAY_INTERVAL * 1024)));
329 else 334 else
330 snprintf(bytes, 11, "%u B/s ", (unsigned) (ptr->bytes / DISPLAY_INTERVAL)); 335 snprintf(bytes, 11, "%u B/s ", (unsigned) (ptr->bytes / DISPLAY_INTERVAL));
331 336
@@ -363,9 +368,13 @@ static void hnode_print(unsigned bw) {
363 368
364 if (protocol == NULL) 369 if (protocol == NULL)
365 protocol = ""; 370 protocol = "";
371 if (ptr->port_src == 0)
372 len = snprintf(line, LINE_MAX, "%10s %s %d.%d.%d.%d (ICMP) %s\n",
373 bytes, bwline, PRINT_IP(ptr->ip_src), ptr->hostname);
374 else
375 len = snprintf(line, LINE_MAX, "%10s %s %d.%d.%d.%d:%u%s %s\n",
376 bytes, bwline, PRINT_IP(ptr->ip_src), ptr->port_src, protocol, ptr->hostname);
366 377
367 len = snprintf(line, LINE_MAX, "%10s %s %d.%d.%d.%d:%u%s %s\n",
368 bytes, bwline, PRINT_IP(ptr->ip_src), ptr->port_src, protocol, ptr->hostname);
369 adjust_line(line, len, cols); 378 adjust_line(line, len, cols);
370 printf("%s", line); 379 printf("%s", line);
371 380
@@ -399,6 +408,7 @@ static void hnode_print(unsigned bw) {
399#endif 408#endif
400} 409}
401 410
411// trace rx traffic coming in
402static void run_trace(void) { 412static void run_trace(void) {
403 if (arg_netfilter) 413 if (arg_netfilter)
404 logprintf("accumulating traffic for %d seconds\n", NETLOCK_INTERVAL); 414 logprintf("accumulating traffic for %d seconds\n", NETLOCK_INTERVAL);
@@ -406,7 +416,8 @@ static void run_trace(void) {
406 // trace only rx ipv4 tcp and upd 416 // trace only rx ipv4 tcp and upd
407 int s1 = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); 417 int s1 = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
408 int s2 = socket(AF_INET, SOCK_RAW, IPPROTO_UDP); 418 int s2 = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
409 if (s1 < 0 || s2 < 0) 419 int s3 = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
420 if (s1 < 0 || s2 < 0 || s3 < 0)
410 errExit("socket"); 421 errExit("socket");
411 422
412 unsigned start = time(NULL); 423 unsigned start = time(NULL);
@@ -434,18 +445,29 @@ static void run_trace(void) {
434 FD_ZERO(&rfds); 445 FD_ZERO(&rfds);
435 FD_SET(s1, &rfds); 446 FD_SET(s1, &rfds);
436 FD_SET(s2, &rfds); 447 FD_SET(s2, &rfds);
448 FD_SET(s3, &rfds);
437 int maxfd = (s1 > s2) ? s1 : s2; 449 int maxfd = (s1 > s2) ? s1 : s2;
438 maxfd++; 450 maxfd = (s3 > maxfd) ? s3 : maxfd;
451 maxfd++;
452
439 struct timeval tv; 453 struct timeval tv;
440 tv.tv_sec = 1; 454 tv.tv_sec = 1;
441 tv.tv_usec = 0; 455 tv.tv_usec = 0;
456
442 int rv = select(maxfd, &rfds, NULL, NULL, &tv); 457 int rv = select(maxfd, &rfds, NULL, NULL, &tv);
443 if (rv < 0) 458 if (rv < 0)
444 errExit("select"); 459 errExit("select");
445 else if (rv == 0) 460 else if (rv == 0)
446 continue; 461 continue;
447 462
448 int sock = (FD_ISSET(s1, &rfds)) ? s1 : s2; 463 int icmp = 0;
464 int sock = s1;
465 if (FD_ISSET(s2, &rfds))
466 sock = s2;
467 else if (FD_ISSET(s3, &rfds)) {
468 sock = s3;
469 icmp = 1;
470 }
449 471
450 unsigned bytes = recvfrom(sock, buf, MAX_BUF_SIZE, 0, NULL, NULL); 472 unsigned bytes = recvfrom(sock, buf, MAX_BUF_SIZE, 0, NULL, NULL);
451 if (bytes >= 20) { // size of IP header 473 if (bytes >= 20) { // size of IP header
@@ -470,12 +492,16 @@ static void run_trace(void) {
470 ip_src = ntohl(ip_src); 492 ip_src = ntohl(ip_src);
471 493
472 uint8_t hlen = (buf[0] & 0x0f) * 4; 494 uint8_t hlen = (buf[0] & 0x0f) * 4;
473 uint16_t port_src; 495 if (icmp)
474 memcpy(&port_src, buf + hlen, 2); 496 hnode_add(ip_src, 0, 0, bytes + 14);
475 port_src = ntohs(port_src); 497 else {
476 498 uint16_t port_src;
477 uint8_t protocol = buf[9]; 499 memcpy(&port_src, buf + hlen, 2);
478 hnode_add(ip_src, protocol, port_src, bytes + 14); 500 port_src = ntohs(port_src);
501
502 uint8_t protocol = buf[9];
503 hnode_add(ip_src, protocol, port_src, bytes + 14);
504 }
479 } 505 }
480 } 506 }
481 } 507 }
@@ -506,7 +532,7 @@ static int print_filter(FILE *fp) {
506 // filter rules are targeting ip address, the port number is disregarded, 532 // filter rules are targeting ip address, the port number is disregarded,
507 // so we look only at the first instance of an address 533 // so we look only at the first instance of an address
508 if (ptr->ip_instance == 1) { 534 if (ptr->ip_instance == 1) {
509 char *protocol = (ptr->protocol == 6)? "tcp": "udp"; 535 char *protocol = (ptr->protocol == 6) ? "tcp" : "udp";
510 fprintf(fp, "-A INPUT -s %d.%d.%d.%d -p %s -j ACCEPT\n", 536 fprintf(fp, "-A INPUT -s %d.%d.%d.%d -p %s -j ACCEPT\n",
511 PRINT_IP(ptr->ip_src), 537 PRINT_IP(ptr->ip_src),
512 protocol); 538 protocol);
@@ -583,7 +609,7 @@ static void deploy_netfilter(void) {
583 exit(1); 609 exit(1);
584 } 610 }
585 611
586 FILE* fp = fdopen(fd, "w"); 612 FILE *fp = fdopen(fd, "w");
587 if (!fp) { 613 if (!fp) {
588 rv = unlink(fname); 614 rv = unlink(fname);
589 (void) rv; 615 (void) rv;
@@ -621,21 +647,21 @@ static void deploy_netfilter(void) {
621 logprintf("\nfirewall deployed\n"); 647 logprintf("\nfirewall deployed\n");
622} 648}
623 649
624void logprintf(char* fmt, ...) { 650void logprintf(char *fmt, ...) {
625 if (!arg_log) 651 if (!arg_log)
626 return; 652 return;
627 653
628 FILE *fp = fopen(arg_log, "a"); 654 FILE *fp = fopen(arg_log, "a");
629 if (fp) { // disregard if error 655 if (fp) { // disregard if error
630 va_list args; 656 va_list args;
631 va_start(args,fmt); 657 va_start(args, fmt);
632 vfprintf(fp, fmt, args); 658 vfprintf(fp, fmt, args);
633 va_end(args); 659 va_end(args);
634 fclose(fp); 660 fclose(fp);
635 } 661 }
636 662
637 va_list args; 663 va_list args;
638 va_start(args,fmt); 664 va_start(args, fmt);
639 vfprintf(stdout, fmt, args); 665 vfprintf(stdout, fmt, args);
640 va_end(args); 666 va_end(args);
641} 667}
diff --git a/src/fnettrace/static-ip-map b/src/fnettrace/static-ip-map
index d1ce29dac..dfde16f6e 100644
--- a/src/fnettrace/static-ip-map
+++ b/src/fnettrace/static-ip-map
@@ -65,9 +65,13 @@
65214.0.0.0/8 US Army 65214.0.0.0/8 US Army
66215.0.0.0/8 US Army 66215.0.0.0/8 US Army
67 67
68# whois/DNS 68# DNS
691.1.1.0/24 Cloudflare DNS 691.1.1.0/24 Cloudflare DNS
701.0.0.0/24 Cloudflare DNS 701.0.0.0/24 Cloudflare DNS
714.2.2.1/32 Level3 DNS
724.2.2.2/32 Level3 DNS
734.2.2.3/32 Level3 DNS
744.2.2.4/32 Level3 DNS
718.8.4.0/24 Google DNS 758.8.4.0/24 Google DNS
728.8.8.0/24 Google DNS 768.8.8.0/24 Google DNS
739.9.9.0/24 Quad9 DNS 779.9.9.0/24 Quad9 DNS
@@ -76,6 +80,9 @@
76149.112.120.0/21 CIRA DNS Canada 80149.112.120.0/21 CIRA DNS Canada
77176.103.128.0/19 Adguard DNS 81176.103.128.0/19 Adguard DNS
78185.228.168.0/24 Cleanbrowsing DNS 82185.228.168.0/24 Cleanbrowsing DNS
83208.67.216.0/21 OpenDNS
84
85# whois
79193.0.0.0/21 whois.ripe.net Netherlands 86193.0.0.0/21 whois.ripe.net Netherlands
80199.5.26.0/24 whois.arin.net US 87199.5.26.0/24 whois.arin.net US
81199.15.80.0/21 whois.publicinterestregistry.net Canada 88199.15.80.0/21 whois.publicinterestregistry.net Canada