Statistics
| Branch: | Revision:

root / net.c @ 9036de1a

History | View | Annotate | Download (50 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 3f4cb3d3 blueswir1
    snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%ld", (long)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
static ssize_t tap_receive_iov(void *opaque, const struct iovec *iov,
706 b535b7b2 aliguori
                               int iovcnt)
707 b535b7b2 aliguori
{
708 b535b7b2 aliguori
    TAPState *s = opaque;
709 b535b7b2 aliguori
    ssize_t len;
710 b535b7b2 aliguori
711 b535b7b2 aliguori
    do {
712 b535b7b2 aliguori
        len = writev(s->fd, iov, iovcnt);
713 b535b7b2 aliguori
    } while (len == -1 && (errno == EINTR || errno == EAGAIN));
714 b535b7b2 aliguori
715 b535b7b2 aliguori
    return len;
716 b535b7b2 aliguori
}
717 b535b7b2 aliguori
718 63a01ef8 aliguori
static void tap_receive(void *opaque, const uint8_t *buf, int size)
719 63a01ef8 aliguori
{
720 63a01ef8 aliguori
    TAPState *s = opaque;
721 63a01ef8 aliguori
    int ret;
722 63a01ef8 aliguori
    for(;;) {
723 63a01ef8 aliguori
        ret = write(s->fd, buf, size);
724 63a01ef8 aliguori
        if (ret < 0 && (errno == EINTR || errno == EAGAIN)) {
725 63a01ef8 aliguori
        } else {
726 63a01ef8 aliguori
            break;
727 63a01ef8 aliguori
        }
728 63a01ef8 aliguori
    }
729 63a01ef8 aliguori
}
730 63a01ef8 aliguori
731 63a01ef8 aliguori
static void tap_send(void *opaque)
732 63a01ef8 aliguori
{
733 63a01ef8 aliguori
    TAPState *s = opaque;
734 63a01ef8 aliguori
    uint8_t buf[4096];
735 63a01ef8 aliguori
    int size;
736 63a01ef8 aliguori
737 63a01ef8 aliguori
#ifdef __sun__
738 63a01ef8 aliguori
    struct strbuf sbuf;
739 63a01ef8 aliguori
    int f = 0;
740 63a01ef8 aliguori
    sbuf.maxlen = sizeof(buf);
741 3f4cb3d3 blueswir1
    sbuf.buf = (char *)buf;
742 63a01ef8 aliguori
    size = getmsg(s->fd, NULL, &sbuf, &f) >=0 ? sbuf.len : -1;
743 63a01ef8 aliguori
#else
744 63a01ef8 aliguori
    size = read(s->fd, buf, sizeof(buf));
745 63a01ef8 aliguori
#endif
746 63a01ef8 aliguori
    if (size > 0) {
747 63a01ef8 aliguori
        qemu_send_packet(s->vc, buf, size);
748 63a01ef8 aliguori
    }
749 63a01ef8 aliguori
}
750 63a01ef8 aliguori
751 63a01ef8 aliguori
/* fd support */
752 63a01ef8 aliguori
753 7a9f6e4a aliguori
static TAPState *net_tap_fd_init(VLANState *vlan,
754 7a9f6e4a aliguori
                                 const char *model,
755 7a9f6e4a aliguori
                                 const char *name,
756 7a9f6e4a aliguori
                                 int fd)
757 63a01ef8 aliguori
{
758 63a01ef8 aliguori
    TAPState *s;
759 63a01ef8 aliguori
760 63a01ef8 aliguori
    s = qemu_mallocz(sizeof(TAPState));
761 63a01ef8 aliguori
    s->fd = fd;
762 7a9f6e4a aliguori
    s->vc = qemu_new_vlan_client(vlan, model, name, tap_receive, NULL, s);
763 b535b7b2 aliguori
    s->vc->fd_readv = tap_receive_iov;
764 63a01ef8 aliguori
    qemu_set_fd_handler(s->fd, tap_send, NULL, s);
765 7cb7434b aliguori
    snprintf(s->vc->info_str, sizeof(s->vc->info_str), "fd=%d", fd);
766 63a01ef8 aliguori
    return s;
767 63a01ef8 aliguori
}
768 63a01ef8 aliguori
769 179a2c19 blueswir1
#if defined (HOST_BSD) || defined (__FreeBSD_kernel__)
770 63a01ef8 aliguori
static int tap_open(char *ifname, int ifname_size)
771 63a01ef8 aliguori
{
772 63a01ef8 aliguori
    int fd;
773 63a01ef8 aliguori
    char *dev;
774 63a01ef8 aliguori
    struct stat s;
775 63a01ef8 aliguori
776 63a01ef8 aliguori
    TFR(fd = open("/dev/tap", O_RDWR));
777 63a01ef8 aliguori
    if (fd < 0) {
778 63a01ef8 aliguori
        fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n");
779 63a01ef8 aliguori
        return -1;
780 63a01ef8 aliguori
    }
781 63a01ef8 aliguori
782 63a01ef8 aliguori
    fstat(fd, &s);
783 63a01ef8 aliguori
    dev = devname(s.st_rdev, S_IFCHR);
784 63a01ef8 aliguori
    pstrcpy(ifname, ifname_size, dev);
785 63a01ef8 aliguori
786 63a01ef8 aliguori
    fcntl(fd, F_SETFL, O_NONBLOCK);
787 63a01ef8 aliguori
    return fd;
788 63a01ef8 aliguori
}
789 63a01ef8 aliguori
#elif defined(__sun__)
790 63a01ef8 aliguori
#define TUNNEWPPA       (('T'<<16) | 0x0001)
791 63a01ef8 aliguori
/*
792 63a01ef8 aliguori
 * Allocate TAP device, returns opened fd.
793 63a01ef8 aliguori
 * Stores dev name in the first arg(must be large enough).
794 63a01ef8 aliguori
 */
795 3f4cb3d3 blueswir1
static int tap_alloc(char *dev, size_t dev_size)
796 63a01ef8 aliguori
{
797 63a01ef8 aliguori
    int tap_fd, if_fd, ppa = -1;
798 63a01ef8 aliguori
    static int ip_fd = 0;
799 63a01ef8 aliguori
    char *ptr;
800 63a01ef8 aliguori
801 63a01ef8 aliguori
    static int arp_fd = 0;
802 63a01ef8 aliguori
    int ip_muxid, arp_muxid;
803 63a01ef8 aliguori
    struct strioctl  strioc_if, strioc_ppa;
804 63a01ef8 aliguori
    int link_type = I_PLINK;;
805 63a01ef8 aliguori
    struct lifreq ifr;
806 63a01ef8 aliguori
    char actual_name[32] = "";
807 63a01ef8 aliguori
808 63a01ef8 aliguori
    memset(&ifr, 0x0, sizeof(ifr));
809 63a01ef8 aliguori
810 63a01ef8 aliguori
    if( *dev ){
811 63a01ef8 aliguori
       ptr = dev;
812 47398b9c blueswir1
       while( *ptr && !qemu_isdigit((int)*ptr) ) ptr++;
813 63a01ef8 aliguori
       ppa = atoi(ptr);
814 63a01ef8 aliguori
    }
815 63a01ef8 aliguori
816 63a01ef8 aliguori
    /* Check if IP device was opened */
817 63a01ef8 aliguori
    if( ip_fd )
818 63a01ef8 aliguori
       close(ip_fd);
819 63a01ef8 aliguori
820 63a01ef8 aliguori
    TFR(ip_fd = open("/dev/udp", O_RDWR, 0));
821 63a01ef8 aliguori
    if (ip_fd < 0) {
822 63a01ef8 aliguori
       syslog(LOG_ERR, "Can't open /dev/ip (actually /dev/udp)");
823 63a01ef8 aliguori
       return -1;
824 63a01ef8 aliguori
    }
825 63a01ef8 aliguori
826 63a01ef8 aliguori
    TFR(tap_fd = open("/dev/tap", O_RDWR, 0));
827 63a01ef8 aliguori
    if (tap_fd < 0) {
828 63a01ef8 aliguori
       syslog(LOG_ERR, "Can't open /dev/tap");
829 63a01ef8 aliguori
       return -1;
830 63a01ef8 aliguori
    }
831 63a01ef8 aliguori
832 63a01ef8 aliguori
    /* Assign a new PPA and get its unit number. */
833 63a01ef8 aliguori
    strioc_ppa.ic_cmd = TUNNEWPPA;
834 63a01ef8 aliguori
    strioc_ppa.ic_timout = 0;
835 63a01ef8 aliguori
    strioc_ppa.ic_len = sizeof(ppa);
836 63a01ef8 aliguori
    strioc_ppa.ic_dp = (char *)&ppa;
837 63a01ef8 aliguori
    if ((ppa = ioctl (tap_fd, I_STR, &strioc_ppa)) < 0)
838 63a01ef8 aliguori
       syslog (LOG_ERR, "Can't assign new interface");
839 63a01ef8 aliguori
840 63a01ef8 aliguori
    TFR(if_fd = open("/dev/tap", O_RDWR, 0));
841 63a01ef8 aliguori
    if (if_fd < 0) {
842 63a01ef8 aliguori
       syslog(LOG_ERR, "Can't open /dev/tap (2)");
843 63a01ef8 aliguori
       return -1;
844 63a01ef8 aliguori
    }
845 63a01ef8 aliguori
    if(ioctl(if_fd, I_PUSH, "ip") < 0){
846 63a01ef8 aliguori
       syslog(LOG_ERR, "Can't push IP module");
847 63a01ef8 aliguori
       return -1;
848 63a01ef8 aliguori
    }
849 63a01ef8 aliguori
850 63a01ef8 aliguori
    if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
851 63a01ef8 aliguori
        syslog(LOG_ERR, "Can't get flags\n");
852 63a01ef8 aliguori
853 63a01ef8 aliguori
    snprintf (actual_name, 32, "tap%d", ppa);
854 63a01ef8 aliguori
    pstrcpy(ifr.lifr_name, sizeof(ifr.lifr_name), actual_name);
855 63a01ef8 aliguori
856 63a01ef8 aliguori
    ifr.lifr_ppa = ppa;
857 63a01ef8 aliguori
    /* Assign ppa according to the unit number returned by tun device */
858 63a01ef8 aliguori
859 63a01ef8 aliguori
    if (ioctl (if_fd, SIOCSLIFNAME, &ifr) < 0)
860 63a01ef8 aliguori
        syslog (LOG_ERR, "Can't set PPA %d", ppa);
861 63a01ef8 aliguori
    if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0)
862 63a01ef8 aliguori
        syslog (LOG_ERR, "Can't get flags\n");
863 63a01ef8 aliguori
    /* Push arp module to if_fd */
864 63a01ef8 aliguori
    if (ioctl (if_fd, I_PUSH, "arp") < 0)
865 63a01ef8 aliguori
        syslog (LOG_ERR, "Can't push ARP module (2)");
866 63a01ef8 aliguori
867 63a01ef8 aliguori
    /* Push arp module to ip_fd */
868 63a01ef8 aliguori
    if (ioctl (ip_fd, I_POP, NULL) < 0)
869 63a01ef8 aliguori
        syslog (LOG_ERR, "I_POP failed\n");
870 63a01ef8 aliguori
    if (ioctl (ip_fd, I_PUSH, "arp") < 0)
871 63a01ef8 aliguori
        syslog (LOG_ERR, "Can't push ARP module (3)\n");
872 63a01ef8 aliguori
    /* Open arp_fd */
873 63a01ef8 aliguori
    TFR(arp_fd = open ("/dev/tap", O_RDWR, 0));
874 63a01ef8 aliguori
    if (arp_fd < 0)
875 63a01ef8 aliguori
       syslog (LOG_ERR, "Can't open %s\n", "/dev/tap");
876 63a01ef8 aliguori
877 63a01ef8 aliguori
    /* Set ifname to arp */
878 63a01ef8 aliguori
    strioc_if.ic_cmd = SIOCSLIFNAME;
879 63a01ef8 aliguori
    strioc_if.ic_timout = 0;
880 63a01ef8 aliguori
    strioc_if.ic_len = sizeof(ifr);
881 63a01ef8 aliguori
    strioc_if.ic_dp = (char *)&ifr;
882 63a01ef8 aliguori
    if (ioctl(arp_fd, I_STR, &strioc_if) < 0){
883 63a01ef8 aliguori
        syslog (LOG_ERR, "Can't set ifname to arp\n");
884 63a01ef8 aliguori
    }
885 63a01ef8 aliguori
886 63a01ef8 aliguori
    if((ip_muxid = ioctl(ip_fd, I_LINK, if_fd)) < 0){
887 63a01ef8 aliguori
       syslog(LOG_ERR, "Can't link TAP device to IP");
888 63a01ef8 aliguori
       return -1;
889 63a01ef8 aliguori
    }
890 63a01ef8 aliguori
891 63a01ef8 aliguori
    if ((arp_muxid = ioctl (ip_fd, link_type, arp_fd)) < 0)
892 63a01ef8 aliguori
        syslog (LOG_ERR, "Can't link TAP device to ARP");
893 63a01ef8 aliguori
894 63a01ef8 aliguori
    close (if_fd);
895 63a01ef8 aliguori
896 63a01ef8 aliguori
    memset(&ifr, 0x0, sizeof(ifr));
897 63a01ef8 aliguori
    pstrcpy(ifr.lifr_name, sizeof(ifr.lifr_name), actual_name);
898 63a01ef8 aliguori
    ifr.lifr_ip_muxid  = ip_muxid;
899 63a01ef8 aliguori
    ifr.lifr_arp_muxid = arp_muxid;
900 63a01ef8 aliguori
901 63a01ef8 aliguori
    if (ioctl (ip_fd, SIOCSLIFMUXID, &ifr) < 0)
902 63a01ef8 aliguori
    {
903 63a01ef8 aliguori
      ioctl (ip_fd, I_PUNLINK , arp_muxid);
904 63a01ef8 aliguori
      ioctl (ip_fd, I_PUNLINK, ip_muxid);
905 63a01ef8 aliguori
      syslog (LOG_ERR, "Can't set multiplexor id");
906 63a01ef8 aliguori
    }
907 63a01ef8 aliguori
908 63a01ef8 aliguori
    snprintf(dev, dev_size, "tap%d", ppa);
909 63a01ef8 aliguori
    return tap_fd;
910 63a01ef8 aliguori
}
911 63a01ef8 aliguori
912 63a01ef8 aliguori
static int tap_open(char *ifname, int ifname_size)
913 63a01ef8 aliguori
{
914 63a01ef8 aliguori
    char  dev[10]="";
915 63a01ef8 aliguori
    int fd;
916 63a01ef8 aliguori
    if( (fd = tap_alloc(dev, sizeof(dev))) < 0 ){
917 63a01ef8 aliguori
       fprintf(stderr, "Cannot allocate TAP device\n");
918 63a01ef8 aliguori
       return -1;
919 63a01ef8 aliguori
    }
920 63a01ef8 aliguori
    pstrcpy(ifname, ifname_size, dev);
921 63a01ef8 aliguori
    fcntl(fd, F_SETFL, O_NONBLOCK);
922 63a01ef8 aliguori
    return fd;
923 63a01ef8 aliguori
}
924 b29fe3ed malc
#elif defined (_AIX)
925 b29fe3ed malc
static int tap_open(char *ifname, int ifname_size)
926 b29fe3ed malc
{
927 b29fe3ed malc
    fprintf (stderr, "no tap on AIX\n");
928 b29fe3ed malc
    return -1;
929 b29fe3ed malc
}
930 63a01ef8 aliguori
#else
931 63a01ef8 aliguori
static int tap_open(char *ifname, int ifname_size)
932 63a01ef8 aliguori
{
933 63a01ef8 aliguori
    struct ifreq ifr;
934 63a01ef8 aliguori
    int fd, ret;
935 63a01ef8 aliguori
936 63a01ef8 aliguori
    TFR(fd = open("/dev/net/tun", O_RDWR));
937 63a01ef8 aliguori
    if (fd < 0) {
938 63a01ef8 aliguori
        fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
939 63a01ef8 aliguori
        return -1;
940 63a01ef8 aliguori
    }
941 63a01ef8 aliguori
    memset(&ifr, 0, sizeof(ifr));
942 63a01ef8 aliguori
    ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
943 63a01ef8 aliguori
    if (ifname[0] != '\0')
944 63a01ef8 aliguori
        pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname);
