Statistics
| Branch: | Revision:

root / net.c @ fad6cb1a

History | View | Annotate | Download (41.8 kB)

1 63a01ef8 aliguori
/*
2 63a01ef8 aliguori
 * QEMU System Emulator
3 63a01ef8 aliguori
 *
4 63a01ef8 aliguori
 * Copyright (c) 2003-2008 Fabrice Bellard
5 63a01ef8 aliguori
 *
6 63a01ef8 aliguori
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 63a01ef8 aliguori
 * of this software and associated documentation files (the "Software"), to deal
8 63a01ef8 aliguori
 * in the Software without restriction, including without limitation the rights
9 63a01ef8 aliguori
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 63a01ef8 aliguori
 * copies of the Software, and to permit persons to whom the Software is
11 63a01ef8 aliguori
 * furnished to do so, subject to the following conditions:
12 63a01ef8 aliguori
 *
13 63a01ef8 aliguori
 * The above copyright notice and this permission notice shall be included in
14 63a01ef8 aliguori
 * all copies or substantial portions of the Software.
15 63a01ef8 aliguori
 *
16 63a01ef8 aliguori
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 63a01ef8 aliguori
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 63a01ef8 aliguori
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 63a01ef8 aliguori
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 63a01ef8 aliguori
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 63a01ef8 aliguori
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 63a01ef8 aliguori
 * THE SOFTWARE.
23 63a01ef8 aliguori
 */
24 559b90fb aliguori
#include "qemu-common.h"
25 63a01ef8 aliguori
#include "net.h"
26 63a01ef8 aliguori
#include "console.h"
27 63a01ef8 aliguori
#include "sysemu.h"
28 63a01ef8 aliguori
#include "qemu-timer.h"
29 63a01ef8 aliguori
#include "qemu-char.h"
30 63a01ef8 aliguori
#include "audio/audio.h"
31 63a01ef8 aliguori
32 63a01ef8 aliguori
#include <unistd.h>
33 63a01ef8 aliguori
#include <fcntl.h>
34 63a01ef8 aliguori
#include <signal.h>
35 63a01ef8 aliguori
#include <time.h>
36 63a01ef8 aliguori
#include <errno.h>
37 63a01ef8 aliguori
#include <sys/time.h>
38 63a01ef8 aliguori
#include <zlib.h>
39 63a01ef8 aliguori
40 63a01ef8 aliguori
#ifndef _WIN32
41 63a01ef8 aliguori
#include <sys/times.h>
42 63a01ef8 aliguori
#include <sys/wait.h>
43 63a01ef8 aliguori
#include <termios.h>
44 63a01ef8 aliguori
#include <sys/mman.h>
45 63a01ef8 aliguori
#include <sys/ioctl.h>
46 24646c7e blueswir1
#include <sys/resource.h>
47 63a01ef8 aliguori
#include <sys/socket.h>
48 63a01ef8 aliguori
#include <netinet/in.h>
49 24646c7e blueswir1
#include <net/if.h>
50 24646c7e blueswir1
#ifdef __NetBSD__
51 24646c7e blueswir1
#include <net/if_tap.h>
52 24646c7e blueswir1
#endif
53 24646c7e blueswir1
#ifdef __linux__
54 24646c7e blueswir1
#include <linux/if_tun.h>
55 24646c7e blueswir1
#endif
56 24646c7e blueswir1
#include <arpa/inet.h>
57 63a01ef8 aliguori
#include <dirent.h>
58 63a01ef8 aliguori
#include <netdb.h>
59 63a01ef8 aliguori
#include <sys/select.h>
60 63a01ef8 aliguori
#ifdef _BSD
61 63a01ef8 aliguori
#include <sys/stat.h>
62 24646c7e blueswir1
#ifdef __FreeBSD__
63 63a01ef8 aliguori
#include <libutil.h>
64 24646c7e blueswir1
#else
65 24646c7e blueswir1
#include <util.h>
66 63a01ef8 aliguori
#endif
67 63a01ef8 aliguori
#elif defined (__GLIBC__) && defined (__FreeBSD_kernel__)
68 63a01ef8 aliguori
#include <freebsd/stdlib.h>
69 63a01ef8 aliguori
#else
70 63a01ef8 aliguori
#ifdef __linux__
71 63a01ef8 aliguori
#include <pty.h>
72 63a01ef8 aliguori
#include <malloc.h>
73 63a01ef8 aliguori
#include <linux/rtc.h>
74 63a01ef8 aliguori
75 63a01ef8 aliguori
/* For the benefit of older linux systems which don't supply it,
76 63a01ef8 aliguori
   we use a local copy of hpet.h. */
77 63a01ef8 aliguori
/* #include <linux/hpet.h> */
78 63a01ef8 aliguori
#include "hpet.h"
79 63a01ef8 aliguori
80 63a01ef8 aliguori
#include <linux/ppdev.h>
81 63a01ef8 aliguori
#include <linux/parport.h>
82 63a01ef8 aliguori
#endif
83 63a01ef8 aliguori
#ifdef __sun__
84 63a01ef8 aliguori
#include <sys/stat.h>
85 63a01ef8 aliguori
#include <sys/ethernet.h>
86 63a01ef8 aliguori
#include <sys/sockio.h>
87 63a01ef8 aliguori
#include <netinet/arp.h>
88 63a01ef8 aliguori
#include <netinet/in.h>
89 63a01ef8 aliguori
#include <netinet/in_systm.h>
90 63a01ef8 aliguori
#include <netinet/ip.h>
91 63a01ef8 aliguori
#include <netinet/ip_icmp.h> // must come after ip.h
92 63a01ef8 aliguori
#include <netinet/udp.h>
93 63a01ef8 aliguori
#include <netinet/tcp.h>
94 63a01ef8 aliguori
#include <net/if.h>
95 63a01ef8 aliguori
#include <syslog.h>
96 63a01ef8 aliguori
#include <stropts.h>
97 63a01ef8 aliguori
#endif
98 63a01ef8 aliguori
#endif
99 63a01ef8 aliguori
#endif
100 63a01ef8 aliguori
101 63a01ef8 aliguori
#include "qemu_socket.h"
102 63a01ef8 aliguori
103 63a01ef8 aliguori
#if defined(CONFIG_SLIRP)
104 63a01ef8 aliguori
#include "libslirp.h"
105 63a01ef8 aliguori
#endif
106 63a01ef8 aliguori
107 63a01ef8 aliguori
#if defined(__OpenBSD__)
108 63a01ef8 aliguori
#include <util.h>
109 63a01ef8 aliguori
#endif
110 63a01ef8 aliguori
111 63a01ef8 aliguori
#if defined(CONFIG_VDE)
112 63a01ef8 aliguori
#include <libvdeplug.h>
113 63a01ef8 aliguori
#endif
114 63a01ef8 aliguori
115 63a01ef8 aliguori
#ifdef _WIN32
116 63a01ef8 aliguori
#include <malloc.h>
117 63a01ef8 aliguori
#include <sys/timeb.h>
118 63a01ef8 aliguori
#include <mmsystem.h>
119 63a01ef8 aliguori
#define getopt_long_only getopt_long
120 63a01ef8 aliguori
#define memalign(align, size) malloc(size)
121 63a01ef8 aliguori
#endif
122 63a01ef8 aliguori
123 63a01ef8 aliguori
static VLANState *first_vlan;
124 63a01ef8 aliguori
125 63a01ef8 aliguori
/***********************************************************/
126 63a01ef8 aliguori
/* network device redirectors */
127 63a01ef8 aliguori
128 63a01ef8 aliguori
#if defined(DEBUG_NET) || defined(DEBUG_SLIRP)
129 63a01ef8 aliguori
static void hex_dump(FILE *f, const uint8_t *buf, int size)
130 63a01ef8 aliguori
{
131 63a01ef8 aliguori
    int len, i, j, c;
132 63a01ef8 aliguori
133 63a01ef8 aliguori
    for(i=0;i<size;i+=16) {
134 63a01ef8 aliguori
        len = size - i;
135 63a01ef8 aliguori
        if (len > 16)
136 63a01ef8 aliguori
            len = 16;
137 63a01ef8 aliguori
        fprintf(f, "%08x ", i);
138 63a01ef8 aliguori
        for(j=0;j<16;j++) {
139 63a01ef8 aliguori
            if (j < len)
140 63a01ef8 aliguori
                fprintf(f, " %02x", buf[i+j]);
141 63a01ef8 aliguori
            else
142 63a01ef8 aliguori
                fprintf(f, "   ");
143 63a01ef8 aliguori
        }
144 63a01ef8 aliguori
        fprintf(f, " ");
145 63a01ef8 aliguori
        for(j=0;j<len;j++) {
146 63a01ef8 aliguori
            c = buf[i+j];
147 63a01ef8 aliguori
            if (c < ' ' || c > '~')
148 63a01ef8 aliguori
                c = '.';
149 63a01ef8 aliguori
            fprintf(f, "%c", c);
150 63a01ef8 aliguori
        }
151 63a01ef8 aliguori
        fprintf(f, "\n");
152 63a01ef8 aliguori
    }
153 63a01ef8 aliguori
}
154 63a01ef8 aliguori
#endif
155 63a01ef8 aliguori
156 63a01ef8 aliguori
static int parse_macaddr(uint8_t *macaddr, const char *p)
157 63a01ef8 aliguori
{
158 63a01ef8 aliguori
    int i;
159 63a01ef8 aliguori
    char *last_char;
160 63a01ef8 aliguori
    long int offset;
161 63a01ef8 aliguori
162 63a01ef8 aliguori
    errno = 0;
163 63a01ef8 aliguori
    offset = strtol(p, &last_char, 0);    
164 63a01ef8 aliguori
    if (0 == errno && '\0' == *last_char &&
165 63a01ef8 aliguori
            offset >= 0 && offset <= 0xFFFFFF) {
166 63a01ef8 aliguori
        macaddr[3] = (offset & 0xFF0000) >> 16;
167 63a01ef8 aliguori
        macaddr[4] = (offset & 0xFF00) >> 8;
168 63a01ef8 aliguori
        macaddr[5] = offset & 0xFF;
169 63a01ef8 aliguori
        return 0;
170 63a01ef8 aliguori
    } else {
171 63a01ef8 aliguori
        for(i = 0; i < 6; i++) {
172 63a01ef8 aliguori
            macaddr[i] = strtol(p, (char **)&p, 16);
173 63a01ef8 aliguori
            if (i == 5) {
174 63a01ef8 aliguori
                if (*p != '\0')
175 63a01ef8 aliguori
                    return -1;
176 63a01ef8 aliguori
            } else {
177 63a01ef8 aliguori
                if (*p != ':' && *p != '-')
178 63a01ef8 aliguori
                    return -1;
179 63a01ef8 aliguori
                p++;
180 63a01ef8 aliguori
            }
181 63a01ef8 aliguori
        }
182 63a01ef8 aliguori
        return 0;    
183 63a01ef8 aliguori
    }
184 63a01ef8 aliguori
185 63a01ef8 aliguori
    return -1;
186 63a01ef8 aliguori
}
187 63a01ef8 aliguori
188 63a01ef8 aliguori
static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
189 63a01ef8 aliguori
{
190 63a01ef8 aliguori
    const char *p, *p1;
191 63a01ef8 aliguori
    int len;
192 63a01ef8 aliguori
    p = *pp;
193 63a01ef8 aliguori
    p1 = strchr(p, sep);
194 63a01ef8 aliguori
    if (!p1)
195 63a01ef8 aliguori
        return -1;
196 63a01ef8 aliguori
    len = p1 - p;
197 63a01ef8 aliguori
    p1++;
198 63a01ef8 aliguori
    if (buf_size > 0) {
199 63a01ef8 aliguori
        if (len > buf_size - 1)
200 63a01ef8 aliguori
            len = buf_size - 1;
201 63a01ef8 aliguori
        memcpy(buf, p, len);
202 63a01ef8 aliguori
        buf[len] = '\0';
203 63a01ef8 aliguori
    }
204 63a01ef8 aliguori
    *pp = p1;
205 63a01ef8 aliguori
    return 0;
206 63a01ef8 aliguori
}
207 63a01ef8 aliguori
208 63a01ef8 aliguori
int parse_host_src_port(struct sockaddr_in *haddr,
209 63a01ef8 aliguori
                        struct sockaddr_in *saddr,
210 63a01ef8 aliguori
                        const char *input_str)
