relibc/header/net_if/mod.rs
1//! `net/if.h` implementation.
2//!
3//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/net_if.h.html>.
4
5use core::ptr::null;
6
7use crate::{
8 c_str::CStr,
9 platform::{
10 ERRNO,
11 types::{c_char, c_int, c_uint},
12 },
13};
14
15use super::errno::ENXIO;
16
17/// See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/net_if.h.html>.
18#[repr(C)]
19pub struct if_nameindex {
20 /// Numeric index of the interface.
21 if_index: c_uint,
22 /// Null-terminated name of the interface.
23 if_name: *const c_char,
24}
25
26/// See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/net_if.h.html>.
27///
28/// Interface name length.
29pub const IF_NAMESIZE: usize = 16;
30
31/// cbindgen:ignore
32const IF_STUB_INTERFACE: *const c_char = (c"stub").as_ptr();
33
34/// cbindgen:ignore
35const INTERFACES: &[if_nameindex] = &[
36 if_nameindex {
37 if_index: 1,
38 if_name: IF_STUB_INTERFACE,
39 },
40 if_nameindex {
41 if_index: 0,
42 if_name: null::<c_char>(),
43 },
44];
45
46/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/if_freenameindex.html>.
47///
48/// # Safety
49/// this is a no-op: the list returned by if_nameindex() is a ref to a constant
50#[unsafe(no_mangle)]
51pub unsafe extern "C" fn if_freenameindex(s: *mut if_nameindex) {}
52
53/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/if_indextoname.html>.
54///
55/// # Safety
56/// Returns only static lifetime references to const names, does not reuse the buf pointer.
57/// Returns NULL in case of not found + ERRNO being set to ENXIO.
58/// Currently only checks against inteface index 1.
59#[unsafe(no_mangle)]
60pub unsafe extern "C" fn if_indextoname(idx: c_uint, buf: *mut c_char) -> *const c_char {
61 if idx == 1 {
62 return IF_STUB_INTERFACE;
63 }
64 ERRNO.set(ENXIO);
65 null::<c_char>()
66}
67
68/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/if_nameindex.html>.
69///
70/// # Safety
71/// Returns a constant pointer to a pre defined const stub list
72/// The end of the list is determined by an if_nameindex struct having if_index 0 and if_name NULL
73#[unsafe(no_mangle)]
74pub unsafe extern "C" fn if_nameindex() -> *const if_nameindex {
75 core::ptr::from_ref::<if_nameindex>(&INTERFACES[0])
76}
77
78/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/if_nametoindex.html>.
79///
80/// # Safety
81/// Compares the name to a constant string and only returns an int as a result.
82/// An invalid name string will return an index of 0
83#[unsafe(no_mangle)]
84pub unsafe extern "C" fn if_nametoindex(name: *const c_char) -> c_uint {
85 if name.is_null() {
86 return 0;
87 }
88 let name = unsafe { CStr::from_ptr(name).to_str().unwrap_or("") };
89 if name.eq("stub") {
90 return 1;
91 }
92 0
93}
94
95// Nonstandard, used alongside ifaddrs.h
96// See https://man7.org/linux/man-pages/man7/netdevice.7.html
97
98/// Interface is running.
99pub const IFF_UP: c_int = 0x1;
100/// Valid broadcast address set.
101pub const IFF_BROADCAST: c_int = 0x2;
102/// Internal debugging flag.
103pub const IFF_DEBUG: c_int = 0x4;
104/// Interface is a loopback interface.
105pub const IFF_LOOPBACK: c_int = 0x8;
106/// Interface is a point-to-point link.
107pub const IFF_POINTOPOINT: c_int = 0x10;
108/// Avoid use of trailers.
109pub const IFF_NOTRAILERS: c_int = 0x20;
110/// Resources allocated.
111pub const IFF_RUNNING: c_int = 0x40;
112/// No arp protocol, L2 destination address not set.
113pub const IFF_NOARP: c_int = 0x80;
114/// Interface is in promiscuous mode.
115pub const IFF_PROMISC: c_int = 0x100;
116/// Receive all multicast packets.
117pub const IFF_ALLMULTI: c_int = 0x200;
118/// Master of a load balancing bundle.
119pub const IFF_MASTER: c_int = 0x400;
120/// Slave of a load balancing bundle.
121pub const IFF_SLAVE: c_int = 0x800;
122/// Supports multicast.
123pub const IFF_MULTICAST: c_int = 0x1000;
124/// Is able to select media type via ifmap.
125pub const IFF_PORTSEL: c_int = 0x2000;
126/// Auto media selection active.
127pub const IFF_AUTOMEDIA: c_int = 0x4000;
128/// The addresses are lost when the interface goes down.
129pub const IFF_DYNAMIC: c_int = 0x8000;
130/// Driver signals L1 up.
131pub const IFF_LOWER_UP: c_int = 0x10000;
132/// Driver signals dormant.
133pub const IFF_DORMANT: c_int = 0x20000;
134/// Echo sent packets.
135pub const IFF_ECHO: c_int = 0x40000;
136pub const IFF_VOLATILE: c_int = IFF_LOOPBACK
137 | IFF_POINTOPOINT
138 | IFF_BROADCAST
139 | IFF_ECHO
140 | IFF_MASTER
141 | IFF_SLAVE
142 | IFF_RUNNING
143 | IFF_LOWER_UP
144 | IFF_DORMANT;