945 63a01ef8 aliguori
    else
946 63a01ef8 aliguori
        pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d");
947 63a01ef8 aliguori
    ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
948 63a01ef8 aliguori
    if (ret != 0) {
949 63a01ef8 aliguori
        fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
950 63a01ef8 aliguori
        close(fd);
951 63a01ef8 aliguori
        return -1;
952 63a01ef8 aliguori
    }
953 63a01ef8 aliguori
    pstrcpy(ifname, ifname_size, ifr.ifr_name);
954 63a01ef8 aliguori
    fcntl(fd, F_SETFL, O_NONBLOCK);
955 63a01ef8 aliguori
    return fd;
956 63a01ef8 aliguori
}
957 63a01ef8 aliguori
#endif
958 63a01ef8 aliguori
959 63a01ef8 aliguori
static int launch_script(const char *setup_script, const char *ifname, int fd)
960 63a01ef8 aliguori
{
961 63a01ef8 aliguori
    int pid, status;
962 63a01ef8 aliguori
    char *args[3];
963 63a01ef8 aliguori
    char **parg;
964 63a01ef8 aliguori
965 63a01ef8 aliguori
        /* try to launch network script */
966 63a01ef8 aliguori
        pid = fork();
967 63a01ef8 aliguori
        if (pid >= 0) {
968 63a01ef8 aliguori
            if (pid == 0) {
969 63a01ef8 aliguori
                int open_max = sysconf (_SC_OPEN_MAX), i;
970 63a01ef8 aliguori
                for (i = 0; i < open_max; i++)
971 63a01ef8 aliguori
                    if (i != STDIN_FILENO &&
972 63a01ef8 aliguori
                        i != STDOUT_FILENO &&
973 63a01ef8 aliguori
                        i != STDERR_FILENO &&
974 63a01ef8 aliguori
                        i != fd)
975 63a01ef8 aliguori
                        close(i);
976 63a01ef8 aliguori
977 63a01ef8 aliguori
                parg = args;
978 63a01ef8 aliguori
                *parg++ = (char *)setup_script;
979 63a01ef8 aliguori
                *parg++ = (char *)ifname;
980 63a01ef8 aliguori
                *parg++ = NULL;
981 63a01ef8 aliguori
                execv(setup_script, args);
982 63a01ef8 aliguori
                _exit(1);
983 63a01ef8 aliguori
            }
984 63a01ef8 aliguori
            while (waitpid(pid, &status, 0) != pid);
985 63a01ef8 aliguori
            if (!WIFEXITED(status) ||
986 63a01ef8 aliguori
                WEXITSTATUS(status) != 0) {
987 63a01ef8 aliguori
                fprintf(stderr, "%s: could not launch network script\n",
988 63a01ef8 aliguori
                        setup_script);
989 63a01ef8 aliguori
                return -1;
990 63a01ef8 aliguori
            }
991 63a01ef8 aliguori
        }
992 63a01ef8 aliguori
    return 0;
993 63a01ef8 aliguori
}
994 63a01ef8 aliguori
995 7a9f6e4a aliguori
static int net_tap_init(VLANState *vlan, const char *model,
996 7a9f6e4a aliguori
                        const char *name, const char *ifname1,
997 63a01ef8 aliguori
                        const char *setup_script, const char *down_script)