211 63a01ef8 aliguori
{
212 63a01ef8 aliguori
    char *str = strdup(input_str);
213 63a01ef8 aliguori
    char *host_str = str;
214 63a01ef8 aliguori
    char *src_str;
215 63a01ef8 aliguori
    const char *src_str2;
216 63a01ef8 aliguori
    char *ptr;
217 63a01ef8 aliguori
218 63a01ef8 aliguori
    /*
219 63a01ef8 aliguori
     * Chop off any extra arguments at the end of the string which
220 63a01ef8 aliguori
     * would start with a comma, then fill in the src port information
221 63a01ef8 aliguori
     * if it was provided else use the "any address" and "any port".
222 63a01ef8 aliguori
     */
223 63a01ef8 aliguori
    if ((ptr = strchr(str,',')))
224 63a01ef8 aliguori
        *ptr = '\0';
225 63a01ef8 aliguori
226 63a01ef8 aliguori
    if ((src_str = strchr(input_str,'@'))) {
227 63a01ef8 aliguori
        *src_str = '\0';
228 63a01ef8 aliguori
        src_str++;
229 63a01ef8 aliguori
    }
230 63a01ef8 aliguori
231 63a01ef8 aliguori
    if (parse_host_port(haddr, host_str) < 0)
232 63a01ef8 aliguori
        goto fail;
233 63a01ef8 aliguori
234 63a01ef8 aliguori
    src_str2 = src_str;
235 63a01ef8 aliguori
    if (!src_str || *src_str == '\0')
236 63a01ef8 aliguori
        src_str2 = ":0";
237 63a01ef8 aliguori
238 63a01ef8 aliguori
    if (parse_host_port(saddr, src_str2) < 0)
239 63a01ef8 aliguori
        goto fail;
240 63a01ef8 aliguori
241 63a01ef8 aliguori
    free(str);
242 63a01ef8 aliguori
    return(0);
243 63a01ef8 aliguori
244 63a01ef8 aliguori
fail:
245 63a01ef8 aliguori
    free(str);
246 63a01ef8 aliguori
    return -1;
247 63a01ef8 aliguori
}
248 63a01ef8 aliguori
249 63a01ef8 aliguori
int parse_host_port(struct sockaddr_in *saddr, const char *str)
250 63a01ef8 aliguori
{
251 63a01ef8 aliguori
    char buf[512];
252 63a01ef8 aliguori
    struct hostent *he;
253 63a01ef8 aliguori
    const char *p, *r;
254 63a01ef8 aliguori
    int port;
255 63a01ef8 aliguori
256 63a01ef8 aliguori
    p = str;
257 63a01ef8 aliguori
    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
258 63a01ef8 aliguori
        return -1;
259 63a01ef8 aliguori
    saddr->sin_family = AF_INET;
260 63a01ef8 aliguori
    if (buf[0] == '\0') {
261 63a01ef8 aliguori
        saddr->sin_addr.s_addr = 0;
262 63a01ef8 aliguori
    } else {
263 cd390083 blueswir1
        if (qemu_isdigit(buf[0])) {
264 63a01ef8 aliguori
            if (!inet_aton(buf, &saddr->sin_addr))
265 63a01ef8 aliguori
                return -1;
266 63a01ef8 aliguori
        } else {
267 63a01ef8 aliguori
            if ((he = gethostbyname(buf)) == NULL)
268 63a01ef8 aliguori
                return - 1;
269 63a01ef8 aliguori
            saddr->sin_addr = *(struct in_addr *)he->h_addr;
270 63a01ef8 aliguori
        }
271 63a01ef8 aliguori
    }
272 63a01ef8 aliguori
    port = strtol(p, (char **)&r, 0);
273 63a01ef8 aliguori
    if (r == p)
274 63a01ef8 aliguori
        return -1;
275 63a01ef8 aliguori
    saddr->sin_port = htons(port);
276 63a01ef8 aliguori
    return 0;
277 63a01ef8 aliguori
}
278 63a01ef8 aliguori
279 69d6451c blueswir1
#if !defined(_WIN32) && 0
280 69d6451c blueswir1
static int parse_unix_path(struct sockaddr_un *uaddr, const char *str)
281 63a01ef8 aliguori
{
282 63a01ef8 aliguori
    const char *p;
283 63a01ef8 aliguori
    int len;
284 63a01ef8 aliguori
285 63a01ef8 aliguori
    len = MIN(108, strlen(str));
286 63a01ef8 aliguori
    p = strchr(str, ',');
287 63a01ef8 aliguori
    if (p)
288 63a01ef8 aliguori
        len = MIN(len, p - str);
289 63a01ef8 aliguori
290 63a01ef8 aliguori
    memset(uaddr, 0, sizeof(*uaddr));
291 63a01ef8 aliguori
292 63a01ef8 aliguori
    uaddr->sun_family = AF_UNIX;
293 63a01ef8 aliguori
    memcpy(uaddr->sun_path, str, len);
294 63a01ef8 aliguori
295 63a01ef8 aliguori
    return 0;
296 63a01ef8 aliguori
}
297 63a01ef8 aliguori
#endif
298 63a01ef8 aliguori
299 63a01ef8 aliguori
VLANClientState *qemu_new_vlan_client(VLANState *vlan,
300 63a01ef8 aliguori
                                      IOReadHandler *fd_read,
301 63a01ef8 aliguori
                                      IOCanRWHandler *fd_can_read,
302 63a01ef8 aliguori
                                      void *opaque)
303 63a01ef8 aliguori
{
304 63a01ef8 aliguori
    VLANClientState *vc, **pvc;
305 63a01ef8 aliguori
    vc = qemu_mallocz(sizeof(VLANClientState));
306 63a01ef8 aliguori
    if (!vc)
307 63a01ef8 aliguori
        return NULL;
308 63a01ef8 aliguori
    vc->fd_read = fd_read;
309 63a01ef8 aliguori
    vc->fd_can_read = fd_can_read;
310 63a01ef8 aliguori
    vc->opaque = opaque;
311 63a01ef8 aliguori
    vc->vlan = vlan;
312 63a01ef8 aliguori
313 63a01ef8 aliguori
    vc->next = NULL;
314 63a01ef8 aliguori
    pvc = &vlan->first_client;
315 63a01ef8 aliguori
    while (*pvc != NULL)
316 63a01ef8 aliguori
        pvc = &(*pvc)->next;
317 63a01ef8 aliguori
    *pvc = vc;
318 63a01ef8 aliguori
    return vc;
319 63a01ef8 aliguori
}
320 63a01ef8 aliguori
321 63a01ef8 aliguori
void qemu_del_vlan_client(VLANClientState *vc)
322 63a01ef8 aliguori
{
323 63a01ef8 aliguori
    VLANClientState **pvc = &vc->vlan->first_client;
324 63a01ef8 aliguori
325 63a01ef8 aliguori
    while (*pvc != NULL)
326 63a01ef8 aliguori
        if (*pvc == vc) {
327 63a01ef8 aliguori
            *pvc = vc->next;
328 63a01ef8 aliguori
            free(vc);
329 63a01ef8 aliguori
            break;
330 63a01ef8 aliguori
        } else
331 63a01ef8 aliguori
            pvc = &(*pvc)->next;
332 63a01ef8 aliguori
}
333 63a01ef8 aliguori
334 63a01ef8 aliguori
int qemu_can_send_packet(VLANClientState *vc1)
335 63a01ef8 aliguori
{
336 63a01ef8 aliguori
    VLANState *vlan = vc1->vlan;
337 63a01ef8 aliguori
    VLANClientState *vc;
338 63a01ef8 aliguori
339 63a01ef8 aliguori
    for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
340 63a01ef8 aliguori
        if (vc != vc1) {
341 63a01ef8 aliguori
            if (vc->fd_can_read && vc->fd_can_read(vc->opaque))
342 63a01ef8 aliguori
                return 1;
343 63a01ef8 aliguori
        }
344 63a01ef8 aliguori
    }
345 63a01ef8 aliguori
    return 0;
346 63a01ef8 aliguori
}
347 63a01ef8 aliguori
348 63a01ef8 aliguori
void qemu_send_packet(VLANClientState *vc1, const uint8_t *buf, int size)
349 63a01ef8 aliguori
{
350 63a01ef8 aliguori
    VLANState *vlan = vc1->vlan;
351 63a01ef8 aliguori
    VLANClientState *vc;
352 63a01ef8 aliguori
353 63a01ef8 aliguori
#ifdef DEBUG_NET
354 63a01ef8 aliguori
    printf("vlan %d send:\n", vlan->id);
355 63a01ef8 aliguori
    hex_dump(stdout, buf, size);
356 63a01ef8 aliguori
#endif
357 63a01ef8 aliguori
    for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
358 63a01ef8 aliguori
        if (vc != vc1) {
359 63a01ef8 aliguori
            vc->fd_read(vc->opaque, buf, size);
360 63a01ef8 aliguori
        }
361 63a01ef8 aliguori
    }
362 63a01ef8 aliguori
}
363 63a01ef8 aliguori
364 fbe78f4f aliguori
static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov,
365 fbe78f4f aliguori
                               int iovcnt)
366 fbe78f4f aliguori
{
367 fbe78f4f aliguori
    uint8_t buffer[4096];
368 fbe78f4f aliguori
    size_t offset = 0;
369 fbe78f4f aliguori
    int i;
370 fbe78f4f aliguori
371 fbe78f4f aliguori
    for (i = 0; i < iovcnt; i++) {
372 fbe78f4f aliguori
        size_t len;
373 fbe78f4f aliguori
374 fbe78f4f aliguori
        len = MIN(sizeof(buffer) - offset, iov[i].iov_len);
375 fbe78f4f aliguori
        memcpy(buffer + offset, iov[i].iov_base, len);
376 fbe78f4f aliguori
        offset += len;
377 fbe78f4f aliguori
    }
378 fbe78f4f aliguori
379 fbe78f4f aliguori
    vc->fd_read(vc->opaque, buffer, offset);
380 fbe78f4f aliguori
381 fbe78f4f aliguori
    return offset;
382 fbe78f4f aliguori
}
383 fbe78f4f aliguori
384 fbe78f4f aliguori
ssize_t qemu_sendv_packet(VLANClientState *vc1, const struct iovec *iov,
385 fbe78f4f aliguori
                          int iovcnt)
