#ip #tun #smoltcp #networking #udp-packet #netstack #network-programing


A netstack for the special purpose of turning packets from/to a TUN interface into TCP streams and UDP packets. It uses smoltcp-rs as the backend netstack.

2 releases

0.1.2 Apr 14, 2024
0.1.1 Apr 10, 2024
0.1.0 Apr 10, 2024

#1117 in Network programming

Download history 309/week @ 2024-04-10 546/week @ 2024-04-17 11/week @ 2024-04-24 6/week @ 2024-05-22 2/week @ 2024-06-05 8/week @ 2024-06-12 75/week @ 2024-06-26

85 downloads per month



Netstack Smoltcp

A netstack for the special purpose of turning packets from/to a TUN interface into TCP streams and UDP packets. It uses smoltcp-rs as the backend netstack.

Crates.io MIT licensed Apache licensed, Version 2.0 Build Status


  • Supports Future Send and non-Send, mostly pepole use Send.
  • Supports ICMP protocol drive by TCP runner to use ICMP ping.
  • Supports filtering packets by source and destination IP addresses.
  • Can read IP packets from netstack, write IP packets to netstack.
  • Can receive TcpStream from TcpListener exposed from netstack.
  • Can receive UDP datagram from UdpSocket exposed from netstack.
  • Implements popular future streaming traits and asynchronous IO traits:
    • TcpListener implements futures Stream/Sink trait
    • TcpStream implements tokio AsyncRead/AsyncWrite trait
    • UdpSocket(ReadHalf/WriteHalf) implements futures Stream/Sink trait.


This crate provides lightweight netstack support for Linux, iOS, macOS, Android and Windows. Currently, it works on most targets, but mainly tested the popular platforms which includes:

  • linux-amd64: x86_64-unknown-linux-gnu
  • android-arm64: aarch64-linux-android
  • android-amd64: x86_64-linux-android
  • macos-amd64: x86_64-apple-darwin
  • macos-arm64: aarch64-apple-darwin
  • ios-arm64: aarch64-apple-ios
  • windows-amd64: x86_64-pc-windows-msvc
  • windows-arm64: aarch64-pc-windows-msvc


// let device = tun2::create_as_async(&cfg)?;
// let framed = device.into_framed();

// let mut builder = StackBuilder::default();
// let (runner, udp_socket, tcp_listener, stack) = builder.build();
// tokio::task::spawn(runner);
let (udp_socket, tcp_listener, stack) = StackBuilder::default().run();

let (mut stack_sink, mut stack_stream) = stack.split();
let (mut tun_sink, mut tun_stream) = framed.split();

// Reads packet from stack and sends to TUN.
tokio::spawn(async move {
    while let Some(pkt) = stack_stream.next().await {
        if let Ok(pkt) = pkt {

// Reads packet from TUN and sends to stack.
tokio::spawn(async move {
    while let Some(pkt) = tun_stream.next().await {
        if let Ok(pkt) = pkt {

// Extracts TCP connections from stack and sends them to the dispatcher.
tokio::spawn(async move {

// Receive and send UDP packets between netstack and NAT manager. The NAT
// manager would maintain UDP sessions and send them to the dispatcher.
tokio::spawn(async move {


This project is licensed under either of

at your option.


Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in netstack-smoltcp by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Inspired By

Special thanks to these amazing projects that inspired netstack-smoltcp:

Star History

Star History Chart


~204K SLoC