| author | |
| committer | |
| log | 385b7e4808d6f1564256e9f40c903f984a49dca6 |
| tree | b95b5d1b71cb7050b0cf048ebfdd87b48d534da9 |
| parent | 57d7ad9172497dd1e341f5c37228544f38e3959d |
Use libc if_nametoindex for macOS when parsing IPs5 files changed, 50 insertions(+), 19 deletions(-)
lib/std/c.zig+2| ... | @@ -357,6 +357,8 @@ pub extern "c" fn openlog(ident: [*:0]const u8, logopt: c_int, facility: c_int) | ... | @@ -357,6 +357,8 @@ pub extern "c" fn openlog(ident: [*:0]const u8, logopt: c_int, facility: c_int) |
| 357 | pub extern "c" fn closelog() void; | 357 | pub extern "c" fn closelog() void; |
| 358 | pub extern "c" fn setlogmask(maskpri: c_int) c_int; | 358 | pub extern "c" fn setlogmask(maskpri: c_int) c_int; |
| 359 | 359 | ||
| 360 | pub extern "c" fn if_nametoindex([*:0]const u8) c_int; | ||
| 361 | |||
| 360 | pub const max_align_t = if (builtin.abi == .msvc) | 362 | pub const max_align_t = if (builtin.abi == .msvc) |
| 361 | f64 | 363 | f64 |
| 362 | else if (builtin.target.isDarwin()) | 364 | else if (builtin.target.isDarwin()) |
lib/std/c/darwin.zig+2| ... | @@ -108,6 +108,8 @@ pub fn sigaddset(set: *sigset_t, signo: u5) void { | ... | @@ -108,6 +108,8 @@ pub fn sigaddset(set: *sigset_t, signo: u5) void { |
| 108 | 108 | ||
| 109 | pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; | 109 | pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; |
| 110 | 110 | ||
| 111 | pub const IFNAMESIZE = 16; | ||
| 112 | |||
| 111 | pub const AI = struct { | 113 | pub const AI = struct { |
| 112 | /// get address to use bind() | 114 | /// get address to use bind() |
| 113 | pub const PASSIVE = 0x00000001; | 115 | pub const PASSIVE = 0x00000001; |
lib/std/net.zig+26-8| ... | @@ -636,17 +636,35 @@ pub fn connectUnixSocket(path: []const u8) !Stream { | ... | @@ -636,17 +636,35 @@ pub fn connectUnixSocket(path: []const u8) !Stream { |
| 636 | } | 636 | } |
| 637 | 637 | ||
| 638 | fn if_nametoindex(name: []const u8) !u32 { | 638 | fn if_nametoindex(name: []const u8) !u32 { |
| 639 | var ifr: os.ifreq = undefined; | 639 | if (builtin.target.os.tag == .linux) { |
| 640 | var sockfd = try os.socket(os.AF.UNIX, os.SOCK.DGRAM | os.SOCK.CLOEXEC, 0); | 640 | var ifr: os.ifreq = undefined; |
| 641 | defer os.closeSocket(sockfd); | 641 | var sockfd = try os.socket(os.AF.UNIX, os.SOCK.DGRAM | os.SOCK.CLOEXEC, 0); |
| 642 | defer os.closeSocket(sockfd); | ||
| 643 | |||
| 644 | std.mem.copy(u8, &ifr.ifrn.name, name); | ||
| 645 | ifr.ifrn.name[name.len] = 0; | ||
| 646 | |||
| 647 | // TODO investigate if this needs to be integrated with evented I/O. | ||
| 648 | try os.ioctl_SIOCGIFINDEX(sockfd, &ifr); | ||
| 642 | 649 | ||
| 643 | std.mem.copy(u8, &ifr.ifrn.name, name); | 650 | return @bitCast(u32, ifr.ifru.ivalue); |
| 644 | ifr.ifrn.name[name.len] = 0; | 651 | } |
| 652 | |||
| 653 | if (comptime builtin.target.os.tag.isDarwin()) { | ||
| 654 | if (name.len >= os.IFNAMESIZE) | ||
| 655 | return error.NameTooLong; | ||
| 645 | 656 | ||
| 646 | // TODO investigate if this needs to be integrated with evented I/O. | 657 | var if_name: [os.IFNAMESIZE:0]u8 = undefined; |
| 647 | try os.ioctl_SIOCGIFINDEX(sockfd, &ifr); | 658 | std.mem.copy(u8, &if_name, name); |
| 659 | if_name[name.len] = 0; | ||
| 660 | const if_slice = if_name[0..name.len :0]; | ||
| 661 | const index = os.system.if_nametoindex(if_slice); | ||
| 662 | if (index == 0) | ||
| 663 | return error.InterfaceNotFound; | ||
| 664 | return @bitCast(u32, index); | ||
| 665 | } | ||
| 648 | 666 | ||
| 649 | return @bitCast(u32, ifr.ifru.ivalue); | 667 | @compileError("std.net.if_nametoindex unimplemented for this OS"); |
| 650 | } | 668 | } |
| 651 | 669 | ||
| 652 | pub const AddressList = struct { | 670 | pub const AddressList = struct { |
lib/std/net/test.zig+2-2| ... | @@ -49,7 +49,7 @@ test "parse and render IPv6 addresses" { | ... | @@ -49,7 +49,7 @@ test "parse and render IPv6 addresses" { |
| 49 | try testing.expectError(error.Incomplete, net.Address.parseIp6("FF01:", 0)); | 49 | try testing.expectError(error.Incomplete, net.Address.parseIp6("FF01:", 0)); |
| 50 | try testing.expectError(error.InvalidIpv4Mapping, net.Address.parseIp6("::123.123.123.123", 0)); | 50 | try testing.expectError(error.InvalidIpv4Mapping, net.Address.parseIp6("::123.123.123.123", 0)); |
| 51 | // TODO Make this test pass on other operating systems. | 51 | // TODO Make this test pass on other operating systems. |
| 52 | if (builtin.os.tag == .linux) { | 52 | if (builtin.os.tag == .linux or comptime builtin.os.tag.isDarwin()) { |
| 53 | try testing.expectError(error.Incomplete, net.Address.resolveIp6("ff01::fb%", 0)); | 53 | try testing.expectError(error.Incomplete, net.Address.resolveIp6("ff01::fb%", 0)); |
| 54 | try testing.expectError(error.Overflow, net.Address.resolveIp6("ff01::fb%wlp3s0s0s0s0s0s0s0s0", 0)); | 54 | try testing.expectError(error.Overflow, net.Address.resolveIp6("ff01::fb%wlp3s0s0s0s0s0s0s0s0", 0)); |
| 55 | try testing.expectError(error.Overflow, net.Address.resolveIp6("ff01::fb%12345678901234", 0)); | 55 | try testing.expectError(error.Overflow, net.Address.resolveIp6("ff01::fb%12345678901234", 0)); |
| ... | @@ -57,7 +57,7 @@ test "parse and render IPv6 addresses" { | ... | @@ -57,7 +57,7 @@ test "parse and render IPv6 addresses" { |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | test "invalid but parseable IPv6 scope ids" { | 59 | test "invalid but parseable IPv6 scope ids" { |
| 60 | if (builtin.os.tag != .linux) { | 60 | if (builtin.os.tag != .linux or comptime !builtin.os.tag.isDarwin()) { |
| 61 | // Currently, resolveIp6 with alphanumerical scope IDs only works on Linux. | 61 | // Currently, resolveIp6 with alphanumerical scope IDs only works on Linux. |
| 62 | // TODO Make this test pass on other operating systems. | 62 | // TODO Make this test pass on other operating systems. |
| 63 | return error.SkipZigTest; | 63 | return error.SkipZigTest; |
lib/std/x/os/net.zig+18-9| ... | @@ -16,28 +16,37 @@ pub fn resolveScopeId(name: []const u8) !u32 { | ... | @@ -16,28 +16,37 @@ pub fn resolveScopeId(name: []const u8) !u32 { |
| 16 | if (have_ifnamesize) { | 16 | if (have_ifnamesize) { |
| 17 | if (name.len >= os.IFNAMESIZE) return error.NameTooLong; | 17 | if (name.len >= os.IFNAMESIZE) return error.NameTooLong; |
| 18 | 18 | ||
| 19 | if (native_os.tag == .windows) { | 19 | if (native_os.tag == .windows or comptime native_os.tag.isDarwin()) { |
| 20 | var interface_name: [os.IFNAMESIZE:0]u8 = undefined; | 20 | var interface_name: [os.IFNAMESIZE:0]u8 = undefined; |
| 21 | mem.copy(u8, &interface_name, name); | 21 | mem.copy(u8, &interface_name, name); |
| 22 | interface_name[name.len] = 0; | 22 | interface_name[name.len] = 0; |
| 23 | 23 | ||
| 24 | const rc = os.windows.ws2_32.if_nametoindex(@ptrCast([*:0]const u8, &interface_name)); | 24 | const rc = blk: { |
| 25 | if (native_os.tag == .windows) { | ||
| 26 | break :blk os.windows.ws2_32.if_nametoindex(@ptrCast([*:0]const u8, &interface_name)); | ||
| 27 | } else { | ||
| 28 | const index = os.system.if_nametoindex(@ptrCast([*:0]const u8, &interface_name)); | ||
| 29 | break :blk @bitCast(u32, index); | ||
| 30 | } | ||
| 31 | }; | ||
| 25 | if (rc == 0) { | 32 | if (rc == 0) { |
| 26 | return error.InterfaceNotFound; | 33 | return error.InterfaceNotFound; |
| 27 | } | 34 | } |
| 28 | return rc; | 35 | return rc; |
| 29 | } | 36 | } |
| 30 | 37 | ||
| 31 | const fd = try os.socket(os.AF.INET, os.SOCK.DGRAM, 0); | 38 | if (native_os.tag == .linux) { |
| 32 | defer os.closeSocket(fd); | 39 | const fd = try os.socket(os.AF.INET, os.SOCK.DGRAM, 0); |
| 40 | defer os.closeSocket(fd); | ||
| 33 | 41 | ||
| 34 | var f: os.ifreq = undefined; | 42 | var f: os.ifreq = undefined; |
| 35 | mem.copy(u8, &f.ifrn.name, name); | 43 | mem.copy(u8, &f.ifrn.name, name); |
| 36 | f.ifrn.name[name.len] = 0; | 44 | f.ifrn.name[name.len] = 0; |
| 37 | 45 | ||
| 38 | try os.ioctl_SIOCGIFINDEX(fd, &f); | 46 | try os.ioctl_SIOCGIFINDEX(fd, &f); |
| 39 | 47 | ||
| 40 | return @bitCast(u32, f.ifru.ivalue); | 48 | return @bitCast(u32, f.ifru.ivalue); |
| 49 | } | ||
| 41 | } | 50 | } |
| 42 | 51 | ||
| 43 | return error.InterfaceNotFound; | 52 | return error.InterfaceNotFound; |