386 fbe78f4f aliguori
{
387 fbe78f4f aliguori
    VLANState *vlan = vc1->vlan;
388 fbe78f4f aliguori
    VLANClientState *vc;
389 fbe78f4f aliguori
    ssize_t max_len = 0;
390 fbe78f4f aliguori
391 fbe78f4f aliguori
    for (vc = vlan->first_client; vc != NULL; vc = vc->next) {
392 fbe78f4f aliguori
        ssize_t len = 0;
393 fbe78f4f aliguori
394 fbe78f4f aliguori
        if (vc == vc1)
395 fbe78f4f aliguori
            continue;
396 fbe78f4f aliguori
397 fbe78f4f aliguori
        if (vc->fd_readv)
398 fbe78f4f aliguori
            len = vc->fd_readv(vc->opaque, iov, iovcnt);
399 fbe78f4f aliguori
        else if (vc->fd_read)
400 fbe78f4f aliguori
            len = vc_sendv_compat(vc, iov, iovcnt);
401 fbe78f4f aliguori
402 fbe78f4f aliguori
        max_len = MAX(max_len, len);
403 fbe78f4f aliguori
    }
404 fbe78f4f aliguori
405 fbe78f4f aliguori
    return max_len;
406 fbe78f4f aliguori
}
407 fbe78f4f aliguori
408 63a01ef8 aliguori
#if defined(CONFIG_SLIRP)
409 63a01ef8 aliguori
410 63a01ef8 aliguori
/* slirp network adapter */
411 63a01ef8 aliguori
412 63a01ef8 aliguori
static int slirp_inited;
413 63a01ef8 aliguori
static VLANClientState *slirp_vc;
414 63a01ef8 aliguori
415 63a01ef8 aliguori
int slirp_can_output(void)
416 63a01ef8 aliguori
{
417 63a01ef8 aliguori
    return !slirp_vc || qemu_can_send_packet(slirp_vc);
418 63a01ef8 aliguori
}
419 63a01ef8 aliguori
420 63a01ef8 aliguori
void slirp_output(const uint8_t *pkt, int pkt_len)
421 63a01ef8 aliguori
{
422 63a01ef8 aliguori
#ifdef DEBUG_SLIRP
423 63a01ef8 aliguori
    printf("slirp output:\n");
424 63a01ef8 aliguori
    hex_dump(stdout, pkt, pkt_len);
425 63a01ef8 aliguori
#endif
426 63a01ef8 aliguori
    if (!slirp_vc)
427 63a01ef8 aliguori
        return;
428 63a01ef8 aliguori
    qemu_send_packet(slirp_vc, pkt, pkt_len);
429 63a01ef8 aliguori
}
430 63a01ef8 aliguori
431 63a01ef8 aliguori
int slirp_is_inited(void)
432 63a01ef8 aliguori
{
433 63a01ef8 aliguori
    return slirp_inited;
434 63a01ef8 aliguori
}
435 63a01ef8 aliguori
436 63a01ef8 aliguori
static void slirp_receive(void *opaque, const uint8_t *buf, int size)
437 63a01ef8 aliguori
{
438 63a01ef8 aliguori
#ifdef DEBUG_SLIRP
439 63a01ef8 aliguori
    printf("slirp input:\n");
440 63a01ef8 aliguori
    hex_dump(stdout, buf, size);
441 63a01ef8 aliguori
#endif
442 63a01ef8 aliguori
    slirp_input(buf, size);
443 63a01ef8 aliguori
}
444 63a01ef8 aliguori
445 63a01ef8 aliguori
static int net_slirp_init(VLANState *vlan)
446 63a01ef8 aliguori
{
447 63a01ef8 aliguori
    if (!slirp_inited) {
448 63a01ef8 aliguori
        slirp_inited = 1;
449 63a01ef8 aliguori
        slirp_init();
450 63a01ef8 aliguori
    }
451 63a01ef8 aliguori
    slirp_vc = qemu_new_vlan_client(vlan,
452 63a01ef8 aliguori
                                    slirp_receive, NULL, NULL);
453 63a01ef8 aliguori
    snprintf(slirp_vc->info_str, sizeof(slirp_vc->info_str), "user redirector");
454 63a01ef8 aliguori
    return 0;
455 63a01ef8 aliguori
}
456 63a01ef8 aliguori
457 63a01ef8 aliguori
void net_slirp_redir(const char *redir_str)
458 63a01ef8 aliguori
{
459 63a01ef8 aliguori
    int is_udp;
460 63a01ef8 aliguori
    char buf[256], *r;
461 63a01ef8 aliguori
    const char *p;
462 63a01ef8 aliguori
    struct in_addr guest_addr;
463 63a01ef8 aliguori
    int host_port, guest_port;
464 63a01ef8 aliguori
465 63a01ef8 aliguori
    if (!slirp_inited) {
466 63a01ef8 aliguori
        slirp_inited = 1;
467 63a01ef8 aliguori
        slirp_init();
468 63a01ef8 aliguori
    }
469 63a01ef8 aliguori
470 63a01ef8 aliguori
    p = redir_str;
471 63a01ef8 aliguori
    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
472 63a01ef8 aliguori
        goto fail;
473 63a01ef8 aliguori
    if (!strcmp(buf, "tcp")) {
474 63a01ef8 aliguori
        is_udp = 0;
475 63a01ef8 aliguori
    } else if (!strcmp(buf, "udp")) {
476 63a01ef8 aliguori
        is_udp = 1;
477 63a01ef8 aliguori
    } else {
478 63a01ef8 aliguori
        goto fail;
479 63a01ef8 aliguori
    }
480 63a01ef8 aliguori
481 63a01ef8 aliguori
    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
482 63a01ef8 aliguori
        goto fail;
483 63a01ef8 aliguori
    host_port = strtol(buf, &r, 0);
484 63a01ef8 aliguori
    if (r == buf)
485 63a01ef8 aliguori
        goto fail;
486 63a01ef8 aliguori
487 63a01ef8 aliguori
    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
488 63a01ef8 aliguori
        goto fail;
489 63a01ef8 aliguori
    if (buf[0] == '\0') {
490 63a01ef8 aliguori
        pstrcpy(buf, sizeof(buf), "10.0.2.15");
491 63a01ef8 aliguori
    }
492 63a01ef8 aliguori
    if (!inet_aton(buf, &guest_addr))
493 63a01ef8 aliguori
        goto fail;
494 63a01ef8 aliguori
495 63a01ef8 aliguori
    guest_port = strtol(p, &r, 0);
496 63a01ef8 aliguori
    if (r == p)
497 63a01ef8 aliguori
        goto fail;
498 63a01ef8 aliguori
499 63a01ef8 aliguori
    if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) {
500 63a01ef8 aliguori
        fprintf(stderr, "qemu: could not set up redirection\n");
501 63a01ef8 aliguori
        exit(1);
502 63a01ef8 aliguori
    }
503 63a01ef8 aliguori
    return;
504 63a01ef8 aliguori
 fail:
505 63a01ef8 aliguori
    fprintf(stderr, "qemu: syntax: -redir [tcp|udp]:host-port:[guest-host]:guest-port\n");
506 63a01ef8 aliguori
    exit(1);
507 63a01ef8 aliguori
}
508 63a01ef8 aliguori
509 63a01ef8 aliguori
#ifndef _WIN32
510 63a01ef8 aliguori
511 63a01ef8 aliguori
static char smb_dir[1024];
512 63a01ef8 aliguori
513 63a01ef8 aliguori
static void erase_dir(char *dir_name)
514 63a01ef8 aliguori
{
515 63a01ef8 aliguori
    DIR *d;
516 63a01ef8 aliguori
    struct dirent *de;
517 63a01ef8 aliguori
    char filename[1024];
518 63a01ef8 aliguori
519 63a01ef8 aliguori
    /* erase all the files in the directory */
520 63a01ef8 aliguori
    if ((d = opendir(dir_name)) != 0) {
521 63a01ef8 aliguori
        for(;;) {
522 63a01ef8 aliguori
            de = readdir(d);
523 63a01ef8 aliguori
            if (!de)
524 63a01ef8 aliguori
                break;
525 63a01ef8 aliguori
            if (strcmp(de->d_name, ".") != 0 &&
526 63a01ef8 aliguori
                strcmp(de->d_name, "..") != 0) {
527 63a01ef8 aliguori
                snprintf(filename, sizeof(filename), "%s/%s",
528 63a01ef8 aliguori
                         smb_dir, de->d_name);
529 63a01ef8 aliguori
                if (unlink(filename) != 0)  /* is it a directory? */
530 63a01ef8 aliguori
                    erase_dir(filename);
531 63a01ef8 aliguori
            }
532 63a01ef8 aliguori
        }
533 63a01ef8 aliguori
        closedir(d);
534 63a01ef8 aliguori
        rmdir(dir_name);
535 63a01ef8 aliguori
    }
536 63a01ef8 aliguori
}
537 63a01ef8 aliguori
538 63a01ef8 aliguori
/* automatic user mode samba server configuration */
539 63a01ef8 aliguori
static void smb_exit(void)
540 63a01ef8 aliguori
{
541 63a01ef8 aliguori
    erase_dir(smb_dir);
542 63a01ef8 aliguori
}
543 63a01ef8 aliguori
544 63a01ef8 aliguori
/* automatic user mode samba server configuration */
545 63a01ef8 aliguori
void net_slirp_smb(const char *exported_dir)
546 63a01ef8 aliguori
{
547 63a01ef8 aliguori
    char smb_conf[1024];
548 63a01ef8 aliguori
    char smb_cmdline[1024];
549 63a01ef8 aliguori
    FILE *f;
550 63a01ef8 aliguori
551 63a01ef8 aliguori
    if (!slirp_inited) {
552 63a01ef8 aliguori
        slirp_inited = 1;
553 63a01ef8 aliguori
        slirp_init();
554 63a01ef8 aliguori
    }
555 63a01ef8 aliguori
556 63a01ef8 aliguori
    /* XXX: better tmp dir construction */
557 63a01ef8 aliguori
    snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%d", getpid());
558 63a01ef8 aliguori
    if (mkdir(smb_dir, 0700) < 0) {
559 63a01ef8 aliguori
        fprintf(stderr, "qemu: could not create samba server dir '%s'\n", smb_dir);
560 63a01ef8 aliguori
        exit(1);
561 63a01ef8 aliguori
    }
562 63a01ef8 aliguori
    snprintf(smb_conf, sizeof(smb_conf), "%s/%s", smb_dir, "smb.conf");
563 63a01ef8 aliguori
564 63a01ef8 aliguori
    f = fopen(smb_conf, "w");
565 63a01ef8 aliguori
    if (!f) {
566 63a01ef8 aliguori
        fprintf(stderr, "qemu: could not create samba server configuration file '%s'\n", smb_conf);
567 63a01ef8 aliguori
        exit(1);
568 63a01ef8 aliguori
    }
569 63a01ef8 aliguori
    fprintf(f,
570 63a01ef8 aliguori
            "[global]\n"
571 63a01ef8 aliguori
            "private dir=%s\n"
572 63a01ef8 aliguori
            "smb ports=0\n"
573 63a01ef8 aliguori
            "socket address=127.0.0.1\n"
574 63a01ef8 aliguori
            "pid directory=%s\n"
575 63a01ef8 aliguori
            "lock directory=%s\n"
576 63a01ef8 aliguori
            "log file=%s/log.smbd\n"
577 63a01ef8 aliguori
            "smb passwd file=%s/smbpasswd\n"
578 63a01ef8 aliguori
            "security = share\n"
579 63a01ef8 aliguori
            "[qemu]\n"
580 63a01ef8 aliguori
            "path=%s\n"
581 63a01ef8 aliguori
            "read only=no\n"
582 63a01ef8 aliguori
            "guest ok=yes\n",
583 63a01ef8 aliguori
            smb_dir,
584 63a01ef8 aliguori
            smb_dir,
585 63a01ef8 aliguori
            smb_dir,
586 63a01ef8 aliguori
            smb_dir,
587 63a01ef8 aliguori
            smb_dir,
588 63a01ef8 aliguori
            exported_dir
589 63a01ef8 aliguori
            );
590 63a01ef8 aliguori
    fclose(f);
591 63a01ef8 aliguori
    atexit(smb_exit);
592 63a01ef8 aliguori
593 63a01ef8 aliguori
    snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s",
594 63a01ef8 aliguori
             SMBD_COMMAND, smb_conf);
595 63a01ef8 aliguori
596 63a01ef8 aliguori
    slirp_add_exec(0, smb_cmdline, 4, 139);
597 63a01ef8 aliguori
}
598 63a01ef8 aliguori
599 63a01ef8 aliguori
#endif /* !defined(_WIN32) */
600 63a01ef8 aliguori
void do_info_slirp(void)
601 63a01ef8 aliguori
{
602 63a01ef8 aliguori
    slirp_stats();
603 63a01ef8 aliguori
}
604 63a01ef8 aliguori
605 63a01ef8 aliguori
#endif /* CONFIG_SLIRP */
606 63a01ef8 aliguori
607 63a01ef8 aliguori
#if !defined(_WIN32)
608 63a01ef8 aliguori
609 63a01ef8 aliguori
typedef struct TAPState {
610 63a01ef8 aliguori
    VLANClientState *vc;
611 63a01ef8 aliguori
    int fd;
612 63a01ef8 aliguori
    char down_script[1024];
613 63a01ef8 aliguori
} TAPState;
614 63a01ef8 aliguori
615 b535b7b2 aliguori
#ifdef HAVE_IOVEC
616 b535b7b2 aliguori
static ssize_t tap_receive_iov(void *opaque, const struct iovec *iov,
617 b535b7b2 aliguori
                               int iovcnt)
618 b535b7b2 aliguori
{
619 b535b7b2 aliguori
    TAPState *s = opaque;
620 b535b7b2 aliguori
    ssize_t len;
621 b535b7b2 aliguori
622 b535b7b2 aliguori
    do {
623 b535b7b2 aliguori
        len = writev(s->fd, iov, iovcnt);
624 b535b7b2 aliguori
    } while (len == -1 && (errno == EINTR || errno == EAGAIN));
625 b535b7b2 aliguori
626 b535b7b2 aliguori
    return len;
627 b535b7b2 aliguori
}
628 b535b7b2 aliguori
#endif
629 b535b7b2 aliguori
630 63a01ef8 aliguori
static void tap_receive(void *opaque, const uint8_t *buf, int size)
631 63a01ef8 aliguori
{
632 63a01ef8 aliguori
    TAPState *s = opaque;
633 63a01ef8 aliguori
    int ret;
634 63a01ef8 aliguori
    for(;;) {
635 63a01ef8 aliguori
        ret = write(s->fd, buf, size);
636 63a01ef8 aliguori
        if (ret < 0 && (errno == EINTR || errno == EAGAIN)) {
637 63a01ef8 aliguori
        } else {
638 63a01ef8 aliguori
            break;
639 63a01ef8 aliguori
        }
640 63a01ef8 aliguori
    }
641 63a01ef8 aliguori
}
642 63a01ef8 aliguori
643 63a01ef8 aliguori
static void tap_send(void *opaque)
644 63a01ef8 aliguori
{
645 63a01ef8 aliguori
    TAPState *s = opaque;
646 63a01ef8 aliguori
    uint8_t buf[4096];
647 63a01ef8 aliguori
    int size;
648 63a01ef8 aliguori
649 63a01ef8 aliguori
#ifdef __sun__
650 63a01ef8 aliguori
    struct strbuf sbuf;
651 63a01ef8 aliguori
    int f = 0;
652 63a01ef8 aliguori
    sbuf.maxlen = sizeof(buf);
653 63a01ef8 aliguori
    sbuf.buf = buf;
654 63a01ef8 aliguori
    size = getmsg(s->fd, NULL, &sbuf, &f) >=0 ? sbuf.len : -1;
655 63a01ef8 aliguori
#else
656 63a01ef8 aliguori
    size = read(s->fd, buf, sizeof(buf));
657 63a01ef8 aliguori
#endif
658 63a01ef8 aliguori
    if (size > 0) {
659 63a01ef8 aliguori
        qemu_send_packet(s->vc, buf, size);
660 63a01ef8 aliguori
    }
661 63a01ef8 aliguori
}
662 63a01ef8 aliguori
663 63a01ef8 aliguori
/* fd support */
664 63a01ef8 aliguori
665 63a01ef8 aliguori
static TAPState *net_tap_fd_init(VLANState *vlan, int fd)
666 63a01ef8 aliguori
{
667 63a01ef8 aliguori
    TAPState *s;
668 63a01ef8 aliguori
669 63a01ef8 aliguori
    s = qemu_mallocz(sizeof(TAPState));
670 63a01ef8 aliguori
    if (!s)
671 63a01ef8 aliguori
        return NULL;
672 63a01ef8 aliguori
    s->fd = fd;
673 63a01ef8 aliguori
    s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s);
