mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-22 19:51:04 +01:00
b3e7694832
Remove /^\s*\*\n \*\s+\$FreeBSD\$$\n/
417 lines
13 KiB
C
417 lines
13 KiB
C
/*-
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*
|
|
* Copyright (c) 2019 Alexander V. Chernikov
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*/
|
|
|
|
#include "rtsock_common.h"
|
|
#include "rtsock_config.h"
|
|
|
|
static void
|
|
jump_vnet(struct rtsock_test_config *c, const atf_tc_t *tc)
|
|
{
|
|
char vnet_name[512];
|
|
|
|
snprintf(vnet_name, sizeof(vnet_name), "vt-%s", atf_tc_get_ident(tc));
|
|
RLOG("jumping to %s", vnet_name);
|
|
|
|
vnet_switch_one(vnet_name, c->ifname);
|
|
|
|
/* Update ifindex cache */
|
|
c->ifindex = if_nametoindex(c->ifname);
|
|
}
|
|
|
|
static inline struct rtsock_test_config *
|
|
presetup_ipv6(const atf_tc_t *tc)
|
|
{
|
|
struct rtsock_test_config *c;
|
|
int ret;
|
|
|
|
c = config_setup(tc, NULL);
|
|
|
|
jump_vnet(c, tc);
|
|
|
|
ret = iface_turn_up(c->ifname);
|
|
ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifname);
|
|
ret = iface_enable_ipv6(c->ifname);
|
|
ATF_REQUIRE_MSG(ret == 0, "Unable to enable IPv6 on %s", c->ifname);
|
|
|
|
c->rtsock_fd = rtsock_setup_socket();
|
|
|
|
return (c);
|
|
}
|
|
|
|
static inline struct rtsock_test_config *
|
|
presetup_ipv4(const atf_tc_t *tc)
|
|
{
|
|
struct rtsock_test_config *c;
|
|
int ret;
|
|
|
|
c = config_setup(tc, NULL);
|
|
|
|
jump_vnet(c, tc);
|
|
|
|
/* assumes ifconfig doing IFF_UP */
|
|
ret = iface_setup_addr(c->ifname, c->addr4_str, c->plen4);
|
|
ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
|
|
|
|
c->rtsock_fd = rtsock_setup_socket();
|
|
|
|
return (c);
|
|
}
|
|
|
|
static void
|
|
prepare_route_message(struct rt_msghdr *rtm, int cmd, struct sockaddr *dst,
|
|
struct sockaddr *gw)
|
|
{
|
|
|
|
rtsock_prepare_route_message(rtm, cmd, dst, NULL, gw);
|
|
|
|
rtm->rtm_flags |= (RTF_HOST | RTF_STATIC | RTF_LLDATA);
|
|
}
|
|
|
|
/* TESTS */
|
|
#define DECLARE_TEST_VARS \
|
|
char buffer[2048], msg[512]; \
|
|
ssize_t len; \
|
|
int ret; \
|
|
struct rtsock_test_config *c; \
|
|
struct rt_msghdr *rtm = (struct rt_msghdr *)buffer; \
|
|
struct sockaddr *sa; \
|
|
\
|
|
|
|
#define DECLARE_CLEANUP_VARS \
|
|
struct rtsock_test_config *c = config_setup(tc); \
|
|
\
|
|
|
|
#define DESCRIBE_ROOT_TEST(_msg) config_describe_root_test(tc, _msg)
|
|
#define CLEANUP_AFTER_TEST config_generic_cleanup(tc)
|
|
|
|
#define RTM_DECLARE_ROOT_TEST(_name, _descr) \
|
|
ATF_TC_WITH_CLEANUP(_name); \
|
|
ATF_TC_HEAD(_name, tc) \
|
|
{ \
|
|
DESCRIBE_ROOT_TEST(_descr); \
|
|
} \
|
|
ATF_TC_CLEANUP(_name, tc) \
|
|
{ \
|
|
CLEANUP_AFTER_TEST; \
|
|
}
|
|
|
|
RTM_DECLARE_ROOT_TEST(rtm_add_v6_ll_lle_success, "Tests addition of link-local IPv6 ND entry");
|
|
ATF_TC_BODY(rtm_add_v6_ll_lle_success, tc)
|
|
{
|
|
DECLARE_TEST_VARS;
|
|
|
|
c = presetup_ipv6(tc);
|
|
|
|
char str_buf[128];
|
|
struct sockaddr_in6 sin6;
|
|
/* Interface here is optional. XXX: verify kernel side. */
|
|
char *v6addr = "fe80::4242:4242";
|
|
snprintf(str_buf, sizeof(str_buf), "%s%%%s", v6addr, c->ifname);
|
|
sa_convert_str_to_sa(str_buf, (struct sockaddr *)&sin6);
|
|
|
|
struct sockaddr_dl ether;
|
|
snprintf(str_buf, sizeof(str_buf), "%s%%%s", c->remote_lladdr, c->ifname);
|
|
sa_convert_str_to_sa(str_buf, (struct sockaddr *)ðer);
|
|
|
|
prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&sin6, (struct sockaddr *)ðer);
|
|
rtsock_send_rtm(c->rtsock_fd, rtm);
|
|
|
|
/*
|
|
* Got message of size 240 on 2019-12-17 15:06:51
|
|
* RTM_ADD: Add Route: len 240, pid: 0, seq 0, errno 0, flags: <UP,HOST,DONE,LLINFO>
|
|
* sockaddrs: 0x3 <DST,GATEWAY>
|
|
* af=inet6 len=28 addr=fe80::4242:4242 scope_id=3 if_name=tap4242
|
|
* af=link len=54 sdl_index=3 if_name=tap4242 addr=52:54:00:14:E3:10
|
|
*/
|
|
|
|
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
|
|
|
|
sa = rtsock_find_rtm_sa(rtm, RTA_DST);
|
|
ret = sa_equal_msg(sa, (struct sockaddr *)&sin6, msg, sizeof(msg));
|
|
RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "DST sa diff: %s", msg);
|
|
|
|
sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY);
|
|
int sa_flags = SA_F_IGNORE_IFNAME | SA_F_IGNORE_IFTYPE | SA_F_IGNORE_MEMCMP;
|
|
ret = sa_equal_msg_flags(sa, (struct sockaddr *)ðer, msg, sizeof(msg), sa_flags);
|
|
RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "GATEWAY sa diff: %s", msg);
|
|
|
|
#if 0
|
|
/* Disable the check until https://reviews.freebsd.org/D22003 merge */
|
|
/* Some additional checks to verify kernel has filled in interface data */
|
|
struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
|
|
RTSOCK_ATF_REQUIRE_MSG(rtm, sdl->sdl_type > 0, "sdl_type not set");
|
|
#endif
|
|
}
|
|
|
|
RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_lle_success, "Tests addition of global IPv6 ND entry");
|
|
ATF_TC_BODY(rtm_add_v6_gu_lle_success, tc)
|
|
{
|
|
DECLARE_TEST_VARS;
|
|
|
|
c = presetup_ipv6(tc);
|
|
|
|
char str_buf[128];
|
|
|
|
struct sockaddr_in6 sin6;
|
|
sin6 = c->net6;
|
|
#define _s6_addr32 __u6_addr.__u6_addr32
|
|
sin6.sin6_addr._s6_addr32[3] = htonl(0x42424242);
|
|
#undef _s6_addr32
|
|
|
|
struct sockaddr_dl ether;
|
|
snprintf(str_buf, sizeof(str_buf), "%s%%%s", c->remote_lladdr, c->ifname);
|
|
sa_convert_str_to_sa(str_buf, (struct sockaddr *)ðer);
|
|
|
|
prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&sin6, (struct sockaddr *)ðer);
|
|
|
|
rtsock_send_rtm(c->rtsock_fd, rtm);
|
|
|
|
/*
|
|
* Got message of size 240 on 2019-12-17 14:56:43
|
|
* RTM_ADD: Add Route: len 240, pid: 0, seq 0, errno 0, flags: <UP,HOST,DONE,LLINFO>
|
|
* sockaddrs: 0x3 <DST,GATEWAY>
|
|
* af=inet6 len=28 addr=2001:db8::4242:4242
|
|
* af=link len=54 sdl_index=3 if_name=tap4242 addr=52:54:00:14:E3:10
|
|
*/
|
|
|
|
/* XXX: where is uRPF?! this should fail */
|
|
|
|
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
|
|
|
|
sa = rtsock_find_rtm_sa(rtm, RTA_DST);
|
|
ret = sa_equal_msg(sa, (struct sockaddr *)&sin6, msg, sizeof(msg));
|
|
RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "DST sa diff: %s", msg);
|
|
|
|
sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY);
|
|
int sa_flags = SA_F_IGNORE_IFNAME | SA_F_IGNORE_IFTYPE | SA_F_IGNORE_MEMCMP;
|
|
ret = sa_equal_msg_flags(sa, (struct sockaddr *)ðer, msg, sizeof(msg), sa_flags);
|
|
RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "GATEWAY sa diff: %s", msg);
|
|
|
|
#if 0
|
|
/* Disable the check until https://reviews.freebsd.org/D22003 merge */
|
|
/* Some additional checks to verify kernel has filled in interface data */
|
|
struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
|
|
RTSOCK_ATF_REQUIRE_MSG(rtm, sdl->sdl_type > 0, "sdl_type not set");
|
|
#endif
|
|
}
|
|
|
|
RTM_DECLARE_ROOT_TEST(rtm_add_v4_gu_lle_success, "Tests addition of IPv4 ARP entry");
|
|
ATF_TC_BODY(rtm_add_v4_gu_lle_success, tc)
|
|
{
|
|
DECLARE_TEST_VARS;
|
|
|
|
c = presetup_ipv4(tc);
|
|
|
|
char str_buf[128];
|
|
|
|
struct sockaddr_in sin;
|
|
sin = c->addr4;
|
|
/* Use the next IPv4 address after self */
|
|
sin.sin_addr.s_addr = htonl(ntohl(sin.sin_addr.s_addr) + 1);
|
|
|
|
struct sockaddr_dl ether;
|
|
snprintf(str_buf, sizeof(str_buf), "%s%%%s", c->remote_lladdr, c->ifname);
|
|
sa_convert_str_to_sa(str_buf, (struct sockaddr *)ðer);
|
|
|
|
prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&sin, (struct sockaddr *)ðer);
|
|
|
|
len = rtsock_send_rtm(c->rtsock_fd, rtm);
|
|
|
|
/*
|
|
* RTM_ADD: Add Route: len 224, pid: 43131, seq 42, errno 0, flags: <HOST,DONE,LLINFO,STATIC>
|
|
* sockaddrs: 0x3 <DST,GATEWAY>
|
|
* af=inet len=16 addr=192.0.2.2
|
|
* af=link len=54 sdl_index=3 if_name=tap4242 addr=52:54:00:14:E3:10
|
|
*/
|
|
|
|
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
|
|
|
|
sa = rtsock_find_rtm_sa(rtm, RTA_DST);
|
|
ret = sa_equal_msg(sa, (struct sockaddr *)&sin, msg, sizeof(msg));
|
|
RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "DST sa diff: %s", msg);
|
|
|
|
sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY);
|
|
int sa_flags = SA_F_IGNORE_IFNAME | SA_F_IGNORE_IFTYPE | SA_F_IGNORE_MEMCMP;
|
|
ret = sa_equal_msg_flags(sa, (struct sockaddr *)ðer, msg, sizeof(msg), sa_flags);
|
|
RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "GATEWAY sa diff: %s", msg);
|
|
|
|
/*
|
|
* TODO: Currently kernel code does not set sdl_type, contrary to IPv6.
|
|
*/
|
|
}
|
|
|
|
RTM_DECLARE_ROOT_TEST(rtm_del_v6_ll_lle_success, "Tests removal of link-local IPv6 ND entry");
|
|
ATF_TC_BODY(rtm_del_v6_ll_lle_success, tc)
|
|
{
|
|
DECLARE_TEST_VARS;
|
|
|
|
c = presetup_ipv6(tc);
|
|
|
|
char str_buf[128];
|
|
|
|
struct sockaddr_in6 sin6;
|
|
/* Interface here is optional. XXX: verify kernel side. */
|
|
char *v6addr = "fe80::4242:4242";
|
|
snprintf(str_buf, sizeof(str_buf), "%s%%%s", v6addr, c->ifname);
|
|
sa_convert_str_to_sa(str_buf, (struct sockaddr *)&sin6);
|
|
|
|
struct sockaddr_dl ether;
|
|
snprintf(str_buf, sizeof(str_buf), "%s%%%s", c->remote_lladdr, c->ifname);
|
|
sa_convert_str_to_sa(str_buf, (struct sockaddr *)ðer);
|
|
|
|
prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&sin6, (struct sockaddr *)ðer);
|
|
|
|
rtsock_send_rtm(c->rtsock_fd, rtm);
|
|
|
|
/* Successfully added an entry, let's try to remove it. */
|
|
prepare_route_message(rtm, RTM_DELETE, (struct sockaddr *)&sin6, (struct sockaddr *)ðer);
|
|
|
|
rtsock_send_rtm(c->rtsock_fd, rtm);
|
|
|
|
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
|
|
|
|
RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_type == RTM_DELETE, "rtm_type is not delete");
|
|
|
|
sa = rtsock_find_rtm_sa(rtm, RTA_DST);
|
|
ret = sa_equal_msg(sa, (struct sockaddr *)&sin6, msg, sizeof(msg));
|
|
RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "DST sa diff: %s", msg);
|
|
|
|
sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY);
|
|
int sa_flags = SA_F_IGNORE_IFNAME | SA_F_IGNORE_IFTYPE | SA_F_IGNORE_MEMCMP;
|
|
ret = sa_equal_msg_flags(sa, (struct sockaddr *)ðer, msg, sizeof(msg), sa_flags);
|
|
RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "GATEWAY sa diff: %s", msg);
|
|
|
|
/*
|
|
* TODO: Currently kernel code does not set sdl_type on delete.
|
|
*/
|
|
}
|
|
|
|
RTM_DECLARE_ROOT_TEST(rtm_del_v6_gu_lle_success, "Tests removal of global IPv6 ND entry");
|
|
ATF_TC_BODY(rtm_del_v6_gu_lle_success, tc)
|
|
{
|
|
DECLARE_TEST_VARS;
|
|
|
|
c = presetup_ipv6(tc);
|
|
|
|
char str_buf[128];
|
|
|
|
struct sockaddr_in6 sin6;
|
|
sin6 = c->net6;
|
|
#define _s6_addr32 __u6_addr.__u6_addr32
|
|
sin6.sin6_addr._s6_addr32[3] = htonl(0x42424242);
|
|
#undef _s6_addr32
|
|
|
|
struct sockaddr_dl ether;
|
|
snprintf(str_buf, sizeof(str_buf), "%s%%%s", c->remote_lladdr, c->ifname);
|
|
sa_convert_str_to_sa(str_buf, (struct sockaddr *)ðer);
|
|
|
|
prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&sin6, (struct sockaddr *)ðer);
|
|
|
|
len = rtsock_send_rtm(c->rtsock_fd, rtm);
|
|
|
|
/* Successfully added an entry, let's try to remove it. */
|
|
prepare_route_message(rtm, RTM_DELETE, (struct sockaddr *)&sin6, (struct sockaddr *)ðer);
|
|
|
|
rtsock_send_rtm(c->rtsock_fd, rtm);
|
|
|
|
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
|
|
|
|
RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_type == RTM_DELETE, "rtm_type is not delete");
|
|
|
|
sa = rtsock_find_rtm_sa(rtm, RTA_DST);
|
|
ret = sa_equal_msg(sa, (struct sockaddr *)&sin6, msg, sizeof(msg));
|
|
RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "DST sa diff: %s", msg);
|
|
|
|
sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY);
|
|
int sa_flags = SA_F_IGNORE_IFNAME | SA_F_IGNORE_IFTYPE | SA_F_IGNORE_MEMCMP;
|
|
ret = sa_equal_msg_flags(sa, (struct sockaddr *)ðer, msg, sizeof(msg), sa_flags);
|
|
RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "GATEWAY sa diff: %s", msg);
|
|
|
|
/*
|
|
* TODO: Currently kernel code does not set sdl_type on delete.
|
|
*/
|
|
}
|
|
|
|
RTM_DECLARE_ROOT_TEST(rtm_del_v4_gu_lle_success, "Tests removal of IPv4 ARP entry");
|
|
ATF_TC_BODY(rtm_del_v4_gu_lle_success, tc)
|
|
{
|
|
DECLARE_TEST_VARS;
|
|
|
|
c = presetup_ipv4(tc);
|
|
|
|
char str_buf[128];
|
|
|
|
struct sockaddr_in sin;
|
|
sin = c->addr4;
|
|
/* Use the next IPv4 address after self */
|
|
sin.sin_addr.s_addr = htonl(ntohl(sin.sin_addr.s_addr) + 1);
|
|
|
|
struct sockaddr_dl ether;
|
|
snprintf(str_buf, sizeof(str_buf), "%s%%%s", c->remote_lladdr, c->ifname);
|
|
sa_convert_str_to_sa(str_buf, (struct sockaddr *)ðer);
|
|
|
|
prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&sin, (struct sockaddr *)ðer);
|
|
|
|
rtsock_send_rtm(c->rtsock_fd, rtm);
|
|
|
|
/* We successfully added an entry, let's try to remove it. */
|
|
prepare_route_message(rtm, RTM_DELETE, (struct sockaddr *)&sin, (struct sockaddr *)ðer);
|
|
|
|
rtsock_send_rtm(c->rtsock_fd, rtm);
|
|
|
|
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
|
|
|
|
RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_type == RTM_DELETE, "rtm_type is not delete");
|
|
|
|
sa = rtsock_find_rtm_sa(rtm, RTA_DST);
|
|
ret = sa_equal_msg(sa, (struct sockaddr *)&sin, msg, sizeof(msg));
|
|
RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "DST sa diff: %s", msg);
|
|
|
|
sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY);
|
|
int sa_flags = SA_F_IGNORE_IFNAME | SA_F_IGNORE_IFTYPE | SA_F_IGNORE_MEMCMP;
|
|
ret = sa_equal_msg_flags(sa, (struct sockaddr *)ðer, msg, sizeof(msg), sa_flags);
|
|
RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "GATEWAY sa diff: %s", msg);
|
|
|
|
/*
|
|
* TODO: Currently kernel code does not set sdl_type, contrary to IPv6.
|
|
*/
|
|
}
|
|
|
|
ATF_TP_ADD_TCS(tp)
|
|
{
|
|
ATF_TP_ADD_TC(tp, rtm_add_v6_ll_lle_success);
|
|
ATF_TP_ADD_TC(tp, rtm_add_v6_gu_lle_success);
|
|
ATF_TP_ADD_TC(tp, rtm_add_v4_gu_lle_success);
|
|
ATF_TP_ADD_TC(tp, rtm_del_v6_ll_lle_success);
|
|
ATF_TP_ADD_TC(tp, rtm_del_v6_gu_lle_success);
|
|
ATF_TP_ADD_TC(tp, rtm_del_v4_gu_lle_success);
|
|
|
|
return (atf_no_error());
|
|
}
|
|
|
|
|