Files
netio1/if.c.v
T
2026-04-29 21:45:37 +03:00

119 lines
2.6 KiB
V

module netio
import os
#include <net/if.h>
struct C.if_nameindex {
if_index u32
if_name &char
}
fn C.if_nametoindex(&char) u32
fn C.if_indextoname(u32, &char) &char
fn C.if_nameindex() &C.if_nameindex
fn C.if_freenameindex(voidptr)
pub struct NetworkInterfaceNotFound {
Error
pub:
index u32
name string
}
pub fn (e NetworkInterfaceNotFound) msg() string {
if e.index != 0 {
return 'network interface with index ${e.index} not found'
} else {
return 'network interface named `${e.name}` not found'
}
}
// name_to_index translates the network interface name to index.
// See also if_nametoindex(3).
pub fn name_to_index(name string) !u32 {
index := C.if_nametoindex(&char(name.str))
if index == 0 {
err := os.last_error()
if err.code() == 19 { // ENODEV
return NetworkInterfaceNotFound{
name: name
}
} else {
return err
}
}
return index
}
// index_to_name translates the network interface index to name e.g. 'eth0'.
// See also if_indextoname(3).
pub fn index_to_name(index u32) !string {
name := []u8{len: C.IF_NAMESIZE}
ifname := C.if_indextoname(index, name.data)
if isnil(ifname) {
err := os.last_error()
if err.code() == 6 { // ENXIO
return NetworkInterfaceNotFound{
index: index
}
} else {
return err
}
return os.last_error()
}
return unsafe { cstring_to_vstring(ifname) }
}
pub struct NetworkInterfaceId {
pub:
index u32
name string
}
// find_network_interface returns the network interface index and name by provided string s.
// If network interface is not present the NetworkInterfaceNotFound error will be returned.
// See also `index_to_name()` and `name_to_index()`.
// Example: assert netio.find_network_interface('eth0')!.index == 2
// Example: assert netio.find_network_interface('2')!.name == 'eth0'
pub fn find_network_interface(s string) !NetworkInterfaceId {
mut index := u32(0)
mut name := ''
if s.is_int() {
index = s.u32()
name = index_to_name(index)!
} else {
name = s
index = name_to_index(name)!
}
return NetworkInterfaceId{
index: index
name: name
}
}
// network_interfaces returns an array with names and indexes of all network interfaces in system.
pub fn network_interfaces() ![]NetworkInterfaceId {
ifaces := C.if_nameindex()
if isnil(ifaces) {
return os.last_error()
}
defer {
C.if_freenameindex(ifaces)
}
mut result := []NetworkInterfaceId{}
mut i := 0
for {
iface := unsafe { ifaces[i] }
i++
if iface.if_index == 0 && isnil(iface.if_name) {
break
}
result << NetworkInterfaceId{
index: iface.if_index
name: unsafe { cstring_to_vstring(iface.if_name) }
}
}
return result
}