Statistics
| Branch: | Revision:

root / net.c @ 4dda4063

History | View | Annotate | Download (44.5 kB)

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