998 63a01ef8 aliguori
{
999 63a01ef8 aliguori
    TAPState *s;
1000 63a01ef8 aliguori
    int fd;
1001 63a01ef8 aliguori
    char ifname[128];
1002 63a01ef8 aliguori
1003 63a01ef8 aliguori
    if (ifname1 != NULL)
1004 63a01ef8 aliguori
        pstrcpy(ifname, sizeof(ifname), ifname1);
1005 63a01ef8 aliguori
    else
1006 63a01ef8 aliguori
        ifname[0] = '\0';
1007 63a01ef8 aliguori
    TFR(fd = tap_open(ifname, sizeof(ifname)));
1008 63a01ef8 aliguori
    if (fd < 0)
1009 63a01ef8 aliguori
        return -1;
1010 63a01ef8 aliguori
1011 63a01ef8 aliguori
    if (!setup_script || !strcmp(setup_script, "no"))
1012 63a01ef8 aliguori
        setup_script = "";
1013 63a01ef8 aliguori
    if (setup_script[0] != '\0') {
1014 63a01ef8 aliguori
        if (launch_script(setup_script, ifname, fd))
1015 63a01ef8 aliguori
            return -1;
1016 63a01ef8 aliguori
    }
1017 7a9f6e4a aliguori
    s = net_tap_fd_init(vlan, model, name, fd);
1018 63a01ef8 aliguori
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
1019 7cb7434b aliguori
             "ifname=%s,script=%s,downscript=%s",
1020 7cb7434b aliguori
             ifname, setup_script, down_script);
1021 973cbd37 aliguori
    if (down_script && strcmp(down_script, "no")) {
1022 63a01ef8 aliguori
        snprintf(s->down_script, sizeof(s->down_script), "%s", down_script);
1023 973cbd37 aliguori
        snprintf(s->down_script_arg, sizeof(s->down_script_arg), "%s", ifname);
1024 973cbd37 aliguori
    }
1025 63a01ef8 aliguori
    return 0;
1026 63a01ef8 aliguori
}
1027 63a01ef8 aliguori
1028 63a01ef8 aliguori
#endif /* !_WIN32 */
1029 63a01ef8 aliguori
1030 63a01ef8 aliguori
#if defined(CONFIG_VDE)
1031 63a01ef8 aliguori
typedef struct VDEState {
1032 63a01ef8 aliguori
    VLANClientState *vc;
1033 63a01ef8 aliguori
    VDECONN *vde;
1034 63a01ef8 aliguori
} VDEState;
1035 63a01ef8 aliguori
1036 63a01ef8 aliguori
static void vde_to_qemu(void *opaque)
1037 63a01ef8 aliguori
{
1038 63a01ef8 aliguori
    VDEState *s = opaque;
1039 63a01ef8 aliguori
    uint8_t buf[4096];
1040 63a01ef8 aliguori
    int size;
1041 63a01ef8 aliguori
1042 63a01ef8 aliguori
    size = vde_recv(s->vde, buf, sizeof(buf), 0);
1043 63a01ef8 aliguori
    if (size > 0) {
1044 63a01ef8 aliguori
        qemu_send_packet(s->vc, buf, size);
1045 63a01ef8 aliguori
    }
1046 63a01ef8 aliguori
}
1047 63a01ef8 aliguori
1048 63a01ef8 aliguori
static void vde_from_qemu(void *opaque, const uint8_t *buf, int size)
1049 63a01ef8 aliguori
{
1050 63a01ef8 aliguori
    VDEState *s = opaque;
1051 63a01ef8 aliguori
    int ret;
1052 63a01ef8 aliguori
    for(;;) {
1053 63a01ef8 aliguori
        ret = vde_send(s->vde, buf, size, 0);
1054 63a01ef8 aliguori
        if (ret < 0 && errno == EINTR) {
1055 63a01ef8 aliguori
        } else {
1056 63a01ef8 aliguori
            break;
1057 63a01ef8 aliguori
        }
1058 63a01ef8 aliguori
    }
1059 63a01ef8 aliguori
}
1060 63a01ef8 aliguori
1061 7a9f6e4a aliguori
static int net_vde_init(VLANState *vlan, const char *model,
1062 7a9f6e4a aliguori
                        const char *name, const char *sock,
1063 bf38c1a0 aliguori
                        int port, const char *group, int mode)
1064 63a01ef8 aliguori
{
1065 63a01ef8 aliguori
    VDEState *s;
1066 63a01ef8 aliguori
    char *init_group = strlen(group) ? (char *)group : NULL;
1067 63a01ef8 aliguori
    char *init_sock = strlen(sock) ? (char *)sock : NULL;
1068 63a01ef8 aliguori
1069 63a01ef8 aliguori
    struct vde_open_args args = {
1070 63a01ef8 aliguori
        .port = port,
1071 63a01ef8 aliguori
        .group = init_group,
1072 63a01ef8 aliguori
        .mode = mode,
1073 63a01ef8 aliguori
    };
1074 63a01ef8 aliguori
1075 63a01ef8 aliguori
    s = qemu_mallocz(sizeof(VDEState));
1076 63a01ef8 aliguori
    s->vde = vde_open(init_sock, "QEMU", &args);
1077 63a01ef8 aliguori
    if (!s->vde){
1078 63a01ef8 aliguori
        free(s);
1079 63a01ef8 aliguori
        return -1;
1080 63a01ef8 aliguori
    }
1081 7a9f6e4a aliguori
    s->vc = qemu_new_vlan_client(vlan, model, name, vde_from_qemu, NULL, s);
1082 63a01ef8 aliguori
    qemu_set_fd_handler(vde_datafd(s->vde), vde_to_qemu, NULL, s);
1083 7cb7434b aliguori
    snprintf(s->vc->info_str, sizeof(s->vc->info_str), "sock=%s,fd=%d",
1084 63a01ef8 aliguori
             sock, vde_datafd(s->vde));
1085 63a01ef8 aliguori
    return 0;
1086 63a01ef8 aliguori
}
1087 63a01ef8 aliguori
#endif
1088 63a01ef8 aliguori
1089 63a01ef8 aliguori
/* network connection */
1090 63a01ef8 aliguori
typedef struct NetSocketState {
1091 63a01ef8 aliguori
    VLANClientState *vc;
1092 63a01ef8 aliguori
    int fd;
1093 63a01ef8 aliguori
    int state; /* 0 = getting length, 1 = getting data */
1094 abcd2baa aliguori
    unsigned int index;
1095 abcd2baa aliguori
    unsigned int packet_len;
1096 63a01ef8 aliguori
    uint8_t buf[4096];
1097 63a01ef8 aliguori
    struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
1098 63a01ef8 aliguori
} NetSocketState;
1099 63a01ef8 aliguori
1100 63a01ef8 aliguori
typedef struct NetSocketListenState {
1101 63a01ef8 aliguori
    VLANState *vlan;
1102 bf38c1a0 aliguori
    char *model;
1103 7a9f6e4a aliguori
    char *name;
1104 63a01ef8 aliguori
    int fd;
1105 63a01ef8 aliguori
} NetSocketListenState;
1106 63a01ef8 aliguori
1107 63a01ef8 aliguori
/* XXX: we consider we can send the whole packet without blocking */
1108 63a01ef8 aliguori
static void net_socket_receive(void *opaque, const uint8_t *buf, int size)
1109 63a01ef8 aliguori
{
1110 63a01ef8 aliguori
    NetSocketState *s = opaque;
1111 63a01ef8 aliguori
    uint32_t len;
1112 63a01ef8 aliguori
    len = htonl(size);
1113 63a01ef8 aliguori
1114 63a01ef8 aliguori
    send_all(s->fd, (const uint8_t *)&len, sizeof(len));
1115 63a01ef8 aliguori
    send_all(s->fd, buf, size);
1116 63a01ef8 aliguori
}
1117 63a01ef8 aliguori
1118 63a01ef8 aliguori
static void net_socket_receive_dgram(void *opaque, const uint8_t *buf, int size)
1119 63a01ef8 aliguori
{
1120 63a01ef8 aliguori
    NetSocketState *s = opaque;
1121 63a01ef8 aliguori
    sendto(s->fd, buf, size, 0,
1122 63a01ef8 aliguori
           (struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));
1123 63a01ef8 aliguori
}
1124 63a01ef8 aliguori
1125 63a01ef8 aliguori
static void net_socket_send(void *opaque)
1126 63a01ef8 aliguori
{
1127 63a01ef8 aliguori
    NetSocketState *s = opaque;
1128 abcd2baa aliguori
    int size, err;
1129 abcd2baa aliguori
    unsigned l;
1130 63a01ef8 aliguori
    uint8_t buf1[4096];
1131 63a01ef8 aliguori
    const uint8_t *buf;
1132 63a01ef8 aliguori
1133 63a01ef8 aliguori
    size = recv(s->fd, buf1, sizeof(buf1), 0);
1134 63a01ef8 aliguori
    if (size < 0) {
1135 63a01ef8 aliguori
        err = socket_error();
1136 63a01ef8 aliguori
        if (err != EWOULDBLOCK)
1137 63a01ef8 aliguori
            goto eoc;
1138 63a01ef8 aliguori
    } else if (size == 0) {
1139 63a01ef8 aliguori
        /* end of connection */
1140 63a01ef8 aliguori
    eoc:
1141 63a01ef8 aliguori
        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
1142 63a01ef8 aliguori
        closesocket(s->fd);
1143 63a01ef8 aliguori
        return;
1144 63a01ef8 aliguori
    }
1145 63a01ef8 aliguori
    buf = buf1;
1146 63a01ef8 aliguori
    while (size > 0) {
1147 63a01ef8 aliguori
        /* reassemble a packet from the network */
1148 63a01ef8 aliguori
        switch(s->state) {
1149 63a01ef8 aliguori
        case 0:
1150 63a01ef8 aliguori
            l = 4 - s->index;
1151 63a01ef8 aliguori
            if (l > size)
1152 63a01ef8 aliguori
                l = size;
1153 63a01ef8 aliguori
            memcpy(s->buf + s->index, buf, l);
1154 63a01ef8 aliguori
            buf += l;
1155 63a01ef8 aliguori
            size -= l;
1156 63a01ef8 aliguori
            s->index += l;
1157 63a01ef8 aliguori
            if (s->index == 4) {
1158 63a01ef8 aliguori
                /* got length */
1159 63a01ef8 aliguori
                s->packet_len = ntohl(*(uint32_t *)s->buf);
1160 63a01ef8 aliguori
                s->index = 0;
1161 63a01ef8 aliguori
                s->state = 1;
1162 63a01ef8 aliguori
            }
1163 63a01ef8 aliguori
            break;
1164 63a01ef8 aliguori
        case 1:
1165 63a01ef8 aliguori
            l = s->packet_len - s->index;
1166 63a01ef8 aliguori
            if (l > size)
1167 63a01ef8 aliguori
                l = size;
1168 abcd2baa aliguori
            if (s->index + l <= sizeof(s->buf)) {
1169 abcd2baa aliguori
                memcpy(s->buf + s->index, buf, l);
1170 abcd2baa aliguori
            } else {
1171 abcd2baa aliguori
                fprintf(stderr, "serious error: oversized packet received,"
1172 abcd2baa aliguori
                    "connection terminated.\n");
1173 abcd2baa aliguori
                s->state = 0;
1174 abcd2baa aliguori
                goto eoc;
1175 abcd2baa aliguori
            }
1176 abcd2baa aliguori
1177 63a01ef8 aliguori
            s->index += l;
1178 63a01ef8 aliguori
            buf += l;
1179 63a01ef8 aliguori
            size -= l;
1180 63a01ef8 aliguori
            if (s->index >= s->packet_len) {
1181 63a01ef8 aliguori
                qemu_send_packet(s->vc, s->buf, s->packet_len);
1182 63a01ef8 aliguori
                s->index = 0;
1183 63a01ef8 aliguori
                s->state = 0;
1184 63a01ef8 aliguori
            }
1185 63a01ef8 aliguori
            break;
1186 63a01ef8 aliguori
        }
1187 63a01ef8 aliguori
    }
1188 63a01ef8 aliguori
}
1189 63a01ef8 aliguori
1190 63a01ef8 aliguori
static void net_socket_send_dgram(void *opaque)
1191 63a01ef8 aliguori
{
1192 63a01ef8 aliguori
    NetSocketState *s = opaque;
1193 63a01ef8 aliguori
    int size;
1194 63a01ef8 aliguori
1195 63a01ef8 aliguori
    size = recv(s->fd, s->buf, sizeof(s->buf), 0);
1196 63a01ef8 aliguori
    if (size < 0)
1197 63a01ef8 aliguori
        return;
1198 63a01ef8 aliguori
    if (size == 0) {
1199 63a01ef8 aliguori
        /* end of connection */
1200 63a01ef8 aliguori
        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
1201 63a01ef8 aliguori
        return;
1202 63a01ef8 aliguori
    }
1203 63a01ef8 aliguori
    qemu_send_packet(s->vc, s->buf, size);
1204 63a01ef8 aliguori
}
1205 63a01ef8 aliguori
1206 63a01ef8 aliguori
static int net_socket_mcast_create(struct sockaddr_in *mcastaddr)
1207 63a01ef8 aliguori
{
1208 63a01ef8 aliguori
    struct ip_mreq imr;
1209 63a01ef8 aliguori
    int fd;
1210 63a01ef8 aliguori
    int val, ret;
1211 63a01ef8 aliguori
    if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) {
1212 63a01ef8 aliguori
        fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) does not contain a multicast address\n",