674 b535b7b2 aliguori
#ifdef HAVE_IOVEC
675 b535b7b2 aliguori
    s->vc->fd_readv = tap_receive_iov;
676 b535b7b2 aliguori
#endif
677 63a01ef8 aliguori
    qemu_set_fd_handler(s->fd, tap_send, NULL, s);
678 63a01ef8 aliguori
    snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: fd=%d", fd);
679 63a01ef8 aliguori
    return s;
680 63a01ef8 aliguori
}
681 63a01ef8 aliguori
682 63a01ef8 aliguori
#if defined (_BSD) || defined (__FreeBSD_kernel__)
683 63a01ef8 aliguori
static int tap_open(char *ifname, int ifname_size)
684 63a01ef8 aliguori
{
685 63a01ef8 aliguori
    int fd;
686 63a01ef8 aliguori
    char *dev;
687 63a01ef8 aliguori
    struct stat s;
688 63a01ef8 aliguori
689 63a01ef8 aliguori
    TFR(fd = open("/dev/tap", O_RDWR));
690 63a01ef8 aliguori
    if (fd < 0) {
691 63a01ef8 aliguori
        fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n");
692 63a01ef8 aliguori
        return -1;
693 63a01ef8 aliguori
    }
694 63a01ef8 aliguori
695 63a01ef8 aliguori
    fstat(fd, &s);
696 63a01ef8 aliguori
    dev = devname(s.st_rdev, S_IFCHR);
697 63a01ef8 aliguori
    pstrcpy(ifname, ifname_size, dev);
698 63a01ef8 aliguori
699 63a01ef8 aliguori
    fcntl(fd, F_SETFL, O_NONBLOCK);
700 63a01ef8 aliguori
    return fd;
701 63a01ef8 aliguori
}
702 63a01ef8 aliguori
#elif defined(__sun__)
703 63a01ef8 aliguori
#define TUNNEWPPA       (('T'<<16) | 0x0001)
704 63a01ef8 aliguori
/*
705 63a01ef8 aliguori
 * Allocate TAP device, returns opened fd.
706 63a01ef8 aliguori
 * Stores dev name in the first arg(must be large enough).
707 63a01ef8 aliguori
 */
708 63a01ef8 aliguori
int tap_alloc(char *dev, size_t dev_size)
709 63a01ef8 aliguori
{
710 63a01ef8 aliguori
    int tap_fd, if_fd, ppa = -1;
711 63a01ef8 aliguori
    static int ip_fd = 0;
712 63a01ef8 aliguori
    char *ptr;
713 63a01ef8 aliguori
714 63a01ef8 aliguori
    static int arp_fd = 0;
715 63a01ef8 aliguori
    int ip_muxid, arp_muxid;
716 63a01ef8 aliguori
    struct strioctl  strioc_if, strioc_ppa;
717 63a01ef8 aliguori
    int link_type = I_PLINK;;
718 63a01ef8 aliguori
    struct lifreq ifr;
719 63a01ef8 aliguori
    char actual_name[32] = "";
720 63a01ef8 aliguori
721 63a01ef8 aliguori
    memset(&ifr, 0x0, sizeof(ifr));
722 63a01ef8 aliguori
723 63a01ef8 aliguori
    if( *dev ){
724 63a01ef8 aliguori
       ptr = dev;
725 47398b9c blueswir1
       while( *ptr && !qemu_isdigit((int)*ptr) ) ptr++;
726 63a01ef8 aliguori
       ppa = atoi(ptr);
727 63a01ef8 aliguori
    }
728 63a01ef8 aliguori
729 63a01ef8 aliguori
    /* Check if IP device was opened */
730 63a01ef8 aliguori
    if( ip_fd )
731 63a01ef8 aliguori
       close(ip_fd);
732 63a01ef8 aliguori
733 63a01ef8 aliguori
    TFR(ip_fd = open("/dev/udp", O_RDWR, 0));
734 63a01ef8 aliguori
    if (ip_fd < 0) {
735 63a01ef8 aliguori
       syslog(LOG_ERR, "Can't open /dev/ip (actually /dev/udp)");
736 63a01ef8 aliguori
       return -1;
737 63a01ef8 aliguori
    }
738 63a01ef8 aliguori
739 63a01ef8 aliguori
    TFR(tap_fd = open("/dev/tap", O_RDWR, 0));
740 63a01ef8 aliguori
    if (tap_fd < 0) {
741 63a01ef8 aliguori
       syslog(LOG_ERR, "Can't open /dev/tap");
742 63a01ef8 aliguori
       return -1;
743 63a01ef8 aliguori
    }
744 63a01ef8 aliguori
745 63a01ef8 aliguori
    /* Assign a new PPA and get its unit number. */
746 63a01ef8 aliguori
    strioc_ppa.ic_cmd = TUNNEWPPA;
747 63a01ef8 aliguori
    strioc_ppa.ic_timout = 0;
748 63a01ef8 aliguori
    strioc_ppa.ic_len = sizeof(ppa);
749 63a01ef8 aliguori
    strioc_ppa.ic_dp = (char *)&ppa;
750 63a01ef8 aliguori
    if ((ppa = ioctl (tap_fd, I_STR, &strioc_ppa)) < 0)
751 63a01ef8 aliguori
       syslog (LOG_ERR, "Can't assign new interface");
752 63a01ef8 aliguori
753 63a01ef8 aliguori
    TFR(if_fd = open("/dev/tap", O_RDWR, 0));
754 63a01ef8 aliguori
    if (if_fd < 0) {
755 63a01ef8 aliguori
       syslog(LOG_ERR, "Can't open /dev/tap (2)");
756 63a01ef8 aliguori
       return -1;
757 63a01ef8 aliguori
    }
758 63a01ef8 aliguori
    if(ioctl(if_fd, I_PUSH, "ip") < 0){
759 63a01ef8 aliguori
       syslog(LOG_ERR, "Can't push IP module");
760 63a01ef8 aliguori
       return -1;
761 63a01ef8 aliguori
    }
762 63a01ef8 aliguori
763 63a01ef8 aliguori
    if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
764 63a01ef8 aliguori
        syslog(LOG_ERR, "Can't get flags\n");
765 63a01ef8 aliguori
766 63a01ef8 aliguori
    snprintf (actual_name, 32, "tap%d", ppa);
767 63a01ef8 aliguori
    pstrcpy(ifr.lifr_name, sizeof(ifr.lifr_name), actual_name);
768 63a01ef8 aliguori
769 63a01ef8 aliguori
    ifr.lifr_ppa = ppa;
770 63a01ef8 aliguori
    /* Assign ppa according to the unit number returned by tun device */
771 63a01ef8 aliguori
772 63a01ef8 aliguori
    if (ioctl (if_fd, SIOCSLIFNAME, &ifr) < 0)
773 63a01ef8 aliguori
        syslog (LOG_ERR, "Can't set PPA %d", ppa);
774 63a01ef8 aliguori
    if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0)
775 63a01ef8 aliguori
        syslog (LOG_ERR, "Can't get flags\n");
776 63a01ef8 aliguori
    /* Push arp module to if_fd */
777 63a01ef8 aliguori
    if (ioctl (if_fd, I_PUSH, "arp") < 0)
778 63a01ef8 aliguori
        syslog (LOG_ERR, "Can't push ARP module (2)");
779 63a01ef8 aliguori
780 63a01ef8 aliguori
    /* Push arp module to ip_fd */
781 63a01ef8 aliguori
    if (ioctl (ip_fd, I_POP, NULL) < 0)
782 63a01ef8 aliguori
        syslog (LOG_ERR, "I_POP failed\n");
783 63a01ef8 aliguori
    if (ioctl (ip_fd, I_PUSH, "arp") < 0)
784 63a01ef8 aliguori
        syslog (LOG_ERR, "Can't push ARP module (3)\n");
785 63a01ef8 aliguori
    /* Open arp_fd */
786 63a01ef8 aliguori
    TFR(arp_fd = open ("/dev/tap", O_RDWR, 0));
787 63a01ef8 aliguori
    if (arp_fd < 0)
788 63a01ef8 aliguori
       syslog (LOG_ERR, "Can't open %s\n", "/dev/tap");
789 63a01ef8 aliguori
790 63a01ef8 aliguori
    /* Set ifname to arp */
791 63a01ef8 aliguori
    strioc_if.ic_cmd = SIOCSLIFNAME;
792 63a01ef8 aliguori
    strioc_if.ic_timout = 0;
793 63a01ef8 aliguori
    strioc_if.ic_len = sizeof(ifr);
794 63a01ef8 aliguori
    strioc_if.ic_dp = (char *)&ifr;
795 63a01ef8 aliguori
    if (ioctl(arp_fd, I_STR, &strioc_if) < 0){
796 63a01ef8 aliguori
        syslog (LOG_ERR, "Can't set ifname to arp\n");
797 63a01ef8 aliguori
    }
798 63a01ef8 aliguori
799 63a01ef8 aliguori
    if((ip_muxid = ioctl(ip_fd, I_LINK, if_fd)) < 0){
800 63a01ef8 aliguori
       syslog(LOG_ERR, "Can't link TAP device to IP");
801 63a01ef8 aliguori
       return -1;
802 63a01ef8 aliguori
    }
803 63a01ef8 aliguori
804 63a01ef8 aliguori
    if ((arp_muxid = ioctl (ip_fd, link_type, arp_fd)) < 0)
805 63a01ef8 aliguori
        syslog (LOG_ERR, "Can't link TAP device to ARP");
806 63a01ef8 aliguori
807 63a01ef8 aliguori
    close (if_fd);
808 63a01ef8 aliguori
809 63a01ef8 aliguori
    memset(&ifr, 0x0, sizeof(ifr));
810 63a01ef8 aliguori
    pstrcpy(ifr.lifr_name, sizeof(ifr.lifr_name), actual_name);
811 63a01ef8 aliguori
    ifr.lifr_ip_muxid  = ip_muxid;
812 63a01ef8 aliguori
    ifr.lifr_arp_muxid = arp_muxid;
813 63a01ef8 aliguori
814 63a01ef8 aliguori
    if (ioctl (ip_fd, SIOCSLIFMUXID, &ifr) < 0)
815 63a01ef8 aliguori
    {
816 63a01ef8 aliguori
      ioctl (ip_fd, I_PUNLINK , arp_muxid);
817 63a01ef8 aliguori
      ioctl (ip_fd, I_PUNLINK, ip_muxid);
818 63a01ef8 aliguori
      syslog (LOG_ERR, "Can't set multiplexor id");
819 63a01ef8 aliguori
    }
820 63a01ef8 aliguori
821 63a01ef8 aliguori
    snprintf(dev, dev_size, "tap%d", ppa);
822 63a01ef8 aliguori
    return tap_fd;
823 63a01ef8 aliguori
}
824 63a01ef8 aliguori
825 63a01ef8 aliguori
static int tap_open(char *ifname, int ifname_size)
826 63a01ef8 aliguori
{
827 63a01ef8 aliguori
    char  dev[10]="";
828 63a01ef8 aliguori
    int fd;
829 63a01ef8 aliguori
    if( (fd = tap_alloc(dev, sizeof(dev))) < 0 ){
830 63a01ef8 aliguori
       fprintf(stderr, "Cannot allocate TAP device\n");
831 63a01ef8 aliguori
       return -1;
832 63a01ef8 aliguori
    }
833 63a01ef8 aliguori
    pstrcpy(ifname, ifname_size, dev);
834 63a01ef8 aliguori
    fcntl(fd, F_SETFL, O_NONBLOCK);
835 63a01ef8 aliguori
    return fd;
836 63a01ef8 aliguori
}
837 b29fe3ed malc
#elif defined (_AIX)
838 b29fe3ed malc
static int tap_open(char *ifname, int ifname_size)
839 b29fe3ed malc
{
840 b29fe3ed malc
    fprintf (stderr, "no tap on AIX\n");
841 b29fe3ed malc
    return -1;
842 b29fe3ed malc
}
843 63a01ef8 aliguori
#else
844 63a01ef8 aliguori
static int tap_open(char *ifname, int ifname_size)
845 63a01ef8 aliguori
{
846 63a01ef8 aliguori
    struct ifreq ifr;
847 63a01ef8 aliguori
    int fd, ret;
848 63a01ef8 aliguori
849 63a01ef8 aliguori
    TFR(fd = open("/dev/net/tun", O_RDWR));
850 63a01ef8 aliguori
    if (fd < 0) {
851 63a01ef8 aliguori
        fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
852 63a01ef8 aliguori
        return -1;
853 63a01ef8 aliguori
    }
854 63a01ef8 aliguori
    memset(&ifr, 0, sizeof(ifr));
855 63a01ef8 aliguori
    ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
856 63a01ef8 aliguori
    if (ifname[0] != '\0')
857 63a01ef8 aliguori
        pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname);
