mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 22:35:24 +00:00
Merge pull request #10576 from schmee/macos-resolve-ip
Use libc if_nametoindex for macOS when parsing IPs
This commit is contained in:
commit
ba0f72363a
@ -357,6 +357,8 @@ pub extern "c" fn openlog(ident: [*:0]const u8, logopt: c_int, facility: c_int)
|
||||
pub extern "c" fn closelog() void;
|
||||
pub extern "c" fn setlogmask(maskpri: c_int) c_int;
|
||||
|
||||
pub extern "c" fn if_nametoindex([*:0]const u8) c_int;
|
||||
|
||||
pub const max_align_t = if (builtin.abi == .msvc)
|
||||
f64
|
||||
else if (builtin.target.isDarwin())
|
||||
|
||||
@ -108,6 +108,8 @@ pub fn sigaddset(set: *sigset_t, signo: u5) void {
|
||||
|
||||
pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
|
||||
|
||||
pub const IFNAMESIZE = 16;
|
||||
|
||||
pub const AI = struct {
|
||||
/// get address to use bind()
|
||||
pub const PASSIVE = 0x00000001;
|
||||
|
||||
@ -636,17 +636,35 @@ pub fn connectUnixSocket(path: []const u8) !Stream {
|
||||
}
|
||||
|
||||
fn if_nametoindex(name: []const u8) !u32 {
|
||||
var ifr: os.ifreq = undefined;
|
||||
var sockfd = try os.socket(os.AF.UNIX, os.SOCK.DGRAM | os.SOCK.CLOEXEC, 0);
|
||||
defer os.closeSocket(sockfd);
|
||||
if (builtin.target.os.tag == .linux) {
|
||||
var ifr: os.ifreq = undefined;
|
||||
var sockfd = try os.socket(os.AF.UNIX, os.SOCK.DGRAM | os.SOCK.CLOEXEC, 0);
|
||||
defer os.closeSocket(sockfd);
|
||||
|
||||
std.mem.copy(u8, &ifr.ifrn.name, name);
|
||||
ifr.ifrn.name[name.len] = 0;
|
||||
std.mem.copy(u8, &ifr.ifrn.name, name);
|
||||
ifr.ifrn.name[name.len] = 0;
|
||||
|
||||
// TODO investigate if this needs to be integrated with evented I/O.
|
||||
try os.ioctl_SIOCGIFINDEX(sockfd, &ifr);
|
||||
// TODO investigate if this needs to be integrated with evented I/O.
|
||||
try os.ioctl_SIOCGIFINDEX(sockfd, &ifr);
|
||||
|
||||
return @bitCast(u32, ifr.ifru.ivalue);
|
||||
return @bitCast(u32, ifr.ifru.ivalue);
|
||||
}
|
||||
|
||||
if (comptime builtin.target.os.tag.isDarwin()) {
|
||||
if (name.len >= os.IFNAMESIZE)
|
||||
return error.NameTooLong;
|
||||
|
||||
var if_name: [os.IFNAMESIZE:0]u8 = undefined;
|
||||
std.mem.copy(u8, &if_name, name);
|
||||
if_name[name.len] = 0;
|
||||
const if_slice = if_name[0..name.len :0];
|
||||
const index = os.system.if_nametoindex(if_slice);
|
||||
if (index == 0)
|
||||
return error.InterfaceNotFound;
|
||||
return @bitCast(u32, index);
|
||||
}
|
||||
|
||||
@compileError("std.net.if_nametoindex unimplemented for this OS");
|
||||
}
|
||||
|
||||
pub const AddressList = struct {
|
||||
|
||||
@ -49,7 +49,7 @@ test "parse and render IPv6 addresses" {
|
||||
try testing.expectError(error.Incomplete, net.Address.parseIp6("FF01:", 0));
|
||||
try testing.expectError(error.InvalidIpv4Mapping, net.Address.parseIp6("::123.123.123.123", 0));
|
||||
// TODO Make this test pass on other operating systems.
|
||||
if (builtin.os.tag == .linux) {
|
||||
if (builtin.os.tag == .linux or comptime builtin.os.tag.isDarwin()) {
|
||||
try testing.expectError(error.Incomplete, net.Address.resolveIp6("ff01::fb%", 0));
|
||||
try testing.expectError(error.Overflow, net.Address.resolveIp6("ff01::fb%wlp3s0s0s0s0s0s0s0s0", 0));
|
||||
try testing.expectError(error.Overflow, net.Address.resolveIp6("ff01::fb%12345678901234", 0));
|
||||
@ -57,7 +57,7 @@ test "parse and render IPv6 addresses" {
|
||||
}
|
||||
|
||||
test "invalid but parseable IPv6 scope ids" {
|
||||
if (builtin.os.tag != .linux) {
|
||||
if (builtin.os.tag != .linux or comptime !builtin.os.tag.isDarwin()) {
|
||||
// Currently, resolveIp6 with alphanumerical scope IDs only works on Linux.
|
||||
// TODO Make this test pass on other operating systems.
|
||||
return error.SkipZigTest;
|
||||
|
||||
@ -16,28 +16,37 @@ pub fn resolveScopeId(name: []const u8) !u32 {
|
||||
if (have_ifnamesize) {
|
||||
if (name.len >= os.IFNAMESIZE) return error.NameTooLong;
|
||||
|
||||
if (native_os.tag == .windows) {
|
||||
if (native_os.tag == .windows or comptime native_os.tag.isDarwin()) {
|
||||
var interface_name: [os.IFNAMESIZE:0]u8 = undefined;
|
||||
mem.copy(u8, &interface_name, name);
|
||||
interface_name[name.len] = 0;
|
||||
|
||||
const rc = os.windows.ws2_32.if_nametoindex(@ptrCast([*:0]const u8, &interface_name));
|
||||
const rc = blk: {
|
||||
if (native_os.tag == .windows) {
|
||||
break :blk os.windows.ws2_32.if_nametoindex(@ptrCast([*:0]const u8, &interface_name));
|
||||
} else {
|
||||
const index = os.system.if_nametoindex(@ptrCast([*:0]const u8, &interface_name));
|
||||
break :blk @bitCast(u32, index);
|
||||
}
|
||||
};
|
||||
if (rc == 0) {
|
||||
return error.InterfaceNotFound;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
const fd = try os.socket(os.AF.INET, os.SOCK.DGRAM, 0);
|
||||
defer os.closeSocket(fd);
|
||||
if (native_os.tag == .linux) {
|
||||
const fd = try os.socket(os.AF.INET, os.SOCK.DGRAM, 0);
|
||||
defer os.closeSocket(fd);
|
||||
|
||||
var f: os.ifreq = undefined;
|
||||
mem.copy(u8, &f.ifrn.name, name);
|
||||
f.ifrn.name[name.len] = 0;
|
||||
var f: os.ifreq = undefined;
|
||||
mem.copy(u8, &f.ifrn.name, name);
|
||||
f.ifrn.name[name.len] = 0;
|
||||
|
||||
try os.ioctl_SIOCGIFINDEX(fd, &f);
|
||||
try os.ioctl_SIOCGIFINDEX(fd, &f);
|
||||
|
||||
return @bitCast(u32, f.ifru.ivalue);
|
||||
return @bitCast(u32, f.ifru.ivalue);
|
||||
}
|
||||
}
|
||||
|
||||
return error.InterfaceNotFound;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user