aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@protonmail.com>2022-01-09 22:20:35 -0500
committerLibravatar netblue30 <netblue30@protonmail.com>2022-01-09 22:20:35 -0500
commit55b986d253fcae830d4a5daeaee6b1a784bebef0 (patch)
treea85eb60ecba674771e5dc35dbc39b5ccf5ea400d /src
parentMerge branch 'master' of ssh://github.com/netblue30/firejail (diff)
downloadfirejail-55b986d253fcae830d4a5daeaee6b1a784bebef0.tar.gz
firejail-55b986d253fcae830d4a5daeaee6b1a784bebef0.tar.zst
firejail-55b986d253fcae830d4a5daeaee6b1a784bebef0.zip
nettrace
Diffstat (limited to 'src')
-rw-r--r--src/fnettrace/fnettrace.h1
-rw-r--r--src/fnettrace/hostnames17
-rw-r--r--src/fnettrace/hostnames.c10
-rw-r--r--src/fnettrace/main.c112
-rw-r--r--src/fnettrace/radix.c20
-rw-r--r--src/fnettrace/radix.h1
6 files changed, 121 insertions, 40 deletions
diff --git a/src/fnettrace/fnettrace.h b/src/fnettrace/fnettrace.h
index c2f76f3a6..50c538a71 100644
--- a/src/fnettrace/fnettrace.h
+++ b/src/fnettrace/fnettrace.h
@@ -59,6 +59,7 @@ static inline uint8_t hash(uint32_t ip) {
59void logprintf(char* fmt, ...); 59void logprintf(char* fmt, ...);
60 60
61// hostnames.c 61// hostnames.c
62extern int geoip_calls;
62void load_hostnames(const char *fname); 63void load_hostnames(const char *fname);
63char* retrieve_hostname(uint32_t ip); 64char* retrieve_hostname(uint32_t ip);
64void build_list(const char *fname); 65void build_list(const char *fname);
diff --git a/src/fnettrace/hostnames b/src/fnettrace/hostnames
index b10d9a13d..6b7a19689 100644
--- a/src/fnettrace/hostnames
+++ b/src/fnettrace/hostnames
@@ -66,7 +66,7 @@
669.9.9.0/24 Quad9 DNS 669.9.9.0/24 Quad9 DNS
6745.90.28.0/22 NextDNS 6745.90.28.0/22 NextDNS
68149.112.112.0/24 Quad9 DNS 68149.112.112.0/24 Quad9 DNS
69149.112.120.0/21 CIRA DNS Canada 69149.112.120.0/21 CIRA DNS Csnada
70176.103.128.0/19 Adguard DNS 70176.103.128.0/19 Adguard DNS
71185.228.168.0/24 Cleanbrowsing DNS 71185.228.168.0/24 Cleanbrowsing DNS
72193.0.0.0/21 whois.ripe.net Netherlands 72193.0.0.0/21 whois.ripe.net Netherlands
@@ -160,6 +160,21 @@
160108.46.0.0/16 MCI 160108.46.0.0/16 MCI
161192.229.128.0/17 MCI 161192.229.128.0/17 MCI
162 162
163# Microsoft
16440.76.0.0/14 Microsoft
16540.96.0.0/12 Microsoft
16640.112.0.0/13 Microsoft
16740.124.0.0/16 Microsoft
16840.74.0.0/15 Microsoft
16940.80.0.0/12 Microsoft
17040.120.0.0/14 Microsoft
17140.125.0.0/17 Microsoft
17252.145.0.0/16 Microsoft
17352.148.0.0/14 Microsoft
17452.152.0.0/13 Microsoft
17552.146.0.0/15 Microsoft
17652.160.0.0/11 Microsoft
177
163# Yahoo 178# Yahoo
16463.250.192.0/19 Yahoo 17963.250.192.0/19 Yahoo
16566.196.64.0/18 Yahoo 18066.196.64.0/18 Yahoo
diff --git a/src/fnettrace/hostnames.c b/src/fnettrace/hostnames.c
index e1ad45f81..733d13853 100644
--- a/src/fnettrace/hostnames.c
+++ b/src/fnettrace/hostnames.c
@@ -21,8 +21,14 @@
21#include "radix.h" 21#include "radix.h"
22#define MAXBUF 1024 22#define MAXBUF 1024
23 23
24int geoip_calls = 0;
25static int geoip_not_found = 0;
24 26
25char *retrieve_hostname(uint32_t ip) { 27char *retrieve_hostname(uint32_t ip) {
28 if (geoip_not_found)
29 return NULL;
30 geoip_calls++;
31
26 char *rv = NULL; 32 char *rv = NULL;
27 char *cmd; 33 char *cmd;
28 if (asprintf(&cmd, "/usr/bin/geoiplookup %d.%d.%d.%d", PRINT_IP(ip)) == -1) 34 if (asprintf(&cmd, "/usr/bin/geoiplookup %d.%d.%d.%d", PRINT_IP(ip)) == -1)
@@ -47,6 +53,10 @@ char *retrieve_hostname(uint32_t ip) {
47 fclose(fp); 53 fclose(fp);
48 return rv; 54 return rv;
49 } 55 }
56 else
57 geoip_not_found = 1;
58
59 free(cmd);
50 60
51 return NULL; 61 return NULL;
52} 62}
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
47HNode *dlist = NULL; 47HNode *dlist = NULL;
48 48
49static unsigned bwmax = 0; // max bytes received in a display interval
50
51static void hnode_add(uint32_t ip_src, uint32_t ip_dst, uint8_t protocol, uint16_t port_src, uint32_t bytes) { 49static 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
167static void hnode_print(void) { 166#define LINE_MAX 200
167static 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
177static 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
197static 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
251static void run_trace(void) { 305static 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
diff --git a/src/fnettrace/radix.c b/src/fnettrace/radix.c
index a1f44dd31..d68aaf85c 100644
--- a/src/fnettrace/radix.c
+++ b/src/fnettrace/radix.c
@@ -26,6 +26,7 @@
26#include "fnettrace.h" 26#include "fnettrace.h"
27 27
28RNode *head = 0; 28RNode *head = 0;
29int radix_nodes = 0;
29 30
30static inline RNode *addOne(RNode *ptr, uint32_t ip, uint32_t mask, char *name) { 31static inline RNode *addOne(RNode *ptr, uint32_t ip, uint32_t mask, char *name) {
31 assert(ptr); 32 assert(ptr);
@@ -34,6 +35,7 @@ static inline RNode *addOne(RNode *ptr, uint32_t ip, uint32_t mask, char *name)
34 RNode *node = malloc(sizeof(RNode)); 35 RNode *node = malloc(sizeof(RNode));
35 if (!node) 36 if (!node)
36 errExit("malloc"); 37 errExit("malloc");
38 radix_nodes++;
37 memset(node, 0, sizeof(RNode)); 39 memset(node, 0, sizeof(RNode));
38 node->ip = ip; 40 node->ip = ip;
39 node->mask = mask; 41 node->mask = mask;
@@ -42,7 +44,7 @@ static inline RNode *addOne(RNode *ptr, uint32_t ip, uint32_t mask, char *name)
42 if (!node->name) 44 if (!node->name)
43 errExit("strdup"); 45 errExit("strdup");
44 } 46 }
45 47
46 ptr->one = node; 48 ptr->one = node;
47 return node; 49 return node;
48} 50}
@@ -62,7 +64,7 @@ static inline RNode *addZero(RNode *ptr, uint32_t ip, uint32_t mask, char *name)
62 if (!node->name) 64 if (!node->name)
63 errExit("strdup"); 65 errExit("strdup");
64 } 66 }
65 67
66 ptr->zero = node; 68 ptr->zero = node;
67 return node; 69 return node;
68} 70}
@@ -146,13 +148,13 @@ char *radix_find_last(uint32_t ip) {
146 if (ptr->name) 148 if (ptr->name)
147 rv = ptr; 149 rv = ptr;
148 } 150 }
149 151
150 return (rv)? rv->name: NULL; 152 return (rv)? rv->name: NULL;
151} 153}
152 154
153static void radix_print_node(RNode *ptr, int level) { 155static void radix_print_node(RNode *ptr, int level) {
154 assert(ptr); 156 assert(ptr);
155 157
156 int i; 158 int i;
157 for (i = 0; i < level; i++) 159 for (i = 0; i < level; i++)
158 printf(" "); 160 printf(" ");
@@ -173,7 +175,7 @@ void radix_print(void) {
173 printf("radix tree is empty\n"); 175 printf("radix tree is empty\n");
174 return; 176 return;
175 } 177 }
176 178
177 printf("radix IPv4 tree\n"); 179 printf("radix IPv4 tree\n");
178 radix_print_node(head, 0); 180 radix_print_node(head, 0);
179} 181}
@@ -187,14 +189,14 @@ static inline int mask2cidr(uint32_t mask) {
187 if (mask & m) 189 if (mask & m)
188 cnt++; 190 cnt++;
189 } 191 }
190 192
191 return cnt; 193 return cnt;
192} 194}
193 195
194static void radix_build_list_node(RNode *ptr) { 196static void radix_build_list_node(RNode *ptr) {
195 assert(ptr); 197 assert(ptr);
196 198
197 199
198 if (ptr->name) { 200 if (ptr->name) {
199 printf("%d.%d.%d.%d/%d %s\n", PRINT_IP(ptr->ip), mask2cidr(ptr->mask), ptr->name); 201 printf("%d.%d.%d.%d/%d %s\n", PRINT_IP(ptr->ip), mask2cidr(ptr->mask), ptr->name);
200 return; 202 return;
@@ -213,6 +215,6 @@ void radix_build_list(void) {
213 return; 215 return;
214 } 216 }
215 217
216 radix_build_list_node(head); 218 radix_build_list_node(head);
217} 219}
218 220
diff --git a/src/fnettrace/radix.h b/src/fnettrace/radix.h
index b77c24216..ed7ae0cb7 100644
--- a/src/fnettrace/radix.h
+++ b/src/fnettrace/radix.h
@@ -28,6 +28,7 @@ typedef struct rnode_t {
28 char *name; 28 char *name;
29} RNode; 29} RNode;
30 30
31extern int radix_nodes;
31char *radix_find_first(uint32_t ip); 32char *radix_find_first(uint32_t ip);
32char *radix_find_last(uint32_t ip); 33char *radix_find_last(uint32_t ip);
33void radix_add(uint32_t ip, uint32_t mask, char *name); 34void radix_add(uint32_t ip, uint32_t mask, char *name);