Revert "flowtop: Don't init screen until collector is ready"
[netsniff-ng-new.git] / flowtop.c
blob8cf2fd3508d2ce03ed4fc43fc67d1e8bf01df827
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2011 - 2013 Daniel Borkmann.
4 * Copyright 2011 Emmanuel Roullit.
5 * Subject to the GPL, version 2.
6 */
8 #define _LGPL_SOURCE
9 #include <stdio.h>
10 #include <stdint.h>
11 #include <stdlib.h>
12 #include <signal.h>
13 #include <getopt.h>
14 #include <pthread.h>
15 #include <signal.h>
16 #include <netdb.h>
17 #include <ctype.h>
18 #include <netinet/in.h>
19 #include <curses.h>
20 #include <dirent.h>
21 #include <sys/stat.h>
22 #include <sys/fsuid.h>
23 #include <urcu.h>
24 #include <libgen.h>
25 #include <inttypes.h>
26 #include <poll.h>
27 #include <fcntl.h>
29 #include "die.h"
30 #include "xmalloc.h"
31 #include "conntrack.h"
32 #include "config.h"
33 #include "str.h"
34 #include "sig.h"
35 #include "lookup.h"
36 #include "geoip.h"
37 #include "built_in.h"
38 #include "locking.h"
39 #include "pkt_buff.h"
40 #include "screen.h"
41 #include "proc.h"
43 struct flow_entry {
44 uint32_t flow_id, use, status;
45 uint8_t l3_proto, l4_proto;
46 uint32_t ip4_src_addr, ip4_dst_addr;
47 uint32_t ip6_src_addr[4], ip6_dst_addr[4];
48 uint16_t port_src, port_dst;
49 uint8_t tcp_state, tcp_flags, sctp_state, dccp_state;
50 uint64_t counter_pkts, counter_bytes;
51 uint64_t timestamp_start, timestamp_stop;
52 char country_src[128], country_dst[128];
53 char city_src[128], city_dst[128];
54 char rev_dns_src[256], rev_dns_dst[256];
55 char cmdline[256];
56 struct flow_entry *next;
57 int inode;
58 unsigned int procnum;
59 bool is_visible;
60 struct nf_conntrack *ct;
63 struct flow_list {
64 struct flow_entry *head;
65 struct spinlock lock;
68 #ifndef ATTR_TIMESTAMP_START
69 # define ATTR_TIMESTAMP_START 63
70 #endif
71 #ifndef ATTR_TIMESTAMP_STOP
72 # define ATTR_TIMESTAMP_STOP 64
73 #endif
75 #define SCROLL_MAX 1000
77 #define INCLUDE_IPV4 (1 << 0)
78 #define INCLUDE_IPV6 (1 << 1)
79 #define INCLUDE_UDP (1 << 2)
80 #define INCLUDE_TCP (1 << 3)
81 #define INCLUDE_DCCP (1 << 4)
82 #define INCLUDE_ICMP (1 << 5)
83 #define INCLUDE_SCTP (1 << 6)
85 static volatile sig_atomic_t sigint = 0;
86 static int what = INCLUDE_IPV4 | INCLUDE_IPV6 | INCLUDE_TCP, show_src = 0;
87 static struct flow_list flow_list;
88 static int nfct_acct_val = -1;
90 static const char *short_options = "vhTUsDIS46u";
91 static const struct option long_options[] = {
92 {"ipv4", no_argument, NULL, '4'},
93 {"ipv6", no_argument, NULL, '6'},
94 {"tcp", no_argument, NULL, 'T'},
95 {"udp", no_argument, NULL, 'U'},
96 {"dccp", no_argument, NULL, 'D'},
97 {"icmp", no_argument, NULL, 'I'},
98 {"sctp", no_argument, NULL, 'S'},
99 {"show-src", no_argument, NULL, 's'},
100 {"update", no_argument, NULL, 'u'},
101 {"version", no_argument, NULL, 'v'},
102 {"help", no_argument, NULL, 'h'},
103 {NULL, 0, NULL, 0}
106 static const char *copyright = "Please report bugs to <bugs@netsniff-ng.org>\n"
107 "Copyright (C) 2011-2013 Daniel Borkmann <dborkma@tik.ee.ethz.ch>\n"
108 "Copyright (C) 2011-2012 Emmanuel Roullit <emmanuel.roullit@gmail.com>\n"
109 "Swiss federal institute of technology (ETH Zurich)\n"
110 "License: GNU GPL version 2.0\n"
111 "This is free software: you are free to change and redistribute it.\n"
112 "There is NO WARRANTY, to the extent permitted by law.";
114 static const char *const l3proto2str[AF_MAX] = {
115 [AF_INET] = "ipv4",
116 [AF_INET6] = "ipv6",
119 static const char *const l4proto2str[IPPROTO_MAX] = {
120 [IPPROTO_TCP] = "tcp",
121 [IPPROTO_UDP] = "udp",
122 [IPPROTO_UDPLITE] = "udplite",
123 [IPPROTO_ICMP] = "icmp",
124 [IPPROTO_ICMPV6] = "icmpv6",
125 [IPPROTO_SCTP] = "sctp",
126 [IPPROTO_GRE] = "gre",
127 [IPPROTO_DCCP] = "dccp",
128 [IPPROTO_IGMP] = "igmp",
129 [IPPROTO_IPIP] = "ipip",
130 [IPPROTO_EGP] = "egp",
131 [IPPROTO_PUP] = "pup",
132 [IPPROTO_IDP] = "idp",
133 [IPPROTO_RSVP] = "rsvp",
134 [IPPROTO_IPV6] = "ip6tun",
135 [IPPROTO_ESP] = "esp",
136 [IPPROTO_AH] = "ah",
137 [IPPROTO_PIM] = "pim",
138 [IPPROTO_COMP] = "comp",
141 static const char *const tcp_state2str[TCP_CONNTRACK_MAX] = {
142 [TCP_CONNTRACK_NONE] = "NOSTATE",
143 [TCP_CONNTRACK_SYN_SENT] = "SYN_SENT",
144 [TCP_CONNTRACK_SYN_RECV] = "SYN_RECV",
145 [TCP_CONNTRACK_ESTABLISHED] = "ESTABLISHED",
146 [TCP_CONNTRACK_FIN_WAIT] = "FIN_WAIT",
147 [TCP_CONNTRACK_CLOSE_WAIT] = "CLOSE_WAIT",
148 [TCP_CONNTRACK_LAST_ACK] = "LAST_ACK",
149 [TCP_CONNTRACK_TIME_WAIT] = "TIME_WAIT",
150 [TCP_CONNTRACK_CLOSE] = "CLOSE",
151 [TCP_CONNTRACK_SYN_SENT2] = "SYN_SENT2",
154 static const bool tcp_states_show[TCP_CONNTRACK_MAX] = {
155 [TCP_CONNTRACK_SYN_SENT] = true,
156 [TCP_CONNTRACK_SYN_RECV] = true,
157 [TCP_CONNTRACK_ESTABLISHED] = true,
158 [TCP_CONNTRACK_FIN_WAIT] = true,
159 [TCP_CONNTRACK_CLOSE_WAIT] = true,
160 [TCP_CONNTRACK_LAST_ACK] = true,
161 [TCP_CONNTRACK_TIME_WAIT] = true,
162 [TCP_CONNTRACK_CLOSE] = true,
163 [TCP_CONNTRACK_SYN_SENT2] = true,
164 [TCP_CONNTRACK_NONE] = true,
167 static const char *const dccp_state2str[DCCP_CONNTRACK_MAX] = {
168 [DCCP_CONNTRACK_NONE] = "NOSTATE",
169 [DCCP_CONNTRACK_REQUEST] = "REQUEST",
170 [DCCP_CONNTRACK_RESPOND] = "RESPOND",
171 [DCCP_CONNTRACK_PARTOPEN] = "PARTOPEN",
172 [DCCP_CONNTRACK_OPEN] = "OPEN",
173 [DCCP_CONNTRACK_CLOSEREQ] = "CLOSEREQ",
174 [DCCP_CONNTRACK_CLOSING] = "CLOSING",
175 [DCCP_CONNTRACK_TIMEWAIT] = "TIMEWAIT",
176 [DCCP_CONNTRACK_IGNORE] = "IGNORE",
177 [DCCP_CONNTRACK_INVALID] = "INVALID",
180 static const uint8_t dccp_states_show[DCCP_CONNTRACK_MAX] = {
181 [DCCP_CONNTRACK_NONE] = true,
182 [DCCP_CONNTRACK_REQUEST] = true,
183 [DCCP_CONNTRACK_RESPOND] = true,
184 [DCCP_CONNTRACK_PARTOPEN] = true,
185 [DCCP_CONNTRACK_OPEN] = true,
186 [DCCP_CONNTRACK_CLOSEREQ] = true,
187 [DCCP_CONNTRACK_CLOSING] = true,
188 [DCCP_CONNTRACK_TIMEWAIT] = true,
189 [DCCP_CONNTRACK_IGNORE] = true,
190 [DCCP_CONNTRACK_INVALID] = true,
193 static const char *const sctp_state2str[SCTP_CONNTRACK_MAX] = {
194 [SCTP_CONNTRACK_NONE] = "NOSTATE",
195 [SCTP_CONNTRACK_CLOSED] = "CLOSED",
196 [SCTP_CONNTRACK_COOKIE_WAIT] = "COOKIE_WAIT",
197 [SCTP_CONNTRACK_COOKIE_ECHOED] = "COOKIE_ECHOED",
198 [SCTP_CONNTRACK_ESTABLISHED] = "ESTABLISHED",
199 [SCTP_CONNTRACK_SHUTDOWN_SENT] = "SHUTDOWN_SENT",
200 [SCTP_CONNTRACK_SHUTDOWN_RECD] = "SHUTDOWN_RECD",
201 [SCTP_CONNTRACK_SHUTDOWN_ACK_SENT] = "SHUTDOWN_ACK_SENT",
204 static const uint8_t sctp_states_show[SCTP_CONNTRACK_MAX] = {
205 [SCTP_CONNTRACK_NONE] = true,
206 [SCTP_CONNTRACK_CLOSED] = true,
207 [SCTP_CONNTRACK_COOKIE_WAIT] = true,
208 [SCTP_CONNTRACK_COOKIE_ECHOED] = true,
209 [SCTP_CONNTRACK_ESTABLISHED] = true,
210 [SCTP_CONNTRACK_SHUTDOWN_SENT] = true,
211 [SCTP_CONNTRACK_SHUTDOWN_RECD] = true,
212 [SCTP_CONNTRACK_SHUTDOWN_ACK_SENT] = true,
215 static const struct nfct_filter_ipv4 filter_ipv4 = {
216 .addr = __constant_htonl(INADDR_LOOPBACK),
217 .mask = 0xffffffff,
220 static const struct nfct_filter_ipv6 filter_ipv6 = {
221 .addr = { 0x0, 0x0, 0x0, 0x1 },
222 .mask = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff },
225 #define SYS_PATH "/proc/sys/"
227 static int sysctl_set_int(char *file, int value)
229 char path[PATH_MAX];
230 char str[64];
231 ssize_t ret;
232 int fd;
234 strncpy(path, SYS_PATH, PATH_MAX);
235 strncat(path, file, PATH_MAX - sizeof(SYS_PATH) - 1);
237 fd = open(path, O_WRONLY);
238 if (unlikely(fd < 0))
239 return -1;
241 ret = snprintf(str, 63, "%d", value);
242 if (ret < 0) {
243 close(fd);
244 return -1;
247 ret = write(fd, str, strlen(str));
249 close(fd);
250 return ret <= 0 ? -1 : 0;
253 static int sysctl_get_int(char *file, int *value)
255 char path[PATH_MAX];
256 char str[64];
257 ssize_t ret;
258 int fd;
260 strncpy(path, SYS_PATH, PATH_MAX);
261 strncat(path, file, PATH_MAX - sizeof(SYS_PATH) - 1);
263 fd = open(path, O_RDONLY);
264 if (fd < 0)
265 return -1;
267 ret = read(fd, str, sizeof(str));
268 if (ret > 0) {
269 *value = atoi(str);
270 ret = 0;
271 } else {
272 ret = -1;
275 close(fd);
276 return ret;
279 static void signal_handler(int number)
281 switch (number) {
282 case SIGINT:
283 case SIGQUIT:
284 case SIGTERM:
285 sigint = 1;
286 break;
287 case SIGHUP:
288 default:
289 break;
293 static void flow_entry_from_ct(struct flow_entry *n, struct nf_conntrack *ct);
294 static void flow_entry_get_extended(struct flow_entry *n);
296 static void help(void)
298 printf("flowtop %s, top-like netfilter TCP/UDP/SCTP/.. flow tracking\n",
299 VERSION_STRING);
300 puts("http://www.netsniff-ng.org\n\n"
301 "Usage: flowtop [options]\n"
302 "Options:\n"
303 " -4|--ipv4 Show only IPv4 flows (default)\n"
304 " -6|--ipv6 Show only IPv6 flows (default)\n"
305 " -T|--tcp Show only TCP flows (default)\n"
306 " -U|--udp Show only UDP flows\n"
307 " -D|--dccp Show only DCCP flows\n"
308 " -I|--icmp Show only ICMP/ICMPv6 flows\n"
309 " -S|--sctp Show only SCTP flows\n"
310 " -s|--show-src Also show source, not only dest\n"
311 " -u|--update Update GeoIP databases\n"
312 " -v|--version Print version and exit\n"
313 " -h|--help Print this help and exit\n\n"
314 "Examples:\n"
315 " flowtop\n"
316 " flowtop -46UTDISs\n\n"
317 "Note:\n"
318 " If netfilter is not running, you can activate it with e.g.:\n"
319 " iptables -A INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT\n"
320 " iptables -A OUTPUT -p tcp -m state --state NEW,ESTABLISHED -j ACCEPT\n");
321 puts(copyright);
322 die();
325 static void version(void)
327 printf("flowtop %s, Git id: %s\n", VERSION_LONG, GITVERSION);
328 puts("top-like netfilter TCP/UDP/SCTP/.. flow tracking\n"
329 "http://www.netsniff-ng.org\n");
330 puts(copyright);
331 die();
334 static inline struct flow_entry *flow_entry_xalloc(void)
336 return xzmalloc(sizeof(struct flow_entry));
339 static inline void flow_entry_xfree(struct flow_entry *n)
341 if (n->ct)
342 nfct_destroy(n->ct);
344 xfree(n);
347 static inline void flow_list_init(struct flow_list *fl)
349 fl->head = NULL;
350 spinlock_init(&fl->lock);
353 static void flow_list_new_entry(struct flow_list *fl, struct nf_conntrack *ct)
355 struct flow_entry *n = flow_entry_xalloc();
357 n->ct = nfct_clone(ct);
359 flow_entry_from_ct(n, ct);
360 flow_entry_get_extended(n);
362 rcu_assign_pointer(n->next, fl->head);
363 rcu_assign_pointer(fl->head, n);
366 static struct flow_entry *flow_list_find_id(struct flow_list *fl,
367 uint32_t id)
369 struct flow_entry *n = rcu_dereference(fl->head);
371 while (n != NULL) {
372 if (n->flow_id == id)
373 return n;
375 n = rcu_dereference(n->next);
378 return NULL;
381 static struct flow_entry *flow_list_find_prev_id(struct flow_list *fl,
382 uint32_t id)
384 struct flow_entry *n = rcu_dereference(fl->head), *tmp;
386 if (n->flow_id == id)
387 return NULL;
389 while ((tmp = rcu_dereference(n->next)) != NULL) {
390 if (tmp->flow_id == id)
391 return n;
393 n = tmp;
396 return NULL;
399 static void flow_list_update_entry(struct flow_list *fl,
400 struct nf_conntrack *ct)
402 struct flow_entry *n;
404 n = flow_list_find_id(fl, nfct_get_attr_u32(ct, ATTR_ID));
405 if (n == NULL) {
406 flow_list_new_entry(fl, ct);
407 return;
410 flow_entry_from_ct(n, ct);
413 static void flow_list_destroy_entry(struct flow_list *fl,
414 struct nf_conntrack *ct)
416 struct flow_entry *n1, *n2;
417 uint32_t id = nfct_get_attr_u32(ct, ATTR_ID);
419 n1 = flow_list_find_id(fl, id);
420 if (n1) {
421 n2 = flow_list_find_prev_id(fl, id);
422 if (n2) {
423 rcu_assign_pointer(n2->next, n1->next);
424 n1->next = NULL;
426 flow_entry_xfree(n1);
427 } else {
428 struct flow_entry *next = fl->head->next;
430 flow_entry_xfree(fl->head);
431 fl->head = next;
436 static void flow_list_destroy(struct flow_list *fl)
438 struct flow_entry *n;
440 while (fl->head != NULL) {
441 n = rcu_dereference(fl->head->next);
442 fl->head->next = NULL;
444 flow_entry_xfree(fl->head);
445 rcu_assign_pointer(fl->head, n);
448 synchronize_rcu();
449 spinlock_destroy(&fl->lock);
452 static int walk_process(unsigned int pid, struct flow_entry *n)
454 int ret;
455 DIR *dir;
456 struct dirent *ent;
457 char path[1024];
459 if (snprintf(path, sizeof(path), "/proc/%u/fd", pid) == -1)
460 panic("giant process name! %u\n", pid);
462 dir = opendir(path);
463 if (!dir)
464 return 0;
466 while ((ent = readdir(dir))) {
467 struct stat statbuf;
469 if (snprintf(path, sizeof(path), "/proc/%u/fd/%s",
470 pid, ent->d_name) < 0)
471 continue;
473 if (stat(path, &statbuf) < 0)
474 continue;
476 if (S_ISSOCK(statbuf.st_mode) && (ino_t) n->inode == statbuf.st_ino) {
477 ret = proc_get_cmdline(pid, n->cmdline, sizeof(n->cmdline));
478 if (ret < 0)
479 panic("Failed to get process cmdline: %s\n", strerror(errno));
481 n->procnum = pid;
482 closedir(dir);
483 return 1;
487 closedir(dir);
488 return 0;
491 static void walk_processes(struct flow_entry *n)
493 int ret;
494 DIR *dir;
495 struct dirent *ent;
497 /* n->inode must be set */
498 if (n->inode <= 0) {
499 n->cmdline[0] = '\0';
500 return;
503 dir = opendir("/proc");
504 if (!dir)
505 panic("Cannot open /proc: %s\n", strerror(errno));
507 while ((ent = readdir(dir))) {
508 const char *name = ent->d_name;
509 char *end;
510 unsigned int pid = strtoul(name, &end, 10);
512 /* not a PID */
513 if (pid == 0 && end == name)
514 continue;
516 ret = walk_process(pid, n);
517 if (ret > 0)
518 break;
521 closedir(dir);
524 static int get_port_inode(uint16_t port, int proto, int is_ip6)
526 int ret = -ENOENT;
527 char path[128], buff[1024];
528 FILE *proc;
530 memset(path, 0, sizeof(path));
531 snprintf(path, sizeof(path), "/proc/net/%s%s",
532 l4proto2str[proto], is_ip6 ? "6" : "");
534 proc = fopen(path, "r");
535 if (!proc)
536 return -EIO;
538 memset(buff, 0, sizeof(buff));
540 while (fgets(buff, sizeof(buff), proc) != NULL) {
541 int inode = 0;
542 unsigned int lport = 0;
544 buff[sizeof(buff) - 1] = 0;
545 if (sscanf(buff, "%*u: %*X:%X %*X:%*X %*X %*X:%*X %*X:%*X "
546 "%*X %*u %*u %u", &lport, &inode) == 2) {
547 if ((uint16_t) lport == port) {
548 ret = inode;
549 break;
553 memset(buff, 0, sizeof(buff));
556 fclose(proc);
557 return ret;
560 #define CP_NFCT(elem, attr, x) \
561 do { n->elem = nfct_get_attr_u##x(ct,(attr)); } while (0)
562 #define CP_NFCT_BUFF(elem, attr) do { \
563 const uint8_t *buff = nfct_get_attr(ct,(attr)); \
564 if (buff != NULL) \
565 memcpy(n->elem, buff, sizeof(n->elem)); \
566 } while (0)
568 static void flow_entry_from_ct(struct flow_entry *n, struct nf_conntrack *ct)
570 CP_NFCT(l3_proto, ATTR_ORIG_L3PROTO, 8);
571 CP_NFCT(l4_proto, ATTR_ORIG_L4PROTO, 8);
573 CP_NFCT(ip4_src_addr, ATTR_ORIG_IPV4_SRC, 32);
574 CP_NFCT(ip4_dst_addr, ATTR_ORIG_IPV4_DST, 32);
576 CP_NFCT(port_src, ATTR_ORIG_PORT_SRC, 16);
577 CP_NFCT(port_dst, ATTR_ORIG_PORT_DST, 16);
579 CP_NFCT(status, ATTR_STATUS, 32);
581 CP_NFCT(tcp_state, ATTR_TCP_STATE, 8);
582 CP_NFCT(tcp_flags, ATTR_TCP_FLAGS_ORIG, 8);
583 CP_NFCT(sctp_state, ATTR_SCTP_STATE, 8);
584 CP_NFCT(dccp_state, ATTR_DCCP_STATE, 8);
586 CP_NFCT(counter_pkts, ATTR_ORIG_COUNTER_PACKETS, 64);
587 CP_NFCT(counter_bytes, ATTR_ORIG_COUNTER_BYTES, 64);
589 CP_NFCT(timestamp_start, ATTR_TIMESTAMP_START, 64);
590 CP_NFCT(timestamp_stop, ATTR_TIMESTAMP_STOP, 64);
592 CP_NFCT(flow_id, ATTR_ID, 32);
593 CP_NFCT(use, ATTR_USE, 32);
595 CP_NFCT_BUFF(ip6_src_addr, ATTR_ORIG_IPV6_SRC);
596 CP_NFCT_BUFF(ip6_dst_addr, ATTR_ORIG_IPV6_DST);
598 n->port_src = ntohs(n->port_src);
599 n->port_dst = ntohs(n->port_dst);
601 n->ip4_src_addr = ntohl(n->ip4_src_addr);
602 n->ip4_dst_addr = ntohl(n->ip4_dst_addr);
605 enum flow_entry_direction {
606 flow_entry_src,
607 flow_entry_dst,
610 static inline int flow_entry_get_extended_is_dns(struct flow_entry *n)
612 /* We don't want to analyze / display DNS itself, since we
613 * use it to resolve reverse dns.
615 return n->port_src == 53 || n->port_dst == 53;
618 #define SELFLD(dir,src_member,dst_member) \
619 (((dir) == flow_entry_src) ? n->src_member : n->dst_member)
621 static void flow_entry_get_sain4_obj(struct flow_entry *n,
622 enum flow_entry_direction dir,
623 struct sockaddr_in *sa)
625 memset(sa, 0, sizeof(*sa));
626 sa->sin_family = PF_INET;
627 sa->sin_addr.s_addr = htonl(SELFLD(dir, ip4_src_addr, ip4_dst_addr));
630 static void flow_entry_get_sain6_obj(struct flow_entry *n,
631 enum flow_entry_direction dir,
632 struct sockaddr_in6 *sa)
634 memset(sa, 0, sizeof(*sa));
635 sa->sin6_family = PF_INET6;
637 memcpy(&sa->sin6_addr, SELFLD(dir, ip6_src_addr, ip6_dst_addr),
638 sizeof(sa->sin6_addr));
641 static void
642 flow_entry_geo_city_lookup_generic(struct flow_entry *n,
643 enum flow_entry_direction dir)
645 struct sockaddr_in sa4;
646 struct sockaddr_in6 sa6;
647 const char *city = NULL;
649 switch (n->l3_proto) {
650 default:
651 bug();
653 case AF_INET:
654 flow_entry_get_sain4_obj(n, dir, &sa4);
655 city = geoip4_city_name(&sa4);
656 break;
658 case AF_INET6:
659 flow_entry_get_sain6_obj(n, dir, &sa6);
660 city = geoip6_city_name(&sa6);
661 break;
664 bug_on(sizeof(n->city_src) != sizeof(n->city_dst));
666 if (city) {
667 memcpy(SELFLD(dir, city_src, city_dst), city,
668 min(sizeof(n->city_src), strlen(city)));
669 } else {
670 memset(SELFLD(dir, city_src, city_dst), 0,
671 sizeof(n->city_src));
675 static void
676 flow_entry_geo_country_lookup_generic(struct flow_entry *n,
677 enum flow_entry_direction dir)
679 struct sockaddr_in sa4;
680 struct sockaddr_in6 sa6;
681 const char *country = NULL;
683 switch (n->l3_proto) {
684 default:
685 bug();
687 case AF_INET:
688 flow_entry_get_sain4_obj(n, dir, &sa4);
689 country = geoip4_country_name(&sa4);
690 break;
692 case AF_INET6:
693 flow_entry_get_sain6_obj(n, dir, &sa6);
694 country = geoip6_country_name(&sa6);
695 break;
698 bug_on(sizeof(n->country_src) != sizeof(n->country_dst));
700 if (country) {
701 memcpy(SELFLD(dir, country_src, country_dst), country,
702 min(sizeof(n->country_src), strlen(country)));
703 } else {
704 memset(SELFLD(dir, country_src, country_dst), 0,
705 sizeof(n->country_src));
709 static void flow_entry_get_extended_geo(struct flow_entry *n,
710 enum flow_entry_direction dir)
712 flow_entry_geo_city_lookup_generic(n, dir);
713 flow_entry_geo_country_lookup_generic(n, dir);
716 static void flow_entry_get_extended_revdns(struct flow_entry *n,
717 enum flow_entry_direction dir)
719 size_t sa_len;
720 struct sockaddr_in sa4;
721 struct sockaddr_in6 sa6;
722 struct sockaddr *sa;
723 struct hostent *hent;
725 switch (n->l3_proto) {
726 default:
727 bug();
729 case AF_INET:
730 flow_entry_get_sain4_obj(n, dir, &sa4);
731 sa = (struct sockaddr *) &sa4;
732 sa_len = sizeof(sa4);
733 hent = gethostbyaddr(&sa4.sin_addr, sizeof(sa4.sin_addr), AF_INET);
734 break;
736 case AF_INET6:
737 flow_entry_get_sain6_obj(n, dir, &sa6);
738 sa = (struct sockaddr *) &sa6;
739 sa_len = sizeof(sa6);
740 hent = gethostbyaddr(&sa6.sin6_addr, sizeof(sa6.sin6_addr), AF_INET6);
741 break;
744 bug_on(sizeof(n->rev_dns_src) != sizeof(n->rev_dns_dst));
745 getnameinfo(sa, sa_len, SELFLD(dir, rev_dns_src, rev_dns_dst),
746 sizeof(n->rev_dns_src), NULL, 0, NI_NUMERICHOST);
748 if (hent) {
749 memset(n->rev_dns_dst, 0, sizeof(n->rev_dns_dst));
750 memcpy(SELFLD(dir, rev_dns_src, rev_dns_dst),
751 hent->h_name, min(sizeof(n->rev_dns_src),
752 strlen(hent->h_name)));
756 static void flow_entry_get_extended(struct flow_entry *n)
758 if (n->flow_id == 0 || flow_entry_get_extended_is_dns(n))
759 return;
761 flow_entry_get_extended_revdns(n, flow_entry_src);
762 flow_entry_get_extended_geo(n, flow_entry_src);
764 flow_entry_get_extended_revdns(n, flow_entry_dst);
765 flow_entry_get_extended_geo(n, flow_entry_dst);
767 /* Lookup application */
768 n->inode = get_port_inode(n->port_src, n->l4_proto,
769 n->l3_proto == AF_INET6);
770 if (n->inode > 0)
771 walk_processes(n);
774 static uint16_t presenter_get_port(uint16_t src, uint16_t dst, int tcp)
776 if (src < dst && src < 1024) {
777 return src;
778 } else if (dst < src && dst < 1024) {
779 return dst;
780 } else {
781 const char *tmp1, *tmp2;
782 if (tcp) {
783 tmp1 = lookup_port_tcp(src);
784 tmp2 = lookup_port_tcp(dst);
785 } else {
786 tmp1 = lookup_port_udp(src);
787 tmp2 = lookup_port_udp(dst);
789 if (tmp1 && !tmp2) {
790 return src;
791 } else if (!tmp1 && tmp2) {
792 return dst;
793 } else {
794 if (src < dst)
795 return src;
796 else
797 return dst;
802 static char *bandw2str(double bytes, char *buf, size_t len)
804 if (bytes > 1000000000.)
805 snprintf(buf, len, "%.1fG", bytes / 1000000000.);
806 if (bytes > 1000000.)
807 snprintf(buf, len, "%.1fM", bytes / 1000000.);
808 else if (bytes > 1000.)
809 snprintf(buf, len, "%.1fK", bytes / 1000.);
810 else
811 snprintf(buf, len, "%g", bytes);
813 return buf;
816 static void presenter_screen_do_line(WINDOW *screen, struct flow_entry *n,
817 unsigned int *line)
819 char tmp[128], *pname = NULL;
820 uint16_t port;
822 mvwprintw(screen, *line, 2, "");
824 /* PID, application name */
825 if (n->procnum > 0) {
826 slprintf(tmp, sizeof(tmp), "%s(%d)", basename(n->cmdline),
827 n->procnum);
829 printw("[");
830 attron(COLOR_PAIR(3));
831 printw("%s", tmp);
832 attroff(COLOR_PAIR(3));
833 printw("]:");
836 /* L3 protocol, L4 protocol, states */
837 printw("%s:%s", l3proto2str[n->l3_proto], l4proto2str[n->l4_proto]);
838 printw("[");
839 attron(COLOR_PAIR(3));
840 switch (n->l4_proto) {
841 case IPPROTO_TCP:
842 printw("%s", tcp_state2str[n->tcp_state]);
843 break;
844 case IPPROTO_SCTP:
845 printw("%s", sctp_state2str[n->sctp_state]);
846 break;
847 case IPPROTO_DCCP:
848 printw("%s", dccp_state2str[n->dccp_state]);
849 break;
850 case IPPROTO_UDP:
851 case IPPROTO_UDPLITE:
852 case IPPROTO_ICMP:
853 case IPPROTO_ICMPV6:
854 printw("NOSTATE");
855 break;
857 attroff(COLOR_PAIR(3));
858 printw("]");
860 /* Guess application port */
861 switch (n->l4_proto) {
862 case IPPROTO_TCP:
863 port = presenter_get_port(n->port_src, n->port_dst, 1);
864 pname = lookup_port_tcp(port);
865 break;
866 case IPPROTO_UDP:
867 case IPPROTO_UDPLITE:
868 port = presenter_get_port(n->port_src, n->port_dst, 0);
869 pname = lookup_port_udp(port);
870 break;
872 if (pname) {
873 attron(A_BOLD);
874 printw(":%s", pname);
875 attroff(A_BOLD);
877 printw(" ->");
879 /* Number packets, bytes */
880 if (n->counter_pkts > 0 && n->counter_bytes > 0) {
881 char bytes_str[64];
883 printw(" (%"PRIu64" pkts, %s bytes) ->", n->counter_pkts,
884 bandw2str(n->counter_bytes, bytes_str,
885 sizeof(bytes_str) - 1));
888 /* Show source information: reverse DNS, port, country, city */
889 if (show_src) {
890 attron(COLOR_PAIR(1));
891 mvwprintw(screen, ++(*line), 8, "src: %s", n->rev_dns_src);
892 attroff(COLOR_PAIR(1));
894 printw(":%"PRIu16, n->port_src);
896 if (n->country_src[0]) {
897 printw(" (");
899 attron(COLOR_PAIR(4));
900 printw("%s", n->country_src);
901 attroff(COLOR_PAIR(4));
903 if (n->city_src[0])
904 printw(", %s", n->city_src);
906 printw(")");
909 printw(" => ");
912 /* Show dest information: reverse DNS, port, country, city */
913 attron(COLOR_PAIR(2));
914 mvwprintw(screen, ++(*line), 8, "dst: %s", n->rev_dns_dst);
915 attroff(COLOR_PAIR(2));
917 printw(":%"PRIu16, n->port_dst);
919 if (n->country_dst[0]) {
920 printw(" (");
922 attron(COLOR_PAIR(4));
923 printw("%s", n->country_dst);
924 attroff(COLOR_PAIR(4));
926 if (n->city_dst[0])
927 printw(", %s", n->city_dst);
929 printw(")");
933 static inline int presenter_flow_wrong_state(struct flow_entry *n)
935 int ret = 1;
937 switch (n->l4_proto) {
938 case IPPROTO_TCP:
939 if (tcp_states_show[n->tcp_state])
940 ret = 0;
941 break;
942 case IPPROTO_SCTP:
943 if (sctp_states_show[n->sctp_state])
944 ret = 0;
945 break;
946 case IPPROTO_DCCP:
947 if (dccp_states_show[n->dccp_state])
948 ret = 0;
949 break;
950 case IPPROTO_UDP:
951 case IPPROTO_UDPLITE:
952 case IPPROTO_ICMP:
953 case IPPROTO_ICMPV6:
954 ret = 0;
955 break;
958 return ret;
961 static void presenter_screen_update(WINDOW *screen, struct flow_list *fl,
962 int skip_lines)
964 int maxy;
965 int skip_left = skip_lines;
966 unsigned int flows = 0;
967 unsigned int line = 3;
968 struct flow_entry *n;
970 curs_set(0);
972 maxy = getmaxy(screen);
973 maxy -= 6;
975 start_color();
976 init_pair(1, COLOR_RED, COLOR_BLACK);
977 init_pair(2, COLOR_BLUE, COLOR_BLACK);
978 init_pair(3, COLOR_YELLOW, COLOR_BLACK);
979 init_pair(4, COLOR_GREEN, COLOR_BLACK);
981 wclear(screen);
982 clear();
984 rcu_read_lock();
986 n = rcu_dereference(fl->head);
987 if (!n)
988 mvwprintw(screen, line, 2, "(No active sessions! "
989 "Is netfilter running?)");
991 for (; n; n = rcu_dereference(n->next)) {
992 if (presenter_get_port(n->port_src, n->port_dst, 0) == 53)
993 goto skip;
995 if (presenter_flow_wrong_state(n))
996 goto skip;
998 /* count only flows which might be showed */
999 flows++;
1001 if (maxy <= 0)
1002 goto skip;
1004 if (skip_left > 0) {
1005 skip_left--;
1006 goto skip;
1009 presenter_screen_do_line(screen, n, &line);
1011 line++;
1012 maxy -= (2 + 1 * show_src);
1013 n->is_visible = true;
1014 continue;
1015 skip:
1016 n->is_visible = false;
1017 continue;
1020 mvwprintw(screen, 1, 2, "Kernel netfilter flows(%u) for %s%s%s%s%s%s"
1021 "[+%d]", flows, what & INCLUDE_TCP ? "TCP, " : "" ,
1022 what & INCLUDE_UDP ? "UDP, " : "",
1023 what & INCLUDE_SCTP ? "SCTP, " : "",
1024 what & INCLUDE_DCCP ? "DCCP, " : "",
1025 what & INCLUDE_ICMP && what & INCLUDE_IPV4 ? "ICMP, " : "",
1026 what & INCLUDE_ICMP && what & INCLUDE_IPV6 ? "ICMP6, " : "",
1027 skip_lines);
1029 rcu_read_unlock();
1031 wrefresh(screen);
1032 refresh();
1035 static void presenter(void)
1037 int skip_lines = 0;
1038 WINDOW *screen;
1040 lookup_init_ports(PORTS_TCP);
1041 lookup_init_ports(PORTS_UDP);
1042 screen = screen_init(false);
1044 rcu_register_thread();
1045 while (!sigint) {
1046 switch (getch()) {
1047 case 'q':
1048 sigint = 1;
1049 break;
1050 case KEY_UP:
1051 case 'u':
1052 case 'k':
1053 skip_lines--;
1054 if (skip_lines < 0)
1055 skip_lines = 0;
1056 break;
1057 case KEY_DOWN:
1058 case 'd':
1059 case 'j':
1060 skip_lines++;
1061 if (skip_lines > SCROLL_MAX)
1062 skip_lines = SCROLL_MAX;
1063 break;
1064 default:
1065 fflush(stdin);
1066 break;
1069 presenter_screen_update(screen, &flow_list, skip_lines);
1070 usleep(200000);
1072 rcu_unregister_thread();
1074 screen_end();
1075 lookup_cleanup_ports(PORTS_UDP);
1076 lookup_cleanup_ports(PORTS_TCP);
1079 static int collector_cb(enum nf_conntrack_msg_type type,
1080 struct nf_conntrack *ct, void *data __maybe_unused)
1082 if (sigint)
1083 return NFCT_CB_STOP;
1085 synchronize_rcu();
1086 spinlock_lock(&flow_list.lock);
1088 switch (type) {
1089 case NFCT_T_NEW:
1090 flow_list_new_entry(&flow_list, ct);
1091 break;
1092 case NFCT_T_UPDATE:
1093 flow_list_update_entry(&flow_list, ct);
1094 break;
1095 case NFCT_T_DESTROY:
1096 flow_list_destroy_entry(&flow_list, ct);
1097 break;
1098 default:
1099 break;
1102 spinlock_unlock(&flow_list.lock);
1104 return NFCT_CB_CONTINUE;
1107 static inline void collector_flush(struct nfct_handle *handle, uint8_t family)
1109 nfct_query(handle, NFCT_Q_FLUSH, &family);
1112 static void restore_sysctl(void *value)
1114 int int_val = *(int *)value;
1116 if (int_val == 0)
1117 sysctl_set_int("net/netfilter/nf_conntrack_acct", int_val);
1120 static void on_panic_handler(void *arg)
1122 restore_sysctl(arg);
1123 screen_end();
1126 static void conntrack_acct_enable(void)
1128 /* We can still work w/o traffic accounting so just warn about error */
1129 if (sysctl_get_int("net/netfilter/nf_conntrack_acct", &nfct_acct_val)) {
1130 fprintf(stderr, "Can't read net/netfilter/nf_conntrack_acct: %s\n",
1131 strerror(errno));
1134 if (nfct_acct_val == 1)
1135 return;
1137 if (sysctl_set_int("net/netfilter/nf_conntrack_acct", 1)) {
1138 fprintf(stderr, "Can't write net/netfilter/nf_conntrack_acct: %s\n",
1139 strerror(errno));
1143 static int dump_cb(enum nf_conntrack_msg_type type,
1144 struct nf_conntrack *ct, void *data __maybe_unused)
1146 struct flow_entry *n;
1148 if (type != NFCT_T_UPDATE)
1149 return NFCT_CB_CONTINUE;
1151 if (sigint)
1152 return NFCT_CB_STOP;
1154 n = flow_list_find_id(&flow_list, nfct_get_attr_u32(ct, ATTR_ID));
1155 if (!n)
1156 return NFCT_CB_CONTINUE;
1158 flow_entry_from_ct(n, ct);
1160 return NFCT_CB_CONTINUE;
1163 static void collector_refresh_flows(struct nfct_handle *handle)
1165 struct flow_entry *n;
1167 n = rcu_dereference(flow_list.head);
1168 for (; n; n = rcu_dereference(n->next)) {
1169 if (!n->is_visible)
1170 continue;
1172 nfct_query(handle, NFCT_Q_GET, n->ct);
1176 static void *collector(void *null __maybe_unused)
1178 struct nfct_handle *ct_event;
1179 struct nfct_handle *ct_dump;
1180 struct nfct_filter *filter;
1181 struct pollfd poll_fd[1];
1182 int ret;
1184 ct_event = nfct_open(CONNTRACK, NF_NETLINK_CONNTRACK_NEW |
1185 NF_NETLINK_CONNTRACK_UPDATE |
1186 NF_NETLINK_CONNTRACK_DESTROY);
1187 if (!ct_event)
1188 panic("Cannot create a nfct handle: %s\n", strerror(errno));
1190 collector_flush(ct_event, AF_INET);
1191 collector_flush(ct_event, AF_INET6);
1193 filter = nfct_filter_create();
1194 if (!filter)
1195 panic("Cannot create a nfct filter: %s\n", strerror(errno));
1197 ret = nfct_filter_attach(nfct_fd(ct_event), filter);
1198 if (ret < 0)
1199 panic("Cannot attach filter to handle: %s\n", strerror(errno));
1201 if (what & INCLUDE_UDP) {
1202 nfct_filter_add_attr_u32(filter, NFCT_FILTER_L4PROTO, IPPROTO_UDP);
1203 nfct_filter_add_attr_u32(filter, NFCT_FILTER_L4PROTO, IPPROTO_UDPLITE);
1205 if (what & INCLUDE_TCP)
1206 nfct_filter_add_attr_u32(filter, NFCT_FILTER_L4PROTO, IPPROTO_TCP);
1207 if (what & INCLUDE_DCCP)
1208 nfct_filter_add_attr_u32(filter, NFCT_FILTER_L4PROTO, IPPROTO_DCCP);
1209 if (what & INCLUDE_SCTP)
1210 nfct_filter_add_attr_u32(filter, NFCT_FILTER_L4PROTO, IPPROTO_SCTP);
1211 if (what & INCLUDE_ICMP && what & INCLUDE_IPV4)
1212 nfct_filter_add_attr_u32(filter, NFCT_FILTER_L4PROTO, IPPROTO_ICMP);
1213 if (what & INCLUDE_ICMP && what & INCLUDE_IPV6)
1214 nfct_filter_add_attr_u32(filter, NFCT_FILTER_L4PROTO, IPPROTO_ICMPV6);
1215 if (what & INCLUDE_IPV4) {
1216 nfct_filter_set_logic(filter, NFCT_FILTER_SRC_IPV4, NFCT_FILTER_LOGIC_NEGATIVE);
1217 nfct_filter_add_attr(filter, NFCT_FILTER_SRC_IPV4, &filter_ipv4);
1219 if (what & INCLUDE_IPV6) {
1220 nfct_filter_set_logic(filter, NFCT_FILTER_SRC_IPV6, NFCT_FILTER_LOGIC_NEGATIVE);
1221 nfct_filter_add_attr(filter, NFCT_FILTER_SRC_IPV6, &filter_ipv6);
1224 ret = nfct_filter_attach(nfct_fd(ct_event), filter);
1225 if (ret < 0)
1226 panic("Cannot attach filter to handle: %s\n", strerror(errno));
1228 nfct_filter_destroy(filter);
1230 nfct_callback_register(ct_event, NFCT_T_ALL, collector_cb, NULL);
1231 flow_list_init(&flow_list);
1233 ct_dump = nfct_open(CONNTRACK, NF_NETLINK_CONNTRACK_UPDATE);
1234 if (!ct_dump)
1235 panic("Cannot create a nfct handle: %s\n", strerror(errno));
1237 nfct_callback_register(ct_dump, NFCT_T_ALL, dump_cb, NULL);
1239 poll_fd[0].fd = nfct_fd(ct_event);
1240 poll_fd[0].events = POLLIN;
1242 if (fcntl(nfct_fd(ct_event), F_SETFL, O_NONBLOCK) == -1)
1243 panic("Cannot set non-blocking socket: fcntl(): %s\n",
1244 strerror(errno));
1246 if (fcntl(nfct_fd(ct_dump), F_SETFL, O_NONBLOCK) == -1)
1247 panic("Cannot set non-blocking socket: fcntl(): %s\n",
1248 strerror(errno));
1250 rcu_register_thread();
1252 while (!sigint && ret >= 0) {
1253 int status;
1255 usleep(300000);
1257 collector_refresh_flows(ct_dump);
1259 status = poll(poll_fd, 1, 0);
1260 if (status < 0) {
1261 if (errno == EAGAIN || errno == EINTR)
1262 continue;
1264 panic("Error while polling: %s\n", strerror(errno));
1265 } else if (status == 0) {
1266 continue;
1269 if (poll_fd[0].revents & POLLIN)
1270 nfct_catch(ct_event);
1273 rcu_unregister_thread();
1275 flow_list_destroy(&flow_list);
1276 nfct_close(ct_event);
1277 nfct_close(ct_dump);
1279 pthread_exit(NULL);
1282 int main(int argc, char **argv)
1284 pthread_t tid;
1285 int ret, c, opt_index, what_cmd = 0;
1287 setfsuid(getuid());
1288 setfsgid(getgid());
1290 while ((c = getopt_long(argc, argv, short_options, long_options,
1291 &opt_index)) != EOF) {
1292 switch (c) {
1293 case '4':
1294 what_cmd |= INCLUDE_IPV4;
1295 break;
1296 case '6':
1297 what_cmd |= INCLUDE_IPV6;
1298 break;
1299 case 'T':
1300 what_cmd |= INCLUDE_TCP;
1301 break;
1302 case 'U':
1303 what_cmd |= INCLUDE_UDP;
1304 break;
1305 case 'D':
1306 what_cmd |= INCLUDE_DCCP;
1307 break;
1308 case 'I':
1309 what_cmd |= INCLUDE_ICMP;
1310 break;
1311 case 'S':
1312 what_cmd |= INCLUDE_SCTP;
1313 break;
1314 case 's':
1315 show_src = 1;
1316 break;
1317 case 'u':
1318 update_geoip();
1319 die();
1320 break;
1321 case 'h':
1322 help();
1323 break;
1324 case 'v':
1325 version();
1326 break;
1327 default:
1328 break;
1332 if (what_cmd > 0)
1333 what = what_cmd;
1335 rcu_init();
1337 register_signal(SIGINT, signal_handler);
1338 register_signal(SIGQUIT, signal_handler);
1339 register_signal(SIGTERM, signal_handler);
1340 register_signal(SIGHUP, signal_handler);
1342 panic_handler_add(on_panic_handler, &nfct_acct_val);
1344 conntrack_acct_enable();
1346 init_geoip(1);
1348 ret = pthread_create(&tid, NULL, collector, NULL);
1349 if (ret < 0)
1350 panic("Cannot create phthread!\n");
1352 presenter();
1354 destroy_geoip();
1356 restore_sysctl(&nfct_acct_val);
1358 return 0;