1 1.10 joerg /* $NetBSD: netconfig.c,v 1.10 2020/04/23 00:31:51 joerg Exp $ */ 2 1.1 pooka 3 1.1 pooka /*- 4 1.1 pooka * Copyright (c) 2010 The NetBSD Foundation, Inc. 5 1.1 pooka * All rights reserved. 6 1.1 pooka * 7 1.1 pooka * Redistribution and use in source and binary forms, with or without 8 1.1 pooka * modification, are permitted provided that the following conditions 9 1.1 pooka * are met: 10 1.1 pooka * 1. Redistributions of source code must retain the above copyright 11 1.1 pooka * notice, this list of conditions and the following disclaimer. 12 1.1 pooka * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 pooka * notice, this list of conditions and the following disclaimer in the 14 1.1 pooka * documentation and/or other materials provided with the distribution. 15 1.1 pooka * 16 1.1 pooka * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 17 1.1 pooka * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 18 1.1 pooka * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 1.1 pooka * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 1.1 pooka * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 21 1.1 pooka * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 1.1 pooka * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23 1.1 pooka * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 1.1 pooka * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 1.1 pooka * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26 1.1 pooka * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 1.1 pooka * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 1.1 pooka */ 29 1.1 pooka 30 1.1 pooka #include <sys/cdefs.h> 31 1.1 pooka #ifndef lint 32 1.10 joerg __RCSID("$NetBSD: netconfig.c,v 1.10 2020/04/23 00:31:51 joerg Exp $"); 33 1.1 pooka #endif /* not lint */ 34 1.1 pooka 35 1.1 pooka #include <sys/types.h> 36 1.1 pooka #include <sys/socket.h> 37 1.1 pooka #include <sys/ioctl.h> 38 1.1 pooka 39 1.2 pooka #include <arpa/inet.h> 40 1.2 pooka 41 1.1 pooka #include <net/route.h> 42 1.4 pooka 43 1.2 pooka #include <netinet/in.h> 44 1.4 pooka #include <netinet/in_systm.h> 45 1.4 pooka #include <netinet/ip.h> 46 1.4 pooka #include <netinet/ip_icmp.h> 47 1.1 pooka 48 1.1 pooka #include <atf-c.h> 49 1.7 pooka #include <err.h> 50 1.1 pooka #include <errno.h> 51 1.1 pooka #include <string.h> 52 1.1 pooka 53 1.1 pooka #include <rump/rump.h> 54 1.1 pooka #include <rump/rump_syscalls.h> 55 1.1 pooka 56 1.9 christos #include "h_macros.h" 57 1.1 pooka 58 1.7 pooka 59 1.6 pooka static void __unused 60 1.1 pooka netcfg_rump_makeshmif(const char *busname, char *ifname) 61 1.1 pooka { 62 1.1 pooka int rv, ifnum; 63 1.1 pooka 64 1.1 pooka if ((rv = rump_pub_shmif_create(busname, &ifnum)) != 0) { 65 1.10 joerg #ifdef RUMPNFSD_NOATF 66 1.10 joerg err(1, "makeshmif: rump_pub_shmif_create %d", rv); 67 1.10 joerg #else 68 1.10 joerg atf_tc_fail("makeshmif: rump_pub_shmif_create %d", rv); 69 1.10 joerg #endif 70 1.1 pooka } 71 1.1 pooka sprintf(ifname, "shmif%d", ifnum); 72 1.1 pooka } 73 1.1 pooka 74 1.6 pooka static void __unused 75 1.3 pooka netcfg_rump_if(const char *ifname, const char *addr, const char *mask) 76 1.1 pooka { 77 1.1 pooka struct ifaliasreq ia; 78 1.1 pooka struct sockaddr_in *sin; 79 1.3 pooka in_addr_t inaddr, inmask; 80 1.1 pooka int s, rv; 81 1.1 pooka 82 1.1 pooka s = -1; 83 1.1 pooka if ((s = rump_sys_socket(PF_INET, SOCK_DGRAM, 0)) < 0) { 84 1.10 joerg #ifdef RUMPNFSD_NOATF 85 1.10 joerg err(1, "if config socket"); 86 1.10 joerg #else 87 1.10 joerg atf_tc_fail_errno("if config socket"); 88 1.10 joerg #endif 89 1.1 pooka } 90 1.1 pooka 91 1.3 pooka inaddr = inet_addr(addr); 92 1.3 pooka inmask = inet_addr(mask); 93 1.3 pooka 94 1.1 pooka /* Address */ 95 1.1 pooka memset(&ia, 0, sizeof(ia)); 96 1.1 pooka strcpy(ia.ifra_name, ifname); 97 1.1 pooka sin = (struct sockaddr_in *)&ia.ifra_addr; 98 1.1 pooka sin->sin_family = AF_INET; 99 1.1 pooka sin->sin_len = sizeof(struct sockaddr_in); 100 1.3 pooka sin->sin_addr.s_addr = inaddr; 101 1.1 pooka 102 1.1 pooka /* Netmask */ 103 1.1 pooka sin = (struct sockaddr_in *)&ia.ifra_mask; 104 1.1 pooka sin->sin_family = AF_INET; 105 1.1 pooka sin->sin_len = sizeof(struct sockaddr_in); 106 1.3 pooka sin->sin_addr.s_addr = inmask; 107 1.1 pooka 108 1.1 pooka /* Broadcast address */ 109 1.1 pooka sin = (struct sockaddr_in *)&ia.ifra_broadaddr; 110 1.1 pooka sin->sin_family = AF_INET; 111 1.1 pooka sin->sin_len = sizeof(struct sockaddr_in); 112 1.3 pooka sin->sin_addr.s_addr = inaddr | ~inmask; 113 1.1 pooka 114 1.1 pooka rv = rump_sys_ioctl(s, SIOCAIFADDR, &ia); 115 1.7 pooka if (rv == -1) { 116 1.10 joerg #ifdef RUMPNFSD_NOATF 117 1.10 joerg err(1, "SIOCAIFADDR"); 118 1.10 joerg #else 119 1.10 joerg atf_tc_fail_errno("SIOCAIFADDR"); 120 1.10 joerg #endif 121 1.1 pooka } 122 1.1 pooka rump_sys_close(s); 123 1.1 pooka } 124 1.1 pooka 125 1.1 pooka static void __unused 126 1.1 pooka netcfg_rump_route(const char *dst, const char *mask, const char *gw) 127 1.1 pooka { 128 1.1 pooka size_t len; 129 1.1 pooka struct { 130 1.1 pooka struct rt_msghdr m_rtm; 131 1.1 pooka uint8_t m_space[512]; 132 1.1 pooka } m_rtmsg; 133 1.1 pooka #define rtm m_rtmsg.m_rtm 134 1.1 pooka uint8_t *bp = m_rtmsg.m_space; 135 1.1 pooka struct sockaddr_in sinstore; 136 1.1 pooka int s, rv; 137 1.1 pooka 138 1.1 pooka s = rump_sys_socket(PF_ROUTE, SOCK_RAW, 0); 139 1.1 pooka if (s == -1) { 140 1.10 joerg #ifdef RUMPNFSD_NOATF 141 1.10 joerg err(1, "routing socket"); 142 1.10 joerg #else 143 1.10 joerg atf_tc_fail_errno("routing socket"); 144 1.10 joerg #endif 145 1.1 pooka } 146 1.1 pooka 147 1.1 pooka memset(&m_rtmsg, 0, sizeof(m_rtmsg)); 148 1.1 pooka rtm.rtm_type = RTM_ADD; 149 1.1 pooka rtm.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC; 150 1.1 pooka rtm.rtm_version = RTM_VERSION; 151 1.1 pooka rtm.rtm_seq = 2; 152 1.1 pooka rtm.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; 153 1.1 pooka 154 1.1 pooka /* dst */ 155 1.1 pooka memset(&sinstore, 0, sizeof(sinstore)); 156 1.1 pooka sinstore.sin_family = AF_INET; 157 1.1 pooka sinstore.sin_len = sizeof(sinstore); 158 1.1 pooka sinstore.sin_addr.s_addr = inet_addr(dst); 159 1.1 pooka memcpy(bp, &sinstore, sizeof(sinstore)); 160 1.1 pooka bp += sizeof(sinstore); 161 1.1 pooka 162 1.1 pooka /* gw */ 163 1.1 pooka memset(&sinstore, 0, sizeof(sinstore)); 164 1.1 pooka sinstore.sin_family = AF_INET; 165 1.1 pooka sinstore.sin_len = sizeof(sinstore); 166 1.1 pooka sinstore.sin_addr.s_addr = inet_addr(gw); 167 1.1 pooka memcpy(bp, &sinstore, sizeof(sinstore)); 168 1.1 pooka bp += sizeof(sinstore); 169 1.1 pooka 170 1.1 pooka /* netmask */ 171 1.1 pooka memset(&sinstore, 0, sizeof(sinstore)); 172 1.1 pooka sinstore.sin_family = AF_INET; 173 1.1 pooka sinstore.sin_len = sizeof(sinstore); 174 1.1 pooka sinstore.sin_addr.s_addr = inet_addr(mask); 175 1.1 pooka memcpy(bp, &sinstore, sizeof(sinstore)); 176 1.1 pooka bp += sizeof(sinstore); 177 1.1 pooka 178 1.1 pooka len = bp - (uint8_t *)&m_rtmsg; 179 1.1 pooka rtm.rtm_msglen = len; 180 1.1 pooka 181 1.1 pooka rv = rump_sys_write(s, &m_rtmsg, len); 182 1.1 pooka if (rv != (int)len) { 183 1.10 joerg #ifdef RUMPNFSD_NOATF 184 1.10 joerg err(1, "write routing message"); 185 1.10 joerg #else 186 1.10 joerg atf_tc_fail_errno("write routing message"); 187 1.10 joerg #endif 188 1.1 pooka } 189 1.1 pooka rump_sys_close(s); 190 1.1 pooka } 191 1.4 pooka 192 1.5 pooka static bool __unused 193 1.4 pooka netcfg_rump_pingtest(const char *dst, int ms_timo) 194 1.4 pooka { 195 1.4 pooka struct timeval tv; 196 1.4 pooka struct sockaddr_in sin; 197 1.4 pooka struct icmp icmp; 198 1.4 pooka socklen_t slen; 199 1.4 pooka int s; 200 1.6 pooka bool rv = false; 201 1.4 pooka 202 1.4 pooka s = rump_sys_socket(PF_INET, SOCK_RAW, IPPROTO_ICMP); 203 1.4 pooka if (s == -1) 204 1.4 pooka return false; 205 1.4 pooka tv.tv_sec = ms_timo / 1000; 206 1.4 pooka tv.tv_usec = 1000 * (ms_timo % 1000); 207 1.4 pooka if (rump_sys_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, 208 1.4 pooka &tv, sizeof(tv)) == -1) 209 1.6 pooka goto out; 210 1.4 pooka 211 1.4 pooka memset(&sin, 0, sizeof(sin)); 212 1.4 pooka sin.sin_len = sizeof(sin); 213 1.4 pooka sin.sin_family = AF_INET; 214 1.4 pooka sin.sin_addr.s_addr = inet_addr(dst); 215 1.4 pooka 216 1.4 pooka memset(&icmp, 0, sizeof(icmp)); 217 1.4 pooka icmp.icmp_type = ICMP_ECHO; 218 1.4 pooka icmp.icmp_id = htons(37); 219 1.4 pooka icmp.icmp_cksum = htons(0xf7da); /* precalc */ 220 1.4 pooka 221 1.4 pooka slen = sizeof(sin); 222 1.4 pooka if (rump_sys_sendto(s, &icmp, sizeof(icmp), 0, 223 1.6 pooka (struct sockaddr *)&sin, slen) == -1) { 224 1.6 pooka goto out; 225 1.6 pooka } 226 1.4 pooka 227 1.4 pooka if (rump_sys_recvfrom(s, &icmp, sizeof(icmp), 0, 228 1.4 pooka (struct sockaddr *)&sin, &slen) == -1) 229 1.6 pooka goto out; 230 1.4 pooka 231 1.6 pooka rv = true; 232 1.6 pooka out: 233 1.6 pooka rump_sys_close(s); 234 1.6 pooka return rv; 235 1.4 pooka } 236