1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2019 Alexander V. Chernikov 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * $FreeBSD$ 28 */ 29 30 #ifndef _NET_ROUTING_RTSOCK_CONFIG_H_ 31 #define _NET_ROUTING_RTSOCK_CONFIG_H_ 32 33 struct rtsock_test_config { 34 int ifindex; 35 char net4_str[INET_ADDRSTRLEN]; 36 char addr4_str[INET_ADDRSTRLEN]; 37 char net6_str[INET6_ADDRSTRLEN]; 38 char addr6_str[INET6_ADDRSTRLEN]; 39 struct sockaddr_in net4; 40 struct sockaddr_in mask4; 41 struct sockaddr_in addr4; 42 struct sockaddr_in6 net6; 43 struct sockaddr_in6 mask6; 44 struct sockaddr_in6 addr6; 45 int plen4; 46 int plen6; 47 char *remote_lladdr; 48 char *ifname; 49 bool autocreated_interface; 50 int rtsock_fd; 51 }; 52 53 struct rtsock_test_config * 54 config_setup_base(const atf_tc_t *tc) 55 { 56 struct rtsock_test_config *c; 57 58 c = calloc(1, sizeof(struct rtsock_test_config)); 59 c->rtsock_fd = -1; 60 61 return c; 62 } 63 64 struct rtsock_test_config * 65 config_setup(const atf_tc_t *tc) 66 { 67 struct rtsock_test_config *c; 68 char buf[64], *s; 69 const char *key; 70 int mask; 71 72 c = config_setup_base(tc); 73 74 key = atf_tc_get_config_var_wd(tc, "rtsock.v4prefix", "192.0.2.0/24"); 75 strlcpy(buf, key, sizeof(buf)); 76 if ((s = strchr(buf, '/')) == NULL) 77 return (NULL); 78 *s++ = '\0'; 79 mask = strtol(s, NULL, 10); 80 if (mask < 0 || mask > 32) 81 return (NULL); 82 c->plen4 = mask; 83 inet_pton(AF_INET, buf, &c->net4.sin_addr); 84 85 c->net4.sin_len = sizeof(struct sockaddr_in); 86 c->net4.sin_family = AF_INET; 87 c->addr4.sin_len = sizeof(struct sockaddr_in); 88 c->addr4.sin_family = AF_INET; 89 90 sa_fill_mask4(&c->mask4, c->plen4); 91 92 /* Fill in interface IPv4 address. Assume the first address in net */ 93 c->addr4.sin_addr.s_addr = htonl(ntohl(c->net4.sin_addr.s_addr) + 1); 94 inet_ntop(AF_INET, &c->net4.sin_addr, c->net4_str, INET_ADDRSTRLEN); 95 inet_ntop(AF_INET, &c->addr4.sin_addr, c->addr4_str, INET_ADDRSTRLEN); 96 97 key = atf_tc_get_config_var_wd(tc, "rtsock.v6prefix", "2001:DB8::/32"); 98 strlcpy(buf, key, sizeof(buf)); 99 if ((s = strchr(buf, '/')) == NULL) 100 return (NULL); 101 *s++ = '\0'; 102 mask = strtol(s, NULL, 10); 103 if (mask < 0 || mask > 128) 104 return (NULL); 105 c->plen6 = mask; 106 107 inet_pton(AF_INET6, buf, &c->net6.sin6_addr); 108 109 c->net6.sin6_len = sizeof(struct sockaddr_in6); 110 c->net6.sin6_family = AF_INET6; 111 c->addr6.sin6_len = sizeof(struct sockaddr_in6); 112 c->addr6.sin6_family = AF_INET6; 113 114 sa_fill_mask6(&c->mask6, c->plen6); 115 116 /* Fill in interface IPv6 address. Assume the first address in net */ 117 memcpy(&c->addr6.sin6_addr, &c->net6.sin6_addr, sizeof(struct in6_addr)); 118 #define _s6_addr32 __u6_addr.__u6_addr32 119 c->addr6.sin6_addr._s6_addr32[3] = htonl(ntohl(c->net6.sin6_addr._s6_addr32[3]) + 1); 120 #undef _s6_addr32 121 inet_ntop(AF_INET6, &c->net6.sin6_addr, c->net6_str, INET6_ADDRSTRLEN); 122 inet_ntop(AF_INET6, &c->addr6.sin6_addr, c->addr6_str, INET6_ADDRSTRLEN); 123 124 c->ifname = strdup(atf_tc_get_config_var_wd(tc, "rtsock.ifname", "tap4242")); 125 c->autocreated_interface = atf_tc_get_config_var_as_bool_wd(tc, "rtsock.create_interface", true); 126 127 if (c->autocreated_interface && (if_nametoindex(c->ifname) == 0)) 128 { 129 /* create our own interface */ 130 char new_ifname[IFNAMSIZ]; 131 strlcpy(new_ifname, c->ifname, sizeof(new_ifname)); 132 int ret = iface_create_cloned(new_ifname); 133 ATF_REQUIRE_MSG(ret != 0, "tap interface creation failed: %s", strerror(errno)); 134 c->ifname = strdup(new_ifname); 135 } 136 c->ifindex = if_nametoindex(c->ifname); 137 ATF_REQUIRE_MSG(c->ifindex != 0, "inteface %s not found", c->ifname); 138 139 c->remote_lladdr = strdup(atf_tc_get_config_var_wd(tc, 140 "rtsock.remote_lladdr", "00:00:5E:00:53:42")); 141 142 return (c); 143 } 144 145 void 146 config_generic_cleanup(struct rtsock_test_config *c) 147 { 148 if (c->ifname != NULL && c->autocreated_interface) { 149 iface_destroy(c->ifname); 150 free(c->ifname); 151 c->ifname = NULL; 152 } 153 } 154 155 void 156 config_describe_root_test(atf_tc_t *tc, char *test_descr) 157 { 158 159 atf_tc_set_md_var(tc, "descr", test_descr); 160 // Adding/deleting prefix requires root privileges 161 atf_tc_set_md_var(tc, "require.user", "root"); 162 } 163 164 #endif 165