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