Terminal bandwidth utilization tool

Overview

bandwhich

demo

This is a CLI utility for displaying current network utilization by process, connection and remote IP/hostname

How does it work?

bandwhich sniffs a given network interface and records IP packet size, cross referencing it with the /proc filesystem on linux, lsof on macOS, or using WinApi on windows. It is responsive to the terminal window size, displaying less info if there is no room for it. It will also attempt to resolve ips to their host name in the background using reverse DNS on a best effort basis.

Installation

Download a prebuilt binary

If you're on linux, you can download the generic binary from the releases.

Arch Linux

pacman -S bandwhich

Nix/NixOS

bandwhich is available in nixpkgs, and can be installed, for example, with nix-env:

nix-env -iA nixpkgs.bandwhich

Void Linux

xbps-install -S bandwhich

Fedora

bandwhich is available in COPR, and can be installed via DNF:

sudo dnf copr enable atim/bandwhich -y && sudo dnf install bandwhich

macOS/Linux (using Homebrew)

brew install bandwhich

FreeBSD

pkg install bandwhich

or

cd /usr/ports/net-mgmt/bandwhich && make install clean

Windows / Other Linux flavours

bandwhich can be installed using the Rust package manager, cargo. It might be in your distro repositories if you're on linux, or you can install it via rustup. You can find additional installation instructions here.

The minimum supported Rust version is 1.39.0.

cargo install bandwhich
On Linux, after installing with cargo:

