aboutsummaryrefslogtreecommitdiffstats
path: root/src/fnettrace/main.c
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/fnettrace/main.c
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/fnettrace/main.c')
-rw-r--r--src/fnettrace/main.c112
1 files changed, 82 insertions, 30 deletions
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