1213 63a01ef8 aliguori
                inet_ntoa(mcastaddr->sin_addr),
1214 63a01ef8 aliguori
                (int)ntohl(mcastaddr->sin_addr.s_addr));
1215 63a01ef8 aliguori
        return -1;
1216 63a01ef8 aliguori
1217 63a01ef8 aliguori
    }
1218 63a01ef8 aliguori
    fd = socket(PF_INET, SOCK_DGRAM, 0);
1219 63a01ef8 aliguori
    if (fd < 0) {
1220 63a01ef8 aliguori
        perror("socket(PF_INET, SOCK_DGRAM)");
1221 63a01ef8 aliguori
        return -1;
1222 63a01ef8 aliguori
    }
1223 63a01ef8 aliguori
1224 63a01ef8 aliguori
    val = 1;
1225 63a01ef8 aliguori
    ret=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
1226 63a01ef8 aliguori
                   (const char *)&val, sizeof(val));
1227 63a01ef8 aliguori
    if (ret < 0) {
1228 63a01ef8 aliguori
        perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)");
1229 63a01ef8 aliguori
        goto fail;
1230 63a01ef8 aliguori
    }
1231 63a01ef8 aliguori
1232 63a01ef8 aliguori
    ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
1233 63a01ef8 aliguori
    if (ret < 0) {
1234 63a01ef8 aliguori
        perror("bind");
1235 63a01ef8 aliguori
        goto fail;
1236 63a01ef8 aliguori
    }
1237 63a01ef8 aliguori
1238 63a01ef8 aliguori
    /* Add host to multicast group */
1239 63a01ef8 aliguori
    imr.imr_multiaddr = mcastaddr->sin_addr;
1240 63a01ef8 aliguori
    imr.imr_interface.s_addr = htonl(INADDR_ANY);
1241 63a01ef8 aliguori
1242 63a01ef8 aliguori
    ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
1243 63a01ef8 aliguori
                     (const char *)&imr, sizeof(struct ip_mreq));
1244 63a01ef8 aliguori
    if (ret < 0) {
1245 63a01ef8 aliguori
        perror("setsockopt(IP_ADD_MEMBERSHIP)");
1246 63a01ef8 aliguori
        goto fail;
1247 63a01ef8 aliguori
    }
1248 63a01ef8 aliguori
1249 63a01ef8 aliguori
    /* Force mcast msgs to loopback (eg. several QEMUs in same host */
1250 63a01ef8 aliguori
    val = 1;
1251 63a01ef8 aliguori
    ret=setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
1252 63a01ef8 aliguori
                   (const char *)&val, sizeof(val));
1253 63a01ef8 aliguori
    if (ret < 0) {
1254 63a01ef8 aliguori
        perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)");
1255 63a01ef8 aliguori
        goto fail;
1256 63a01ef8 aliguori
    }
1257 63a01ef8 aliguori
1258 63a01ef8 aliguori
    socket_set_nonblock(fd);
1259 63a01ef8 aliguori
    return fd;
1260 63a01ef8 aliguori
fail:
1261 63a01ef8 aliguori
    if (fd >= 0)
1262 63a01ef8 aliguori
        closesocket(fd);
1263 63a01ef8 aliguori
    return -1;
1264 63a01ef8 aliguori
}
1265 63a01ef8 aliguori
1266 7a9f6e4a aliguori
static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan,
1267 7a9f6e4a aliguori
                                                const char *model,
1268 7a9f6e4a aliguori
                                                const char *name,
1269 bf38c1a0 aliguori
                                                int fd, int is_connected)
1270 63a01ef8 aliguori
{
1271 63a01ef8 aliguori
    struct sockaddr_in saddr;
1272 63a01ef8 aliguori
    int newfd;
1273 63a01ef8 aliguori
    socklen_t saddr_len;
1274 63a01ef8 aliguori
    NetSocketState *s;
1275 63a01ef8 aliguori
1276 63a01ef8 aliguori
    /* fd passed: multicast: "learn" dgram_dst address from bound address and save it
1277 63a01ef8 aliguori
     * Because this may be "shared" socket from a "master" process, datagrams would be recv()
1278 63a01ef8 aliguori
     * by ONLY ONE process: we must "clone" this dgram socket --jjo
1279 63a01ef8 aliguori
     */
1280 63a01ef8 aliguori
1281 63a01ef8 aliguori
    if (is_connected) {
1282 63a01ef8 aliguori
        if (getsockname(fd, (struct sockaddr *) &saddr, &saddr_len) == 0) {
1283 63a01ef8 aliguori
            /* must be bound */
1284 63a01ef8 aliguori
            if (saddr.sin_addr.s_addr==0) {
1285 63a01ef8 aliguori
                fprintf(stderr, "qemu: error: init_dgram: fd=%d unbound, cannot setup multicast dst addr\n",
1286 63a01ef8 aliguori
                        fd);
1287 63a01ef8 aliguori
                return NULL;
1288 63a01ef8 aliguori
            }
1289 63a01ef8 aliguori
            /* clone dgram socket */
1290 63a01ef8 aliguori
            newfd = net_socket_mcast_create(&saddr);
1291 63a01ef8 aliguori
            if (newfd < 0) {
1292 63a01ef8 aliguori
                /* error already reported by net_socket_mcast_create() */
1293 63a01ef8 aliguori
                close(fd);
1294 63a01ef8 aliguori
                return NULL;
1295 63a01ef8 aliguori
            }
1296 63a01ef8 aliguori
            /* clone newfd to fd, close newfd */
1297 63a01ef8 aliguori
            dup2(newfd, fd);
1298 63a01ef8 aliguori
            close(newfd);
1299 63a01ef8 aliguori
1300 63a01ef8 aliguori
        } else {
1301 63a01ef8 aliguori
            fprintf(stderr, "qemu: error: init_dgram: fd=%d failed getsockname(): %s\n",
1302 63a01ef8 aliguori
                    fd, strerror(errno));
1303 63a01ef8 aliguori
            return NULL;
1304 63a01ef8 aliguori
        }
1305 63a01ef8 aliguori
    }
1306 63a01ef8 aliguori
1307 63a01ef8 aliguori
    s = qemu_mallocz(sizeof(NetSocketState));
1308 63a01ef8 aliguori
    s->fd = fd;
1309 63a01ef8 aliguori
1310 7a9f6e4a aliguori
    s->vc = qemu_new_vlan_client(vlan, model, name, net_socket_receive_dgram, NULL, s);
1311 63a01ef8 aliguori
    qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
1312 63a01ef8 aliguori
1313 63a01ef8 aliguori
    /* mcast: save bound address as dst */
1314 63a01ef8 aliguori
    if (is_connected) s->dgram_dst=saddr;
1315 63a01ef8 aliguori
1316 63a01ef8 aliguori
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
1317 63a01ef8 aliguori
            "socket: fd=%d (%s mcast=%s:%d)",
1318 63a01ef8 aliguori
            fd, is_connected? "cloned" : "",
1319 63a01ef8 aliguori
            inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
1320 63a01ef8 aliguori
    return s;
1321 63a01ef8 aliguori
}
1322 63a01ef8 aliguori
1323 63a01ef8 aliguori
static void net_socket_connect(void *opaque)
1324 63a01ef8 aliguori
{
1325 63a01ef8 aliguori
    NetSocketState *s = opaque;
1326 63a01ef8 aliguori
    qemu_set_fd_handler(s->fd, net_socket_send, NULL, s);
1327 63a01ef8 aliguori
}
1328 63a01ef8 aliguori
1329 7a9f6e4a aliguori
static NetSocketState *net_socket_fd_init_stream(VLANState *vlan,
1330 7a9f6e4a aliguori
                                                 const char *model,
1331 7a9f6e4a aliguori
                                                 const char *name,
1332 bf38c1a0 aliguori
                                                 int fd, int is_connected)