858 63a01ef8 aliguori
    else
859 63a01ef8 aliguori
        pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d");
860 63a01ef8 aliguori
    ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
861 63a01ef8 aliguori
    if (ret != 0) {
862 63a01ef8 aliguori
        fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
863 63a01ef8 aliguori
        close(fd);
864 63a01ef8 aliguori
        return -1;
865 63a01ef8 aliguori
    }
866 63a01ef8 aliguori
    pstrcpy(ifname, ifname_size, ifr.ifr_name);
867 63a01ef8 aliguori
    fcntl(fd, F_SETFL, O_NONBLOCK);
868 63a01ef8 aliguori
    return fd;
869 63a01ef8 aliguori
}
870 63a01ef8 aliguori
#endif
871 63a01ef8 aliguori
872 63a01ef8 aliguori
static int launch_script(const char *setup_script, const char *ifname, int fd)
873 63a01ef8 aliguori
{
874 63a01ef8 aliguori
    int pid, status;
875 63a01ef8 aliguori
    char *args[3];
876 63a01ef8 aliguori
    char **parg;
877 63a01ef8 aliguori
878 63a01ef8 aliguori
        /* try to launch network script */
879 63a01ef8 aliguori
        pid = fork();
880 63a01ef8 aliguori
        if (pid >= 0) {
881 63a01ef8 aliguori
            if (pid == 0) {
882 63a01ef8 aliguori
                int open_max = sysconf (_SC_OPEN_MAX), i;
883 63a01ef8 aliguori
                for (i = 0; i < open_max; i++)
884 63a01ef8 aliguori
                    if (i != STDIN_FILENO &&
885 63a01ef8 aliguori
                        i != STDOUT_FILENO &&
886 63a01ef8 aliguori
                        i != STDERR_FILENO &&
887 63a01ef8 aliguori
                        i != fd)
888 63a01ef8 aliguori
                        close(i);
889 63a01ef8 aliguori
890 63a01ef8 aliguori
                parg = args;
891 63a01ef8 aliguori
                *parg++ = (char *)setup_script;
892 63a01ef8 aliguori
                *parg++ = (char *)ifname;
893 63a01ef8 aliguori
                *parg++ = NULL;
894 63a01ef8 aliguori
                execv(setup_script, args);
895 63a01ef8 aliguori
                _exit(1);
896 63a01ef8 aliguori
            }
897 63a01ef8 aliguori
            while (waitpid(pid, &status, 0) != pid);
898 63a01ef8 aliguori
            if (!WIFEXITED(status) ||
899 63a01ef8 aliguori
                WEXITSTATUS(status) != 0) {
900 63a01ef8 aliguori
                fprintf(stderr, "%s: could not launch network script\n",
901 63a01ef8 aliguori
                        setup_script);
902 63a01ef8 aliguori
                return -1;
903 63a01ef8 aliguori
            }
904 63a01ef8 aliguori
        }
905 63a01ef8 aliguori
    return 0;
906 63a01ef8 aliguori
}
907 63a01ef8 aliguori
908 63a01ef8 aliguori
static int net_tap_init(VLANState *vlan, const char *ifname1,
909 63a01ef8 aliguori
                        const char *setup_script, const char *down_script)
910 63a01ef8 aliguori
{
911 63a01ef8 aliguori
    TAPState *s;
912 63a01ef8 aliguori
    int fd;
913 63a01ef8 aliguori
    char ifname[128];
914 63a01ef8 aliguori
915 63a01ef8 aliguori
    if (ifname1 != NULL)
916 63a01ef8 aliguori
        pstrcpy(ifname, sizeof(ifname), ifname1);
917 63a01ef8 aliguori
    else
918 63a01ef8 aliguori
        ifname[0] = '\0';
919 63a01ef8 aliguori
    TFR(fd = tap_open(ifname, sizeof(ifname)));
920 63a01ef8 aliguori
    if (fd < 0)
921 63a01ef8 aliguori
        return -1;
922 63a01ef8 aliguori
923 63a01ef8 aliguori
    if (!setup_script || !strcmp(setup_script, "no"))
924 63a01ef8 aliguori
        setup_script = "";
925 63a01ef8 aliguori
    if (setup_script[0] != '\0') {
926 63a01ef8 aliguori
        if (launch_script(setup_script, ifname, fd))
927 63a01ef8 aliguori
            return -1;
928 63a01ef8 aliguori
    }
929 63a01ef8 aliguori
    s = net_tap_fd_init(vlan, fd);
930 63a01ef8 aliguori
    if (!s)
931 63a01ef8 aliguori
        return -1;
932 63a01ef8 aliguori
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
933 63a01ef8 aliguori
             "tap: ifname=%s setup_script=%s", ifname, setup_script);
934 63a01ef8 aliguori
    if (down_script && strcmp(down_script, "no"))
935 63a01ef8 aliguori
        snprintf(s->down_script, sizeof(s->down_script), "%s", down_script);
936 63a01ef8 aliguori
    return 0;
937 63a01ef8 aliguori
}
938 63a01ef8 aliguori
939 63a01ef8 aliguori
#endif /* !_WIN32 */
940 63a01ef8 aliguori
941 63a01ef8 aliguori
#if defined(CONFIG_VDE)
942 63a01ef8 aliguori
typedef struct VDEState {
943 63a01ef8 aliguori
    VLANClientState *vc;
944 63a01ef8 aliguori
    VDECONN *vde;
945 63a01ef8 aliguori
} VDEState;
946 63a01ef8 aliguori
947 63a01ef8 aliguori
static void vde_to_qemu(void *opaque)
948 63a01ef8 aliguori
{
949 63a01ef8 aliguori
    VDEState *s = opaque;
950 63a01ef8 aliguori
    uint8_t buf[4096];
951 63a01ef8 aliguori
    int size;
952 63a01ef8 aliguori
953 63a01ef8 aliguori
    size = vde_recv(s->vde, buf, sizeof(buf), 0);
954 63a01ef8 aliguori
    if (size > 0) {
955 63a01ef8 aliguori
        qemu_send_packet(s->vc, buf, size);
956 63a01ef8 aliguori
    }
957 63a01ef8 aliguori
}
958 63a01ef8 aliguori
959 63a01ef8 aliguori
static void vde_from_qemu(void *opaque, const uint8_t *buf, int size)
960 63a01ef8 aliguori
{
961 63a01ef8 aliguori
    VDEState *s = opaque;
962 63a01ef8 aliguori
    int ret;
963 63a01ef8 aliguori
    for(;;) {
964 63a01ef8 aliguori
        ret = vde_send(s->vde, buf, size, 0);
965 63a01ef8 aliguori
        if (ret < 0 && errno == EINTR) {
966 63a01ef8 aliguori
        } else {
967 63a01ef8 aliguori
            break;
968 63a01ef8 aliguori
        }
969 63a01ef8 aliguori
    }
970 63a01ef8 aliguori
}
971 63a01ef8 aliguori
972 63a01ef8 aliguori
static int net_vde_init(VLANState *vlan, const char *sock, int port,
973 63a01ef8 aliguori
                        const char *group, int mode)
974 63a01ef8 aliguori
{
975 63a01ef8 aliguori
    VDEState *s;
976 63a01ef8 aliguori
    char *init_group = strlen(group) ? (char *)group : NULL;
977 63a01ef8 aliguori
    char *init_sock = strlen(sock) ? (char *)sock : NULL;
978 63a01ef8 aliguori
979 63a01ef8 aliguori
    struct vde_open_args args = {
980 63a01ef8 aliguori
        .port = port,
981 63a01ef8 aliguori
        .group = init_group,
982 63a01ef8 aliguori
        .mode = mode,
983 63a01ef8 aliguori
    };
984 63a01ef8 aliguori
985 63a01ef8 aliguori
    s = qemu_mallocz(sizeof(VDEState));
986 63a01ef8 aliguori
    if (!s)
987 63a01ef8 aliguori
        return -1;
988 63a01ef8 aliguori
    s->vde = vde_open(init_sock, "QEMU", &args);
989 63a01ef8 aliguori
    if (!s->vde){
990 63a01ef8 aliguori
        free(s);
991 63a01ef8 aliguori
        return -1;
992 63a01ef8 aliguori
    }
993 63a01ef8 aliguori
    s->vc = qemu_new_vlan_client(vlan, vde_from_qemu, NULL, s);
994 63a01ef8 aliguori
    qemu_set_fd_handler(vde_datafd(s->vde), vde_to_qemu, NULL, s);
995 63a01ef8 aliguori
    snprintf(s->vc->info_str, sizeof(s->vc->info_str), "vde: sock=%s fd=%d",
996 63a01ef8 aliguori
             sock, vde_datafd(s->vde));
997 63a01ef8 aliguori
    return 0;
998 63a01ef8 aliguori
}
999 63a01ef8 aliguori
#endif
1000 63a01ef8 aliguori
1001 63a01ef8 aliguori
/* network connection */
1002 63a01ef8 aliguori
typedef struct NetSocketState {
1003 63a01ef8 aliguori
    VLANClientState *vc;
1004 63a01ef8 aliguori
    int fd;
1005 63a01ef8 aliguori
    int state; /* 0 = getting length, 1 = getting data */
1006 63a01ef8 aliguori
    int index;
1007 63a01ef8 aliguori
    int packet_len;
1008 63a01ef8 aliguori
    uint8_t buf[4096];
1009 63a01ef8 aliguori
    struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
1010 63a01ef8 aliguori
} NetSocketState;
1011 63a01ef8 aliguori
1012 63a01ef8 aliguori
typedef struct NetSocketListenState {
1013 63a01ef8 aliguori
    VLANState *vlan;
1014 63a01ef8 aliguori
    int fd;
1015 63a01ef8 aliguori
} NetSocketListenState;
1016 63a01ef8 aliguori
1017 63a01ef8 aliguori
/* XXX: we consider we can send the whole packet without blocking */
1018 63a01ef8 aliguori
static void net_socket_receive(void *opaque, const uint8_t *buf, int size)
1019 63a01ef8 aliguori
{
1020 63a01ef8 aliguori
    NetSocketState *s = opaque;
1021 63a01ef8 aliguori
    uint32_t len;
1022 63a01ef8 aliguori
    len = htonl(size);
1023 63a01ef8 aliguori
1024 63a01ef8 aliguori
    send_all(s->fd, (const uint8_t *)&len, sizeof(len));
1025 63a01ef8 aliguori
    send_all(s->fd, buf, size);
1026 63a01ef8 aliguori
}
1027 63a01ef8 aliguori
1028 63a01ef8 aliguori
static void net_socket_receive_dgram(void *opaque, const uint8_t *buf, int size)
1029 63a01ef8 aliguori
{
1030 63a01ef8 aliguori
    NetSocketState *s = opaque;
1031 63a01ef8 aliguori
    sendto(s->fd, buf, size, 0,
1032 63a01ef8 aliguori
           (struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));
1033 63a01ef8 aliguori
}
1034 63a01ef8 aliguori
1035 63a01ef8 aliguori
static void net_socket_send(void *opaque)
1036 63a01ef8 aliguori
{
1037 63a01ef8 aliguori
    NetSocketState *s = opaque;
1038 63a01ef8 aliguori
    int l, size, err;
1039 63a01ef8 aliguori
    uint8_t buf1[4096];
1040 63a01ef8 aliguori
    const uint8_t *buf;
1041 63a01ef8 aliguori
1042 63a01ef8 aliguori
    size = recv(s->fd, buf1, sizeof(buf1), 0);
1043 63a01ef8 aliguori
    if (size < 0) {
1044 63a01ef8 aliguori
        err = socket_error();
1045 63a01ef8 aliguori
        if (err != EWOULDBLOCK)
1046 63a01ef8 aliguori
            goto eoc;
1047 63a01ef8 aliguori
    } else if (size == 0) {
1048 63a01ef8 aliguori
        /* end of connection */
1049 63a01ef8 aliguori
    eoc:
1050 63a01ef8 aliguori
        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
1051 63a01ef8 aliguori
        closesocket(s->fd);
1052 63a01ef8 aliguori
        return;
1053 63a01ef8 aliguori
    }
1054 63a01ef8 aliguori
    buf = buf1;
1055 63a01ef8 aliguori
    while (size > 0) {
1056 63a01ef8 aliguori
        /* reassemble a packet from the network */
1057 63a01ef8 aliguori
        switch(s->state) {
1058 63a01ef8 aliguori
        case 0:
1059 63a01ef8 aliguori
            l = 4 - s->index;
1060 63a01ef8 aliguori
            if (l > size)
1061 63a01ef8 aliguori
                l = size;
1062 63a01ef8 aliguori
            memcpy(s->buf + s->index, buf, l);
1063 63a01ef8 aliguori
            buf += l;
1064 63a01ef8 aliguori
            size -= l;
1065 63a01ef8 aliguori
            s->index += l;
1066 63a01ef8 aliguori
            if (s->index == 4) {
1067 63a01ef8 aliguori
                /* got length */
1068 63a01ef8 aliguori
                s->packet_len = ntohl(*(uint32_t *)s->buf);
1069 63a01ef8 aliguori
                s->index = 0;
1070 63a01ef8 aliguori
                s->state = 1;
1071 63a01ef8 aliguori
            }
1072 63a01ef8 aliguori
            break;
1073 63a01ef8 aliguori
        case 1:
1074 63a01ef8 aliguori
            l = s->packet_len - s->index;
1075 63a01ef8 aliguori
            if (l > size)
1076 63a01ef8 aliguori
                l = size;
1077 63a01ef8 aliguori
            memcpy(s->buf + s->index, buf, l);
1078 63a01ef8 aliguori
            s->index += l;
1079 63a01ef8 aliguori
            buf += l;
1080 63a01ef8 aliguori
            size -= l;
1081 63a01ef8 aliguori
            if (s->index >= s->packet_len) {
1082 63a01ef8 aliguori
                qemu_send_packet(s->vc, s->buf, s->packet_len);
1083 63a01ef8 aliguori
                s->index = 0;
1084 63a01ef8 aliguori
                s->state = 0;
1085 63a01ef8 aliguori
            }
1086 63a01ef8 aliguori
            break;
1087 63a01ef8 aliguori
        }
1088 63a01ef8 aliguori
    }
1089 63a01ef8 aliguori
}
1090 63a01ef8 aliguori
1091 63a01ef8 aliguori
static void net_socket_send_dgram(void *opaque)
1092 63a01ef8 aliguori
{
1093 63a01ef8 aliguori
    NetSocketState *s = opaque;
1094 63a01ef8 aliguori
    int size;
1095 63a01ef8 aliguori
1096 63a01ef8 aliguori
    size = recv(s->fd, s->buf, sizeof(s->buf), 0);
1097 63a01ef8 aliguori
    if (size < 0)
1098 63a01ef8 aliguori
        return;
1099 63a01ef8 aliguori
    if (size == 0) {
1100 63a01ef8 aliguori
        /* end of connection */
1101 63a01ef8 aliguori
        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
1102 63a01ef8 aliguori
        return;
1103 63a01ef8 aliguori
    }
1104 63a01ef8 aliguori
    qemu_send_packet(s->vc, s->buf, size);
1105 63a01ef8 aliguori
}
1106 63a01ef8 aliguori
1107 63a01ef8 aliguori
static int net_socket_mcast_create(struct sockaddr_in *mcastaddr)
1108 63a01ef8 aliguori
{
1109 63a01ef8 aliguori
    struct ip_mreq imr;
1110 63a01ef8 aliguori
    int fd;
1111 63a01ef8 aliguori
    int val, ret;
1112 63a01ef8 aliguori
    if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) {
1113 63a01ef8 aliguori
        fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) does not contain a multicast address\n",
