Skip to content

Instantly share code, notes, and snippets.

@theoparis
Created October 26, 2022 05:49
Show Gist options
  • Save theoparis/6b3fc0dfc248a037df9c46fbb64844ba to your computer and use it in GitHub Desktop.
Save theoparis/6b3fc0dfc248a037df9c46fbb64844ba to your computer and use it in GitHub Desktop.
yes
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