Statistics
| Branch: | Revision:

root / net.c @ 7ffa4767

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