support ipv4-mapped ipv6 addresses
parent
32ac1b5927
commit
6e786b60d4
|
@ -32,6 +32,7 @@ pub const IpAddress = extern union {
|
||||||
error.InvalidEnd,
|
error.InvalidEnd,
|
||||||
error.InvalidCharacter,
|
error.InvalidCharacter,
|
||||||
error.Incomplete,
|
error.Incomplete,
|
||||||
|
error.InvalidIpv4Mapping,
|
||||||
=> {},
|
=> {},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +104,24 @@ pub const IpAddress = extern union {
|
||||||
}
|
}
|
||||||
scope_id = true;
|
scope_id = true;
|
||||||
saw_any_digits = false;
|
saw_any_digits = false;
|
||||||
|
} else if (c == '.') {
|
||||||
|
if (!abbrv or ip_slice[0] != 0xff or ip_slice[1] != 0xff) {
|
||||||
|
// must start with '::ffff:'
|
||||||
|
return error.InvalidIpv4Mapping;
|
||||||
|
}
|
||||||
|
const start_index = mem.lastIndexOfScalar(u8, buf[0..i], ':').? + 1;
|
||||||
|
const addr = (parseIp4(buf[start_index..], 0) catch {
|
||||||
|
return error.InvalidIpv4Mapping;
|
||||||
|
}).in.addr;
|
||||||
|
ip_slice = result.in6.addr[0..];
|
||||||
|
ip_slice[10] = 0xff;
|
||||||
|
ip_slice[11] = 0xff;
|
||||||
|
|
||||||
|
ip_slice[12] = @truncate(u8, addr >> 24 & 0xff);
|
||||||
|
ip_slice[13] = @truncate(u8, addr >> 16 & 0xff);
|
||||||
|
ip_slice[14] = @truncate(u8, addr >> 8 & 0xff);
|
||||||
|
ip_slice[15] = @truncate(u8, addr & 0xff);
|
||||||
|
return result;
|
||||||
} else {
|
} else {
|
||||||
const digit = try std.fmt.charToDigit(c, 16);
|
const digit = try std.fmt.charToDigit(c, 16);
|
||||||
if (@mulWithOverflow(u16, x, 16, &x)) {
|
if (@mulWithOverflow(u16, x, 16, &x)) {
|
||||||
|
@ -783,6 +802,7 @@ fn linuxLookupNameFromHosts(
|
||||||
error.InvalidCharacter,
|
error.InvalidCharacter,
|
||||||
error.Incomplete,
|
error.Incomplete,
|
||||||
error.InvalidIPAddressFormat,
|
error.InvalidIPAddressFormat,
|
||||||
|
error.InvalidIpv4Mapping,
|
||||||
=> continue,
|
=> continue,
|
||||||
};
|
};
|
||||||
try addrs.append(LookupAddr{ .addr = addr });
|
try addrs.append(LookupAddr{ .addr = addr });
|
||||||
|
|
|
@ -14,6 +14,7 @@ test "parse and render IPv6 addresses" {
|
||||||
"::1234:5678",
|
"::1234:5678",
|
||||||
"2001:db8::1234:5678",
|
"2001:db8::1234:5678",
|
||||||
"FF01::FB%1234",
|
"FF01::FB%1234",
|
||||||
|
"::ffff:123.123.123.123",
|
||||||
};
|
};
|
||||||
const printed = [_][]const u8{
|
const printed = [_][]const u8{
|
||||||
"ff01::fb",
|
"ff01::fb",
|
||||||
|
@ -23,7 +24,8 @@ test "parse and render IPv6 addresses" {
|
||||||
"2001:db8::",
|
"2001:db8::",
|
||||||
"::1234:5678",
|
"::1234:5678",
|
||||||
"2001:db8::1234:5678",
|
"2001:db8::1234:5678",
|
||||||
"ff01::fb"
|
"ff01::fb",
|
||||||
|
"::ffff:7b7b:7b7b",
|
||||||
};
|
};
|
||||||
for (ips) |ip, i| {
|
for (ips) |ip, i| {
|
||||||
var addr = net.IpAddress.parseIp6(ip, 0) catch unreachable;
|
var addr = net.IpAddress.parseIp6(ip, 0) catch unreachable;
|
||||||
|
@ -36,6 +38,7 @@ test "parse and render IPv6 addresses" {
|
||||||
testing.expectError(error.InvalidCharacter, net.IpAddress.parseIp6("FF01::Fb:zig", 0));
|
testing.expectError(error.InvalidCharacter, net.IpAddress.parseIp6("FF01::Fb:zig", 0));
|
||||||
testing.expectError(error.InvalidEnd, net.IpAddress.parseIp6("FF01:0:0:0:0:0:0:FB:", 0));
|
testing.expectError(error.InvalidEnd, net.IpAddress.parseIp6("FF01:0:0:0:0:0:0:FB:", 0));
|
||||||
testing.expectError(error.Incomplete, net.IpAddress.parseIp6("FF01:", 0));
|
testing.expectError(error.Incomplete, net.IpAddress.parseIp6("FF01:", 0));
|
||||||
|
testing.expectError(error.InvalidIpv4Mapping, net.IpAddress.parseIp6("::123.123.123.123", 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
test "parse and render IPv4 addresses" {
|
test "parse and render IPv4 addresses" {
|
||||||
|
|
Loading…
Reference in New Issue