1 /* $NetBSD: rumptest_net.c,v 1.11 2009/10/14 19:14:39 pooka Exp $ */
4 * Copyright (c) 2008 Antti Kantee. All Rights Reserved.
6 * Development of this software was supported by then
7 * Finnish Cultural Foundation.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 #include <sys/types.h>
33 #include <sys/sockio.h>
35 #include <arpa/inet.h>
37 #include <net/route.h>
38 #include <netinet/in.h>
40 #include <rump/rump.h>
41 #include <rump/rump_syscalls.h>
48 #define DEST_ADDR "204.152.190.12" /* www.NetBSD.org */
49 #define DEST_PORT 80 /* take a wild guess */
51 #ifdef FULL_NETWORK_STACK
53 * If we are running with the full networking stack, configure
54 * virtual interface. For this to currently work, you *must* have
55 * tap0 bridged with your main networking interface. Essentially
56 * the following steps are required:
58 * # ifconfig tap0 create
60 * # ifconfig bridge0 create
61 * # brconfig bridge0 add tap0 add yourrealif0
62 * # brconfig bridge0 up
64 * The usability is likely to be improved later.
66 #define MYADDR "10.181.181.11"
67 #define MYBCAST "10.181.181.255"
68 #define MYMASK "255.255.255.0"
69 #define MYGW "10.181.181.1"
70 #define IFNAME "virt0" /* XXX: hardcoded */
73 configure_interface(void)
75 struct sockaddr_in
*sin
;
76 struct sockaddr_in sinstore
;
80 struct rt_msghdr m_rtm
;
83 #define rtm m_rtmsg.m_rtm
84 uint8_t *bp
= &m_rtmsg
.m_space
;
87 if ((rv
= rump_pub_virtif_create(0)) != 0) {
88 printf("could not configure interface %d\n", rv
);
92 /* get a socket for configuring the interface */
93 s
= rump_sys_socket(PF_INET
, SOCK_DGRAM
, 0);
95 err(1, "configuration socket");
97 /* fill out struct ifaliasreq */
98 memset(&ia
, 0, sizeof(ia
));
99 strcpy(ia
.ifra_name
, IFNAME
);
100 sin
= (struct sockaddr_in
*)&ia
.ifra_addr
;
101 sin
->sin_family
= AF_INET
;
102 sin
->sin_len
= sizeof(struct sockaddr_in
);
103 sin
->sin_addr
.s_addr
= inet_addr(MYADDR
);
105 sin
= (struct sockaddr_in
*)&ia
.ifra_broadaddr
;
106 sin
->sin_family
= AF_INET
;
107 sin
->sin_len
= sizeof(struct sockaddr_in
);
108 sin
->sin_addr
.s_addr
= inet_addr(MYBCAST
);
110 sin
= (struct sockaddr_in
*)&ia
.ifra_mask
;
111 sin
->sin_family
= AF_INET
;
112 sin
->sin_len
= sizeof(struct sockaddr_in
);
113 sin
->sin_addr
.s_addr
= inet_addr(MYMASK
);
115 /* toss to the configuration socket and see what it thinks */
116 rv
= rump_sys_ioctl(s
, SIOCAIFADDR
, &ia
);
118 err(1, "SIOCAIFADDR");
121 /* open routing socket and configure our default router */
122 s
= rump_sys_socket(PF_ROUTE
, SOCK_RAW
, 0);
124 err(1, "routing socket");
126 /* create routing message */
127 memset(&m_rtmsg
, 0, sizeof(m_rtmsg
));
128 rtm
.rtm_type
= RTM_ADD
;
129 rtm
.rtm_flags
= RTF_UP
| RTF_GATEWAY
| RTF_STATIC
;
130 rtm
.rtm_version
= RTM_VERSION
;
132 rtm
.rtm_addrs
= RTA_DST
| RTA_GATEWAY
| RTA_NETMASK
;
135 memset(&sinstore
, 0, sizeof(sinstore
));
136 sinstore
.sin_family
= AF_INET
;
137 sinstore
.sin_len
= sizeof(sinstore
);
138 memcpy(bp
, &sinstore
, sizeof(sinstore
));
139 bp
+= sizeof(sinstore
);
142 memset(&sinstore
, 0, sizeof(sinstore
));
143 sinstore
.sin_family
= AF_INET
;
144 sinstore
.sin_len
= sizeof(sinstore
);
145 sinstore
.sin_addr
.s_addr
= inet_addr(MYGW
);
146 memcpy(bp
, &sinstore
, sizeof(sinstore
));
147 bp
+= sizeof(sinstore
);
150 memset(&sinstore
, 0, sizeof(sinstore
));
151 sinstore
.sin_family
= AF_INET
;
152 sinstore
.sin_len
= sizeof(sinstore
);
153 memcpy(bp
, &sinstore
, sizeof(sinstore
));
154 bp
+= sizeof(sinstore
);
156 len
= bp
- (uint8_t *)&m_rtmsg
;
157 rtm
.rtm_msglen
= len
;
159 /* stuff that to the routing socket and wait for happy days */
160 if (rump_sys_write(s
, &m_rtmsg
, len
) != len
)
161 err(1, "routing incomplete");
164 #endif /* FULL_NETWORK_STACK */
167 main(int argc
, char *argv
[])
170 struct sockaddr_in sin
;
177 errx(1, "rump_init failed");
179 #ifdef FULL_NETWORK_STACK
180 configure_interface();
183 s
= rump_sys_socket(PF_INET
, SOCK_STREAM
, 0);
185 err(1, "can't open socket");
189 if (rump_sys_setsockopt(s
, SOL_SOCKET
, SO_RCVTIMEO
,
190 &tv
, sizeof(tv
)) == -1)
191 err(1, "setsockopt");
193 memset(&sin
, 0, sizeof(sin
));
194 sin
.sin_family
= AF_INET
;
195 sin
.sin_port
= htons(DEST_PORT
);
196 sin
.sin_addr
.s_addr
= inet_addr(DEST_ADDR
);
198 if (rump_sys_connect(s
, (struct sockaddr
*)&sin
, sizeof(sin
)) == -1) {
199 err(1, "connect failed");
202 printf("connected\n");
204 strcpy(buf
, "GET / HTTP/1.0\n\n");
205 n
= rump_sys_write(s
, buf
, strlen(buf
));
206 if (n
!= (ssize_t
)strlen(buf
))
207 err(1, "wrote only %zd vs. %zu\n",
210 memset(buf
, 0, sizeof(buf
));
211 for (off
= 0; off
< sizeof(buf
) && n
> 0;) {
212 n
= rump_sys_read(s
, buf
+off
, sizeof(buf
)-off
);
216 printf("read %zd (max %zu):\n", off
, sizeof(buf
));