1333 63a01ef8 aliguori
{
1334 63a01ef8 aliguori
    NetSocketState *s;
1335 63a01ef8 aliguori
    s = qemu_mallocz(sizeof(NetSocketState));
1336 63a01ef8 aliguori
    s->fd = fd;
1337 7a9f6e4a aliguori
    s->vc = qemu_new_vlan_client(vlan, model, name,
1338 63a01ef8 aliguori
                                 net_socket_receive, NULL, s);
1339 63a01ef8 aliguori
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
1340 63a01ef8 aliguori
             "socket: fd=%d", fd);
1341 63a01ef8 aliguori
    if (is_connected) {
1342 63a01ef8 aliguori
        net_socket_connect(s);
1343 63a01ef8 aliguori
    } else {
1344 63a01ef8 aliguori
        qemu_set_fd_handler(s->fd, NULL, net_socket_connect, s);
1345 63a01ef8 aliguori
    }
1346 63a01ef8 aliguori
    return s;
1347 63a01ef8 aliguori
}
1348 63a01ef8 aliguori
1349 7a9f6e4a aliguori
static NetSocketState *net_socket_fd_init(VLANState *vlan,
1350 7a9f6e4a aliguori
                                          const char *model, const char *name,
1351 bf38c1a0 aliguori
                                          int fd, int is_connected)
1352 63a01ef8 aliguori
{
1353 63a01ef8 aliguori
    int so_type=-1, optlen=sizeof(so_type);
1354 63a01ef8 aliguori
1355 63a01ef8 aliguori
    if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type,
1356 63a01ef8 aliguori
        (socklen_t *)&optlen)< 0) {
1357 63a01ef8 aliguori
        fprintf(stderr, "qemu: error: getsockopt(SO_TYPE) for fd=%d failed\n", fd);
1358 63a01ef8 aliguori
        return NULL;
1359 63a01ef8 aliguori
    }
1360 63a01ef8 aliguori
    switch(so_type) {
1361 63a01ef8 aliguori
    case SOCK_DGRAM:
1362 7a9f6e4a aliguori
        return net_socket_fd_init_dgram(vlan, model, name, fd, is_connected);
1363 63a01ef8 aliguori
    case SOCK_STREAM:
1364 7a9f6e4a aliguori
        return net_socket_fd_init_stream(vlan, model, name, fd, is_connected);
1365 63a01ef8 aliguori
    default:
1366 63a01ef8 aliguori
        /* who knows ... this could be a eg. a pty, do warn and continue as stream */
1367 63a01ef8 aliguori
        fprintf(stderr, "qemu: warning: socket type=%d for fd=%d is not SOCK_DGRAM or SOCK_STREAM\n", so_type, fd);
1368 7a9f6e4a aliguori
        return net_socket_fd_init_stream(vlan, model, name, fd, is_connected);
1369 63a01ef8 aliguori
    }
1370 63a01ef8 aliguori
    return NULL;
1371 63a01ef8 aliguori
}
1372 63a01ef8 aliguori
1373 63a01ef8 aliguori
static void net_socket_accept(void *opaque)
1374 63a01ef8 aliguori
{
1375 63a01ef8 aliguori
    NetSocketListenState *s = opaque;
1376 63a01ef8 aliguori
    NetSocketState *s1;
1377 63a01ef8 aliguori
    struct sockaddr_in saddr;
1378 63a01ef8 aliguori
    socklen_t len;
1379 63a01ef8 aliguori
    int fd;
1380 63a01ef8 aliguori
1381 63a01ef8 aliguori
    for(;;) {
1382 63a01ef8 aliguori
        len = sizeof(saddr);
1383 63a01ef8 aliguori
        fd = accept(s->fd, (struct sockaddr *)&saddr, &len);
1384 63a01ef8 aliguori
        if (fd < 0 && errno != EINTR) {
1385 63a01ef8 aliguori
            return;
1386 63a01ef8 aliguori
        } else if (fd >= 0) {
1387 63a01ef8 aliguori
            break;
1388 63a01ef8 aliguori
        }
1389 63a01ef8 aliguori
    }
1390 7a9f6e4a aliguori
    s1 = net_socket_fd_init(s->vlan, s->model, s->name, fd, 1);
1391 63a01ef8 aliguori
    if (!s1) {
1392 63a01ef8 aliguori
        closesocket(fd);
1393 63a01ef8 aliguori
    } else {
1394 63a01ef8 aliguori
        snprintf(s1->vc->info_str, sizeof(s1->vc->info_str),
1395 63a01ef8 aliguori
                 "socket: connection from %s:%d",
1396 63a01ef8 aliguori
                 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
1397 63a01ef8 aliguori
    }
1398 63a01ef8 aliguori
}
1399 63a01ef8 aliguori
1400 7a9f6e4a aliguori
static int net_socket_listen_init(VLANState *vlan,
1401 7a9f6e4a aliguori
                                  const char *model,
1402 7a9f6e4a aliguori
                                  const char *name,
1403 bf38c1a0 aliguori
                                  const char *host_str)
1404 63a01ef8 aliguori
{
1405 63a01ef8 aliguori
    NetSocketListenState *s;
1406 63a01ef8 aliguori
    int fd, val, ret;
1407 63a01ef8 aliguori
    struct sockaddr_in saddr;
1408 63a01ef8 aliguori
1409 63a01ef8 aliguori
    if (parse_host_port(&saddr, host_str) < 0)
1410 63a01ef8 aliguori
        return -1;
1411 63a01ef8 aliguori
1412 63a01ef8 aliguori
    s = qemu_mallocz(sizeof(NetSocketListenState));
1413 63a01ef8 aliguori
1414 63a01ef8 aliguori
    fd = socket(PF_INET, SOCK_STREAM, 0);
1415 63a01ef8 aliguori
    if (fd < 0) {
1416 63a01ef8 aliguori
        perror("socket");
1417 63a01ef8 aliguori
        return -1;
1418 63a01ef8 aliguori
    }
1419 63a01ef8 aliguori
    socket_set_nonblock(fd);
1420 63a01ef8 aliguori
1421 63a01ef8 aliguori
    /* allow fast reuse */
1422 63a01ef8 aliguori
    val = 1;
1423 63a01ef8 aliguori
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
1424 63a01ef8 aliguori
1425 63a01ef8 aliguori
    ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
1426 63a01ef8 aliguori
    if (ret < 0) {
1427 63a01ef8 aliguori
        perror("bind");
1428 63a01ef8 aliguori
        return -1;
1429 63a01ef8 aliguori
    }
1430 63a01ef8 aliguori
    ret = listen(fd, 0);
1431 63a01ef8 aliguori
    if (ret < 0) {
1432 63a01ef8 aliguori
        perror("listen");
1433 63a01ef8 aliguori
        return -1;
1434 63a01ef8 aliguori
    }
1435 63a01ef8 aliguori
    s->vlan = vlan;
1436 bf38c1a0 aliguori
    s->model = strdup(model);
1437 7a9f6e4a aliguori
    s->name = strdup(name);
1438 63a01ef8 aliguori
    s->fd = fd;
1439 63a01ef8 aliguori
    qemu_set_fd_handler(fd, net_socket_accept, NULL, s);
1440 63a01ef8 aliguori
    return 0;
1441 63a01ef8 aliguori
}
1442 63a01ef8 aliguori
1443 7a9f6e4a aliguori
static int net_socket_connect_init(VLANState *vlan,
1444 7a9f6e4a aliguori
                                   const char *model,
1445 7a9f6e4a aliguori
                                   const char *name,
1446 bf38c1a0 aliguori
                                   const char *host_str)
1447 63a01ef8 aliguori
{
1448 63a01ef8 aliguori
    NetSocketState *s;
1449 63a01ef8 aliguori
    int fd, connected, ret, err;
1450 63a01ef8 aliguori
    struct sockaddr_in saddr;
1451 63a01ef8 aliguori
1452 63a01ef8 aliguori
    if (parse_host_port(&saddr, host_str) < 0)
1453 63a01ef8 aliguori
        return -1;
1454 63a01ef8 aliguori
1455 63a01ef8 aliguori
    fd = socket(PF_INET, SOCK_STREAM, 0);
1456 63a01ef8 aliguori
    if (fd < 0) {
1457 63a01ef8 aliguori
        perror("socket");
1458 63a01ef8 aliguori
        return -1;
1459 63a01ef8 aliguori
    }
1460 63a01ef8 aliguori
    socket_set_nonblock(fd);
1461 63a01ef8 aliguori
1462 63a01ef8 aliguori
    connected = 0;
1463 63a01ef8 aliguori
    for(;;) {
1464 63a01ef8 aliguori
        ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
1465 63a01ef8 aliguori
        if (ret < 0) {
1466 63a01ef8 aliguori
            err = socket_error();
1467 63a01ef8 aliguori
            if (err == EINTR || err == EWOULDBLOCK) {
1468 63a01ef8 aliguori
            } else if (err == EINPROGRESS) {
1469 63a01ef8 aliguori
                break;
1470 63a01ef8 aliguori
#ifdef _WIN32
1471 63a01ef8 aliguori
            } else if (err == WSAEALREADY) {
1472 63a01ef8 aliguori
                break;
1473 63a01ef8 aliguori
#endif
1474 63a01ef8 aliguori
            } else {
1475 63a01ef8 aliguori
                perror("connect");
1476 63a01ef8 aliguori
                closesocket(fd);
1477 63a01ef8 aliguori
                return -1;
1478 63a01ef8 aliguori
            }
1479 63a01ef8 aliguori
        } else {
1480 63a01ef8 aliguori
            connected = 1;
1481 63a01ef8 aliguori
            break;
1482 63a01ef8 aliguori
        }
1483 63a01ef8 aliguori
    }
1484 7a9f6e4a aliguori
    s = net_socket_fd_init(vlan, model, name, fd, connected);
1485 63a01ef8 aliguori
    if (!s)
1486 63a01ef8 aliguori
        return -1;
1487 63a01ef8 aliguori
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
1488 63a01ef8 aliguori
             "socket: connect to %s:%d",
1489 63a01ef8 aliguori
             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
1490 63a01ef8 aliguori
    return 0;
1491 63a01ef8 aliguori
}
1492 63a01ef8 aliguori
1493 7a9f6e4a aliguori
static int net_socket_mcast_init(VLANState *vlan,
1494 7a9f6e4a aliguori
                                 const char *model,
1495 7a9f6e4a aliguori
                                 const char *name,
1496 bf38c1a0 aliguori
                                 const char *host_str)
1497 63a01ef8 aliguori
{
1498 63a01ef8 aliguori
    NetSocketState *s;
1499 63a01ef8 aliguori
    int fd;
1500 63a01ef8 aliguori
    struct sockaddr_in saddr;
1501 63a01ef8 aliguori
1502 63a01ef8 aliguori
    if (parse_host_port(&saddr, host_str) < 0)
1503 63a01ef8 aliguori
        return -1;
1504 63a01ef8 aliguori
1505 63a01ef8 aliguori
1506 63a01ef8 aliguori
    fd = net_socket_mcast_create(&saddr);
1507 63a01ef8 aliguori
    if (fd < 0)
1508 63a01ef8 aliguori
        return -1;
1509 63a01ef8 aliguori
1510 7a9f6e4a aliguori
    s = net_socket_fd_init(vlan, model, name, fd, 0);
1511 63a01ef8 aliguori
    if (!s)
1512 63a01ef8 aliguori
        return -1;
1513 63a01ef8 aliguori
1514 63a01ef8 aliguori
    s->dgram_dst = saddr;
1515 63a01ef8 aliguori
1516 63a01ef8 aliguori
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
1517 63a01ef8 aliguori
             "socket: mcast=%s:%d",
1518 63a01ef8 aliguori
             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
1519 63a01ef8 aliguori
    return 0;
1520 63a01ef8 aliguori
1521 63a01ef8 aliguori
}
1522 63a01ef8 aliguori
1523 63a01ef8 aliguori
/* find or alloc a new VLAN */
1524 63a01ef8 aliguori
VLANState *qemu_find_vlan(int id)
1525 63a01ef8 aliguori
{
1526 63a01ef8 aliguori
    VLANState **pvlan, *vlan;
1527 63a01ef8 aliguori
    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
1528 63a01ef8 aliguori
        if (vlan->id == id)
1529 63a01ef8 aliguori
            return vlan;
1530 63a01ef8 aliguori
    }
1531 63a01ef8 aliguori
    vlan = qemu_mallocz(sizeof(VLANState));
1532 63a01ef8 aliguori
    vlan->id = id;
1533 63a01ef8 aliguori
    vlan->next = NULL;
1534 63a01ef8 aliguori
    pvlan = &first_vlan;
1535 63a01ef8 aliguori
    while (*pvlan != NULL)
1536 63a01ef8 aliguori
        pvlan = &(*pvlan)->next;
1537 63a01ef8 aliguori
    *pvlan = vlan;
1538 63a01ef8 aliguori
    return vlan;
1539 63a01ef8 aliguori
}
1540 63a01ef8 aliguori
1541 7697079b aliguori
static int nic_get_free_idx(void)
1542 7697079b aliguori
{
1543 7697079b aliguori
    int index;
1544 7697079b aliguori
1545 7697079b aliguori
    for (index = 0; index < MAX_NICS; index++)
1546 7697079b aliguori
        if (!nd_table[index].used)
1547 7697079b aliguori
            return index;
1548 7697079b aliguori
    return -1;
1549 7697079b aliguori
}
1550 7697079b aliguori
1551 d07f22c5 aliguori
void qemu_check_nic_model(NICInfo *nd, const char *model)
1552 d07f22c5 aliguori
{
1553 d07f22c5 aliguori
    const char *models[2];
1554 d07f22c5 aliguori
1555 d07f22c5 aliguori
    models[0] = model;
1556 d07f22c5 aliguori
    models[1] = NULL;
1557 d07f22c5 aliguori
1558 d07f22c5 aliguori
    qemu_check_nic_model_list(nd, models, model);
1559 d07f22c5 aliguori
}
1560 d07f22c5 aliguori
1561 d07f22c5 aliguori
void qemu_check_nic_model_list(NICInfo *nd, const char * const *models,
1562 d07f22c5 aliguori
                               const char *default_model)
