Getting Network Interfaces with `pnet` in Rust - Akmot9/pnet_tutorial GitHub Wiki

Introduction

  • In this tutorial, we will explore how to find and list network interfaces on your machine using the pnet library in Rust.
  • Understanding your network interfaces is crucial when you want to engage in low-level network programming tasks, such as packet capturing or custom packet creation.

Setting up the Environment

  • Ensure Rust is installed on your machine. If it's not, you can download it from the official site.
  • Create a new Rust project via Cargo:
cargo new pnet_packet_capture
  • Open your Cargo.toml file and add pnet as a dependency:
[dependencies]
pnet = "0.34.0"

Finding Network Interfaces

This section will guide you on how to list all available network interfaces on your system.

Code Snippet 1: Listing Detailed Interface Information

use pnet::datalink;

fn main() {
    let interfaces = datalink::interfaces();
    for interface in interfaces {
        println!("{:#?}", interface);
    }
}

Output Example

NetworkInterface {
    name: "lo",
    description: "",
    index: 1,
    mac: Some(
        00:00:00:00:00:00,
    ),
    ips: [
        V4(
            Ipv4Network {
                addr: 127.0.0.1,
                prefix: 8,
            },
        ),
        V6(
            Ipv6Network {
                addr: ::1,
                prefix: 128,
            },
        ),
    ],
    flags: 65609,
}
  • Note: The flags field can provide additional information like whether the interface is up, broadcast capable, etc. It's a bitmask and you may need to refer to system-specific documentation to decode its meaning.

Code Snippet 2: Listing Names and Indices

Correcting the typo, the code is:

use pnet::datalink;

fn main() {
    let interfaces = datalink::interfaces();
    for interface in interfaces {
        println!("{}: {}", interface.index, interface.name);
    }
}

Output Example

1: lo
2: enp0s31f6
4: docker0
5: vmnet1
6: vmnet8
8: enx0a87c76ee9f1
  • Note: The index numbers might not always be sequential because they're generated by the system and could be arbitrary.

Code Snippet 3: Using an Iterator for Better Display

fn main() {
    println!("Available interfaces:");
    let interfaces = datalink::interfaces();
    for (index, interface) in interfaces.iter().enumerate() {
        println!("{}: {}", index + 1, interface.name);
    }
}

Output Example

Available interfaces:
1: lo
2: enp0s31f6
3: docker0
4: vmnet1
5: vmnet8
6: enx0a87c76ee9f1
  • This version offers a more readable output by creating a zero-based index for each interface.

Conclusion

In this tutorial, we've covered the essentials of listing network interfaces using the pnet library in Rust. This is a foundational skill for anyone interested in network programming, packet capturing, or even cybersecurity tasks. As a next step, you can delve deeper into each interface's capabilities or begin capturing network packets for analysis.