From 9a9661d6bdf403fd812d7cab1e61de692d284ab7 Mon Sep 17 00:00:00 2001 From: utox39 Date: Mon, 17 Mar 2025 01:14:42 +0100 Subject: [PATCH] feat(linux): add net info --- src/linux/linux.zig | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/linux/linux.zig b/src/linux/linux.zig index 418a0dc..0b912c0 100644 --- a/src/linux/linux.zig +++ b/src/linux/linux.zig @@ -2,6 +2,11 @@ const std = @import("std"); const c_sysinfo = @cImport(@cInclude("sys/sysinfo.h")); const c_unistd = @cImport(@cInclude("unistd.h")); const c_utsname = @cImport(@cInclude("sys/utsname.h")); +const c_ifaddrs = @cImport(@cInclude("ifaddrs.h")); +const c_inet = @cImport(@cInclude("arpa/inet.h")); +const c_net_if = @cImport(@cInclude("net/if.h")); +const c_netinet_in = @cImport(@cInclude("netinet/in.h")); +const c_socket = @cImport(@cInclude("sys/socket.h")); /// Structure representing system uptime in days, hours, and minutes. pub const SystemUptime = struct { @@ -27,6 +32,11 @@ pub const KernelInfo = struct { kernel_release: []u8, }; +pub const NetInfo = struct { + interface_name: []u8, + ipv4_addr: []u8, +}; + pub fn getUsername(allocator: std.mem.Allocator) ![]u8 { const username = try std.process.getEnvVarOwned(allocator, "USER"); return username; @@ -232,3 +242,37 @@ pub fn getOsInfo(allocator: std.mem.Allocator) ![]u8 { return try allocator.dupe(u8, pretty_name orelse "Unknown"); } + +pub fn getNetInfo(allocator: std.mem.Allocator) !std.ArrayList(NetInfo) { + var net_info_list = std.ArrayList(NetInfo).init(allocator); + + var ifap: ?*c_ifaddrs.ifaddrs = null; + if (c_ifaddrs.getifaddrs(&ifap) != 0) { + return error.GetifaddrsFailed; + } + defer c_ifaddrs.freeifaddrs(ifap); + + var cur: ?*c_ifaddrs.ifaddrs = ifap; + while (cur) |ifa| : (cur = ifa.ifa_next) { + if (ifa.ifa_addr) |addr| { + // Skips the loopback + if ((ifa.ifa_flags & c_net_if.IFF_LOOPBACK) != 0) continue; + + const sockaddr_ptr = @as(*const c_socket.sockaddr, @ptrCast(@alignCast(addr))); + + if (sockaddr_ptr.sa_family != c_inet.AF_INET) continue; + + var addr_in = @as(*const c_netinet_in.sockaddr_in, @ptrCast(@alignCast(sockaddr_ptr))); + var ip_buf: [c_inet.INET_ADDRSTRLEN]u8 = undefined; + const ip_str = c_inet.inet_ntop(c_inet.AF_INET, &addr_in.sin_addr, &ip_buf, c_inet.INET_ADDRSTRLEN); + if (ip_str) |ip| { + try net_info_list.append(NetInfo{ + .interface_name = try allocator.dupe(u8, std.mem.span(ifa.ifa_name)), + .ipv4_addr = try allocator.dupe(u8, std.mem.span(ip)), + }); + } + } + } + + return net_info_list; +}