1563 d07f22c5 aliguori
{
1564 d07f22c5 aliguori
    int i, exit_status = 0;
1565 d07f22c5 aliguori
1566 d07f22c5 aliguori
    if (!nd->model)
1567 d07f22c5 aliguori
        nd->model = strdup(default_model);
1568 d07f22c5 aliguori
1569 d07f22c5 aliguori
    if (strcmp(nd->model, "?") != 0) {
1570 d07f22c5 aliguori
        for (i = 0 ; models[i]; i++)
1571 d07f22c5 aliguori
            if (strcmp(nd->model, models[i]) == 0)
1572 d07f22c5 aliguori
                return;
1573 d07f22c5 aliguori
1574 d07f22c5 aliguori
        fprintf(stderr, "qemu: Unsupported NIC model: %s\n", nd->model);
1575 d07f22c5 aliguori
        exit_status = 1;
1576 d07f22c5 aliguori
    }
1577 d07f22c5 aliguori
1578 d07f22c5 aliguori
    fprintf(stderr, "qemu: Supported NIC models: ");
1579 d07f22c5 aliguori
    for (i = 0 ; models[i]; i++)
1580 d07f22c5 aliguori
        fprintf(stderr, "%s%c", models[i], models[i+1] ? ',' : '\n');
1581 d07f22c5 aliguori
1582 d07f22c5 aliguori
    exit(exit_status);
1583 d07f22c5 aliguori
}
1584 d07f22c5 aliguori
1585 63a01ef8 aliguori
int net_client_init(const char *device, const char *p)
1586 63a01ef8 aliguori
{
1587 63a01ef8 aliguori
    char buf[1024];
1588 63a01ef8 aliguori
    int vlan_id, ret;
1589 63a01ef8 aliguori
    VLANState *vlan;
1590 7a9f6e4a aliguori
    char *name = NULL;
1591 63a01ef8 aliguori
1592 63a01ef8 aliguori
    vlan_id = 0;
1593 63a01ef8 aliguori
    if (get_param_value(buf, sizeof(buf), "vlan", p)) {
1594 63a01ef8 aliguori
        vlan_id = strtol(buf, NULL, 0);
1595 63a01ef8 aliguori
    }
1596 63a01ef8 aliguori
    vlan = qemu_find_vlan(vlan_id);
1597 9036de1a aliguori
1598 7a9f6e4a aliguori
    if (get_param_value(buf, sizeof(buf), "name", p)) {
1599 7a9f6e4a aliguori
        name = strdup(buf);
1600 7a9f6e4a aliguori
    }
1601 63a01ef8 aliguori
    if (!strcmp(device, "nic")) {
1602 63a01ef8 aliguori
        NICInfo *nd;
1603 63a01ef8 aliguori
        uint8_t *macaddr;
1604 7697079b aliguori
        int idx = nic_get_free_idx();
1605 63a01ef8 aliguori
1606 7697079b aliguori
        if (idx == -1 || nb_nics >= MAX_NICS) {
1607 63a01ef8 aliguori
            fprintf(stderr, "Too Many NICs\n");
1608 771f1339 aliguori
            ret = -1;
1609 771f1339 aliguori
            goto out;
1610 63a01ef8 aliguori
        }
1611 7697079b aliguori
        nd = &nd_table[idx];
1612 63a01ef8 aliguori
        macaddr = nd->macaddr;
1613 63a01ef8 aliguori
        macaddr[0] = 0x52;
1614 63a01ef8 aliguori
        macaddr[1] = 0x54;
1615 63a01ef8 aliguori
        macaddr[2] = 0x00;
1616 63a01ef8 aliguori
        macaddr[3] = 0x12;
1617 63a01ef8 aliguori
        macaddr[4] = 0x34;
1618 7697079b aliguori
        macaddr[5] = 0x56 + idx;
1619 63a01ef8 aliguori
1620 63a01ef8 aliguori
        if (get_param_value(buf, sizeof(buf), "macaddr", p)) {
1621 63a01ef8 aliguori
            if (parse_macaddr(macaddr, buf) < 0) {
1622 63a01ef8 aliguori
                fprintf(stderr, "invalid syntax for ethernet address\n");
1623 771f1339 aliguori
                ret = -1;
1624 771f1339 aliguori
                goto out;
1625 63a01ef8 aliguori
            }
1626 63a01ef8 aliguori
        }
1627 63a01ef8 aliguori
        if (get_param_value(buf, sizeof(buf), "model", p)) {
1628 63a01ef8 aliguori
            nd->model = strdup(buf);
1629 63a01ef8 aliguori
        }
1630 63a01ef8 aliguori
        nd->vlan = vlan;
1631 7a9f6e4a aliguori
        nd->name = name;
1632 7697079b aliguori
        nd->used = 1;
1633 7a9f6e4a aliguori
        name = NULL;
1634 63a01ef8 aliguori
        nb_nics++;
1635 63a01ef8 aliguori
        vlan->nb_guest_devs++;
1636 4d73cd3b aliguori
        ret = idx;
1637 63a01ef8 aliguori
    } else
1638 63a01ef8 aliguori
    if (!strcmp(device, "none")) {
1639 63a01ef8 aliguori
        /* does nothing. It is needed to signal that no network cards
1640 63a01ef8 aliguori
           are wanted */
1641 63a01ef8 aliguori
        ret = 0;
1642 63a01ef8 aliguori
    } else
1643 63a01ef8 aliguori
#ifdef CONFIG_SLIRP
1644 63a01ef8 aliguori
    if (!strcmp(device, "user")) {
1645 63a01ef8 aliguori
        if (get_param_value(buf, sizeof(buf), "hostname", p)) {
1646 63a01ef8 aliguori
            pstrcpy(slirp_hostname, sizeof(slirp_hostname), buf);
1647 63a01ef8 aliguori
        }
1648 49ec9b40 aliguori
        if (get_param_value(buf, sizeof(buf), "restrict", p)) {
1649 49ec9b40 aliguori
            slirp_restrict = (buf[0] == 'y') ? 1 : 0;
1650 49ec9b40 aliguori
        }
1651 49ec9b40 aliguori
        if (get_param_value(buf, sizeof(buf), "ip", p)) {
1652 49ec9b40 aliguori
            slirp_ip = strdup(buf);
1653 49ec9b40 aliguori
        }
1654 63a01ef8 aliguori
        vlan->nb_host_devs++;
1655 7a9f6e4a aliguori
        ret = net_slirp_init(vlan, device, name);
1656 8ca9217d aliguori
    } else if (!strcmp(device, "channel")) {
1657 8ca9217d aliguori
        long port;
1658 8ca9217d aliguori
        char name[20], *devname;
1659 8ca9217d aliguori
        struct VMChannel *vmc;
1660 8ca9217d aliguori
1661 8ca9217d aliguori
        port = strtol(p, &devname, 10);
1662 8ca9217d aliguori
        devname++;
1663 8ca9217d aliguori
        if (port < 1 || port > 65535) {
1664 771f1339 aliguori
            fprintf(stderr, "vmchannel wrong port number\n");
1665 771f1339 aliguori
            ret = -1;
1666 771f1339 aliguori
            goto out;
1667 8ca9217d aliguori
        }
1668 8ca9217d aliguori
        vmc = malloc(sizeof(struct VMChannel));
1669 8ca9217d aliguori
        snprintf(name, 20, "vmchannel%ld", port);
1670 8ca9217d aliguori
        vmc->hd = qemu_chr_open(name, devname, NULL);
1671 8ca9217d aliguori
        if (!vmc->hd) {
1672 8ca9217d aliguori
            fprintf(stderr, "qemu: could not open vmchannel device"
1673 8ca9217d aliguori
                    "'%s'\n", devname);
1674 771f1339 aliguori
            ret = -1;
1675 771f1339 aliguori
            goto out;
1676 8ca9217d aliguori
        }
1677 8ca9217d aliguori
        vmc->port = port;
1678 8ca9217d aliguori
        slirp_add_exec(3, vmc->hd, 4, port);
1679 8ca9217d aliguori
        qemu_chr_add_handlers(vmc->hd, vmchannel_can_read, vmchannel_read,
1680 8ca9217d aliguori
                NULL, vmc);
1681 8ca9217d aliguori
        ret = 0;
1682 63a01ef8 aliguori
    } else
1683 63a01ef8 aliguori
#endif
1684 63a01ef8 aliguori
#ifdef _WIN32
1685 63a01ef8 aliguori
    if (!strcmp(device, "tap")) {
1686 63a01ef8 aliguori
        char ifname[64];
1687 63a01ef8 aliguori
        if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
1688 63a01ef8 aliguori
            fprintf(stderr, "tap: no interface name\n");
1689 771f1339 aliguori
            ret = -1;
1690 771f1339 aliguori
            goto out;
1691 63a01ef8 aliguori
        }
1692 63a01ef8 aliguori
        vlan->nb_host_devs++;
1693 7a9f6e4a aliguori
        ret = tap_win32_init(vlan, device, name, ifname);
1694 63a01ef8 aliguori
    } else
