feature. See also
. The project being documented here (as the example) is the Zig library itself.
Threaded.netInterfaceNameResolve
fn netInterfaceNameResolve(
userdata: ?*anyopaque,
name: *const net.Interface.Name,
) net.Interface.Name.ResolveError!net.Interface
File
Code
fn netInterfaceNameResolve(
userdata: ?*anyopaque,
name: *const net.Interface.Name,
) net.Interface.Name.ResolveError!net.Interface {
if (!have_networking) return error.InterfaceNotFound;
const t: *Threaded = @ptrCast(@alignCast(userdata));
if (native_os == .linux) {
const sock_fd = openSocketPosix(posix.AF.UNIX, .{ .mode = .dgram }) catch |err| switch (err) {
error.ProcessFdQuotaExceeded => return error.SystemResources,
error.SystemFdQuotaExceeded => return error.SystemResources,
error.AddressFamilyUnsupported => return error.Unexpected,
error.ProtocolUnsupportedBySystem => return error.Unexpected,
error.ProtocolUnsupportedByAddressFamily => return error.Unexpected,
error.SocketModeUnsupported => return error.Unexpected,
error.OptionUnsupported => return error.Unexpected,
else => |e| return e,
};
defer closeFd(sock_fd);
var ifr: posix.ifreq = .{
.ifrn = .{ .name = @bitCast(name.bytes) },
.ifru = undefined,
};
const syscall: Syscall = try .start();
while (true) switch (posix.errno(posix.system.ioctl(sock_fd, posix.SIOCGIFINDEX, @intFromPtr(&ifr)))) {
.SUCCESS => {
syscall.finish();
return .{ .index = @bitCast(ifr.ifru.ivalue) };
},
.INTR => {
try syscall.checkCancel();
continue;
},
.NODEV => return syscall.fail(error.InterfaceNotFound),
else => |err| return syscall.unexpectedErrno(err),
};
}
if (is_windows) {
var ConvertInterfaceNameToLuidW = t.dl.ConvertInterfaceNameToLuidW.load(.acquire);
var ConvertInterfaceLuidToIndex = t.dl.ConvertInterfaceLuidToIndex.load(.acquire);
if (ConvertInterfaceNameToLuidW == null or ConvertInterfaceLuidToIndex == null) {
const iphlpapi_dll = t.dl.iphlpapi_dll.load(.acquire) orelse iphlpapi_dll: {
try Thread.checkCancel();
var iphlpapi_dll: *anyopaque = undefined;
switch (windows.ntdll.LdrLoadDll(null, null, &.init(
&.{ 'I', 'P', 'H', 'L', 'P', 'A', 'P', 'I', '.', 'D', 'L', 'L' },
), &iphlpapi_dll)) {
.SUCCESS => {},
.DLL_NOT_FOUND => return error.Unexpected,
else => |status| return windows.unexpectedStatus(status),
}
const handle = t.dl.iphlpapi_dll.cmpxchgStrong(null, iphlpapi_dll, .release, .monotonic) orelse
break :iphlpapi_dll iphlpapi_dll;
switch (windows.ntdll.LdrUnloadDll(iphlpapi_dll)) {
.SUCCESS => break :iphlpapi_dll handle.?,
else => |status| return windows.unexpectedStatus(status),
}
};
switch (windows.ntdll.LdrGetProcedureAddress(iphlpapi_dll, &.init(
&.{
'C', 'o', 'n', 'v', 'e', 'r', 't', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e',
'N', 'a', 'm', 'e', 'T', 'o', 'L', 'u', 'i', 'd', 'W',
},
), 0, @ptrCast(&ConvertInterfaceNameToLuidW))) {
.SUCCESS => t.dl.ConvertInterfaceNameToLuidW.store(ConvertInterfaceNameToLuidW, .release),
else => |status| return windows.unexpectedStatus(status),
}
switch (windows.ntdll.LdrGetProcedureAddress(iphlpapi_dll, &.init(
&.{
'C', 'o', 'n', 'v', 'e', 'r', 't', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e',
'L', 'u', 'i', 'd', 'T', 'o', 'I', 'n', 'd', 'e', 'x',
},
), 0, @ptrCast(&ConvertInterfaceLuidToIndex))) {
.SUCCESS => t.dl.ConvertInterfaceLuidToIndex.store(ConvertInterfaceLuidToIndex, .release),
else => |status| return windows.unexpectedStatus(status),
}
}
try Thread.checkCancel();
var name_w: [net.Interface.Name.max_len:0]windows.WCHAR = undefined;
name_w[
std.unicode.wtf8ToWtf16Le(&name_w, name.toSlice()) catch |err| switch (err) {
error.InvalidWtf8 => return error.InterfaceNotFound,
}
] = 0;
var luid: windows.NET.LUID = undefined;
switch (ConvertInterfaceNameToLuidW.?(&name_w, &luid)) {
.SUCCESS => {},
.INVALID_NAME => return error.InterfaceNotFound,
.INVALID_PARAMETER => unreachable,
else => |err| return windows.unexpectedError(err),
}
var index: windows.NET.IFINDEX = undefined;
switch (ConvertInterfaceLuidToIndex.?(&luid, &index)) {
.SUCCESS => {},
.INVALID_PARAMETER => unreachable,
else => |err| return windows.unexpectedError(err),
}
return .{ .index = @backingInt(index) };
}
if (builtin.link_libc) {
try Thread.checkCancel();
const index = std.c.if_nametoindex(&name.bytes);
if (index == 0) return error.InterfaceNotFound;
return .{ .index = @bitCast(index) };
}
@panic("unimplemented");
}