mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add bind syscall tests for ICMP and ICMPv6
Updates #5711 Updates #6021 Updates #6022 PiperOrigin-RevId: 377582446
This commit is contained in:
@@ -1572,10 +1572,13 @@ cc_binary(
|
||||
srcs = ["ping_socket.cc"],
|
||||
linkstatic = 1,
|
||||
deps = [
|
||||
":ip_socket_test_util",
|
||||
":socket_test_util",
|
||||
"//test/util:file_descriptor",
|
||||
"@com_google_absl//absl/algorithm:container",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/types:optional",
|
||||
gtest,
|
||||
"//test/util:save_util",
|
||||
"//test/util:test_main",
|
||||
"//test/util:test_util",
|
||||
],
|
||||
|
||||
@@ -140,6 +140,22 @@ SocketPairKind IPv4UDPUnboundSocketPair(int type) {
|
||||
/* dual_stack = */ false)};
|
||||
}
|
||||
|
||||
SocketKind ICMPUnboundSocket(int type) {
|
||||
std::string description =
|
||||
absl::StrCat(DescribeSocketType(type), "ICMP socket");
|
||||
return SocketKind{
|
||||
description, AF_INET, type | SOCK_DGRAM, IPPROTO_ICMP,
|
||||
UnboundSocketCreator(AF_INET, type | SOCK_DGRAM, IPPROTO_ICMP)};
|
||||
}
|
||||
|
||||
SocketKind ICMPv6UnboundSocket(int type) {
|
||||
std::string description =
|
||||
absl::StrCat(DescribeSocketType(type), "ICMPv6 socket");
|
||||
return SocketKind{
|
||||
description, AF_INET6, type | SOCK_DGRAM, IPPROTO_ICMPV6,
|
||||
UnboundSocketCreator(AF_INET6, type | SOCK_DGRAM, IPPROTO_ICMPV6)};
|
||||
}
|
||||
|
||||
SocketKind IPv4UDPUnboundSocket(int type) {
|
||||
std::string description =
|
||||
absl::StrCat(DescribeSocketType(type), "IPv4 UDP socket");
|
||||
|
||||
@@ -84,20 +84,28 @@ SocketPairKind DualStackUDPBidirectionalBindSocketPair(int type);
|
||||
// SocketPairs created with AF_INET and the given type.
|
||||
SocketPairKind IPv4UDPUnboundSocketPair(int type);
|
||||
|
||||
// ICMPUnboundSocket returns a SocketKind that represents a SimpleSocket created
|
||||
// with AF_INET, SOCK_DGRAM, IPPROTO_ICMP, and the given type.
|
||||
SocketKind ICMPUnboundSocket(int type);
|
||||
|
||||
// ICMPv6UnboundSocket returns a SocketKind that represents a SimpleSocket
|
||||
// created with AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6, and the given type.
|
||||
SocketKind ICMPv6UnboundSocket(int type);
|
||||
|
||||
// IPv4UDPUnboundSocket returns a SocketKind that represents a SimpleSocket
|
||||
// created with AF_INET, SOCK_DGRAM, and the given type.
|
||||
// created with AF_INET, SOCK_DGRAM, IPPROTO_UDP, and the given type.
|
||||
SocketKind IPv4UDPUnboundSocket(int type);
|
||||
|
||||
// IPv6UDPUnboundSocket returns a SocketKind that represents a SimpleSocket
|
||||
// created with AF_INET6, SOCK_DGRAM, and the given type.
|
||||
// created with AF_INET6, SOCK_DGRAM, IPPROTO_UDP, and the given type.
|
||||
SocketKind IPv6UDPUnboundSocket(int type);
|
||||
|
||||
// IPv4TCPUnboundSocket returns a SocketKind that represents a SimpleSocket
|
||||
// created with AF_INET, SOCK_STREAM and the given type.
|
||||
// created with AF_INET, SOCK_STREAM, IPPROTO_TCP and the given type.
|
||||
SocketKind IPv4TCPUnboundSocket(int type);
|
||||
|
||||
// IPv6TCPUnboundSocket returns a SocketKind that represents a SimpleSocket
|
||||
// created with AF_INET6, SOCK_STREAM and the given type.
|
||||
// created with AF_INET6, SOCK_STREAM, IPPROTO_TCP and the given type.
|
||||
SocketKind IPv6TCPUnboundSocket(int type);
|
||||
|
||||
// IfAddrHelper is a helper class that determines the local interfaces present
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <errno.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_icmp.h>
|
||||
@@ -19,14 +20,22 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/algorithm/container.h"
|
||||
#include "absl/strings/str_join.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "test/syscalls/linux/ip_socket_test_util.h"
|
||||
#include "test/syscalls/linux/socket_test_util.h"
|
||||
#include "test/util/file_descriptor.h"
|
||||
#include "test/util/save_util.h"
|
||||
#include "test/util/test_util.h"
|
||||
|
||||
// Note: These tests require /proc/sys/net/ipv4/ping_group_range to be
|
||||
// configured to allow the tester to create ping sockets (see icmp(7)).
|
||||
|
||||
namespace gvisor {
|
||||
namespace testing {
|
||||
namespace {
|
||||
@@ -42,7 +51,8 @@ TEST(PingSocket, ICMPPortExhaustion) {
|
||||
auto s = Socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
|
||||
if (!s.ok()) {
|
||||
ASSERT_EQ(s.error().errno_value(), EACCES);
|
||||
GTEST_SKIP();
|
||||
GTEST_SKIP() << "TODO(gvisor.dev/issue/6126): Buildkite does not allow "
|
||||
"creation of ICMP or ICMPv6 sockets";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +80,212 @@ TEST(PingSocket, ICMPPortExhaustion) {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
struct BindTestCase {
|
||||
TestAddress bind_to;
|
||||
int want = 0;
|
||||
absl::optional<int> want_gvisor;
|
||||
};
|
||||
|
||||
// Test fixture for socket binding.
|
||||
class Fixture
|
||||
: public ::testing::TestWithParam<std::tuple<SocketKind, BindTestCase>> {};
|
||||
|
||||
TEST_P(Fixture, Bind) {
|
||||
auto [socket_factory, test_case] = GetParam();
|
||||
auto socket = socket_factory.Create();
|
||||
if (!socket.ok()) {
|
||||
ASSERT_EQ(socket.error().errno_value(), EACCES);
|
||||
GTEST_SKIP() << "TODO(gvisor.dev/issue/6126): Buildkite does not allow "
|
||||
"creation of ICMP or ICMPv6 sockets";
|
||||
}
|
||||
auto socket_fd = std::move(socket).ValueOrDie();
|
||||
|
||||
const int want = test_case.want_gvisor.has_value() && IsRunningOnGvisor()
|
||||
? *test_case.want_gvisor
|
||||
: test_case.want;
|
||||
if (want == 0) {
|
||||
EXPECT_THAT(bind(socket_fd->get(), AsSockAddr(&test_case.bind_to.addr),
|
||||
test_case.bind_to.addr_len),
|
||||
SyscallSucceeds());
|
||||
} else {
|
||||
EXPECT_THAT(bind(socket_fd->get(), AsSockAddr(&test_case.bind_to.addr),
|
||||
test_case.bind_to.addr_len),
|
||||
SyscallFailsWithErrno(want));
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::tuple<SocketKind, BindTestCase>> ICMPTestCases() {
|
||||
return ApplyVec<std::tuple<SocketKind, BindTestCase>>(
|
||||
[](const BindTestCase& test_case) {
|
||||
return std::make_tuple(ICMPUnboundSocket(0), test_case);
|
||||
},
|
||||
std::vector<BindTestCase>{
|
||||
{
|
||||
.bind_to = V4Any(),
|
||||
.want = 0,
|
||||
.want_gvisor = 0,
|
||||
},
|
||||
{
|
||||
.bind_to = V4Broadcast(),
|
||||
.want = EADDRNOTAVAIL,
|
||||
// TODO(gvisor.dev/issue/5711): Remove want_gvisor once ICMP
|
||||
// sockets are no longer allowed to bind to broadcast addresses.
|
||||
.want_gvisor = 0,
|
||||
},
|
||||
{
|
||||
.bind_to = V4Loopback(),
|
||||
.want = 0,
|
||||
},
|
||||
{
|
||||
.bind_to = V4LoopbackSubnetBroadcast(),
|
||||
.want = EADDRNOTAVAIL,
|
||||
// TODO(gvisor.dev/issue/5711): Remove want_gvisor once ICMP
|
||||
// sockets are no longer allowed to bind to broadcast addresses.
|
||||
.want_gvisor = 0,
|
||||
},
|
||||
{
|
||||
.bind_to = V4Multicast(),
|
||||
.want = EADDRNOTAVAIL,
|
||||
},
|
||||
{
|
||||
.bind_to = V4MulticastAllHosts(),
|
||||
.want = EADDRNOTAVAIL,
|
||||
},
|
||||
{
|
||||
.bind_to = V4AddrStr("IPv4UnknownUnicast", "192.168.1.1"),
|
||||
.want = EADDRNOTAVAIL,
|
||||
},
|
||||
// TODO(gvisor.dev/issue/6021): Remove want_gvisor from all the test
|
||||
// cases below once ICMP sockets return EAFNOSUPPORT when binding to
|
||||
// IPv6 addresses.
|
||||
{
|
||||
.bind_to = V6Any(),
|
||||
.want = EAFNOSUPPORT,
|
||||
.want_gvisor = EINVAL,
|
||||
},
|
||||
{
|
||||
.bind_to = V6Loopback(),
|
||||
.want = EAFNOSUPPORT,
|
||||
.want_gvisor = EINVAL,
|
||||
},
|
||||
{
|
||||
.bind_to = V6Multicast(),
|
||||
.want = EAFNOSUPPORT,
|
||||
.want_gvisor = EINVAL,
|
||||
},
|
||||
{
|
||||
.bind_to = V6MulticastInterfaceLocalAllNodes(),
|
||||
.want = EAFNOSUPPORT,
|
||||
.want_gvisor = EINVAL,
|
||||
},
|
||||
{
|
||||
.bind_to = V6MulticastLinkLocalAllNodes(),
|
||||
.want = EAFNOSUPPORT,
|
||||
.want_gvisor = EINVAL,
|
||||
},
|
||||
{
|
||||
.bind_to = V6MulticastLinkLocalAllRouters(),
|
||||
.want = EAFNOSUPPORT,
|
||||
.want_gvisor = EINVAL,
|
||||
},
|
||||
{
|
||||
.bind_to = V6AddrStr("IPv6UnknownUnicast", "fc00::1"),
|
||||
.want = EAFNOSUPPORT,
|
||||
.want_gvisor = EINVAL,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
std::vector<std::tuple<SocketKind, BindTestCase>> ICMPv6TestCases() {
|
||||
return ApplyVec<std::tuple<SocketKind, BindTestCase>>(
|
||||
[](const BindTestCase& test_case) {
|
||||
return std::make_tuple(ICMPv6UnboundSocket(0), test_case);
|
||||
},
|
||||
std::vector<BindTestCase>{
|
||||
{
|
||||
.bind_to = V4Any(),
|
||||
.want = EINVAL,
|
||||
},
|
||||
{
|
||||
.bind_to = V4Broadcast(),
|
||||
.want = EINVAL,
|
||||
},
|
||||
{
|
||||
.bind_to = V4Loopback(),
|
||||
.want = EINVAL,
|
||||
},
|
||||
{
|
||||
.bind_to = V4LoopbackSubnetBroadcast(),
|
||||
.want = EINVAL,
|
||||
},
|
||||
{
|
||||
.bind_to = V4Multicast(),
|
||||
.want = EINVAL,
|
||||
},
|
||||
{
|
||||
.bind_to = V4MulticastAllHosts(),
|
||||
.want = EINVAL,
|
||||
},
|
||||
{
|
||||
.bind_to = V4AddrStr("IPv4UnknownUnicast", "192.168.1.1"),
|
||||
.want = EINVAL,
|
||||
},
|
||||
{
|
||||
.bind_to = V6Any(),
|
||||
.want = 0,
|
||||
},
|
||||
{
|
||||
.bind_to = V6Loopback(),
|
||||
.want = 0,
|
||||
},
|
||||
// TODO(gvisor.dev/issue/6021): Remove want_gvisor from all the
|
||||
// multicast test cases below once ICMPv6 sockets return EINVAL when
|
||||
// binding to IPv6 multicast addresses.
|
||||
{
|
||||
.bind_to = V6Multicast(),
|
||||
.want = EINVAL,
|
||||
.want_gvisor = EADDRNOTAVAIL,
|
||||
},
|
||||
{
|
||||
.bind_to = V6MulticastInterfaceLocalAllNodes(),
|
||||
.want = EINVAL,
|
||||
.want_gvisor = EADDRNOTAVAIL,
|
||||
},
|
||||
{
|
||||
.bind_to = V6MulticastLinkLocalAllNodes(),
|
||||
.want = EINVAL,
|
||||
.want_gvisor = EADDRNOTAVAIL,
|
||||
},
|
||||
{
|
||||
.bind_to = V6MulticastLinkLocalAllRouters(),
|
||||
.want = EINVAL,
|
||||
.want_gvisor = EADDRNOTAVAIL,
|
||||
},
|
||||
{
|
||||
.bind_to = V6AddrStr("IPv6UnknownUnicast", "fc00::1"),
|
||||
.want = EADDRNOTAVAIL,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
std::vector<std::tuple<SocketKind, BindTestCase>> AllTestCases() {
|
||||
return VecCat<std::tuple<SocketKind, BindTestCase>>(ICMPTestCases(),
|
||||
ICMPv6TestCases());
|
||||
}
|
||||
|
||||
std::string TestDescription(
|
||||
const ::testing::TestParamInfo<Fixture::ParamType>& info) {
|
||||
auto [socket_factory, test_case] = info.param;
|
||||
std::string name = absl::StrJoin(
|
||||
{socket_factory.description, test_case.bind_to.description}, "_");
|
||||
absl::c_replace_if(
|
||||
name, [](char c) { return !std::isalnum(c); }, '_');
|
||||
return name;
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(PingSockets, Fixture,
|
||||
::testing::ValuesIn(AllTestCases()), TestDescription);
|
||||
|
||||
} // namespace
|
||||
} // namespace testing
|
||||
} // namespace gvisor
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "test/syscalls/linux/socket_test_util.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <poll.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
@@ -798,84 +799,82 @@ TestAddress TestAddress::WithPort(uint16_t port) const {
|
||||
return addr;
|
||||
}
|
||||
|
||||
TestAddress V4Any() {
|
||||
TestAddress t("V4Any");
|
||||
namespace {
|
||||
|
||||
TestAddress V4Addr(std::string description, in_addr_t addr) {
|
||||
TestAddress t(std::move(description));
|
||||
t.addr.ss_family = AF_INET;
|
||||
t.addr_len = sizeof(sockaddr_in);
|
||||
reinterpret_cast<sockaddr_in*>(&t.addr)->sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
reinterpret_cast<sockaddr_in*>(&t.addr)->sin_addr.s_addr = addr;
|
||||
return t;
|
||||
}
|
||||
|
||||
TestAddress V6Addr(std::string description, const in6_addr& addr) {
|
||||
TestAddress t(std::move(description));
|
||||
t.addr.ss_family = AF_INET6;
|
||||
t.addr_len = sizeof(sockaddr_in6);
|
||||
reinterpret_cast<sockaddr_in6*>(&t.addr)->sin6_addr = addr;
|
||||
return t;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TestAddress V4AddrStr(std::string description, const char* addr) {
|
||||
in_addr_t s_addr;
|
||||
inet_pton(AF_INET, addr, &s_addr);
|
||||
return V4Addr(description, s_addr);
|
||||
}
|
||||
|
||||
TestAddress V6AddrStr(std::string description, const char* addr) {
|
||||
struct in6_addr s_addr;
|
||||
inet_pton(AF_INET6, addr, &s_addr);
|
||||
return V6Addr(description, s_addr);
|
||||
}
|
||||
|
||||
TestAddress V4Any() { return V4Addr("V4Any", htonl(INADDR_ANY)); }
|
||||
|
||||
TestAddress V4Broadcast() {
|
||||
return V4Addr("V4Broadcast", htonl(INADDR_BROADCAST));
|
||||
}
|
||||
|
||||
TestAddress V4Loopback() {
|
||||
TestAddress t("V4Loopback");
|
||||
t.addr.ss_family = AF_INET;
|
||||
t.addr_len = sizeof(sockaddr_in);
|
||||
reinterpret_cast<sockaddr_in*>(&t.addr)->sin_addr.s_addr =
|
||||
htonl(INADDR_LOOPBACK);
|
||||
return t;
|
||||
return V4Addr("V4Loopback", htonl(INADDR_LOOPBACK));
|
||||
}
|
||||
|
||||
TestAddress V4MappedAny() {
|
||||
TestAddress t("V4MappedAny");
|
||||
t.addr.ss_family = AF_INET6;
|
||||
t.addr_len = sizeof(sockaddr_in6);
|
||||
inet_pton(AF_INET6, "::ffff:0.0.0.0",
|
||||
reinterpret_cast<sockaddr_in6*>(&t.addr)->sin6_addr.s6_addr);
|
||||
return t;
|
||||
TestAddress V4LoopbackSubnetBroadcast() {
|
||||
return V4AddrStr("V4LoopbackSubnetBroadcast", "127.255.255.255");
|
||||
}
|
||||
|
||||
TestAddress V4MappedAny() { return V6AddrStr("V4MappedAny", "::ffff:0.0.0.0"); }
|
||||
|
||||
TestAddress V4MappedLoopback() {
|
||||
TestAddress t("V4MappedLoopback");
|
||||
t.addr.ss_family = AF_INET6;
|
||||
t.addr_len = sizeof(sockaddr_in6);
|
||||
inet_pton(AF_INET6, "::ffff:127.0.0.1",
|
||||
reinterpret_cast<sockaddr_in6*>(&t.addr)->sin6_addr.s6_addr);
|
||||
return t;
|
||||
return V6AddrStr("V4MappedLoopback", "::ffff:127.0.0.1");
|
||||
}
|
||||
|
||||
TestAddress V4Multicast() {
|
||||
TestAddress t("V4Multicast");
|
||||
t.addr.ss_family = AF_INET;
|
||||
t.addr_len = sizeof(sockaddr_in);
|
||||
reinterpret_cast<sockaddr_in*>(&t.addr)->sin_addr.s_addr =
|
||||
inet_addr(kMulticastAddress);
|
||||
return t;
|
||||
return V4Addr("V4Multicast", inet_addr(kMulticastAddress));
|
||||
}
|
||||
|
||||
TestAddress V4Broadcast() {
|
||||
TestAddress t("V4Broadcast");
|
||||
t.addr.ss_family = AF_INET;
|
||||
t.addr_len = sizeof(sockaddr_in);
|
||||
reinterpret_cast<sockaddr_in*>(&t.addr)->sin_addr.s_addr =
|
||||
htonl(INADDR_BROADCAST);
|
||||
return t;
|
||||
TestAddress V4MulticastAllHosts() {
|
||||
return V4Addr("V4MulticastAllHosts", htonl(INADDR_ALLHOSTS_GROUP));
|
||||
}
|
||||
|
||||
TestAddress V6Any() {
|
||||
TestAddress t("V6Any");
|
||||
t.addr.ss_family = AF_INET6;
|
||||
t.addr_len = sizeof(sockaddr_in6);
|
||||
reinterpret_cast<sockaddr_in6*>(&t.addr)->sin6_addr = in6addr_any;
|
||||
return t;
|
||||
TestAddress V6Any() { return V6Addr("V6Any", in6addr_any); }
|
||||
|
||||
TestAddress V6Loopback() { return V6Addr("V6Loopback", in6addr_loopback); }
|
||||
|
||||
TestAddress V6Multicast() { return V6AddrStr("V6Multicast", "ff05::1234"); }
|
||||
|
||||
TestAddress V6MulticastInterfaceLocalAllNodes() {
|
||||
return V6AddrStr("V6MulticastInterfaceLocalAllNodes", "ff01::1");
|
||||
}
|
||||
|
||||
TestAddress V6Loopback() {
|
||||
TestAddress t("V6Loopback");
|
||||
t.addr.ss_family = AF_INET6;
|
||||
t.addr_len = sizeof(sockaddr_in6);
|
||||
reinterpret_cast<sockaddr_in6*>(&t.addr)->sin6_addr = in6addr_loopback;
|
||||
return t;
|
||||
TestAddress V6MulticastLinkLocalAllNodes() {
|
||||
return V6AddrStr("V6MulticastLinkLocalAllNodes", "ff02::1");
|
||||
}
|
||||
|
||||
TestAddress V6Multicast() {
|
||||
TestAddress t("V6Multicast");
|
||||
t.addr.ss_family = AF_INET6;
|
||||
t.addr_len = sizeof(sockaddr_in6);
|
||||
EXPECT_EQ(
|
||||
1,
|
||||
inet_pton(AF_INET6, "ff05::1234",
|
||||
reinterpret_cast<sockaddr_in6*>(&t.addr)->sin6_addr.s6_addr));
|
||||
return t;
|
||||
TestAddress V6MulticastLinkLocalAllRouters() {
|
||||
return V6AddrStr("V6MulticastLinkLocalAllRouters", "ff02::2");
|
||||
}
|
||||
|
||||
// Checksum computes the internet checksum of a buffer.
|
||||
|
||||
@@ -499,15 +499,45 @@ struct TestAddress {
|
||||
constexpr char kMulticastAddress[] = "224.0.2.1";
|
||||
constexpr char kBroadcastAddress[] = "255.255.255.255";
|
||||
|
||||
// Returns a TestAddress with `addr` parsed as an IPv4 address described by
|
||||
// `description`.
|
||||
TestAddress V4AddrStr(std::string description, const char* addr);
|
||||
// Returns a TestAddress with `addr` parsed as an IPv6 address described by
|
||||
// `description`.
|
||||
TestAddress V6AddrStr(std::string description, const char* addr);
|
||||
|
||||
// Returns a TestAddress for the IPv4 any address.
|
||||
TestAddress V4Any();
|
||||
// Returns a TestAddress for the IPv4 limited broadcast address.
|
||||
TestAddress V4Broadcast();
|
||||
// Returns a TestAddress for the IPv4 loopback address.
|
||||
TestAddress V4Loopback();
|
||||
// Returns a TestAddress for the subnet broadcast of the IPv4 loopback address.
|
||||
TestAddress V4LoopbackSubnetBroadcast();
|
||||
// Returns a TestAddress for the IPv4-mapped IPv6 any address.
|
||||
TestAddress V4MappedAny();
|
||||
// Returns a TestAddress for the IPv4-mapped IPv6 loopback address.
|
||||
TestAddress V4MappedLoopback();
|
||||
// Returns a TestAddress for a IPv4 multicast address.
|
||||
TestAddress V4Multicast();
|
||||
// Returns a TestAddress for the IPv4 all-hosts multicast group address.
|
||||
TestAddress V4MulticastAllHosts();
|
||||
|
||||
// Returns a TestAddress for the IPv6 any address.
|
||||
TestAddress V6Any();
|
||||
// Returns a TestAddress for the IPv6 loopback address.
|
||||
TestAddress V6Loopback();
|
||||
// Returns a TestAddress for a IPv6 multicast address.
|
||||
TestAddress V6Multicast();
|
||||
// Returns a TestAddress for the IPv6 interface-local all-nodes multicast group
|
||||
// address.
|
||||
TestAddress V6MulticastInterfaceLocalAllNodes();
|
||||
// Returns a TestAddress for the IPv6 link-local all-nodes multicast group
|
||||
// address.
|
||||
TestAddress V6MulticastLinkLocalAllNodes();
|
||||
// Returns a TestAddress for the IPv6 link-local all-routers multicast group
|
||||
// address.
|
||||
TestAddress V6MulticastLinkLocalAllRouters();
|
||||
|
||||
// Compute the internet checksum of an IP header.
|
||||
uint16_t IPChecksum(struct iphdr ip);
|
||||
|
||||
Reference in New Issue
Block a user