authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-01-15 00:47:12+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-01-15 00:47:12+01:00
logba0f72363accc19edbfc5a7ae42d5a8970f56f64
tree324b3c9a6fefd0399fd01722a7be78cbaf45f553
parentb3471ef3009c4e3164145692b1b5d0662077d949
parentc992164dc71ec38c42d14a0c9380a19b8e357880
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #10576 from schmee/macos-resolve-ip

Use libc if_nametoindex for macOS when parsing IPs

5 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)
357357pub extern "c" fn closelog() void;
358358pub extern "c" fn setlogmask(maskpri: c_int) c_int;
359359
360pub extern "c" fn if_nametoindex([*:0]const u8) c_int;
361
360362pub const max_align_t = if (builtin.abi == .msvc)
361363 f64
362364else if (builtin.target.isDarwin())
lib/std/c/darwin.zig+2
......@@ -108,6 +108,8 @@ pub fn sigaddset(set: *sigset_t, signo: u5) void {
108108
109109pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
110110
111pub const IFNAMESIZE = 16;
112
111113pub const AI = struct {
112114 /// get address to use bind()
113115 pub const PASSIVE = 0x00000001;
lib/std/net.zig+26-8
......@@ -636,17 +636,35 @@ pub fn connectUnixSocket(path: []const u8) !Stream {
636636}
637637
638638fn if_nametoindex(name: []const u8) !u32 {
639 var ifr: os.ifreq = undefined;
640 var sockfd = try os.socket(os.AF.UNIX, os.SOCK.DGRAM | os.SOCK.CLOEXEC, 0);
641 defer os.closeSocket(sockfd);
639 if (builtin.target.os.tag == .linux) {
640 var ifr: os.ifreq = undefined;
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);
642649
643 std.mem.copy(u8, &ifr.ifrn.name, name);
644 ifr.ifrn.name[name.len] = 0;
650 return @bitCast(u32, ifr.ifru.ivalue);
651 }
652
653 if (comptime builtin.target.os.tag.isDarwin()) {
654 if (name.len >= os.IFNAMESIZE)
655 return error.NameTooLong;
645656
646 // TODO investigate if this needs to be integrated with evented I/O.
647 try os.ioctl_SIOCGIFINDEX(sockfd, &ifr);
657 var if_name: [os.IFNAMESIZE:0]u8 = undefined;
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 }
648666
649 return @bitCast(u32, ifr.ifru.ivalue);
667 @compileError("std.net.if_nametoindex unimplemented for this OS");
650668}
651669
652670pub const AddressList = struct {
lib/std/net/test.zig+2-2
......@@ -49,7 +49,7 @@ test "parse and render IPv6 addresses" {
4949 try testing.expectError(error.Incomplete, net.Address.parseIp6("FF01:", 0));
5050 try testing.expectError(error.InvalidIpv4Mapping, net.Address.parseIp6("::123.123.123.123", 0));
5151 // 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()) {
5353 try testing.expectError(error.Incomplete, net.Address.resolveIp6("ff01::fb%", 0));
5454 try testing.expectError(error.Overflow, net.Address.resolveIp6("ff01::fb%wlp3s0s0s0s0s0s0s0s0", 0));
5555 try testing.expectError(error.Overflow, net.Address.resolveIp6("ff01::fb%12345678901234", 0));
......@@ -57,7 +57,7 @@ test "parse and render IPv6 addresses" {
5757}
5858
5959test "invalid but parseable IPv6 scope ids" {
60 if (builtin.os.tag != .linux) {
60 if (builtin.os.tag != .linux or comptime !builtin.os.tag.isDarwin()) {
6161 // Currently, resolveIp6 with alphanumerical scope IDs only works on Linux.
6262 // TODO Make this test pass on other operating systems.
6363 return error.SkipZigTest;
lib/std/x/os/net.zig+18-9
......@@ -16,28 +16,37 @@ pub fn resolveScopeId(name: []const u8) !u32 {
1616 if (have_ifnamesize) {
1717 if (name.len >= os.IFNAMESIZE) return error.NameTooLong;
1818
19 if (native_os.tag == .windows) {
19 if (native_os.tag == .windows or comptime native_os.tag.isDarwin()) {
2020 var interface_name: [os.IFNAMESIZE:0]u8 = undefined;
2121 mem.copy(u8, &interface_name, name);
2222 interface_name[name.len] = 0;
2323
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 };
2532 if (rc == 0) {
2633 return error.InterfaceNotFound;
2734 }
2835 return rc;
2936 }
3037
31 const fd = try os.socket(os.AF.INET, os.SOCK.DGRAM, 0);
32 defer os.closeSocket(fd);
38 if (native_os.tag == .linux) {
39 const fd = try os.socket(os.AF.INET, os.SOCK.DGRAM, 0);
40 defer os.closeSocket(fd);
3341
34 var f: os.ifreq = undefined;
35 mem.copy(u8, &f.ifrn.name, name);
36 f.ifrn.name[name.len] = 0;
42 var f: os.ifreq = undefined;
43 mem.copy(u8, &f.ifrn.name, name);
44 f.ifrn.name[name.len] = 0;
3745
38 try os.ioctl_SIOCGIFINDEX(fd, &f);
46 try os.ioctl_SIOCGIFINDEX(fd, &f);
3947
40 return @bitCast(u32, f.ifru.ivalue);
48 return @bitCast(u32, f.ifru.ivalue);
49 }
4150 }
4251
4352 return error.InterfaceNotFound;