| ... | ... | @@ -75,6 +75,8 @@ pub const Address = extern union { |
| 75 | 75 | } |
| 76 | 76 | } |
| 77 | 77 | |
| 78 | /// Parse a given IPv6 address string into an Address. |
| 79 | /// Assumes the Scope ID of the address is fully numeric. |
| 78 | 80 | pub fn parseIp6(buf: []const u8, port: u16) !Address { |
| 79 | 81 | var result = Address{ |
| 80 | 82 | .in6 = os.sockaddr_in6{ |
| ... | ... | @@ -274,7 +276,7 @@ pub const Address = extern union { |
| 274 | 276 | const resolved_scope_id = std.fmt.parseInt(u32, scope_id_value, 10) catch |err| blk: { |
| 275 | 277 | if (err != err.InvalidCharacter) return err; |
| 276 | 278 | break :blk if_nametoindex(scope_id_value); |
| 277 | | } |
| 279 | }; |
| 278 | 280 | |
| 279 | 281 | result.in6.scope_id = resolved_scope_id; |
| 280 | 282 | |
| ... | ... | @@ -515,6 +517,23 @@ pub fn connectUnixSocket(path: []const u8) !fs.File { |
| 515 | 517 | }; |
| 516 | 518 | } |
| 517 | 519 | |
| 520 | fn if_nametoindex(name: []const u8) !u32 { |
| 521 | var ifr: os.ifreq = undefined; |
| 522 | var sockfd = try os.socket(os.AF_UNIX, os.SOCK_DGRAM | os.SOCK_CLOEXEC, 0); |
| 523 | defer os.close(sockfd); |
| 524 | |
| 525 | std.mem.copy(u8, ifr.ifr_ifrn.name, &name); |
| 526 | |
| 527 | const rc = os.system.syscall3( |
| 528 | os.linux.SYS_ioctl, |
| 529 | @bitCast(usize, @as(isize, sockfd)), |
| 530 | os.linux.SIOCGIFINDEX, |
| 531 | @ptrToInt(&ifr), |
| 532 | ); |
| 533 | |
| 534 | return ifr.ifr_ifru.ifru_ivalue; |
| 535 | } |
| 536 | |
| 518 | 537 | pub const AddressList = struct { |
| 519 | 538 | arena: std.heap.ArenaAllocator, |
| 520 | 539 | addrs: []Address, |