1114 63a01ef8 aliguori
                inet_ntoa(mcastaddr->sin_addr),
1115 63a01ef8 aliguori
                (int)ntohl(mcastaddr->sin_addr.s_addr));
1116 63a01ef8 aliguori
        return -1;
1117 63a01ef8 aliguori
1118 63a01ef8 aliguori
    }
1119 63a01ef8 aliguori
    fd = socket(PF_INET, SOCK_DGRAM, 0);
1120 63a01ef8 aliguori
    if (fd < 0) {
1121 63a01ef8 aliguori
        perror("socket(PF_INET, SOCK_DGRAM)");
1122 63a01ef8 aliguori
        return -1;
1123 63a01ef8 aliguori
    }
1124 63a01ef8 aliguori
1125 63a01ef8 aliguori
    val = 1;
1126 63a01ef8 aliguori
    ret=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
1127 63a01ef8 aliguori
                   (const char *)&val, sizeof(val));
1128 63a01ef8 aliguori
    if (ret < 0) {
1129 63a01ef8 aliguori
        perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)");
1130 63a01ef8 aliguori
        goto fail;
1131 63a01ef8 aliguori
    }
1132 63a01ef8 aliguori
1133 63a01ef8 aliguori
    ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
1134 63a01ef8 aliguori
    if (ret < 0) {
1135 63a01ef8 aliguori
        perror("bind");
1136 63a01ef8 aliguori
        goto fail;
1137 63a01ef8 aliguori
    }
1138 63a01ef8 aliguori
1139 63a01ef8 aliguori
    /* Add host to multicast group */
1140 63a01ef8 aliguori
    imr.imr_multiaddr = mcastaddr->sin_addr;
1141 63a01ef8 aliguori
    imr.imr_interface.s_addr = htonl(INADDR_ANY);
1142 63a01ef8 aliguori
1143 63a01ef8 aliguori
    ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
1144 63a01ef8 aliguori
                     (const char *)&imr, sizeof(struct ip_mreq));
1145 63a01ef8 aliguori
    if (ret < 0) {
1146 63a01ef8 aliguori
        perror("setsockopt(IP_ADD_MEMBERSHIP)");
1147 63a01ef8 aliguori
        goto fail;
1148 63a01ef8 aliguori
    }
1149 63a01ef8 aliguori
1150 63a01ef8 aliguori
    /* Force mcast msgs to loopback (eg. several QEMUs in same host */
1151 63a01ef8 aliguori
    val = 1;
1152 63a01ef8 aliguori
    ret=setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
1153 63a01ef8 aliguori
                   (const char *)&val, sizeof(val));
1154 63a01ef8 aliguori
    if (ret < 0) {
1155 63a01ef8 aliguori
        perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)");
1156 63a01ef8 aliguori
        goto fail;
1157 63a01ef8 aliguori
    }
1158 63a01ef8 aliguori
1159 63a01ef8 aliguori
    socket_set_nonblock(fd);
1160 63a01ef8 aliguori
    return fd;
1161 63a01ef8 aliguori
fail:
1162 63a01ef8 aliguori
    if (fd >= 0)
1163 63a01ef8 aliguori
        closesocket(fd);
1164 63a01ef8 aliguori
    return -1;
1165 63a01ef8 aliguori
}
1166 63a01ef8 aliguori
1167 63a01ef8 aliguori
static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan, int fd,
1168 63a01ef8 aliguori
                                          int is_connected)
1169 63a01ef8 aliguori
{
1170 63a01ef8 aliguori
    struct sockaddr_in saddr;
1171 63a01ef8 aliguori
    int newfd;
1172 63a01ef8 aliguori
    socklen_t saddr_len;
1173 63a01ef8 aliguori
    NetSocketState *s;
1174 63a01ef8 aliguori
1175 63a01ef8 aliguori
    /* fd passed: multicast: "learn" dgram_dst address from bound address and save it
1176 63a01ef8 aliguori
     * Because this may be "shared" socket from a "master" process, datagrams would be recv()
1177 63a01ef8 aliguori
     * by ONLY ONE process: we must "clone" this dgram socket --jjo
1178 63a01ef8 aliguori
     */
1179 63a01ef8 aliguori
1180 63a01ef8 aliguori
    if (is_connected) {
1181 63a01ef8 aliguori
        if (getsockname(fd, (struct sockaddr *) &saddr, &saddr_len) == 0) {
1182 63a01ef8 aliguori
            /* must be bound */
1183 63a01ef8 aliguori
            if (saddr.sin_addr.s_addr==0) {
1184 63a01ef8 aliguori
                fprintf(stderr, "qemu: error: init_dgram: fd=%d unbound, cannot setup multicast dst addr\n",
1185 63a01ef8 aliguori
                        fd);
1186 63a01ef8 aliguori
                return NULL;
1187 63a01ef8 aliguori
            }
1188 63a01ef8 aliguori
            /* clone dgram socket */
1189 63a01ef8 aliguori
            newfd = net_socket_mcast_create(&saddr);
1190 63a01ef8 aliguori
            if (newfd < 0) {
1191 63a01ef8 aliguori
                /* error already reported by net_socket_mcast_create() */
1192 63a01ef8 aliguori
                close(fd);
1193 63a01ef8 aliguori
                return NULL;
1194 63a01ef8 aliguori
            }
1195 63a01ef8 aliguori
            /* clone newfd to fd, close newfd */
1196 63a01ef8 aliguori
            dup2(newfd, fd);
1197 63a01ef8 aliguori
            close(newfd);
1198 63a01ef8 aliguori
1199 63a01ef8 aliguori
        } else {
1200 63a01ef8 aliguori
            fprintf(stderr, "qemu: error: init_dgram: fd=%d failed getsockname(): %s\n",
1201 63a01ef8 aliguori
                    fd, strerror(errno));
1202 63a01ef8 aliguori
            return NULL;
1203 63a01ef8 aliguori
        }
1204 63a01ef8 aliguori
    }
1205 63a01ef8 aliguori
1206 63a01ef8 aliguori
    s = qemu_mallocz(sizeof(NetSocketState));
1207 63a01ef8 aliguori
    if (!s)
1208 63a01ef8 aliguori
        return NULL;
1209 63a01ef8 aliguori
    s->fd = fd;
1210 63a01ef8 aliguori
1211 63a01ef8 aliguori
    s->vc = qemu_new_vlan_client(vlan, net_socket_receive_dgram, NULL, s);
1212 63a01ef8 aliguori
    qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
1213 63a01ef8 aliguori
1214 63a01ef8 aliguori
    /* mcast: save bound address as dst */
1215 63a01ef8 aliguori
    if (is_connected) s->dgram_dst=saddr;
1216 63a01ef8 aliguori
1217 63a01ef8 aliguori
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
1218 63a01ef8 aliguori
            "socket: fd=%d (%s mcast=%s:%d)",
1219 63a01ef8 aliguori
            fd, is_connected? "cloned" : "",
1220 63a01ef8 aliguori
            inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
1221 63a01ef8 aliguori
    return s;
1222 63a01ef8 aliguori
}
1223 63a01ef8 aliguori
1224 63a01ef8 aliguori
static void net_socket_connect(void *opaque)
1225 63a01ef8 aliguori
{
1226 63a01ef8 aliguori
    NetSocketState *s = opaque;
1227 63a01ef8 aliguori
    qemu_set_fd_handler(s->fd, net_socket_send, NULL, s);
1228 63a01ef8 aliguori
}
1229 63a01ef8 aliguori
1230 63a01ef8 aliguori
static NetSocketState *net_socket_fd_init_stream(VLANState *vlan, int fd,
1231 63a01ef8 aliguori
                                          int is_connected)
1232 63a01ef8 aliguori
{
1233 63a01ef8 aliguori
    NetSocketState *s;
1234 63a01ef8 aliguori
    s = qemu_mallocz(sizeof(NetSocketState));
1235 63a01ef8 aliguori
    if (!s)
1236 63a01ef8 aliguori
        return NULL;
1237 63a01ef8 aliguori
    s->fd = fd;
1238 63a01ef8 aliguori
    s->vc = qemu_new_vlan_client(vlan,
1239 63a01ef8 aliguori
                                 net_socket_receive, NULL, s);
1240 63a01ef8 aliguori
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
1241 63a01ef8 aliguori
             "socket: fd=%d", fd);
1242 63a01ef8 aliguori
    if (is_connected) {
1243 63a01ef8 aliguori
        net_socket_connect(s);
1244 63a01ef8 aliguori
    } else {
1245 63a01ef8 aliguori
        qemu_set_fd_handler(s->fd, NULL, net_socket_connect, s);
1246 63a01ef8 aliguori
    }
1247 63a01ef8 aliguori
    return s;
1248 63a01ef8 aliguori
}
1249 63a01ef8 aliguori
1250 63a01ef8 aliguori
static NetSocketState *net_socket_fd_init(VLANState *vlan, int fd,
1251 63a01ef8 aliguori
                                          int is_connected)
1252 63a01ef8 aliguori
{
1253 63a01ef8 aliguori
    int so_type=-1, optlen=sizeof(so_type);
1254 63a01ef8 aliguori
1255 63a01ef8 aliguori
    if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type,
1256 63a01ef8 aliguori
        (socklen_t *)&optlen)< 0) {
1257 63a01ef8 aliguori
        fprintf(stderr, "qemu: error: getsockopt(SO_TYPE) for fd=%d failed\n", fd);
1258 63a01ef8 aliguori
        return NULL;
1259 63a01ef8 aliguori
    }