Cargo installs bandwhich to ~/.cargo/bin/bandwhich but you need root priviliges to run bandwhich. To fix that, there are a few options:

  • Give the executable elevated permissions: sudo setcap cap_sys_ptrace,cap_dac_read_search,cap_net_raw,cap_net_admin+ep $(which bandwhich)
  • Run sudo ~/.cargo/bin/bandwhich instead of just bandwhich
  • Create a symlink: sudo ln -s ~/.cargo/bin/bandwhich /usr/local/bin/ (or another path on root's PATH)
  • Set root's PATH to match your own: sudo env "PATH=$PATH" bandwhich
  • Tell sudo to use your user's environment variables: sudo -E bandwhich
  • Pass the desired target directory to cargo: sudo cargo install bandwhich --root /usr/local/bin/
On Windows, after installing with cargo:

You might need to first install npcap for capturing packets on windows.

OpenWRT

To install bandwhich on OpenWRT, you'll need to compile a binary that would fit its processor architecture. This might mean you would have to cross compile if, for example, you're working on an x86_64 and the OpenWRT is installed on an arm7. Here is an example of cross compiling in this situation:

  • Check the processor architecture of your router by using uname -m
  • Clone the bandwhich repository git clone https://github.com/imsnif/bandwhich
  • Install cross using cargo install cross
  • build the bandwhich package using cross build --target armv7-unknown-linux-musleabihf
  • Copy the binary files from target/armv7-unknown-linux-musleabihf/debug/bandwhich to the router using scp by running scp bandwhich [email protected]:~/ (here, 192.168.1.1 would be the IP address of your router).
  • Finally enter the router using ssh and run the binary directly with ./bandwhich

Usage

USAGE:
    bandwhich [FLAGS] [OPTIONS]

FLAGS:
    -a, --addresses            Show remote addresses table only
    -c, --connections          Show connections table only
    -h, --help                 Prints help information
    -n, --no-resolve           Do not attempt to resolve IPs to their hostnames
    -p, --processes            Show processes table only
    -r, --raw                  Machine friendlier output
    -s, --show-dns             Show DNS queries
    -t, --total-utilization    Show total (cumulative) usages
    -V, --version              Prints version information

OPTIONS:
    -i, --interface <interface>    The network interface to listen on, eg. eth0
    -d, --dns-server <dns-server>    A dns server ip to use instead of the system default

Note that since bandwhich sniffs network packets, it requires root privileges - so you might want to use it with (for example) sudo.

On Linux, you can give the bandwhich binary a permanent capability to use the required privileges, so that you don't need to use sudo bandwhich anymore:

sudo setcap cap_sys_ptrace,cap_dac_read_search,cap_net_raw,cap_net_admin+ep `which bandwhich`

cap_sys_ptrace,cap_dac_read_search gives bandwhich capability to list /proc/<pid>/fd/ and resolve symlinks in that directory. It needs this capability to determine which opened port belongs to which process. cap_net_raw,cap_net_admin gives bandwhich capability to capture packets on your system.

raw_mode

bandwhich also supports an easier-to-parse mode that can be piped or redirected to a file. For example, try:

bandwhich --raw | grep firefox

Contributing

Contributions of any kind are very welcome. If you'd like a new feature (or found a bug), please open an issue or a PR.

To set up your development environment:

  1. Clone the project
  2. cargo run, or if you prefer cargo run -- -i <network interface name> (you can often find out the name with ifconfig or iwconfig). You might need root privileges to run this application, so be sure to use (for example) sudo.

To run tests: cargo test

Note that at the moment the tests do not test the os layer (anything in the os folder).

If you are stuck, unsure about how to approach an issue or would like some guidance, you are welcome to contact: [email protected]

License

MIT

Issues
  • No traffic shown on some macs

    No traffic shown on some macs

    This is 9d93d34d5ab365ec1c07d6ec197cb12c4b8105f3 on macOS 10.14.6 bandwhich starts but shows no traffic. sudo /Users/diver/.cargo/bin/bandwhich

    Screenshot 2019-12-31 at 13 07 14

    sudo /Users/diver/.cargo/bin/bandwhich -i en0 shows the same.

    List of interfaces:

    lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
    gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280
    stf0: flags=0<> mtu 1280
    EHC26: flags=0<> mtu 0
    XHC20: flags=0<> mtu 0
    EHC29: flags=0<> mtu 0
    en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    p2p0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 2304
    awdl0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1484
    en1: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
    en2: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
    bridge0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    utun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 2000
    vmnet1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    vmnet8: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    
    bug 
    opened by diversys 51
  • Fails to listen to network interface on Catalina

    Fails to listen to network interface on Catalina

    On Catalina (10.15.2):

    ➜ sudo what
    Password:
    Error: Failed to listen on network interface: Device not configured (os error 6)
    
    opened by leonaves 33
  • Add accumlated usage

    Add accumlated usage

    Closes #147

    This works pretty well, but the existing code wasn't really designed for accumulated usage like this, so I've left in some comments where I'd appreciate some others' opinions on refactoring matters.

    This feature really adds a lot to bandwhich for me! I have a metered connection on a server and this PR makes it possible to track down what processes use the most data over a longer period of time!

    This is a draft PR at the moment and I'd be hesitant to merge before we have the chance to address some of the comments I left behind :)

    Additionally, the test snapshots have not been updated yet.

    opened by TheLostLambda 32
  • Failing to report unbound UDP traffic

    Failing to report unbound UDP traffic

    I'm not seeing much traffic (basically just ssh and sshd) despite knowing there's a ton of traffic.

    iftop shows me over 20x streams open, but they are all UDP -- freeswitch VoIP streams.

    They are listed in lsof -i

    Is this a bug or by design? I saw no mention in the docs or issues of tcp vs udp.

    Thanks!

    bug 
    opened by avimar 28
  • Failed to find any network interface to listen on

    Failed to find any network interface to listen on

    Hi,

    I played around with bandwhich a bit and stumpled upon the issue, that on some interface it prints:

    sudo bandwhich -i enp216s0f1
    Error: Failed to find any network interface to listen on.
    

    While other interfaces on this system work. The main difference between those interface is that the working one is the onboard NIC and the other one is a dedicated Intel XL710 card with 10GE SFPs connected and is using i40e driver which is also the same as the onboard NIC is using. Other tools like iftop (which I want to replace with bandwhich), tcpdump etc. work on that interface. I also don't see any other error messages. In dmesg I just see the missing output that the interface went into promiscuous mode.

    I also made sure the interface is up. I also tested in on some other machines with dedicated NICs, where I could also see it happen on normal 1GE cooper cards with e1000e driver. But I also had one system where it worked with a dedicated NIC. So I'm a bit lost on how to narrow it down. Any hint would be nice as bandwhich looks like a very nice replacement for the old and slow iftop :)

    The main test system is a debian stretch with kernel 4.19.

    bug 
    opened by norg 28
  • Add support for OpenWRT

    Add support for OpenWRT

    Thanks a lot for the nice and useful package. As OpenWRT is also a linux distribution, is it possible to build a binary for OpenWRT?

    discussion 
    opened by safwanrahman 25
  • Issue 163 elapsed time

    Issue 163 elapsed time

    Hi @imsnif,

    I found this project recently and think its great. I have done quite a bit of packet-snooping work in C and C++ and think it's great to see a utility like this in Rust. 😁

    I've started looking into #163 as a first issue to learn more about the program and practice some Rust (new rustacean here). I think I have an implementation working, but it still needs a bit more work to get the tests passing and some cleanup.

    I'd welcome some feedback and maybe some advice about getting these failing tests passing... 😅

    failures:
        tests::cases::ui::basic_only_addresses
        tests::cases::ui::basic_only_connections
        tests::cases::ui::basic_only_processes
        tests::cases::ui::basic_processes_with_dns_queries
        tests::cases::ui::basic_startup
        tests::cases::ui::bi_directional_traffic
        tests::cases::ui::layout_full_width_under_30_height
        tests::cases::ui::layout_under_120_width_full_height
        tests::cases::ui::layout_under_120_width_under_30_height
        tests::cases::ui::multiple_connections_from_remote_address
        tests::cases::ui::multiple_packets_of_traffic_from_different_connections
        tests::cases::ui::multiple_packets_of_traffic_from_single_connection
        tests::cases::ui::multiple_processes_with_multiple_connections
        tests::cases::ui::no_resolve_mode
        tests::cases::ui::one_packet_of_traffic
        tests::cases::ui::one_process_with_multiple_connections
        tests::cases::ui::pause_by_space
        tests::cases::ui::sustained_traffic_from_multiple_processes
        tests::cases::ui::sustained_traffic_from_multiple_processes_bi_directional
        tests::cases::ui::sustained_traffic_from_multiple_processes_bi_directional_total
        tests::cases::ui::sustained_traffic_from_multiple_processes_total
        tests::cases::ui::sustained_traffic_from_one_process
        tests::cases::ui::sustained_traffic_from_one_process_total
        tests::cases::ui::traffic_with_host_names
        tests::cases::ui::traffic_with_winch_event
        tests::cases::ui::truncate_long_hostnames
        tests::cases::ui::two_packets_only_addresses
        tests::cases::ui::two_packets_only_connections
        tests::cases::ui::two_packets_only_processes
        tests::cases::ui::two_windows_split_horizontally
        tests::cases::ui::two_windows_split_vertically
    

    Screen Shot 2020-04-26 at 14 27 49

    Screen Shot 2020-04-26 at 14 28 04

    opened by Eosis 24
  • Release 0.8.0

    Release 0.8.0

    I want to release a new version from master. This one's mostly a lot of infra changes (there's exact info about what's inside in the changelog). A lot of these changes are in untested areas.

    Would love to get some feedback on what's in master right now to make sure it's working. @ebroto, @zhangxp1998 - would you be willing to take it for a short spin?

    discussion 
    opened by imsnif 23
  • Fix VPN traffice not displayed bug

    Fix VPN traffice not displayed bug

    Fix issue #126

    opened by zhangxp1998 22
  • cargo install fails on Mac OS Catalina

    cargo install fails on Mac OS Catalina

    Compiling futures v0.3.1 error[E0599]: no method named to_primitive_values found for type pnet_base::MacAddr in the current scope --> /var/folders/32/rk26q2615r31j59ptvscfqpm0000gp/T/cargo-installvKafRX/release/build/pnet_packet-e89ea43c86e9974b/out/ethernet.rs:442:24 | 442 | let vals = val.to_primitive_values(); | ^^^^^^^^^^^^^^^^^^^ method not found in pnet_base::MacAddr

    error[E0599]: no method named to_primitive_values found for type pnet_base::MacAddr in the current scope --> /var/folders/32/rk26q2615r31j59ptvscfqpm0000gp/T/cargo-installvKafRX/release/build/pnet_packet-e89ea43c86e9974b/out/ethernet.rs:499:24 | 499 | let vals = val.to_primitive_values(); | ^^^^^^^^^^^^^^^^^^^ method not found in pnet_base::MacAddr

    Compiling trust-dns-proto v0.18.0-alpha.2 error[E0599]: no method named to_primitive_values found for type pnet_base::MacAddr in the current scope --> /var/folders/32/rk26q2615r31j59ptvscfqpm0000gp/T/cargo-installvKafRX/release/build/pnet_packet-e89ea43c86e9974b/out/arp.rs:776:24 | 776 | let vals = val.to_primitive_values(); | ^^^^^^^^^^^^^^^^^^^ method not found in pnet_base::MacAddr

    error[E0599]: no method named to_primitive_values found for type pnet_base::MacAddr in the current scope --> /var/folders/32/rk26q2615r31j59ptvscfqpm0000gp/T/cargo-installvKafRX/release/build/pnet_packet-e89ea43c86e9974b/out/arp.rs:874:24 | 874 | let vals = val.to_primitive_values(); | ^^^^^^^^^^^^^^^^^^^ method not found in pnet_base::MacAddr

    error: aborting due to 4 previous errors

    For more information about this error, try rustc --explain E0599. error: could not compile pnet_packet. warning: build failed, waiting for other jobs to finish... error: failed to compile bandwhich v0.7.0, intermediate artifacts can be found at /var/folders/32/rk26q2615r31j59ptvscfqpm0000gp/T/cargo-installvKafRX

    Caused by: build failed

    Cargo build works fine, but cargo install fails. Not sure why the difference

    opened by ashpatel 21
  • Fix setcap example

    Fix setcap example

    • Use POSIX sh command substitution syntax
    • Use command -v shell built-in instead of which
    opened by teohhanhui 0
  • Fails to start on MacOS Big Sur

    Fails to start on MacOS Big Sur

    I'm running into an issue running bandwhich on macOS Big Sur 11.3.1. It installed just fine via brew install bandwhich. After starting it up using sudo bandwhich, I get this error in the terminal:

    thread 'display_handler' panicked at 'called `Result::unwrap()` on an `Err` value: AddrParseError(())', src/os/lsof_utils.rs:110:31  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    

    I resize the terminal window and then I see the 3 pane bandwhich appear, but each section is empty. Hit q to exit and see another error message appear:

    thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Any', src/main.rs:311:31
    

    ScreenFlow

    2021-06-01 UPDATE: Here's the backtrace in case it's of any help.

    thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Any', src/main.rs:311:31
    stack backtrace:
       0:        0x106413ede - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h0afb3dc3ec8cd05f
       1:        0x10644a3fe - core::fmt::write::h39441ef24fae20ea
       2:        0x106413c79 - std::io::Write::write_fmt::h2ffecc964e3c3ddd
       3:        0x106430de5 - std::panicking::default_hook::{{closure}}::h1a491655bcf6394f
       4:        0x106430b0c - std::panicking::default_hook::h038c301fad559a62
       5:        0x1064312f5 - std::panicking::rust_panic_with_hook::h489020cfd35413ea
       6:        0x1064146fb - std::panicking::begin_panic_handler::{{closure}}::he498abc45ca35fbf
       7:        0x106414058 - std::sys_common::backtrace::__rust_end_short_backtrace::h4a2a0fae6b0989d8
       8:        0x106430ed3 - _rust_begin_unwind
       9:        0x10646479f - core::panicking::panic_fmt::h0003130af3c08aa0
      10:        0x106464815 - core::result::unwrap_failed::hbfeca77107a6ab03
      11:        0x106232435 - bandwhich::try_main::hef395a59d21efc72
      12:        0x10622face - bandwhich::main::hd5e8acc3a24a7afa
      13:        0x10623cafa - std::sys_common::backtrace::__rust_begin_short_backtrace::h6c395a2a27071850
      14:        0x106251c0c - std::rt::lang_start::{{closure}}::hce1a7f46f8df1be2
      15:        0x10643155c - std::rt::lang_start_internal::h0a88825a8a52fb96
      16:        0x106233299 - _main
    
    opened by bpjones 1
  • Aattempted to leave type uninitialized, which is invalid

    Aattempted to leave type uninitialized, which is invalid

    When bandwhich 0.20.0 is running errors are printed on the screen, messing up the data:

    thread 'resolver' panicked at 'attempted to leave type `linked_hash_map::Node<proto::op::Query, dns_lru::LruValue>` uninitialized, which is invalid', /build/rustc-1.50.0-src/library/core/src/mem/mod.rs:659:9
    

    image

    opened by JohnAZoidberg 1
  • fix(dns): fixup

    fix(dns): fixup "Error parsing resolv.conf: InvalidOption(17)" error

    This error because trust-dns-resolver 0.18.x use the old resolv-conf 0.6.x

    ❯ bandwhich -V
    bandwhich 0.20.0
    ❯ bandwhich
    Error: Could not initialize the DNS resolver. Are you offline?
    
    Reason: ResolveError { inner: Custom { kind: Other, error: "Error parsing resolv.conf: InvalidOption(17)" }
    
    io error }
    

    with systemd-resolved we have the /etc/resolv.conf like this which will trigger the error.

    nameserver 127.0.0.53
    options edns0 trust-ad
    
    opened by ttys3 3
  • Why are speeds sometimes truncated as `20.27KiB[..].12KiBps`?

    Why are speeds sometimes truncated as `20.27KiB[..].12KiBps`?

    Why are speeds sometimes truncated as 20.27KiB[..].12KiBps?

    This happens even on extremely low zooms: image

    opened by NightMachinary 0
  • Feature - bandwidth in Mbit/s

    Feature - bandwidth in Mbit/s

    Please add FLAGS -b, Bandwidth in Mbit/s

    opened by cosmicDustOfLightLength 0
  • Fails to start

    Fails to start

    # /etc/resolv.conf
    
    nameserver 127.0.0.53
    options edns0 trust-ad
    
    
    # bandwhich -i eno1
    Error: Could not initialize the DNS resolver. Are you offline?
    
    Reason: ResolveError { inner: Custom { kind: Other, error: "Error parsing resolv.conf: InvalidOption(17)" }
    
    io error }
    
    
    bandwhich 0.20.0
    

    and I am logged into the box via ssh.

    opened by drahnr 2
  • Interference in the 'Utilization by connection' pane

    Interference in the 'Utilization by connection' pane

    net-mgmt/bandwhich with KDE Plasma on FreeBSD 14-CURRENT

    See for example the first and second screenshots at https://forum.privacytools.io/t/alternative-s-to-fiddler-or-wireshark/5116/4?u=grahamperrin – at a glance, it's as if there's interference from a process that was not utilising the network.

    The system was very busy at the time, with a build of VirtualBox, but not extraordinarily busy …

    opened by grahamperrin 0
  • ResolveError on Ubuntu 20.10

    ResolveError on Ubuntu 20.10

    Same issue as in https://github.com/imsnif/bandwhich/issues/197.

    My OS:

    ~ > lsb_release -a
    No LSB modules are available.
    Distributor ID:	Ubuntu
    Description:	Ubuntu 20.10
    Release:	20.10
    Codename:	groovy
    ~ > uname -r
    5.8.0-41-generic
    

    Steps to install:

    1. Installed Rust with curl https://sh.rustup.rs -sSf | sh.
    2. Installed bandwhich with cargo install bandwhich.
    3. Gave it permissions with sudo setcap cap_sys_ptrace,cap_dac_read_search,cap_net_raw,cap_net_admin+ep $(which bandwhich).

    When I run it, I get an error:

    ~ > bandwhich
    Error: Could not initialize the DNS resolver. Are you offline?
    
    Reason: ResolveError { inner: Custom { kind: Other, error: "Error parsing resolv.conf: InvalidOption(17)" }
    
    io error }
    
    opened by mattwelke 3
  • why some connection is unknown?

    why some connection is unknown?

    and how can I find out what these processes are ? maybe I can also find out the pid of the process that created the connection?

    opened by nsklyarov 0
Releases(0.20.0)
Owner
Aram Drevekenin
Aram Drevekenin
Real-time performance monitoring, done right! https://www.netdata.cloud

Netdata is high-fidelity infrastructure monitoring and troubleshooting. Open-source, free, preconfigured, opinionated, and always real-time. Netdata's

netdata 54.8k Jun 6, 2021
cpupower-gui is a graphical program that is used to change the scaling frequency limits of the cpu, similar to cpupower.

cpupower-gui This program is designed to allow you to change the frequency limits of your cpu and its governor. The application is similar in function

null 136 Jun 2, 2021
Alerta monitoring system

Alerta Release 8.0 The Alerta monitoring tool was developed with the following aims in mind: distributed and de-coupled so that it is SCALABLE minimal

alerta 1.9k May 31, 2021
Network flow analytics (Netflow, sFlow and IPFIX) with the Elastic Stack

ElastiFlow™ We have released the next generation of ElastiFlow™ which introduces the new ElastiFlow Unified Flow Collector for Netflow, IPFIX and sFlo

Rob Cowart 2.2k May 31, 2021
rtop is an interactive, remote system monitoring tool based on SSH

rtop rtop is a remote system monitor. It connects over SSH to a remote system and displays vital system metrics (CPU, disk, memory, network). No speci

RapidLoop 1.9k Jun 3, 2021
Vector is an on-host performance monitoring framework which exposes hand picked high resolution metrics to every engineer’s browser.

Project Status https://groups.google.com/d/msg/vector-users/MWF8nnj1WHw/1EelNPOBAwAJ Today we are sharing with the community that we have contributed

Netflix, Inc. 3.5k May 30, 2021