1695 b29fe3ed malc
#elif defined (_AIX)
1696 63a01ef8 aliguori
#else
1697 63a01ef8 aliguori
    if (!strcmp(device, "tap")) {
1698 63a01ef8 aliguori
        char ifname[64];
1699 63a01ef8 aliguori
        char setup_script[1024], down_script[1024];
1700 63a01ef8 aliguori
        int fd;
1701 63a01ef8 aliguori
        vlan->nb_host_devs++;
1702 63a01ef8 aliguori
        if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
1703 63a01ef8 aliguori
            fd = strtol(buf, NULL, 0);
1704 63a01ef8 aliguori
            fcntl(fd, F_SETFL, O_NONBLOCK);
1705 9036de1a aliguori
            net_tap_fd_init(vlan, device, name, fd);
1706 9036de1a aliguori
            ret = 0;
1707 63a01ef8 aliguori
        } else {
1708 63a01ef8 aliguori
            if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
1709 63a01ef8 aliguori
                ifname[0] = '\0';
1710 63a01ef8 aliguori
            }
1711 63a01ef8 aliguori
            if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) {
1712 63a01ef8 aliguori
                pstrcpy(setup_script, sizeof(setup_script), DEFAULT_NETWORK_SCRIPT);
1713 63a01ef8 aliguori
            }
1714 63a01ef8 aliguori
            if (get_param_value(down_script, sizeof(down_script), "downscript", p) == 0) {
1715 63a01ef8 aliguori
                pstrcpy(down_script, sizeof(down_script), DEFAULT_NETWORK_DOWN_SCRIPT);
1716 63a01ef8 aliguori
            }
1717 7a9f6e4a aliguori
            ret = net_tap_init(vlan, device, name, ifname, setup_script, down_script);
1718 63a01ef8 aliguori
        }
1719 63a01ef8 aliguori
    } else
1720 63a01ef8 aliguori
#endif
1721 63a01ef8 aliguori
    if (!strcmp(device, "socket")) {
1722 63a01ef8 aliguori
        if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
1723 63a01ef8 aliguori
            int fd;
1724 63a01ef8 aliguori
            fd = strtol(buf, NULL, 0);
1725 63a01ef8 aliguori
            ret = -1;
1726 7a9f6e4a aliguori
            if (net_socket_fd_init(vlan, device, name, fd, 1))
1727 63a01ef8 aliguori
                ret = 0;
1728 63a01ef8 aliguori
        } else if (get_param_value(buf, sizeof(buf), "listen", p) > 0) {
1729 7a9f6e4a aliguori
            ret = net_socket_listen_init(vlan, device, name, buf);
1730 63a01ef8 aliguori
        } else if (get_param_value(buf, sizeof(buf), "connect", p) > 0) {
1731 7a9f6e4a aliguori
            ret = net_socket_connect_init(vlan, device, name, buf);
1732 63a01ef8 aliguori
        } else if (get_param_value(buf, sizeof(buf), "mcast", p) > 0) {
1733 7a9f6e4a aliguori
            ret = net_socket_mcast_init(vlan, device, name, buf);
1734 63a01ef8 aliguori
        } else {
1735 63a01ef8 aliguori
            fprintf(stderr, "Unknown socket options: %s\n", p);
1736 771f1339 aliguori
            ret = -1;
1737 771f1339 aliguori
            goto out;
1738 63a01ef8 aliguori
        }
1739 63a01ef8 aliguori
        vlan->nb_host_devs++;
1740 63a01ef8 aliguori
    } else
1741 63a01ef8 aliguori
#ifdef CONFIG_VDE
1742 63a01ef8 aliguori
    if (!strcmp(device, "vde")) {
1743 63a01ef8 aliguori
        char vde_sock[1024], vde_group[512];
1744 63a01ef8 aliguori
        int vde_port, vde_mode;
1745 63a01ef8 aliguori
        vlan->nb_host_devs++;
1746 63a01ef8 aliguori
        if (get_param_value(vde_sock, sizeof(vde_sock), "sock", p) <= 0) {
1747 63a01ef8 aliguori
            vde_sock[0] = '\0';
1748 63a01ef8 aliguori
        }
1749 63a01ef8 aliguori
        if (get_param_value(buf, sizeof(buf), "port", p) > 0) {
1750 63a01ef8 aliguori
            vde_port = strtol(buf, NULL, 10);
1751 63a01ef8 aliguori
        } else {
1752 63a01ef8 aliguori
            vde_port = 0;
1753 63a01ef8 aliguori
        }
1754 63a01ef8 aliguori
        if (get_param_value(vde_group, sizeof(vde_group), "group", p) <= 0) {
1755 63a01ef8 aliguori
            vde_group[0] = '\0';
1756 63a01ef8 aliguori
        }
1757 63a01ef8 aliguori
        if (get_param_value(buf, sizeof(buf), "mode", p) > 0) {
1758 63a01ef8 aliguori
            vde_mode = strtol(buf, NULL, 8);
1759 63a01ef8 aliguori
        } else {
1760 63a01ef8 aliguori
            vde_mode = 0700;
1761 63a01ef8 aliguori
        }
1762 7a9f6e4a aliguori
        ret = net_vde_init(vlan, device, name, vde_sock, vde_port, vde_group, vde_mode);
1763 63a01ef8 aliguori
    } else
1764 63a01ef8 aliguori
#endif
1765 63a01ef8 aliguori
    {
1766 63a01ef8 aliguori
        fprintf(stderr, "Unknown network device: %s\n", device);
1767 771f1339 aliguori
        ret = -1;
1768 771f1339 aliguori
        goto out;
1769 63a01ef8 aliguori
    }
1770 63a01ef8 aliguori
    if (ret < 0) {
1771 63a01ef8 aliguori
        fprintf(stderr, "Could not initialize device '%s'\n", device);
1772 63a01ef8 aliguori
    }