1260 63a01ef8 aliguori
    switch(so_type) {
1261 63a01ef8 aliguori
    case SOCK_DGRAM:
1262 63a01ef8 aliguori
        return net_socket_fd_init_dgram(vlan, fd, is_connected);
1263 63a01ef8 aliguori
    case SOCK_STREAM:
1264 63a01ef8 aliguori
        return net_socket_fd_init_stream(vlan, fd, is_connected);
1265 63a01ef8 aliguori
    default:
1266 63a01ef8 aliguori
        /* who knows ... this could be a eg. a pty, do warn and continue as stream */
1267 63a01ef8 aliguori
        fprintf(stderr, "qemu: warning: socket type=%d for fd=%d is not SOCK_DGRAM or SOCK_STREAM\n", so_type, fd);
1268 63a01ef8 aliguori
        return net_socket_fd_init_stream(vlan, fd, is_connected);
1269 63a01ef8 aliguori
    }
1270 63a01ef8 aliguori
    return NULL;
1271 63a01ef8 aliguori
}
1272 63a01ef8 aliguori
1273 63a01ef8 aliguori
static void net_socket_accept(void *opaque)
1274 63a01ef8 aliguori
{
1275 63a01ef8 aliguori
    NetSocketListenState *s = opaque;
1276 63a01ef8 aliguori
    NetSocketState *s1;
1277 63a01ef8 aliguori
    struct sockaddr_in saddr;
1278 63a01ef8 aliguori
    socklen_t len;
1279 63a01ef8 aliguori
    int fd;
1280 63a01ef8 aliguori
1281 63a01ef8 aliguori
    for(;;) {
1282 63a01ef8 aliguori
        len = sizeof(saddr);
1283 63a01ef8 aliguori
        fd = accept(s->fd, (struct sockaddr *)&saddr, &len);
1284 63a01ef8 aliguori
        if (fd < 0 && errno != EINTR) {
1285 63a01ef8 aliguori
            return;
1286 63a01ef8 aliguori
        } else if (fd >= 0) {
1287 63a01ef8 aliguori
            break;
1288 63a01ef8 aliguori
        }
1289 63a01ef8 aliguori
    }
1290 63a01ef8 aliguori
    s1 = net_socket_fd_init(s->vlan, fd, 1);
1291 63a01ef8 aliguori
    if (!s1) {
1292 63a01ef8 aliguori
        closesocket(fd);
1293 63a01ef8 aliguori
    } else {
1294 63a01ef8 aliguori
        snprintf(s1->vc->info_str, sizeof(s1->vc->info_str),
1295 63a01ef8 aliguori
                 "socket: connection from %s:%d",
1296 63a01ef8 aliguori
                 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
1297 63a01ef8 aliguori
    }
1298 63a01ef8 aliguori
}
1299 63a01ef8 aliguori
1300 63a01ef8 aliguori
static int net_socket_listen_init(VLANState *vlan, const char *host_str)
1301 63a01ef8 aliguori
{
1302 63a01ef8 aliguori
    NetSocketListenState *s;
1303 63a01ef8 aliguori
    int fd, val, ret;
1304 63a01ef8 aliguori
    struct sockaddr_in saddr;
1305 63a01ef8 aliguori
1306 63a01ef8 aliguori
    if (parse_host_port(&saddr, host_str) < 0)
1307 63a01ef8 aliguori
        return -1;
1308 63a01ef8 aliguori
1309 63a01ef8 aliguori
    s = qemu_mallocz(sizeof(NetSocketListenState));
1310 63a01ef8 aliguori
    if (!s)
1311 63a01ef8 aliguori
        return -1;
1312 63a01ef8 aliguori
1313 63a01ef8 aliguori
    fd = socket(PF_INET, SOCK_STREAM, 0);
1314 63a01ef8 aliguori
    if (fd < 0) {
1315 63a01ef8 aliguori
        perror("socket");
1316 63a01ef8 aliguori
        return -1;
1317 63a01ef8 aliguori
    }
1318 63a01ef8 aliguori
    socket_set_nonblock(fd);
1319 63a01ef8 aliguori
1320 63a01ef8 aliguori
    /* allow fast reuse */
1321 63a01ef8 aliguori
    val = 1;
1322 63a01ef8 aliguori
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
1323 63a01ef8 aliguori
1324 63a01ef8 aliguori
    ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
1325 63a01ef8 aliguori
    if (ret < 0) {
1326 63a01ef8 aliguori
        perror("bind");
1327 63a01ef8 aliguori
        return -1;
1328 63a01ef8 aliguori
    }
1329 63a01ef8 aliguori
    ret = listen(fd, 0);
1330 63a01ef8 aliguori
    if (ret < 0) {
1331 63a01ef8 aliguori
        perror("listen");
1332 63a01ef8 aliguori
        return -1;
1333 63a01ef8 aliguori
    }
1334 63a01ef8 aliguori
    s->vlan = vlan;
1335 63a01ef8 aliguori
    s->fd = fd;
1336 63a01ef8 aliguori
    qemu_set_fd_handler(fd, net_socket_accept, NULL, s);
1337 63a01ef8 aliguori
    return 0;
1338 63a01ef8 aliguori
}
1339 63a01ef8 aliguori
1340 63a01ef8 aliguori
static int net_socket_connect_init(VLANState *vlan, const char *host_str)
1341 63a01ef8 aliguori
{
1342 63a01ef8 aliguori
    NetSocketState *s;
1343 63a01ef8 aliguori
    int fd, connected, ret, err;
1344 63a01ef8 aliguori
    struct sockaddr_in saddr;
1345 63a01ef8 aliguori
1346 63a01ef8 aliguori
    if (parse_host_port(&saddr, host_str) < 0)
1347 63a01ef8 aliguori
        return -1;
1348 63a01ef8 aliguori
1349 63a01ef8 aliguori
    fd = socket(PF_INET, SOCK_STREAM, 0);
1350 63a01ef8 aliguori
    if (fd < 0) {
1351 63a01ef8 aliguori
        perror("socket");
1352 63a01ef8 aliguori
        return -1;
1353 63a01ef8 aliguori
    }
1354 63a01ef8 aliguori
    socket_set_nonblock(fd);
1355 63a01ef8 aliguori
1356 63a01ef8 aliguori
    connected = 0;
1357 63a01ef8 aliguori
    for(;;) {
1358 63a01ef8 aliguori
        ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
1359 63a01ef8 aliguori
        if (ret < 0) {
1360 63a01ef8 aliguori
            err = socket_error();
1361 63a01ef8 aliguori
            if (err == EINTR || err == EWOULDBLOCK) {
1362 63a01ef8 aliguori
            } else if (err == EINPROGRESS) {
1363 63a01ef8 aliguori
                break;
1364 63a01ef8 aliguori
#ifdef _WIN32
1365 63a01ef8 aliguori
            } else if (err == WSAEALREADY) {
1366 63a01ef8 aliguori
                break;
1367 63a01ef8 aliguori
#endif
1368 63a01ef8 aliguori
            } else {
1369 63a01ef8 aliguori
                perror("connect");
1370 63a01ef8 aliguori
                closesocket(fd);
1371 63a01ef8 aliguori
                return -1;
1372 63a01ef8 aliguori
            }
1373 63a01ef8 aliguori
        } else {
1374 63a01ef8 aliguori
            connected = 1;
1375 63a01ef8 aliguori
            break;
1376 63a01ef8 aliguori
        }
1377 63a01ef8 aliguori
    }
1378 63a01ef8 aliguori
    s = net_socket_fd_init(vlan, fd, connected);
1379 63a01ef8 aliguori
    if (!s)
1380 63a01ef8 aliguori
        return -1;
1381 63a01ef8 aliguori
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
1382 63a01ef8 aliguori
             "socket: connect to %s:%d",
1383 63a01ef8 aliguori
             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
1384 63a01ef8 aliguori
    return 0;
1385 63a01ef8 aliguori
}
1386 63a01ef8 aliguori
1387 63a01ef8 aliguori
static int net_socket_mcast_init(VLANState *vlan, const char *host_str)
1388 63a01ef8 aliguori
{
1389 63a01ef8 aliguori
    NetSocketState *s;
1390 63a01ef8 aliguori
    int fd;
1391 63a01ef8 aliguori
    struct sockaddr_in saddr;
1392 63a01ef8 aliguori
1393 63a01ef8 aliguori
    if (parse_host_port(&saddr, host_str) < 0)
1394 63a01ef8 aliguori
        return -1;
1395 63a01ef8 aliguori
1396 63a01ef8 aliguori
1397 63a01ef8 aliguori
    fd = net_socket_mcast_create(&saddr);
1398 63a01ef8 aliguori
    if (fd < 0)
1399 63a01ef8 aliguori
        return -1;
1400 63a01ef8 aliguori
1401 63a01ef8 aliguori
    s = net_socket_fd_init(vlan, fd, 0);
1402 63a01ef8 aliguori
    if (!s)
1403 63a01ef8 aliguori
        return -1;
1404 63a01ef8 aliguori
1405 63a01ef8 aliguori
    s->dgram_dst = saddr;
1406 63a01ef8 aliguori
1407 63a01ef8 aliguori
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
1408 63a01ef8 aliguori
             "socket: mcast=%s:%d",
1409 63a01ef8 aliguori
             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
1410 63a01ef8 aliguori
    return 0;
1411 63a01ef8 aliguori
1412 63a01ef8 aliguori
}
1413 63a01ef8 aliguori
1414 63a01ef8 aliguori
/* find or alloc a new VLAN */
1415 63a01ef8 aliguori
VLANState *qemu_find_vlan(int id)
1416 63a01ef8 aliguori
{
1417 63a01ef8 aliguori
    VLANState **pvlan, *vlan;
1418 63a01ef8 aliguori
    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
1419 63a01ef8 aliguori
        if (vlan->id == id)
1420 63a01ef8 aliguori
            return vlan;
1421 63a01ef8 aliguori
    }
1422 63a01ef8 aliguori
    vlan = qemu_mallocz(sizeof(VLANState));
1423 63a01ef8 aliguori
    if (!vlan)
1424 63a01ef8 aliguori
        return NULL;
1425 63a01ef8 aliguori
    vlan->id = id;
1426 63a01ef8 aliguori
    vlan->next = NULL;
1427 63a01ef8 aliguori
    pvlan = &first_vlan;
1428 63a01ef8 aliguori
    while (*pvlan != NULL)
1429 63a01ef8 aliguori
        pvlan = &(*pvlan)->next;
1430 63a01ef8 aliguori
    *pvlan = vlan;
1431 63a01ef8 aliguori
    return vlan;
1432 63a01ef8 aliguori
}
1433 63a01ef8 aliguori
1434 63a01ef8 aliguori
int net_client_init(const char *device, const char *p)
1435 63a01ef8 aliguori
{
1436 63a01ef8 aliguori
    char buf[1024];
1437 63a01ef8 aliguori
    int vlan_id, ret;
1438 63a01ef8 aliguori
    VLANState *vlan;
1439 63a01ef8 aliguori
1440 63a01ef8 aliguori
    vlan_id = 0;
1441 63a01ef8 aliguori
    if (get_param_value(buf, sizeof(buf), "vlan", p)) {
1442 63a01ef8 aliguori
        vlan_id = strtol(buf, NULL, 0);
1443 63a01ef8 aliguori
    }
1444 63a01ef8 aliguori
    vlan = qemu_find_vlan(vlan_id);
1445 63a01ef8 aliguori
    if (!vlan) {
1446 63a01ef8 aliguori
        fprintf(stderr, "Could not create vlan %d\n", vlan_id);
1447 63a01ef8 aliguori
        return -1;
1448 63a01ef8 aliguori
    }
1449 63a01ef8 aliguori
    if (!strcmp(device, "nic")) {
1450 63a01ef8 aliguori
        NICInfo *nd;
1451 63a01ef8 aliguori
        uint8_t *macaddr;
1452 63a01ef8 aliguori
1453 63a01ef8 aliguori
        if (nb_nics >= MAX_NICS) {
1454 63a01ef8 aliguori
            fprintf(stderr, "Too Many NICs\n");
1455 63a01ef8 aliguori
            return -1;
1456 63a01ef8 aliguori
        }
1457 63a01ef8 aliguori
        nd = &nd_table[nb_nics];
1458 63a01ef8 aliguori
        macaddr = nd->macaddr;
1459 63a01ef8 aliguori
        macaddr[0] = 0x52;
1460 63a01ef8 aliguori
        macaddr[1] = 0x54;
1461 63a01ef8 aliguori
        macaddr[2] = 0x00;
1462 63a01ef8 aliguori
        macaddr[3] = 0x12;
1463 63a01ef8 aliguori
        macaddr[4] = 0x34;
1464 63a01ef8 aliguori
        macaddr[5] = 0x56 + nb_nics;
1465 63a01ef8 aliguori
1466 63a01ef8 aliguori
        if (get_param_value(buf, sizeof(buf), "macaddr", p)) {
1467 63a01ef8 aliguori
            if (parse_macaddr(macaddr, buf) < 0) {
1468 63a01ef8 aliguori
                fprintf(stderr, "invalid syntax for ethernet address\n");
1469 63a01ef8 aliguori
                return -1;
1470 63a01ef8 aliguori
            }
1471 63a01ef8 aliguori
        }
1472 63a01ef8 aliguori
        if (get_param_value(buf, sizeof(buf), "model", p)) {
1473 63a01ef8 aliguori
            nd->model = strdup(buf);
1474 63a01ef8 aliguori
        }
1475 63a01ef8 aliguori
        nd->vlan = vlan;
1476 63a01ef8 aliguori
        nb_nics++;
1477 63a01ef8 aliguori
        vlan->nb_guest_devs++;
1478 63a01ef8 aliguori
        ret = 0;
1479 63a01ef8 aliguori
    } else
1480 63a01ef8 aliguori
    if (!strcmp(device, "none")) {
1481 63a01ef8 aliguori
        /* does nothing. It is needed to signal that no network cards
1482 63a01ef8 aliguori
           are wanted */
1483 63a01ef8 aliguori
        ret = 0;
1484 63a01ef8 aliguori
    } else
1485 63a01ef8 aliguori
#ifdef CONFIG_SLIRP
1486 63a01ef8 aliguori
    if (!strcmp(device, "user")) {
1487 63a01ef8 aliguori
        if (get_param_value(buf, sizeof(buf), "hostname", p)) {
1488 63a01ef8 aliguori
            pstrcpy(slirp_hostname, sizeof(slirp_hostname), buf);
1489 63a01ef8 aliguori
        }
1490 63a01ef8 aliguori
        vlan->nb_host_devs++;
1491 63a01ef8 aliguori
        ret = net_slirp_init(vlan);
1492 63a01ef8 aliguori
    } else
1493 63a01ef8 aliguori
#endif
1494 63a01ef8 aliguori
#ifdef _WIN32
1495 63a01ef8 aliguori
    if (!strcmp(device, "tap")) {
1496 63a01ef8 aliguori
        char ifname[64];
1497 63a01ef8 aliguori
        if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
1498 63a01ef8 aliguori
            fprintf(stderr, "tap: no interface name\n");
1499 63a01ef8 aliguori
            return -1;
1500 63a01ef8 aliguori
        }
1501 63a01ef8 aliguori
        vlan->nb_host_devs++;
1502 63a01ef8 aliguori
        ret = tap_win32_init(vlan, ifname);
1503 63a01ef8 aliguori
    } else
