Makko, the people-oriented static site generator made for blogging. forge.starlightnet.work/Team/Makko
ssg static-site-generator makko starlight-network
at main 2.7 kB view raw
1const std = @import("std"); 2 3const sockaddr = std.posix.sockaddr; 4 5const in_addr = extern struct { 6 s_addr: u32, 7}; 8 9const ifaddrs = extern struct { 10 ifa_next: ?*ifaddrs, 11 ifa_name: [*]const u8, 12 ifa_flags: u32, 13 ifa_addr: ?*sockaddr, 14 ifa_netmask: ?*sockaddr, 15 ifa_ifu: ?*sockaddr, 16 ifa_data: ?*anyopaque, 17}; 18 19extern fn getifaddrs(ifap: *?*ifaddrs) c_int; 20extern fn freeifaddrs(ifa: *ifaddrs) void; 21 22extern fn inet_ntop( 23 af: c_int, 24 src: *const anyopaque, 25 dst: [*]u8, 26 size: std.posix.socklen_t, 27) ?[*]u8; 28 29const INET_ADDRSTRLEN = 16; 30const INADDR_LOOPBACK: u32 = std.mem.nativeToBig(u32, 0x7f000001); 31 32fn getLanIP_unix(out: *[32]u8) ![]u8 { 33 var ifap: ?*ifaddrs = null; 34 35 if (getifaddrs(&ifap) != 0) 36 return error.GetIfAddrsFailed; 37 38 defer freeifaddrs(ifap.?); 39 40 var buf: [INET_ADDRSTRLEN]u8 = undefined; 41 42 var cursor = ifap; 43 while (cursor) |ifa| : (cursor = ifa.ifa_next) { 44 const addr = ifa.ifa_addr orelse continue; 45 if (addr.family != std.posix.AF.INET) continue; 46 47 const sa: *const sockaddr.in = @ptrCast(@alignCast(addr)); 48 49 if (sa.addr == INADDR_LOOPBACK) 50 continue; 51 52 if (inet_ntop(std.posix.AF.INET, &sa.addr, &buf, buf.len) != null) { 53 const size = std.mem.indexOfScalar(u8, &buf, 0) orelse buf.len; 54 @memcpy(out[0..size], buf[0..size]); 55 56 return out[0..size]; 57 } 58 } 59 60 return error.CannotFindIP; 61} 62 63fn getLanIP_windows(out: *[32]u8) !?[]u8 { 64 const gpa = std.heap.page_allocator; 65 66 var child = std.process.Child.init( 67 &[_][]const u8{ 68 "powershell", 69 "-NoProfile", 70 "-Command", 71 "Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.IPAddress -ne '127.0.0.1' -and $_.PrefixOrigin -ne 'WellKnown' } | Select-Object -First 1 -ExpandProperty IPAddress", 72 }, 73 gpa, 74 ); 75 76 child.stdout_behavior = .Pipe; 77 child.stderr_behavior = .Ignore; 78 79 try child.spawn(); 80 81 // Capture stdout 82 var stdout = child.stdout.?; 83 var buf = std.ArrayList(u8).init(gpa); 84 defer buf.deinit(); 85 86 try stdout.reader().readAllArrayList(&buf, 4096); 87 88 _ = try child.wait(); 89 90 var trimmed = std.mem.trim(u8, buf.items, " \r\n\t"); 91 if (trimmed.len == 0) return null; 92 93 const size = @min(out.len, trimmed.len); 94 @memcpy(out[0..size], trimmed[0..size]); 95 return out[0..size]; 96} 97 98pub fn getLanIP(out: *[32]u8) ?[]u8 { 99 const os = @import("builtin").os.tag; 100 101 return switch (os) { 102 .windows => return getLanIP_windows(out) catch null, 103 .linux, .macos, .freebsd => return getLanIP_unix(out) catch null, 104 else => null, 105 }; 106}