1 #include <stdio.h> 2 #include <assert.h> 3 #include <linux/bpf.h> 4 #include "libbpf.h" 5 #include "bpf_load.h" 6 #include <unistd.h> 7 #include <arpa/inet.h> 8 9 struct flow_keys { 10 __be32 src; 11 __be32 dst; 12 union { 13 __be32 ports; 14 __be16 port16[2]; 15 }; 16 __u32 ip_proto; 17 }; 18 19 struct pair { 20 __u64 packets; 21 __u64 bytes; 22 }; 23 24 int main(int argc, char **argv) 25 { 26 char filename[256]; 27 FILE *f; 28 int i, sock; 29 30 snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); 31 32 if (load_bpf_file(filename)) { 33 printf("%s", bpf_log_buf); 34 return 1; 35 } 36 37 sock = open_raw_sock("lo"); 38 39 assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, &prog_fd[4], 40 sizeof(__u32)) == 0); 41 42 if (argc > 1) 43 f = popen("ping -c5 localhost", "r"); 44 else 45 f = popen("netperf -l 4 localhost", "r"); 46 (void) f; 47 48 for (i = 0; i < 5; i++) { 49 struct flow_keys key = {}, next_key; 50 struct pair value; 51 52 sleep(1); 53 printf("IP src.port -> dst.port bytes packets\n"); 54 while (bpf_get_next_key(map_fd[2], &key, &next_key) == 0) { 55 bpf_lookup_elem(map_fd[2], &next_key, &value); 56 printf("%s.%05d -> %s.%05d %12lld %12lld\n", 57 inet_ntoa((struct in_addr){htonl(next_key.src)}), 58 next_key.port16[0], 59 inet_ntoa((struct in_addr){htonl(next_key.dst)}), 60 next_key.port16[1], 61 value.bytes, value.packets); 62 key = next_key; 63 } 64 } 65 return 0; 66 } 67