1504 b29fe3ed malc
#elif defined (_AIX)
1505 63a01ef8 aliguori
#else
1506 63a01ef8 aliguori
    if (!strcmp(device, "tap")) {
1507 63a01ef8 aliguori
        char ifname[64];
1508 63a01ef8 aliguori
        char setup_script[1024], down_script[1024];
1509 63a01ef8 aliguori
        int fd;
1510 63a01ef8 aliguori
        vlan->nb_host_devs++;
1511 63a01ef8 aliguori
        if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
1512 63a01ef8 aliguori
            fd = strtol(buf, NULL, 0);
1513 63a01ef8 aliguori
            fcntl(fd, F_SETFL, O_NONBLOCK);
1514 63a01ef8 aliguori
            ret = -1;
1515 63a01ef8 aliguori
            if (net_tap_fd_init(vlan, fd))
1516 63a01ef8 aliguori
                ret = 0;
1517 63a01ef8 aliguori
        } else {
1518 63a01ef8 aliguori
            if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
1519 63a01ef8 aliguori
                ifname[0] = '\0';
1520 63a01ef8 aliguori
            }
1521 63a01ef8 aliguori
            if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) {
1522 63a01ef8 aliguori
                pstrcpy(setup_script, sizeof(setup_script), DEFAULT_NETWORK_SCRIPT);
1523 63a01ef8 aliguori
            }
1524 63a01ef8 aliguori
            if (get_param_value(down_script, sizeof(down_script), "downscript", p) == 0) {
1525 63a01ef8 aliguori
                pstrcpy(down_script, sizeof(down_script), DEFAULT_NETWORK_DOWN_SCRIPT);
1526 63a01ef8 aliguori
            }
1527 63a01ef8 aliguori
            ret = net_tap_init(vlan, ifname, setup_script, down_script);
1528 63a01ef8 aliguori
        }
1529 63a01ef8 aliguori
    } else
1530 63a01ef8 aliguori
#endif
1531 63a01ef8 aliguori
    if (!strcmp(device, "socket")) {
1532 63a01ef8 aliguori
        if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
1533 63a01ef8 aliguori
            int fd;
1534 63a01ef8 aliguori
            fd = strtol(buf, NULL, 0);
1535 63a01ef8 aliguori
            ret = -1;
1536 63a01ef8 aliguori
            if (net_socket_fd_init(vlan, fd, 1))
1537 63a01ef8 aliguori
                ret = 0;
1538 63a01ef8 aliguori
        } else if (get_param_value(buf, sizeof(buf), "listen", p) > 0) {
1539 63a01ef8 aliguori
            ret = net_socket_listen_init(vlan, buf);
1540 63a01ef8 aliguori
        } else if (get_param_value(buf, sizeof(buf), "connect", p) > 0) {
1541 63a01ef8 aliguori
            ret = net_socket_connect_init(vlan, buf);
1542 63a01ef8 aliguori
        } else if (get_param_value(buf, sizeof(buf), "mcast", p) > 0) {
1543 63a01ef8 aliguori
            ret = net_socket_mcast_init(vlan, buf);
1544 63a01ef8 aliguori
        } else {
1545 63a01ef8 aliguori
            fprintf(stderr, "Unknown socket options: %s\n", p);
1546 63a01ef8 aliguori
            return -1;
1547 63a01ef8 aliguori
        }
1548 63a01ef8 aliguori
        vlan->nb_host_devs++;
1549 63a01ef8 aliguori
    } else
1550 63a01ef8 aliguori
#ifdef CONFIG_VDE
1551 63a01ef8 aliguori
    if (!strcmp(device, "vde")) {
1552 63a01ef8 aliguori
        char vde_sock[1024], vde_group[512];
1553 63a01ef8 aliguori
        int vde_port, vde_mode;
1554 63a01ef8 aliguori
        vlan->nb_host_devs++;
1555 63a01ef8 aliguori
        if (get_param_value(vde_sock, sizeof(vde_sock), "sock", p) <= 0) {
1556 63a01ef8 aliguori
            vde_sock[0] = '\0';
1557 63a01ef8 aliguori
        }
1558 63a01ef8 aliguori
        if (get_param_value(buf, sizeof(buf), "port", p) > 0) {
1559 63a01ef8 aliguori
            vde_port = strtol(buf, NULL, 10);
1560 63a01ef8 aliguori
        } else {
1561 63a01ef8 aliguori
            vde_port = 0;
1562 63a01ef8 aliguori
        }
1563 63a01ef8 aliguori
        if (get_param_value(vde_group, sizeof(vde_group), "group", p) <= 0) {
1564 63a01ef8 aliguori
            vde_group[0] = '\0';
1565 63a01ef8 aliguori
        }
1566 63a01ef8 aliguori
        if (get_param_value(buf, sizeof(buf), "mode", p) > 0) {
1567 63a01ef8 aliguori
            vde_mode = strtol(buf, NULL, 8);
1568 63a01ef8 aliguori
        } else {
1569 63a01ef8 aliguori
            vde_mode = 0700;
1570 63a01ef8 aliguori
        }
1571 63a01ef8 aliguori
        ret = net_vde_init(vlan, vde_sock, vde_port, vde_group, vde_mode);
1572 63a01ef8 aliguori
    } else
1573 63a01ef8 aliguori
#endif
1574 63a01ef8 aliguori
    {
1575 63a01ef8 aliguori
        fprintf(stderr, "Unknown network device: %s\n", device);
1576 63a01ef8 aliguori
        return -1;
1577 63a01ef8 aliguori
    }
1578 63a01ef8 aliguori
    if (ret < 0) {
1579 63a01ef8 aliguori
        fprintf(stderr, "Could not initialize device '%s'\n", device);
1580 63a01ef8 aliguori
    }
1581 63a01ef8 aliguori
1582 63a01ef8 aliguori
    return ret;
1583 63a01ef8 aliguori
}
1584 63a01ef8 aliguori
1585 63a01ef8 aliguori
int net_client_parse(const char *str)
1586 63a01ef8 aliguori
{
1587 63a01ef8 aliguori
    const char *p;
1588 63a01ef8 aliguori
    char *q;
1589 63a01ef8 aliguori
    char device[64];
1590 63a01ef8 aliguori
1591 63a01ef8 aliguori
    p = str;
1592 63a01ef8 aliguori
    q = device;
1593 63a01ef8 aliguori
    while (*p != '\0' && *p != ',') {
1594 63a01ef8 aliguori
        if ((q - device) < sizeof(device) - 1)
1595 63a01ef8 aliguori
            *q++ = *p;
1596 63a01ef8 aliguori
        p++;
1597 63a01ef8 aliguori
    }
1598 63a01ef8 aliguori
    *q = '\0';
1599 63a01ef8 aliguori
    if (*p == ',')
1600 63a01ef8 aliguori
        p++;
1601 63a01ef8 aliguori
1602 63a01ef8 aliguori
    return net_client_init(device, p);
1603 63a01ef8 aliguori
}
1604 63a01ef8 aliguori
1605 63a01ef8 aliguori
void do_info_network(void)
1606 63a01ef8 aliguori
{
1607 63a01ef8 aliguori
    VLANState *vlan;
1608 63a01ef8 aliguori
    VLANClientState *vc;
1609 63a01ef8 aliguori
1610 63a01ef8 aliguori
    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
1611 63a01ef8 aliguori
        term_printf("VLAN %d devices:\n", vlan->id);
1612 63a01ef8 aliguori
        for(vc = vlan->first_client; vc != NULL; vc = vc->next)
1613 63a01ef8 aliguori
            term_printf("  %s\n", vc->info_str);
1614 63a01ef8 aliguori
    }
1615 63a01ef8 aliguori
}
1616 63a01ef8 aliguori
1617 63a01ef8 aliguori
void net_cleanup(void)
1618 63a01ef8 aliguori
{
1619 63a01ef8 aliguori
    VLANState *vlan;
1620 63a01ef8 aliguori
1621 63a01ef8 aliguori
#if !defined(_WIN32)
1622 63a01ef8 aliguori
    /* close network clients */
1623 63a01ef8 aliguori
    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
1624 63a01ef8 aliguori
        VLANClientState *vc;
1625 63a01ef8 aliguori
1626 63a01ef8 aliguori
        for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
1627 63a01ef8 aliguori
            if (vc->fd_read == tap_receive) {
1628 63a01ef8 aliguori
                char ifname[64];
1629 63a01ef8 aliguori
                TAPState *s = vc->opaque;
1630 63a01ef8 aliguori
1631 63a01ef8 aliguori
                if (sscanf(vc->info_str, "tap: ifname=%63s ", ifname) == 1 &&
1632 63a01ef8 aliguori
                    s->down_script[0])
1633 63a01ef8 aliguori
                    launch_script(s->down_script, ifname, s->fd);
1634 63a01ef8 aliguori
            }
1635 63a01ef8 aliguori
#if defined(CONFIG_VDE)
1636 63a01ef8 aliguori
            if (vc->fd_read == vde_from_qemu) {
1637 63a01ef8 aliguori
                VDEState *s = vc->opaque;
1638 63a01ef8 aliguori
                vde_close(s->vde);
1639 63a01ef8 aliguori
            }
1640 63a01ef8 aliguori
#endif
1641 63a01ef8 aliguori
        }
1642 63a01ef8 aliguori
    }
1643 63a01ef8 aliguori
#endif
1644 63a01ef8 aliguori
}
1645 63a01ef8 aliguori
1646 63a01ef8 aliguori
void net_client_check(void)
1647 63a01ef8 aliguori
{
1648 63a01ef8 aliguori
    VLANState *vlan;
1649 63a01ef8 aliguori
1650 63a01ef8 aliguori
    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
1651 63a01ef8 aliguori
        if (vlan->nb_guest_devs == 0 && vlan->nb_host_devs == 0)
1652 63a01ef8 aliguori
            continue;
1653 63a01ef8 aliguori
        if (vlan->nb_guest_devs == 0)
1654 63a01ef8 aliguori
            fprintf(stderr, "Warning: vlan %d with no nics\n", vlan->id);
1655 63a01ef8 aliguori
        if (vlan->nb_host_devs == 0)
1656 63a01ef8 aliguori
            fprintf(stderr,
1657 63a01ef8 aliguori
                    "Warning: vlan %d is not connected to host network\n",
1658 63a01ef8 aliguori
                    vlan->id);
1659 63a01ef8 aliguori
    }
1660 63a01ef8 aliguori
}