Created
October 26, 2022 05:49
-
-
Save theoparis/6b3fc0dfc248a037df9c46fbb64844ba to your computer and use it in GitHub Desktop.
yes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const std = @import("std"); | |
const c = @cImport({ | |
// linux networking headers for modifying interfaces | |
@cInclude("ifaddrs.h"); | |
@cInclude("net/if.h"); | |
@cInclude("sys/ioctl.h"); | |
}); | |
pub const SIOCGIFINDEX = 0x8933; | |
pub const SIOCGIFFLAGS = 0x8934; | |
pub const SIOCGIFMTU = 0x8922; | |
pub const SIOCGIFHWADDR = 0x8924; | |
pub extern fn getifaddrs(ifap: **c.ifaddrs) i32; | |
pub const Interface = struct { | |
name: []const u8, | |
index: i32, | |
flags: i16, | |
mtu: i32, | |
mac: [6]u8, | |
ipv4: ?[]const u8, | |
ipv6: ?[]const u8, | |
pub fn get(name: []const u8) !Interface { | |
var ifr: c.ifreq = undefined; | |
std.mem.copy(u8, ifr.ifr_ifrn.ifrn_name[0..], name); | |
var fd = try std.os.socket(std.os.linux.AF.INET, c.SOCK_DGRAM, 0); | |
defer std.os.close(fd); | |
var res = c.ioctl(fd, SIOCGIFINDEX, &ifr); | |
if (res < 0) return error.GetIndexFailed; | |
const index = ifr.ifr_ifru.ifru_ivalue; | |
res = c.ioctl(fd, SIOCGIFFLAGS, &ifr); | |
if (res < 0) return error.GetFlagsFailed; | |
const flags = ifr.ifr_ifru.ifru_flags; | |
res = c.ioctl(fd, SIOCGIFMTU, &ifr); | |
if (res < 0) return error.GetMTUFailed; | |
const mtu = ifr.ifr_ifru.ifru_mtu; | |
res = c.ioctl(fd, SIOCGIFHWADDR, &ifr); | |
if (res < 0) return error.GetMACFailed; | |
const mac = ifr.ifr_ifru.ifru_hwaddr.sa_data[0..6]; | |
var ipv4: ?[]const u8 = null; | |
var ipv6: ?[]const u8 = null; | |
var ifa_p: *c.ifaddrs = undefined; | |
var ifaddrs_res = getifaddrs(&ifa_p); | |
if (ifaddrs_res < 0) return error.GetAddrsFailed; | |
defer c.freeifaddrs(ifa_p); | |
var ifa_o: ?c.ifaddrs = ifa_p.*; | |
while (ifa_o) |ifa| { | |
if (std.mem.eql(u8, std.mem.span(ifa.ifa_name), name)) { | |
if (ifa.ifa_addr != null) { | |
switch (ifa.ifa_addr.*.sa_family) { | |
c.AF_INET => { | |
ipv4 = ifa.ifa_addr.*.sa_data[2..]; | |
}, | |
c.AF_INET6 => { | |
ipv6 = ifa.ifa_addr.*.sa_data[8..]; | |
}, | |
else => {}, | |
} | |
} | |
break; | |
} | |
if (@ptrToInt(ifa.ifa_next) > 0) { | |
ifa_o = ifa.ifa_next.*; | |
} | |
} | |
return Interface{ | |
.name = name, | |
.index = index, | |
.flags = flags, | |
.mtu = mtu, | |
.mac = mac.*, | |
.ipv4 = ipv4, | |
.ipv6 = ipv6, | |
}; | |
} | |
}; | |
pub fn main() !void { | |
const iface = try Interface.get("wlan0"); | |
std.debug.print("interface: {s}\n", .{iface.name}); | |
std.debug.print(" index: {d}\n", .{iface.index}); | |
std.debug.print(" flags: {x}\n", .{iface.flags}); | |
std.debug.print(" mtu: {d}\n", .{iface.mtu}); | |
std.debug.print(" mac: {x}:{x}:{x}:{x}:{x}:{x}\n", .{ iface.mac[0], iface.mac[1], iface.mac[2], iface.mac[3], iface.mac[4], iface.mac[5] }); | |
if (iface.ipv4) |ipv4| { | |
std.debug.print(" ipv4: {x}.{x}.{x}.{x}\n", .{ ipv4[0], ipv4[1], ipv4[2], ipv4[3] }); | |
} | |
if (iface.ipv6) |ipv6| { | |
std.debug.print(" ipv6: {x}:{x}:{x}:{x}:{x}:{x}:{x}:{x}\n", .{ ipv6[0], ipv6[1], ipv6[2], ipv6[3], ipv6[4], ipv6[5], ipv6[6], ipv6[7] }); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment