Skip to content

ncldmg/znetlink

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ZNetlink

A Zig library for interacting with Linux netlink sockets, providing a type-safe interface for network configuration and monitoring.

Features

  • Core Netlink Socket Support: Low-level netlink socket operations
  • Route Netlink Protocol: Query network interfaces, addresses, and routes
  • Network Namespace Management: Create, delete, enter, and list network namespaces
  • Message Parsing: Parse netlink messages and attributes
  • Error Handling: Comprehensive error handling with custom error types
  • Memory Safety: RAII-style resource management

Project Structure

src/
├── root.zig      # Core netlink functionality
├── route.zig     # Route netlink protocol implementation
├── netns.zig     # Network namespace management
└── main.zig      # Example application

Core Components

NetlinkSocket

The main socket interface for netlink communication:

const socket = try NetlinkSocket.init(NetlinkFamily.route, 0);
defer socket.close();
try socket.bind();

Route Protocol

High-level interface for network information:

const route_socket = try RouteSocket.init(0);
defer route_socket.close();

// Get network interfaces
const links = try route_socket.getLinks(allocator);
defer {
    for (links.items) |*link| {
        link.deinit(allocator);
    }
    links.deinit();
}

// Get addresses
const addresses = try route_socket.getAddresses(allocator);
defer {
    for (addresses.items) |*addr| {
        addr.deinit(allocator);
    }
    addresses.deinit();
}

// Get routes
const routes = try route_socket.getRoutes(allocator);
defer {
    for (routes.items) |*route| {
        route.deinit(allocator);
    }
    routes.deinit();
}

// List routes with formatting
try route_socket.listRoutes(allocator, stdout);

// List routes with filtering
const filter = RouteFilter.init()
    .withFamily(std.posix.AF.INET)
    .withGateway(true);
try route_socket.listRoutesFiltered(allocator, stdout, filter);

Building

zig build        # Build library and example
zig build test   # Run tests
zig build run    # Run example (requires root)

Usage

The library provides both low-level netlink socket operations and high-level protocol-specific interfaces.

Example Application

The included example demonstrates querying network interfaces, addresses, and routes:

sudo ./zig-out/bin/znetlink

Note: Netlink sockets require root privileges for most operations.

Supported Netlink Families

  • NETLINK_ROUTE: Network interface and routing information
  • NETLINK_GENERIC: Generic netlink protocol
  • NETLINK_AUDIT: Audit subsystem
  • NETLINK_NETFILTER: Netfilter subsystem
  • And many more...

Error Handling

The library defines comprehensive error types:

pub const NetlinkError = error{
    InvalidMessage,
    InvalidMessageType,
    InvalidMessageLength,
    SocketError,
    BindError,
    SendError,
    ReceiveError,
    InsufficientBuffer,
    InvalidPid,
    InvalidSeq,
    PermissionDenied,
    AddressNotAvailable,
    NoSuchDevice,
    OperationNotSupported,
    NamespaceNotFound,
    NamespaceSwitchFailed,
};

Data Structures

LinkInfo

Network interface information:

  • Interface index and name
  • MTU and flags
  • Hardware addresses

AddressInfo

Network address information:

  • Address family and prefix length
  • Interface index and scope
  • Address data

RouteInfo

Routing table information:

  • Route family and table
  • Destination and gateway
  • Priority and flags

RouteFilter

Route filtering configuration:

  • Family (IPv4/IPv6)
  • Table and protocol
  • Interface and gateway presence

NetworkNamespace

Network namespace management:

  • Name and filesystem path
  • Creation and deletion operations
  • Namespace switching capabilities
  • Existence checking

Route Listing and Filtering

The library provides convenient functions for listing and filtering routes:

// List all routes with formatted output
try route_socket.listRoutes(allocator, writer);

// Filter routes by various criteria
const filter = RouteFilter.init()
    .withFamily(std.posix.AF.INET)        // IPv4 only
    .withTable(254)                       // Main routing table
    .withProtocol(2)                      // Kernel routes
    .withInterface(1)                     // Specific interface
    .withGateway(true);                   // Routes with gateway

try route_socket.listRoutesFiltered(allocator, writer, filter);

Network Namespaces

Manage Linux network namespaces for network isolation:

const netns = @import("netns.zig");

// Create a new network namespace
var network_ns = try netns.NetworkNamespace.init(allocator, "my-netns");
defer network_ns.deinit();

// Create the namespace
try network_ns.create();

// Check if namespace exists
if (network_ns.exists()) {
    std.debug.print("Namespace exists!\n", .{});
}

// Enter the namespace
try network_ns.enter();

// Delete the namespace when done
try network_ns.delete();

// List all available namespaces
var namespaces = try netns.listNamespaces(allocator);
defer netns.cleanupNamespaceList(allocator, &namespaces);

for (namespaces.items) |ns_name| {
    std.debug.print("Found namespace: {s}\n", .{ns_name});
}

Available Filters

  • withFamily(family): Filter by address family (IPv4/IPv6)
  • withTable(table): Filter by routing table
  • withProtocol(protocol): Filter by routing protocol
  • withInterface(interface): Filter by output interface
  • withGateway(has_gateway): Filter by gateway presence

Network Namespace Operations

Network namespaces provide network isolation, allowing multiple independent network stacks on a single Linux system. The library provides comprehensive namespace management:

Basic Operations

const netns = @import("netns.zig");

// Initialize a namespace handler
var ns = try netns.NetworkNamespace.init(allocator, "test-ns");
defer ns.deinit();

// Create namespace (requires root privileges)
try ns.create();

// Check existence
const exists = ns.exists();

// Enter namespace (affects current process)
try ns.enter();

// Clean up when done
try ns.delete();

Listing Namespaces

// Get all available namespaces
var namespaces = try netns.listNamespaces(allocator);
defer netns.cleanupNamespaceList(allocator, &namespaces);

for (namespaces.items) |name| {
    std.debug.print("Namespace: {s}\n", .{name});
}

Important Notes

  • Root Privileges: Network namespace operations require root privileges
  • Process Context: Entering a namespace affects the current process and its children
  • Persistence: Created namespaces persist in /var/run/netns/ until explicitly deleted
  • Isolation: Each namespace has its own network interfaces, routing tables, and firewall rules

License

This project is available under the MIT License.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages