2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
11 * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Jack Lange <jarusl@cs.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
21 #include <palacios/vmm_socket.h>
22 #include <palacios/vmm.h>
23 #include <palacios/vmm_debug.h>
24 #include <palacios/vmm_types.h>
25 #include <palacios/vm_guest.h>
27 static struct v3_socket_hooks * sock_hooks = 0;
30 uint32_t v3_inet_addr(const char * ip_str) {
34 uint32_t * pp = parts;
39 * Collect number up to ``.''.
40 * Values are specified as for C:
41 * 0x=hex, 0=octal, 1-9=decimal.
52 if ((c == 'x') || (c == 'X')) {
62 val = (val * base) + (int)(c - '0');
64 } else if ((base == 16) && (isxdigit(c))) {
65 val = (val << 4) | (int)(c + 10 - (islower(c) ? 'a' : 'A'));
76 * a.b.c (with c treated as 16 bits)
77 * a.b (with b treated as 24 bits)
79 if (pp >= parts + 3) {
91 * Check for trailing characters.
94 ( (!isprint(c)) || (!isspace(c)) ) ) {
99 * Concoct the address according to
100 * the number of parts specified.
106 return 0; /* initial nondigit */
108 case 1: /* a -- 32 bits */
111 case 2: /* a.b -- 8.24 bits */
112 if (val > 0xffffffUL) {
116 val |= parts[0] << 24;
119 case 3: /* a.b.c -- 8.8.16 bits */
124 val |= (parts[0] << 24) | (parts[1] << 16);
127 case 4: /* a.b.c.d -- 8.8.8.8 bits */
132 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
137 return v3_htonl(val);
144 char * v3_inet_ntoa(uint32_t addr) {
154 ap = (uint8_t *)&addr;
156 for (n = 0; n < 4; n++) {
160 rem = *ap % (uint8_t)10;
164 inv[i++] = '0' + rem;
184 uint16_t v3_htons(uint16_t n) {
185 return (((n & 0xff) << 8) | ((n & 0xff00) >> 8));
189 uint16_t v3_ntohs(uint16_t n) {
194 uint32_t v3_htonl(uint32_t n) {
195 return (((n & 0xff) << 24) |
196 ((n & 0xff00) << 8) |
197 ((n & 0xff0000UL) >> 8) |
198 ((n & 0xff000000UL) >> 24));
202 uint32_t v3_ntohl(uint32_t n) {
207 v3_sock_t v3_create_udp_socket(struct v3_vm_info * vm) {
208 V3_ASSERT(sock_hooks);
209 V3_ASSERT(sock_hooks->udp_socket);
210 void * priv_data = NULL;
213 priv_data = vm->host_priv_data;
216 return sock_hooks->udp_socket(0, 0, priv_data);
219 v3_sock_t v3_create_tcp_socket(struct v3_vm_info * vm) {
220 V3_ASSERT(sock_hooks);
221 V3_ASSERT(sock_hooks->tcp_socket);
222 void * priv_data = NULL;
225 priv_data = vm->host_priv_data;
228 return sock_hooks->tcp_socket(0, 1, 0, priv_data);
231 void v3_socket_close(v3_sock_t sock) {
232 V3_ASSERT(sock_hooks);
233 V3_ASSERT(sock_hooks->close);
235 sock_hooks->close(sock);
238 int v3_socket_bind(const v3_sock_t sock, uint16_t port) {
239 V3_ASSERT(sock_hooks);
240 V3_ASSERT(sock_hooks->bind);
242 return sock_hooks->bind(sock, port);
245 int v3_socket_listen(const v3_sock_t sock, int backlog) {
246 V3_ASSERT(sock_hooks);
247 V3_ASSERT(sock_hooks->listen);
249 return sock_hooks->listen(sock, backlog);
252 v3_sock_t v3_socket_accept(const v3_sock_t sock, uint32_t * remote_ip, uint32_t * port) {
253 V3_ASSERT(sock_hooks);
254 V3_ASSERT(sock_hooks->accept);
256 return sock_hooks->accept(sock, remote_ip, port);
259 int v3_connect_to_ip(const v3_sock_t sock, const uint32_t hostip, const uint16_t port) {
260 V3_ASSERT(sock_hooks);
261 V3_ASSERT(sock_hooks->connect_to_ip);
263 return sock_hooks->connect_to_ip(sock, hostip, port);
266 int v3_connect_to_host(const v3_sock_t sock, const char * hostname, const uint16_t port) {
267 V3_ASSERT(sock_hooks);
268 V3_ASSERT(sock_hooks->connect_to_host);
270 return sock_hooks->connect_to_host(sock, hostname, port);
273 int v3_socket_send(const v3_sock_t sock, const uint8_t * buf, const uint32_t len) {
274 V3_ASSERT(sock_hooks);
275 V3_ASSERT(sock_hooks->send);
277 return sock_hooks->send(sock, buf, len);
280 int v3_socket_recv(const v3_sock_t sock, uint8_t * buf, const uint32_t len) {
281 V3_ASSERT(sock_hooks);
282 V3_ASSERT(sock_hooks->recv);
284 return sock_hooks->recv(sock, buf, len);
287 int v3_socket_send_to_host(const v3_sock_t sock, const char * hostname, const uint16_t port,
288 const uint8_t * buf, const uint32_t len) {
289 V3_ASSERT(sock_hooks);
290 V3_ASSERT(sock_hooks->sendto_host);
292 return sock_hooks->sendto_host(sock, hostname, port, buf, len);
295 int v3_socket_send_to_ip(const v3_sock_t sock, const uint32_t ip, const uint16_t port,
296 const uint8_t * buf, const uint32_t len) {
297 V3_ASSERT(sock_hooks);
298 V3_ASSERT(sock_hooks->sendto_ip);
300 return sock_hooks->sendto_ip(sock, ip, port, buf, len);
303 int v3_socket_recv_from_host(const v3_sock_t sock, const char * hostname, const uint16_t port,
304 uint8_t * buf, const uint32_t len) {
305 V3_ASSERT(sock_hooks);
306 V3_ASSERT(sock_hooks->recvfrom_host);
308 return sock_hooks->recvfrom_host(sock, hostname, port, buf, len);
311 int v3_socket_recv_from_ip(const v3_sock_t sock, const uint32_t ip, const uint16_t port,
312 uint8_t * buf, const uint32_t len) {
313 V3_ASSERT(sock_hooks);
314 V3_ASSERT(sock_hooks->recvfrom_ip);
316 return sock_hooks->recvfrom_ip(sock, ip, port, buf, len);
322 void V3_Init_Sockets(struct v3_socket_hooks * hooks) {
324 PrintDebug("V3 sockets inited\n");