1773 771f1339 aliguori
out:
1774 7a9f6e4a aliguori
    if (name)
1775 7a9f6e4a aliguori
        free(name);
1776 63a01ef8 aliguori
    return ret;
1777 63a01ef8 aliguori
}
1778 63a01ef8 aliguori
1779 8b13c4a7 aliguori
void net_client_uninit(NICInfo *nd)
1780 8b13c4a7 aliguori
{
1781 8b13c4a7 aliguori
    nd->vlan->nb_guest_devs--;
1782 8b13c4a7 aliguori
    nb_nics--;
1783 8b13c4a7 aliguori
    nd->used = 0;
1784 8b13c4a7 aliguori
    free((void *)nd->model);
1785 8b13c4a7 aliguori
}
1786 8b13c4a7 aliguori
1787 6f338c34 aliguori
static int net_host_check_device(const char *device)
1788 6f338c34 aliguori
{
1789 6f338c34 aliguori
    int i;
1790 6f338c34 aliguori
    const char *valid_param_list[] = { "tap", "socket"
1791 6f338c34 aliguori
#ifdef CONFIG_SLIRP
1792 6f338c34 aliguori
                                       ,"user"
1793 6f338c34 aliguori
#endif
1794 6f338c34 aliguori
#ifdef CONFIG_VDE
1795 6f338c34 aliguori
                                       ,"vde"
1796 6f338c34 aliguori
#endif
1797 6f338c34 aliguori
    };
1798 6f338c34 aliguori
    for (i = 0; i < sizeof(valid_param_list) / sizeof(char *); i++) {
1799 6f338c34 aliguori
        if (!strncmp(valid_param_list[i], device,
1800 6f338c34 aliguori
                     strlen(valid_param_list[i])))
1801 6f338c34 aliguori
            return 1;
1802 6f338c34 aliguori
    }
1803 6f338c34 aliguori
1804 6f338c34 aliguori
    return 0;
1805 6f338c34 aliguori
}
1806 6f338c34 aliguori
1807 376253ec aliguori
void net_host_device_add(Monitor *mon, const char *device, const char *opts)
1808 6f338c34 aliguori
{
1809 6f338c34 aliguori
    if (!net_host_check_device(device)) {
1810 376253ec aliguori
        monitor_printf(mon, "invalid host network device %s\n", device);
1811 6f338c34 aliguori
        return;
1812 6f338c34 aliguori
    }
1813 6f338c34 aliguori
    net_client_init(device, opts);
1814 6f338c34 aliguori
}
1815 6f338c34 aliguori
1816 376253ec aliguori
void net_host_device_remove(Monitor *mon, int vlan_id, const char *device)
1817 6f338c34 aliguori
{
1818 6f338c34 aliguori
    VLANState *vlan;
1819 6f338c34 aliguori
    VLANClientState *vc;
1820 6f338c34 aliguori
1821 6f338c34 aliguori
    vlan = qemu_find_vlan(vlan_id);
1822 6f338c34 aliguori
1823 6f338c34 aliguori
   for(vc = vlan->first_client; vc != NULL; vc = vc->next)
1824 6f338c34 aliguori
        if (!strcmp(vc->name, device))
1825 6f338c34 aliguori
            break;
1826 6f338c34 aliguori
1827 6f338c34 aliguori
    if (!vc) {
1828 376253ec aliguori
        monitor_printf(mon, "can't find device %s\n", device);
1829 6f338c34 aliguori
        return;
1830 6f338c34 aliguori
    }
1831 6f338c34 aliguori
    qemu_del_vlan_client(vc);
1832 6f338c34 aliguori
}
1833 6f338c34 aliguori
1834 63a01ef8 aliguori
int net_client_parse(const char *str)
1835 63a01ef8 aliguori
{
1836 63a01ef8 aliguori
    const char *p;
1837 63a01ef8 aliguori
    char *q;
1838 63a01ef8 aliguori
    char device[64];
1839 63a01ef8 aliguori
1840 63a01ef8 aliguori
    p = str;
1841 63a01ef8 aliguori
    q = device;
1842 63a01ef8 aliguori
    while (*p != '\0' && *p != ',') {
1843 63a01ef8 aliguori
        if ((q - device) < sizeof(device) - 1)
1844 63a01ef8 aliguori
            *q++ = *p;
1845 63a01ef8 aliguori
        p++;
1846 63a01ef8 aliguori
    }
1847 63a01ef8 aliguori
    *q = '\0';
1848 63a01ef8 aliguori
    if (*p == ',')
1849 63a01ef8 aliguori
        p++;
1850 63a01ef8 aliguori
1851 63a01ef8 aliguori
    return net_client_init(device, p);
1852 63a01ef8 aliguori
}
1853 63a01ef8 aliguori
1854 376253ec aliguori
void do_info_network(Monitor *mon)
1855 63a01ef8 aliguori
{
1856 63a01ef8 aliguori
    VLANState *vlan;
1857 63a01ef8 aliguori
    VLANClientState *vc;
1858 63a01ef8 aliguori
1859 63a01ef8 aliguori
    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
1860 376253ec aliguori
        monitor_printf(mon, "VLAN %d devices:\n", vlan->id);
1861 63a01ef8 aliguori
        for(vc = vlan->first_client; vc != NULL; vc = vc->next)
1862 376253ec aliguori
            monitor_printf(mon, "  %s: %s\n", vc->name, vc->info_str);
1863 63a01ef8 aliguori
    }
1864 63a01ef8 aliguori
}
1865 63a01ef8 aliguori
1866 376253ec aliguori
int do_set_link(Monitor *mon, const char *name, const char *up_or_down)
1867 436e5e53 aliguori
{
1868 436e5e53 aliguori
    VLANState *vlan;
1869 436e5e53 aliguori
    VLANClientState *vc = NULL;
1870 436e5e53 aliguori
1871 436e5e53 aliguori
    for (vlan = first_vlan; vlan != NULL; vlan = vlan->next)
1872 436e5e53 aliguori
        for (vc = vlan->first_client; vc != NULL; vc = vc->next)
1873 436e5e53 aliguori
            if (strcmp(vc->name, name) == 0)
1874 dd5de373 edgar_igl
                goto done;
1875 dd5de373 edgar_igl
done:
1876 436e5e53 aliguori
1877 436e5e53 aliguori
    if (!vc) {
1878 376253ec aliguori
        monitor_printf(mon, "could not find network device '%s'", name);
1879 436e5e53 aliguori
        return 0;
1880 436e5e53 aliguori
    }
1881 436e5e53 aliguori
1882 436e5e53 aliguori
    if (strcmp(up_or_down, "up") == 0)
1883 436e5e53 aliguori
        vc->link_down = 0;
1884 436e5e53 aliguori
    else if (strcmp(up_or_down, "down") == 0)
1885 436e5e53 aliguori
        vc->link_down = 1;
1886 436e5e53 aliguori
    else
1887 376253ec aliguori
        monitor_printf(mon, "invalid link status '%s'; only 'up' or 'down' "
1888 376253ec aliguori
                       "valid\n", up_or_down);
1889 436e5e53 aliguori
1890 34b25ca7 aliguori
    if (vc->link_status_changed)
1891 34b25ca7 aliguori
        vc->link_status_changed(vc);
1892 34b25ca7 aliguori
1893 436e5e53 aliguori
    return 1;
1894 436e5e53 aliguori
}
1895 436e5e53 aliguori
1896 63a01ef8 aliguori
void net_cleanup(void)
1897 63a01ef8 aliguori
{
1898 b9e82a59 blueswir1
#if !defined(_WIN32)
1899 63a01ef8 aliguori
    VLANState *vlan;
1900 63a01ef8 aliguori
1901 63a01ef8 aliguori
    /* close network clients */
1902 63a01ef8 aliguori
    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
1903 63a01ef8 aliguori
        VLANClientState *vc;
1904 63a01ef8 aliguori
1905 63a01ef8 aliguori
        for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
1906 63a01ef8 aliguori
            if (vc->fd_read == tap_receive) {
1907 63a01ef8 aliguori
                TAPState *s = vc->opaque;
1908 63a01ef8 aliguori
1909 973cbd37 aliguori
                if (s->down_script[0])
1910 973cbd37 aliguori
                    launch_script(s->down_script, s->down_script_arg, s->fd);
1911 63a01ef8 aliguori
            }
1912 63a01ef8 aliguori
#if defined(CONFIG_VDE)
1913 63a01ef8 aliguori
            if (vc->fd_read == vde_from_qemu) {
1914 63a01ef8 aliguori
                VDEState *s = vc->opaque;
1915 63a01ef8 aliguori
                vde_close(s->vde);
1916 63a01ef8 aliguori
            }
1917 63a01ef8 aliguori
#endif
1918 63a01ef8 aliguori
        }
1919 63a01ef8 aliguori
    }
1920 63a01ef8 aliguori
#endif
1921 63a01ef8 aliguori
}
1922 63a01ef8 aliguori
1923 63a01ef8 aliguori
void net_client_check(void)
1924 63a01ef8 aliguori
{
1925 63a01ef8 aliguori
    VLANState *vlan;
1926 63a01ef8 aliguori
1927 63a01ef8 aliguori
    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
1928 63a01ef8 aliguori
        if (vlan->nb_guest_devs == 0 && vlan->nb_host_devs == 0)
1929 63a01ef8 aliguori
            continue;
1930 63a01ef8 aliguori
        if (vlan->nb_guest_devs == 0)
1931 63a01ef8 aliguori
            fprintf(stderr, "Warning: vlan %d with no nics\n", vlan->id);
1932 63a01ef8 aliguori
        if (vlan->nb_host_devs == 0)
1933 63a01ef8 aliguori
            fprintf(stderr,
1934 63a01ef8 aliguori
                    "Warning: vlan %d is not connected to host network\n",
1935 63a01ef8 aliguori
                    vlan->id);
1936 63a01ef8 aliguori
    }
1937 63a01ef8 aliguori
}