Commit 63a01ef83ad1135355dfca1e6b8da9404fc5fa5b

Authored by aliguori
1 parent 6f97dba0

Move network redirection code out of vl.c and into net.c

Mostly code motion.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5581 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
... ... @@ -580,6 +580,7 @@ ifndef CONFIG_USER_ONLY
580 580  
581 581 OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o machine.o net-checksum.o
582 582 OBJS+=fw_cfg.o aio.o buffered_file.o migration.o migration-tcp.o qemu-char.o
  583 +OBJS+=net.o
583 584 ifdef CONFIG_WIN32
584 585 OBJS+=block-raw-win32.o
585 586 else
... ...
net.c 0 → 100644
  1 +/*
  2 + * QEMU System Emulator
  3 + *
  4 + * Copyright (c) 2003-2008 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#include "hw/hw.h"
  25 +#include "hw/boards.h"
  26 +#include "hw/usb.h"
  27 +#include "hw/pcmcia.h"
  28 +#include "hw/pc.h"
  29 +#include "hw/audiodev.h"
  30 +#include "hw/isa.h"
  31 +#include "hw/baum.h"
  32 +#include "hw/bt.h"
  33 +#include "net.h"
  34 +#include "console.h"
  35 +#include "sysemu.h"
  36 +#include "gdbstub.h"
  37 +#include "qemu-timer.h"
  38 +#include "qemu-char.h"
  39 +#include "block.h"
  40 +#include "audio/audio.h"
  41 +#include "migration.h"
  42 +
  43 +#include <unistd.h>
  44 +#include <fcntl.h>
  45 +#include <signal.h>
  46 +#include <time.h>
  47 +#include <errno.h>
  48 +#include <sys/time.h>
  49 +#include <zlib.h>
  50 +
  51 +#ifndef _WIN32
  52 +#include <sys/times.h>
  53 +#include <sys/wait.h>
  54 +#include <termios.h>
  55 +#include <sys/mman.h>
  56 +#include <sys/ioctl.h>
  57 +#include <sys/socket.h>
  58 +#include <netinet/in.h>
  59 +#include <dirent.h>
  60 +#include <netdb.h>
  61 +#include <sys/select.h>
  62 +#include <arpa/inet.h>
  63 +#ifdef _BSD
  64 +#include <sys/stat.h>
  65 +#if !defined(__APPLE__) && !defined(__OpenBSD__)
  66 +#include <libutil.h>
  67 +#endif
  68 +#ifdef __OpenBSD__
  69 +#include <net/if.h>
  70 +#endif
  71 +#elif defined (__GLIBC__) && defined (__FreeBSD_kernel__)
  72 +#include <freebsd/stdlib.h>
  73 +#else
  74 +#ifdef __linux__
  75 +#include <linux/if.h>
  76 +#include <linux/if_tun.h>
  77 +#include <pty.h>
  78 +#include <malloc.h>
  79 +#include <linux/rtc.h>
  80 +
  81 +/* For the benefit of older linux systems which don't supply it,
  82 + we use a local copy of hpet.h. */
  83 +/* #include <linux/hpet.h> */
  84 +#include "hpet.h"
  85 +
  86 +#include <linux/ppdev.h>
  87 +#include <linux/parport.h>
  88 +#endif
  89 +#ifdef __sun__
  90 +#include <sys/stat.h>
  91 +#include <sys/ethernet.h>
  92 +#include <sys/sockio.h>
  93 +#include <netinet/arp.h>
  94 +#include <netinet/in.h>
  95 +#include <netinet/in_systm.h>
  96 +#include <netinet/ip.h>
  97 +#include <netinet/ip_icmp.h> // must come after ip.h
  98 +#include <netinet/udp.h>
  99 +#include <netinet/tcp.h>
  100 +#include <net/if.h>
  101 +#include <syslog.h>
  102 +#include <stropts.h>
  103 +#endif
  104 +#endif
  105 +#endif
  106 +
  107 +#include "qemu_socket.h"
  108 +
  109 +#if defined(CONFIG_SLIRP)
  110 +#include "libslirp.h"
  111 +#endif
  112 +
  113 +#if defined(__OpenBSD__)
  114 +#include <util.h>
  115 +#endif
  116 +
  117 +#if defined(CONFIG_VDE)
  118 +#include <libvdeplug.h>
  119 +#endif
  120 +
  121 +#ifdef _WIN32
  122 +#include <malloc.h>
  123 +#include <sys/timeb.h>
  124 +#include <mmsystem.h>
  125 +#define getopt_long_only getopt_long
  126 +#define memalign(align, size) malloc(size)
  127 +#endif
  128 +
  129 +#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
  130 +#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
  131 +#ifdef __sun__
  132 +#define SMBD_COMMAND "/usr/sfw/sbin/smbd"
  133 +#else
  134 +#define SMBD_COMMAND "/usr/sbin/smbd"
  135 +#endif
  136 +
  137 +static VLANState *first_vlan;
  138 +
  139 +/***********************************************************/
  140 +/* network device redirectors */
  141 +
  142 +#if defined(DEBUG_NET) || defined(DEBUG_SLIRP)
  143 +static void hex_dump(FILE *f, const uint8_t *buf, int size)
  144 +{
  145 + int len, i, j, c;
  146 +
  147 + for(i=0;i<size;i+=16) {
  148 + len = size - i;
  149 + if (len > 16)
  150 + len = 16;
  151 + fprintf(f, "%08x ", i);
  152 + for(j=0;j<16;j++) {
  153 + if (j < len)
  154 + fprintf(f, " %02x", buf[i+j]);
  155 + else
  156 + fprintf(f, " ");
  157 + }
  158 + fprintf(f, " ");
  159 + for(j=0;j<len;j++) {
  160 + c = buf[i+j];
  161 + if (c < ' ' || c > '~')
  162 + c = '.';
  163 + fprintf(f, "%c", c);
  164 + }
  165 + fprintf(f, "\n");
  166 + }
  167 +}
  168 +#endif
  169 +
  170 +static int parse_macaddr(uint8_t *macaddr, const char *p)
  171 +{
  172 + int i;
  173 + char *last_char;
  174 + long int offset;
  175 +
  176 + errno = 0;
  177 + offset = strtol(p, &last_char, 0);
  178 + if (0 == errno && '\0' == *last_char &&
  179 + offset >= 0 && offset <= 0xFFFFFF) {
  180 + macaddr[3] = (offset & 0xFF0000) >> 16;
  181 + macaddr[4] = (offset & 0xFF00) >> 8;
  182 + macaddr[5] = offset & 0xFF;
  183 + return 0;
  184 + } else {
  185 + for(i = 0; i < 6; i++) {
  186 + macaddr[i] = strtol(p, (char **)&p, 16);
  187 + if (i == 5) {
  188 + if (*p != '\0')
  189 + return -1;
  190 + } else {
  191 + if (*p != ':' && *p != '-')
  192 + return -1;
  193 + p++;
  194 + }
  195 + }
  196 + return 0;
  197 + }
  198 +
  199 + return -1;
  200 +}
  201 +
  202 +static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
  203 +{
  204 + const char *p, *p1;
  205 + int len;
  206 + p = *pp;
  207 + p1 = strchr(p, sep);
  208 + if (!p1)
  209 + return -1;
  210 + len = p1 - p;
  211 + p1++;
  212 + if (buf_size > 0) {
  213 + if (len > buf_size - 1)
  214 + len = buf_size - 1;
  215 + memcpy(buf, p, len);
  216 + buf[len] = '\0';
  217 + }
  218 + *pp = p1;
  219 + return 0;
  220 +}
  221 +
  222 +int parse_host_src_port(struct sockaddr_in *haddr,
  223 + struct sockaddr_in *saddr,
  224 + const char *input_str)
  225 +{
  226 + char *str = strdup(input_str);
  227 + char *host_str = str;
  228 + char *src_str;
  229 + const char *src_str2;
  230 + char *ptr;
  231 +
  232 + /*
  233 + * Chop off any extra arguments at the end of the string which
  234 + * would start with a comma, then fill in the src port information
  235 + * if it was provided else use the "any address" and "any port".
  236 + */
  237 + if ((ptr = strchr(str,',')))
  238 + *ptr = '\0';
  239 +
  240 + if ((src_str = strchr(input_str,'@'))) {
  241 + *src_str = '\0';
  242 + src_str++;
  243 + }
  244 +
  245 + if (parse_host_port(haddr, host_str) < 0)
  246 + goto fail;
  247 +
  248 + src_str2 = src_str;
  249 + if (!src_str || *src_str == '\0')
  250 + src_str2 = ":0";
  251 +
  252 + if (parse_host_port(saddr, src_str2) < 0)
  253 + goto fail;
  254 +
  255 + free(str);
  256 + return(0);
  257 +
  258 +fail:
  259 + free(str);
  260 + return -1;
  261 +}
  262 +
  263 +int parse_host_port(struct sockaddr_in *saddr, const char *str)
  264 +{
  265 + char buf[512];
  266 + struct hostent *he;
  267 + const char *p, *r;
  268 + int port;
  269 +
  270 + p = str;
  271 + if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
  272 + return -1;
  273 + saddr->sin_family = AF_INET;
  274 + if (buf[0] == '\0') {
  275 + saddr->sin_addr.s_addr = 0;
  276 + } else {
  277 + if (isdigit(buf[0])) {
  278 + if (!inet_aton(buf, &saddr->sin_addr))
  279 + return -1;
  280 + } else {
  281 + if ((he = gethostbyname(buf)) == NULL)
  282 + return - 1;
  283 + saddr->sin_addr = *(struct in_addr *)he->h_addr;
  284 + }
  285 + }
  286 + port = strtol(p, (char **)&r, 0);
  287 + if (r == p)
  288 + return -1;
  289 + saddr->sin_port = htons(port);
  290 + return 0;
  291 +}
  292 +
  293 +#ifndef _WIN32
  294 +int parse_unix_path(struct sockaddr_un *uaddr, const char *str)
  295 +{
  296 + const char *p;
  297 + int len;
  298 +
  299 + len = MIN(108, strlen(str));
  300 + p = strchr(str, ',');
  301 + if (p)
  302 + len = MIN(len, p - str);
  303 +
  304 + memset(uaddr, 0, sizeof(*uaddr));
  305 +
  306 + uaddr->sun_family = AF_UNIX;
  307 + memcpy(uaddr->sun_path, str, len);
  308 +
  309 + return 0;
  310 +}
  311 +#endif
  312 +
  313 +VLANClientState *qemu_new_vlan_client(VLANState *vlan,
  314 + IOReadHandler *fd_read,
  315 + IOCanRWHandler *fd_can_read,
  316 + void *opaque)
  317 +{
  318 + VLANClientState *vc, **pvc;
  319 + vc = qemu_mallocz(sizeof(VLANClientState));
  320 + if (!vc)
  321 + return NULL;
  322 + vc->fd_read = fd_read;
  323 + vc->fd_can_read = fd_can_read;
  324 + vc->opaque = opaque;
  325 + vc->vlan = vlan;
  326 +
  327 + vc->next = NULL;
  328 + pvc = &vlan->first_client;
  329 + while (*pvc != NULL)
  330 + pvc = &(*pvc)->next;
  331 + *pvc = vc;
  332 + return vc;
  333 +}
  334 +
  335 +void qemu_del_vlan_client(VLANClientState *vc)
  336 +{
  337 + VLANClientState **pvc = &vc->vlan->first_client;
  338 +
  339 + while (*pvc != NULL)
  340 + if (*pvc == vc) {
  341 + *pvc = vc->next;
  342 + free(vc);
  343 + break;
  344 + } else
  345 + pvc = &(*pvc)->next;
  346 +}
  347 +
  348 +int qemu_can_send_packet(VLANClientState *vc1)
  349 +{
  350 + VLANState *vlan = vc1->vlan;
  351 + VLANClientState *vc;
  352 +
  353 + for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
  354 + if (vc != vc1) {
  355 + if (vc->fd_can_read && vc->fd_can_read(vc->opaque))
  356 + return 1;
  357 + }
  358 + }
  359 + return 0;
  360 +}
  361 +
  362 +void qemu_send_packet(VLANClientState *vc1, const uint8_t *buf, int size)
  363 +{
  364 + VLANState *vlan = vc1->vlan;
  365 + VLANClientState *vc;
  366 +
  367 +#ifdef DEBUG_NET
  368 + printf("vlan %d send:\n", vlan->id);
  369 + hex_dump(stdout, buf, size);
  370 +#endif
  371 + for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
  372 + if (vc != vc1) {
  373 + vc->fd_read(vc->opaque, buf, size);
  374 + }
  375 + }
  376 +}
  377 +
  378 +#if defined(CONFIG_SLIRP)
  379 +
  380 +/* slirp network adapter */
  381 +
  382 +static int slirp_inited;
  383 +static VLANClientState *slirp_vc;
  384 +
  385 +int slirp_can_output(void)
  386 +{
  387 + return !slirp_vc || qemu_can_send_packet(slirp_vc);
  388 +}
  389 +
  390 +void slirp_output(const uint8_t *pkt, int pkt_len)
  391 +{
  392 +#ifdef DEBUG_SLIRP
  393 + printf("slirp output:\n");
  394 + hex_dump(stdout, pkt, pkt_len);
  395 +#endif
  396 + if (!slirp_vc)
  397 + return;
  398 + qemu_send_packet(slirp_vc, pkt, pkt_len);
  399 +}
  400 +
  401 +int slirp_is_inited(void)
  402 +{
  403 + return slirp_inited;
  404 +}
  405 +
  406 +static void slirp_receive(void *opaque, const uint8_t *buf, int size)
  407 +{
  408 +#ifdef DEBUG_SLIRP
  409 + printf("slirp input:\n");
  410 + hex_dump(stdout, buf, size);
  411 +#endif
  412 + slirp_input(buf, size);
  413 +}
  414 +
  415 +static int net_slirp_init(VLANState *vlan)
  416 +{
  417 + if (!slirp_inited) {
  418 + slirp_inited = 1;
  419 + slirp_init();
  420 + }
  421 + slirp_vc = qemu_new_vlan_client(vlan,
  422 + slirp_receive, NULL, NULL);
  423 + snprintf(slirp_vc->info_str, sizeof(slirp_vc->info_str), "user redirector");
  424 + return 0;
  425 +}
  426 +
  427 +void net_slirp_redir(const char *redir_str)
  428 +{
  429 + int is_udp;
  430 + char buf[256], *r;
  431 + const char *p;
  432 + struct in_addr guest_addr;
  433 + int host_port, guest_port;
  434 +
  435 + if (!slirp_inited) {
  436 + slirp_inited = 1;
  437 + slirp_init();
  438 + }
  439 +
  440 + p = redir_str;
  441 + if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
  442 + goto fail;
  443 + if (!strcmp(buf, "tcp")) {
  444 + is_udp = 0;
  445 + } else if (!strcmp(buf, "udp")) {
  446 + is_udp = 1;
  447 + } else {
  448 + goto fail;
  449 + }
  450 +
  451 + if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
  452 + goto fail;
  453 + host_port = strtol(buf, &r, 0);
  454 + if (r == buf)
  455 + goto fail;
  456 +
  457 + if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
  458 + goto fail;
  459 + if (buf[0] == '\0') {
  460 + pstrcpy(buf, sizeof(buf), "10.0.2.15");
  461 + }
  462 + if (!inet_aton(buf, &guest_addr))
  463 + goto fail;
  464 +
  465 + guest_port = strtol(p, &r, 0);
  466 + if (r == p)
  467 + goto fail;
  468 +
  469 + if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) {
  470 + fprintf(stderr, "qemu: could not set up redirection\n");
  471 + exit(1);
  472 + }
  473 + return;
  474 + fail:
  475 + fprintf(stderr, "qemu: syntax: -redir [tcp|udp]:host-port:[guest-host]:guest-port\n");
  476 + exit(1);
  477 +}
  478 +
  479 +#ifndef _WIN32
  480 +
  481 +static char smb_dir[1024];
  482 +
  483 +static void erase_dir(char *dir_name)
  484 +{
  485 + DIR *d;
  486 + struct dirent *de;
  487 + char filename[1024];
  488 +
  489 + /* erase all the files in the directory */
  490 + if ((d = opendir(dir_name)) != 0) {
  491 + for(;;) {
  492 + de = readdir(d);
  493 + if (!de)
  494 + break;
  495 + if (strcmp(de->d_name, ".") != 0 &&
  496 + strcmp(de->d_name, "..") != 0) {
  497 + snprintf(filename, sizeof(filename), "%s/%s",
  498 + smb_dir, de->d_name);
  499 + if (unlink(filename) != 0) /* is it a directory? */
  500 + erase_dir(filename);
  501 + }
  502 + }
  503 + closedir(d);
  504 + rmdir(dir_name);
  505 + }
  506 +}
  507 +
  508 +/* automatic user mode samba server configuration */
  509 +static void smb_exit(void)
  510 +{
  511 + erase_dir(smb_dir);
  512 +}
  513 +
  514 +/* automatic user mode samba server configuration */
  515 +void net_slirp_smb(const char *exported_dir)
  516 +{
  517 + char smb_conf[1024];
  518 + char smb_cmdline[1024];
  519 + FILE *f;
  520 +
  521 + if (!slirp_inited) {
  522 + slirp_inited = 1;
  523 + slirp_init();
  524 + }
  525 +
  526 + /* XXX: better tmp dir construction */
  527 + snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%d", getpid());
  528 + if (mkdir(smb_dir, 0700) < 0) {
  529 + fprintf(stderr, "qemu: could not create samba server dir '%s'\n", smb_dir);
  530 + exit(1);
  531 + }
  532 + snprintf(smb_conf, sizeof(smb_conf), "%s/%s", smb_dir, "smb.conf");
  533 +
  534 + f = fopen(smb_conf, "w");
  535 + if (!f) {
  536 + fprintf(stderr, "qemu: could not create samba server configuration file '%s'\n", smb_conf);
  537 + exit(1);
  538 + }
  539 + fprintf(f,
  540 + "[global]\n"
  541 + "private dir=%s\n"
  542 + "smb ports=0\n"
  543 + "socket address=127.0.0.1\n"
  544 + "pid directory=%s\n"
  545 + "lock directory=%s\n"
  546 + "log file=%s/log.smbd\n"
  547 + "smb passwd file=%s/smbpasswd\n"
  548 + "security = share\n"
  549 + "[qemu]\n"
  550 + "path=%s\n"
  551 + "read only=no\n"
  552 + "guest ok=yes\n",
  553 + smb_dir,
  554 + smb_dir,
  555 + smb_dir,
  556 + smb_dir,
  557 + smb_dir,
  558 + exported_dir
  559 + );
  560 + fclose(f);
  561 + atexit(smb_exit);
  562 +
  563 + snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s",
  564 + SMBD_COMMAND, smb_conf);
  565 +
  566 + slirp_add_exec(0, smb_cmdline, 4, 139);
  567 +}
  568 +
  569 +#endif /* !defined(_WIN32) */
  570 +void do_info_slirp(void)
  571 +{
  572 + slirp_stats();
  573 +}
  574 +
  575 +#endif /* CONFIG_SLIRP */
  576 +
  577 +#if !defined(_WIN32)
  578 +
  579 +typedef struct TAPState {
  580 + VLANClientState *vc;
  581 + int fd;
  582 + char down_script[1024];
  583 +} TAPState;
  584 +
  585 +static void tap_receive(void *opaque, const uint8_t *buf, int size)
  586 +{
  587 + TAPState *s = opaque;
  588 + int ret;
  589 + for(;;) {
  590 + ret = write(s->fd, buf, size);
  591 + if (ret < 0 && (errno == EINTR || errno == EAGAIN)) {
  592 + } else {
  593 + break;
  594 + }
  595 + }
  596 +}
  597 +
  598 +static void tap_send(void *opaque)
  599 +{
  600 + TAPState *s = opaque;
  601 + uint8_t buf[4096];
  602 + int size;
  603 +
  604 +#ifdef __sun__
  605 + struct strbuf sbuf;
  606 + int f = 0;
  607 + sbuf.maxlen = sizeof(buf);
  608 + sbuf.buf = buf;
  609 + size = getmsg(s->fd, NULL, &sbuf, &f) >=0 ? sbuf.len : -1;
  610 +#else
  611 + size = read(s->fd, buf, sizeof(buf));
  612 +#endif
  613 + if (size > 0) {
  614 + qemu_send_packet(s->vc, buf, size);
  615 + }
  616 +}
  617 +
  618 +/* fd support */
  619 +
  620 +static TAPState *net_tap_fd_init(VLANState *vlan, int fd)
  621 +{
  622 + TAPState *s;
  623 +
  624 + s = qemu_mallocz(sizeof(TAPState));
  625 + if (!s)
  626 + return NULL;
  627 + s->fd = fd;
  628 + s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s);
  629 + qemu_set_fd_handler(s->fd, tap_send, NULL, s);
  630 + snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: fd=%d", fd);
  631 + return s;
  632 +}
  633 +
  634 +#if defined (_BSD) || defined (__FreeBSD_kernel__)
  635 +static int tap_open(char *ifname, int ifname_size)
  636 +{
  637 + int fd;
  638 + char *dev;
  639 + struct stat s;
  640 +
  641 + TFR(fd = open("/dev/tap", O_RDWR));
  642 + if (fd < 0) {
  643 + fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n");
  644 + return -1;
  645 + }
  646 +
  647 + fstat(fd, &s);
  648 + dev = devname(s.st_rdev, S_IFCHR);
  649 + pstrcpy(ifname, ifname_size, dev);
  650 +
  651 + fcntl(fd, F_SETFL, O_NONBLOCK);
  652 + return fd;
  653 +}
  654 +#elif defined(__sun__)
  655 +#define TUNNEWPPA (('T'<<16) | 0x0001)
  656 +/*
  657 + * Allocate TAP device, returns opened fd.
  658 + * Stores dev name in the first arg(must be large enough).
  659 + */
  660 +int tap_alloc(char *dev, size_t dev_size)
  661 +{
  662 + int tap_fd, if_fd, ppa = -1;
  663 + static int ip_fd = 0;
  664 + char *ptr;
  665 +
  666 + static int arp_fd = 0;
  667 + int ip_muxid, arp_muxid;
  668 + struct strioctl strioc_if, strioc_ppa;
  669 + int link_type = I_PLINK;;
  670 + struct lifreq ifr;
  671 + char actual_name[32] = "";
  672 +
  673 + memset(&ifr, 0x0, sizeof(ifr));
  674 +
  675 + if( *dev ){
  676 + ptr = dev;
  677 + while( *ptr && !isdigit((int)*ptr) ) ptr++;
  678 + ppa = atoi(ptr);
  679 + }
  680 +
  681 + /* Check if IP device was opened */
  682 + if( ip_fd )
  683 + close(ip_fd);
  684 +
  685 + TFR(ip_fd = open("/dev/udp", O_RDWR, 0));
  686 + if (ip_fd < 0) {
  687 + syslog(LOG_ERR, "Can't open /dev/ip (actually /dev/udp)");
  688 + return -1;
  689 + }
  690 +
  691 + TFR(tap_fd = open("/dev/tap", O_RDWR, 0));
  692 + if (tap_fd < 0) {
  693 + syslog(LOG_ERR, "Can't open /dev/tap");
  694 + return -1;
  695 + }
  696 +
  697 + /* Assign a new PPA and get its unit number. */
  698 + strioc_ppa.ic_cmd = TUNNEWPPA;
  699 + strioc_ppa.ic_timout = 0;
  700 + strioc_ppa.ic_len = sizeof(ppa);
  701 + strioc_ppa.ic_dp = (char *)&ppa;
  702 + if ((ppa = ioctl (tap_fd, I_STR, &strioc_ppa)) < 0)
  703 + syslog (LOG_ERR, "Can't assign new interface");
  704 +
  705 + TFR(if_fd = open("/dev/tap", O_RDWR, 0));
  706 + if (if_fd < 0) {
  707 + syslog(LOG_ERR, "Can't open /dev/tap (2)");
  708 + return -1;
  709 + }
  710 + if(ioctl(if_fd, I_PUSH, "ip") < 0){
  711 + syslog(LOG_ERR, "Can't push IP module");
  712 + return -1;
  713 + }
  714 +
  715 + if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
  716 + syslog(LOG_ERR, "Can't get flags\n");
  717 +
  718 + snprintf (actual_name, 32, "tap%d", ppa);
  719 + pstrcpy(ifr.lifr_name, sizeof(ifr.lifr_name), actual_name);
  720 +
  721 + ifr.lifr_ppa = ppa;
  722 + /* Assign ppa according to the unit number returned by tun device */
  723 +
  724 + if (ioctl (if_fd, SIOCSLIFNAME, &ifr) < 0)
  725 + syslog (LOG_ERR, "Can't set PPA %d", ppa);
  726 + if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0)
  727 + syslog (LOG_ERR, "Can't get flags\n");
  728 + /* Push arp module to if_fd */
  729 + if (ioctl (if_fd, I_PUSH, "arp") < 0)
  730 + syslog (LOG_ERR, "Can't push ARP module (2)");
  731 +
  732 + /* Push arp module to ip_fd */
  733 + if (ioctl (ip_fd, I_POP, NULL) < 0)
  734 + syslog (LOG_ERR, "I_POP failed\n");
  735 + if (ioctl (ip_fd, I_PUSH, "arp") < 0)
  736 + syslog (LOG_ERR, "Can't push ARP module (3)\n");
  737 + /* Open arp_fd */
  738 + TFR(arp_fd = open ("/dev/tap", O_RDWR, 0));
  739 + if (arp_fd < 0)
  740 + syslog (LOG_ERR, "Can't open %s\n", "/dev/tap");
  741 +
  742 + /* Set ifname to arp */
  743 + strioc_if.ic_cmd = SIOCSLIFNAME;
  744 + strioc_if.ic_timout = 0;
  745 + strioc_if.ic_len = sizeof(ifr);
  746 + strioc_if.ic_dp = (char *)&ifr;
  747 + if (ioctl(arp_fd, I_STR, &strioc_if) < 0){
  748 + syslog (LOG_ERR, "Can't set ifname to arp\n");
  749 + }
  750 +
  751 + if((ip_muxid = ioctl(ip_fd, I_LINK, if_fd)) < 0){
  752 + syslog(LOG_ERR, "Can't link TAP device to IP");
  753 + return -1;
  754 + }
  755 +
  756 + if ((arp_muxid = ioctl (ip_fd, link_type, arp_fd)) < 0)
  757 + syslog (LOG_ERR, "Can't link TAP device to ARP");
  758 +
  759 + close (if_fd);
  760 +
  761 + memset(&ifr, 0x0, sizeof(ifr));
  762 + pstrcpy(ifr.lifr_name, sizeof(ifr.lifr_name), actual_name);
  763 + ifr.lifr_ip_muxid = ip_muxid;
  764 + ifr.lifr_arp_muxid = arp_muxid;
  765 +
  766 + if (ioctl (ip_fd, SIOCSLIFMUXID, &ifr) < 0)
  767 + {
  768 + ioctl (ip_fd, I_PUNLINK , arp_muxid);
  769 + ioctl (ip_fd, I_PUNLINK, ip_muxid);
  770 + syslog (LOG_ERR, "Can't set multiplexor id");
  771 + }
  772 +
  773 + snprintf(dev, dev_size, "tap%d", ppa);
  774 + return tap_fd;
  775 +}
  776 +
  777 +static int tap_open(char *ifname, int ifname_size)
  778 +{
  779 + char dev[10]="";
  780 + int fd;
  781 + if( (fd = tap_alloc(dev, sizeof(dev))) < 0 ){
  782 + fprintf(stderr, "Cannot allocate TAP device\n");
  783 + return -1;
  784 + }
  785 + pstrcpy(ifname, ifname_size, dev);
  786 + fcntl(fd, F_SETFL, O_NONBLOCK);
  787 + return fd;
  788 +}
  789 +#else
  790 +static int tap_open(char *ifname, int ifname_size)
  791 +{
  792 + struct ifreq ifr;
  793 + int fd, ret;
  794 +
  795 + TFR(fd = open("/dev/net/tun", O_RDWR));
  796 + if (fd < 0) {
  797 + fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
  798 + return -1;
  799 + }
  800 + memset(&ifr, 0, sizeof(ifr));
  801 + ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
  802 + if (ifname[0] != '\0')
  803 + pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname);
  804 + else
  805 + pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d");
  806 + ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
  807 + if (ret != 0) {
  808 + fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
  809 + close(fd);
  810 + return -1;
  811 + }
  812 + pstrcpy(ifname, ifname_size, ifr.ifr_name);
  813 + fcntl(fd, F_SETFL, O_NONBLOCK);
  814 + return fd;
  815 +}
  816 +#endif
  817 +
  818 +static int launch_script(const char *setup_script, const char *ifname, int fd)
  819 +{
  820 + int pid, status;
  821 + char *args[3];
  822 + char **parg;
  823 +
  824 + /* try to launch network script */
  825 + pid = fork();
  826 + if (pid >= 0) {
  827 + if (pid == 0) {
  828 + int open_max = sysconf (_SC_OPEN_MAX), i;
  829 + for (i = 0; i < open_max; i++)
  830 + if (i != STDIN_FILENO &&
  831 + i != STDOUT_FILENO &&
  832 + i != STDERR_FILENO &&
  833 + i != fd)
  834 + close(i);
  835 +
  836 + parg = args;
  837 + *parg++ = (char *)setup_script;
  838 + *parg++ = (char *)ifname;
  839 + *parg++ = NULL;
  840 + execv(setup_script, args);
  841 + _exit(1);
  842 + }
  843 + while (waitpid(pid, &status, 0) != pid);
  844 + if (!WIFEXITED(status) ||
  845 + WEXITSTATUS(status) != 0) {
  846 + fprintf(stderr, "%s: could not launch network script\n",
  847 + setup_script);
  848 + return -1;
  849 + }
  850 + }
  851 + return 0;
  852 +}
  853 +
  854 +static int net_tap_init(VLANState *vlan, const char *ifname1,
  855 + const char *setup_script, const char *down_script)
  856 +{
  857 + TAPState *s;
  858 + int fd;
  859 + char ifname[128];
  860 +
  861 + if (ifname1 != NULL)
  862 + pstrcpy(ifname, sizeof(ifname), ifname1);
  863 + else
  864 + ifname[0] = '\0';
  865 + TFR(fd = tap_open(ifname, sizeof(ifname)));
  866 + if (fd < 0)
  867 + return -1;
  868 +
  869 + if (!setup_script || !strcmp(setup_script, "no"))
  870 + setup_script = "";
  871 + if (setup_script[0] != '\0') {
  872 + if (launch_script(setup_script, ifname, fd))
  873 + return -1;
  874 + }
  875 + s = net_tap_fd_init(vlan, fd);
  876 + if (!s)
  877 + return -1;
  878 + snprintf(s->vc->info_str, sizeof(s->vc->info_str),
  879 + "tap: ifname=%s setup_script=%s", ifname, setup_script);
  880 + if (down_script && strcmp(down_script, "no"))
  881 + snprintf(s->down_script, sizeof(s->down_script), "%s", down_script);
  882 + return 0;
  883 +}
  884 +
  885 +#endif /* !_WIN32 */
  886 +
  887 +#if defined(CONFIG_VDE)
  888 +typedef struct VDEState {
  889 + VLANClientState *vc;
  890 + VDECONN *vde;
  891 +} VDEState;
  892 +
  893 +static void vde_to_qemu(void *opaque)
  894 +{
  895 + VDEState *s = opaque;
  896 + uint8_t buf[4096];
  897 + int size;
  898 +
  899 + size = vde_recv(s->vde, buf, sizeof(buf), 0);
  900 + if (size > 0) {
  901 + qemu_send_packet(s->vc, buf, size);
  902 + }
  903 +}
  904 +
  905 +static void vde_from_qemu(void *opaque, const uint8_t *buf, int size)
  906 +{
  907 + VDEState *s = opaque;
  908 + int ret;
  909 + for(;;) {
  910 + ret = vde_send(s->vde, buf, size, 0);
  911 + if (ret < 0 && errno == EINTR) {
  912 + } else {
  913 + break;
  914 + }
  915 + }
  916 +}
  917 +
  918 +static int net_vde_init(VLANState *vlan, const char *sock, int port,
  919 + const char *group, int mode)
  920 +{
  921 + VDEState *s;
  922 + char *init_group = strlen(group) ? (char *)group : NULL;
  923 + char *init_sock = strlen(sock) ? (char *)sock : NULL;
  924 +
  925 + struct vde_open_args args = {
  926 + .port = port,
  927 + .group = init_group,
  928 + .mode = mode,
  929 + };
  930 +
  931 + s = qemu_mallocz(sizeof(VDEState));
  932 + if (!s)
  933 + return -1;
  934 + s->vde = vde_open(init_sock, "QEMU", &args);
  935 + if (!s->vde){
  936 + free(s);
  937 + return -1;
  938 + }
  939 + s->vc = qemu_new_vlan_client(vlan, vde_from_qemu, NULL, s);
  940 + qemu_set_fd_handler(vde_datafd(s->vde), vde_to_qemu, NULL, s);
  941 + snprintf(s->vc->info_str, sizeof(s->vc->info_str), "vde: sock=%s fd=%d",
  942 + sock, vde_datafd(s->vde));
  943 + return 0;
  944 +}
  945 +#endif
  946 +
  947 +/* network connection */
  948 +typedef struct NetSocketState {
  949 + VLANClientState *vc;
  950 + int fd;
  951 + int state; /* 0 = getting length, 1 = getting data */
  952 + int index;
  953 + int packet_len;
  954 + uint8_t buf[4096];
  955 + struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
  956 +} NetSocketState;
  957 +
  958 +typedef struct NetSocketListenState {
  959 + VLANState *vlan;
  960 + int fd;
  961 +} NetSocketListenState;
  962 +
  963 +/* XXX: we consider we can send the whole packet without blocking */
  964 +static void net_socket_receive(void *opaque, const uint8_t *buf, int size)
  965 +{
  966 + NetSocketState *s = opaque;
  967 + uint32_t len;
  968 + len = htonl(size);
  969 +
  970 + send_all(s->fd, (const uint8_t *)&len, sizeof(len));
  971 + send_all(s->fd, buf, size);
  972 +}
  973 +
  974 +static void net_socket_receive_dgram(void *opaque, const uint8_t *buf, int size)
  975 +{
  976 + NetSocketState *s = opaque;
  977 + sendto(s->fd, buf, size, 0,
  978 + (struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));
  979 +}
  980 +
  981 +static void net_socket_send(void *opaque)
  982 +{
  983 + NetSocketState *s = opaque;
  984 + int l, size, err;
  985 + uint8_t buf1[4096];
  986 + const uint8_t *buf;
  987 +
  988 + size = recv(s->fd, buf1, sizeof(buf1), 0);
  989 + if (size < 0) {
  990 + err = socket_error();
  991 + if (err != EWOULDBLOCK)
  992 + goto eoc;
  993 + } else if (size == 0) {
  994 + /* end of connection */
  995 + eoc:
  996 + qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
  997 + closesocket(s->fd);
  998 + return;
  999 + }
  1000 + buf = buf1;
  1001 + while (size > 0) {
  1002 + /* reassemble a packet from the network */
  1003 + switch(s->state) {
  1004 + case 0:
  1005 + l = 4 - s->index;
  1006 + if (l > size)
  1007 + l = size;
  1008 + memcpy(s->buf + s->index, buf, l);
  1009 + buf += l;
  1010 + size -= l;
  1011 + s->index += l;
  1012 + if (s->index == 4) {
  1013 + /* got length */
  1014 + s->packet_len = ntohl(*(uint32_t *)s->buf);
  1015 + s->index = 0;
  1016 + s->state = 1;
  1017 + }
  1018 + break;
  1019 + case 1:
  1020 + l = s->packet_len - s->index;
  1021 + if (l > size)
  1022 + l = size;
  1023 + memcpy(s->buf + s->index, buf, l);
  1024 + s->index += l;
  1025 + buf += l;
  1026 + size -= l;
  1027 + if (s->index >= s->packet_len) {
  1028 + qemu_send_packet(s->vc, s->buf, s->packet_len);
  1029 + s->index = 0;
  1030 + s->state = 0;
  1031 + }
  1032 + break;
  1033 + }
  1034 + }
  1035 +}
  1036 +
  1037 +static void net_socket_send_dgram(void *opaque)
  1038 +{
  1039 + NetSocketState *s = opaque;
  1040 + int size;
  1041 +
  1042 + size = recv(s->fd, s->buf, sizeof(s->buf), 0);
  1043 + if (size < 0)
  1044 + return;
  1045 + if (size == 0) {
  1046 + /* end of connection */
  1047 + qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
  1048 + return;
  1049 + }
  1050 + qemu_send_packet(s->vc, s->buf, size);
  1051 +}
  1052 +
  1053 +static int net_socket_mcast_create(struct sockaddr_in *mcastaddr)
  1054 +{
  1055 + struct ip_mreq imr;
  1056 + int fd;
  1057 + int val, ret;
  1058 + if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) {
  1059 + fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) does not contain a multicast address\n",
  1060 + inet_ntoa(mcastaddr->sin_addr),
  1061 + (int)ntohl(mcastaddr->sin_addr.s_addr));
  1062 + return -1;
  1063 +
  1064 + }
  1065 + fd = socket(PF_INET, SOCK_DGRAM, 0);
  1066 + if (fd < 0) {
  1067 + perror("socket(PF_INET, SOCK_DGRAM)");
  1068 + return -1;
  1069 + }
  1070 +
  1071 + val = 1;
  1072 + ret=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
  1073 + (const char *)&val, sizeof(val));
  1074 + if (ret < 0) {
  1075 + perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)");
  1076 + goto fail;
  1077 + }
  1078 +
  1079 + ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
  1080 + if (ret < 0) {
  1081 + perror("bind");
  1082 + goto fail;
  1083 + }
  1084 +
  1085 + /* Add host to multicast group */
  1086 + imr.imr_multiaddr = mcastaddr->sin_addr;
  1087 + imr.imr_interface.s_addr = htonl(INADDR_ANY);
  1088 +
  1089 + ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
  1090 + (const char *)&imr, sizeof(struct ip_mreq));
  1091 + if (ret < 0) {
  1092 + perror("setsockopt(IP_ADD_MEMBERSHIP)");
  1093 + goto fail;
  1094 + }
  1095 +
  1096 + /* Force mcast msgs to loopback (eg. several QEMUs in same host */
  1097 + val = 1;
  1098 + ret=setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
  1099 + (const char *)&val, sizeof(val));
  1100 + if (ret < 0) {
  1101 + perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)");
  1102 + goto fail;
  1103 + }
  1104 +
  1105 + socket_set_nonblock(fd);
  1106 + return fd;
  1107 +fail:
  1108 + if (fd >= 0)
  1109 + closesocket(fd);
  1110 + return -1;
  1111 +}
  1112 +
  1113 +static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan, int fd,
  1114 + int is_connected)
  1115 +{
  1116 + struct sockaddr_in saddr;
  1117 + int newfd;
  1118 + socklen_t saddr_len;
  1119 + NetSocketState *s;
  1120 +
  1121 + /* fd passed: multicast: "learn" dgram_dst address from bound address and save it
  1122 + * Because this may be "shared" socket from a "master" process, datagrams would be recv()
  1123 + * by ONLY ONE process: we must "clone" this dgram socket --jjo
  1124 + */
  1125 +
  1126 + if (is_connected) {
  1127 + if (getsockname(fd, (struct sockaddr *) &saddr, &saddr_len) == 0) {
  1128 + /* must be bound */
  1129 + if (saddr.sin_addr.s_addr==0) {
  1130 + fprintf(stderr, "qemu: error: init_dgram: fd=%d unbound, cannot setup multicast dst addr\n",
  1131 + fd);
  1132 + return NULL;
  1133 + }
  1134 + /* clone dgram socket */
  1135 + newfd = net_socket_mcast_create(&saddr);
  1136 + if (newfd < 0) {
  1137 + /* error already reported by net_socket_mcast_create() */
  1138 + close(fd);
  1139 + return NULL;
  1140 + }
  1141 + /* clone newfd to fd, close newfd */
  1142 + dup2(newfd, fd);
  1143 + close(newfd);
  1144 +
  1145 + } else {
  1146 + fprintf(stderr, "qemu: error: init_dgram: fd=%d failed getsockname(): %s\n",
  1147 + fd, strerror(errno));
  1148 + return NULL;
  1149 + }
  1150 + }
  1151 +
  1152 + s = qemu_mallocz(sizeof(NetSocketState));
  1153 + if (!s)
  1154 + return NULL;
  1155 + s->fd = fd;
  1156 +
  1157 + s->vc = qemu_new_vlan_client(vlan, net_socket_receive_dgram, NULL, s);
  1158 + qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
  1159 +
  1160 + /* mcast: save bound address as dst */
  1161 + if (is_connected) s->dgram_dst=saddr;
  1162 +
  1163 + snprintf(s->vc->info_str, sizeof(s->vc->info_str),
  1164 + "socket: fd=%d (%s mcast=%s:%d)",
  1165 + fd, is_connected? "cloned" : "",
  1166 + inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
  1167 + return s;
  1168 +}
  1169 +
  1170 +static void net_socket_connect(void *opaque)
  1171 +{
  1172 + NetSocketState *s = opaque;
  1173 + qemu_set_fd_handler(s->fd, net_socket_send, NULL, s);
  1174 +}
  1175 +
  1176 +static NetSocketState *net_socket_fd_init_stream(VLANState *vlan, int fd,
  1177 + int is_connected)
  1178 +{
  1179 + NetSocketState *s;
  1180 + s = qemu_mallocz(sizeof(NetSocketState));
  1181 + if (!s)
  1182 + return NULL;
  1183 + s->fd = fd;
  1184 + s->vc = qemu_new_vlan_client(vlan,
  1185 + net_socket_receive, NULL, s);
  1186 + snprintf(s->vc->info_str, sizeof(s->vc->info_str),
  1187 + "socket: fd=%d", fd);
  1188 + if (is_connected) {
  1189 + net_socket_connect(s);
  1190 + } else {
  1191 + qemu_set_fd_handler(s->fd, NULL, net_socket_connect, s);
  1192 + }
  1193 + return s;
  1194 +}
  1195 +
  1196 +static NetSocketState *net_socket_fd_init(VLANState *vlan, int fd,
  1197 + int is_connected)
  1198 +{
  1199 + int so_type=-1, optlen=sizeof(so_type);
  1200 +
  1201 + if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type,
  1202 + (socklen_t *)&optlen)< 0) {
  1203 + fprintf(stderr, "qemu: error: getsockopt(SO_TYPE) for fd=%d failed\n", fd);
  1204 + return NULL;
  1205 + }
  1206 + switch(so_type) {
  1207 + case SOCK_DGRAM:
  1208 + return net_socket_fd_init_dgram(vlan, fd, is_connected);
  1209 + case SOCK_STREAM:
  1210 + return net_socket_fd_init_stream(vlan, fd, is_connected);
  1211 + default:
  1212 + /* who knows ... this could be a eg. a pty, do warn and continue as stream */
  1213 + fprintf(stderr, "qemu: warning: socket type=%d for fd=%d is not SOCK_DGRAM or SOCK_STREAM\n", so_type, fd);
  1214 + return net_socket_fd_init_stream(vlan, fd, is_connected);
  1215 + }
  1216 + return NULL;
  1217 +}
  1218 +
  1219 +static void net_socket_accept(void *opaque)
  1220 +{
  1221 + NetSocketListenState *s = opaque;
  1222 + NetSocketState *s1;
  1223 + struct sockaddr_in saddr;
  1224 + socklen_t len;
  1225 + int fd;
  1226 +
  1227 + for(;;) {
  1228 + len = sizeof(saddr);
  1229 + fd = accept(s->fd, (struct sockaddr *)&saddr, &len);
  1230 + if (fd < 0 && errno != EINTR) {
  1231 + return;
  1232 + } else if (fd >= 0) {
  1233 + break;
  1234 + }
  1235 + }
  1236 + s1 = net_socket_fd_init(s->vlan, fd, 1);
  1237 + if (!s1) {
  1238 + closesocket(fd);
  1239 + } else {
  1240 + snprintf(s1->vc->info_str, sizeof(s1->vc->info_str),
  1241 + "socket: connection from %s:%d",
  1242 + inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
  1243 + }
  1244 +}
  1245 +
  1246 +static int net_socket_listen_init(VLANState *vlan, const char *host_str)
  1247 +{
  1248 + NetSocketListenState *s;
  1249 + int fd, val, ret;
  1250 + struct sockaddr_in saddr;
  1251 +
  1252 + if (parse_host_port(&saddr, host_str) < 0)
  1253 + return -1;
  1254 +
  1255 + s = qemu_mallocz(sizeof(NetSocketListenState));
  1256 + if (!s)
  1257 + return -1;
  1258 +
  1259 + fd = socket(PF_INET, SOCK_STREAM, 0);
  1260 + if (fd < 0) {
  1261 + perror("socket");
  1262 + return -1;
  1263 + }
  1264 + socket_set_nonblock(fd);
  1265 +
  1266 + /* allow fast reuse */
  1267 + val = 1;
  1268 + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
  1269 +
  1270 + ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
  1271 + if (ret < 0) {
  1272 + perror("bind");
  1273 + return -1;
  1274 + }
  1275 + ret = listen(fd, 0);
  1276 + if (ret < 0) {
  1277 + perror("listen");
  1278 + return -1;
  1279 + }
  1280 + s->vlan = vlan;
  1281 + s->fd = fd;
  1282 + qemu_set_fd_handler(fd, net_socket_accept, NULL, s);
  1283 + return 0;
  1284 +}
  1285 +
  1286 +static int net_socket_connect_init(VLANState *vlan, const char *host_str)
  1287 +{
  1288 + NetSocketState *s;
  1289 + int fd, connected, ret, err;
  1290 + struct sockaddr_in saddr;
  1291 +
  1292 + if (parse_host_port(&saddr, host_str) < 0)
  1293 + return -1;
  1294 +
  1295 + fd = socket(PF_INET, SOCK_STREAM, 0);
  1296 + if (fd < 0) {
  1297 + perror("socket");
  1298 + return -1;
  1299 + }
  1300 + socket_set_nonblock(fd);
  1301 +
  1302 + connected = 0;
  1303 + for(;;) {
  1304 + ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
  1305 + if (ret < 0) {
  1306 + err = socket_error();
  1307 + if (err == EINTR || err == EWOULDBLOCK) {
  1308 + } else if (err == EINPROGRESS) {
  1309 + break;
  1310 +#ifdef _WIN32
  1311 + } else if (err == WSAEALREADY) {
  1312 + break;
  1313 +#endif
  1314 + } else {
  1315 + perror("connect");
  1316 + closesocket(fd);
  1317 + return -1;
  1318 + }
  1319 + } else {
  1320 + connected = 1;
  1321 + break;
  1322 + }
  1323 + }
  1324 + s = net_socket_fd_init(vlan, fd, connected);
  1325 + if (!s)
  1326 + return -1;
  1327 + snprintf(s->vc->info_str, sizeof(s->vc->info_str),
  1328 + "socket: connect to %s:%d",
  1329 + inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
  1330 + return 0;
  1331 +}
  1332 +
  1333 +static int net_socket_mcast_init(VLANState *vlan, const char *host_str)
  1334 +{
  1335 + NetSocketState *s;
  1336 + int fd;
  1337 + struct sockaddr_in saddr;
  1338 +
  1339 + if (parse_host_port(&saddr, host_str) < 0)
  1340 + return -1;
  1341 +
  1342 +
  1343 + fd = net_socket_mcast_create(&saddr);
  1344 + if (fd < 0)
  1345 + return -1;
  1346 +
  1347 + s = net_socket_fd_init(vlan, fd, 0);
  1348 + if (!s)
  1349 + return -1;
  1350 +
  1351 + s->dgram_dst = saddr;
  1352 +
  1353 + snprintf(s->vc->info_str, sizeof(s->vc->info_str),
  1354 + "socket: mcast=%s:%d",
  1355 + inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
  1356 + return 0;
  1357 +
  1358 +}
  1359 +
  1360 +/* find or alloc a new VLAN */
  1361 +VLANState *qemu_find_vlan(int id)
  1362 +{
  1363 + VLANState **pvlan, *vlan;
  1364 + for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
  1365 + if (vlan->id == id)
  1366 + return vlan;
  1367 + }
  1368 + vlan = qemu_mallocz(sizeof(VLANState));
  1369 + if (!vlan)
  1370 + return NULL;
  1371 + vlan->id = id;
  1372 + vlan->next = NULL;
  1373 + pvlan = &first_vlan;
  1374 + while (*pvlan != NULL)
  1375 + pvlan = &(*pvlan)->next;
  1376 + *pvlan = vlan;
  1377 + return vlan;
  1378 +}
  1379 +
  1380 +int net_client_init(const char *device, const char *p)
  1381 +{
  1382 + char buf[1024];
  1383 + int vlan_id, ret;
  1384 + VLANState *vlan;
  1385 +
  1386 + vlan_id = 0;
  1387 + if (get_param_value(buf, sizeof(buf), "vlan", p)) {
  1388 + vlan_id = strtol(buf, NULL, 0);
  1389 + }
  1390 + vlan = qemu_find_vlan(vlan_id);
  1391 + if (!vlan) {
  1392 + fprintf(stderr, "Could not create vlan %d\n", vlan_id);
  1393 + return -1;
  1394 + }
  1395 + if (!strcmp(device, "nic")) {
  1396 + NICInfo *nd;
  1397 + uint8_t *macaddr;
  1398 +
  1399 + if (nb_nics >= MAX_NICS) {
  1400 + fprintf(stderr, "Too Many NICs\n");
  1401 + return -1;
  1402 + }
  1403 + nd = &nd_table[nb_nics];
  1404 + macaddr = nd->macaddr;
  1405 + macaddr[0] = 0x52;
  1406 + macaddr[1] = 0x54;
  1407 + macaddr[2] = 0x00;
  1408 + macaddr[3] = 0x12;
  1409 + macaddr[4] = 0x34;
  1410 + macaddr[5] = 0x56 + nb_nics;
  1411 +
  1412 + if (get_param_value(buf, sizeof(buf), "macaddr", p)) {
  1413 + if (parse_macaddr(macaddr, buf) < 0) {
  1414 + fprintf(stderr, "invalid syntax for ethernet address\n");
  1415 + return -1;
  1416 + }
  1417 + }
  1418 + if (get_param_value(buf, sizeof(buf), "model", p)) {
  1419 + nd->model = strdup(buf);
  1420 + }
  1421 + nd->vlan = vlan;
  1422 + nb_nics++;
  1423 + vlan->nb_guest_devs++;
  1424 + ret = 0;
  1425 + } else
  1426 + if (!strcmp(device, "none")) {
  1427 + /* does nothing. It is needed to signal that no network cards
  1428 + are wanted */
  1429 + ret = 0;
  1430 + } else
  1431 +#ifdef CONFIG_SLIRP
  1432 + if (!strcmp(device, "user")) {
  1433 + if (get_param_value(buf, sizeof(buf), "hostname", p)) {
  1434 + pstrcpy(slirp_hostname, sizeof(slirp_hostname), buf);
  1435 + }
  1436 + vlan->nb_host_devs++;
  1437 + ret = net_slirp_init(vlan);
  1438 + } else
  1439 +#endif
  1440 +#ifdef _WIN32
  1441 + if (!strcmp(device, "tap")) {
  1442 + char ifname[64];
  1443 + if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
  1444 + fprintf(stderr, "tap: no interface name\n");
  1445 + return -1;
  1446 + }
  1447 + vlan->nb_host_devs++;
  1448 + ret = tap_win32_init(vlan, ifname);
  1449 + } else
  1450 +#else
  1451 + if (!strcmp(device, "tap")) {
  1452 + char ifname[64];
  1453 + char setup_script[1024], down_script[1024];
  1454 + int fd;
  1455 + vlan->nb_host_devs++;
  1456 + if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
  1457 + fd = strtol(buf, NULL, 0);
  1458 + fcntl(fd, F_SETFL, O_NONBLOCK);
  1459 + ret = -1;
  1460 + if (net_tap_fd_init(vlan, fd))
  1461 + ret = 0;
  1462 + } else {
  1463 + if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
  1464 + ifname[0] = '\0';
  1465 + }
  1466 + if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) {
  1467 + pstrcpy(setup_script, sizeof(setup_script), DEFAULT_NETWORK_SCRIPT);
  1468 + }
  1469 + if (get_param_value(down_script, sizeof(down_script), "downscript", p) == 0) {
  1470 + pstrcpy(down_script, sizeof(down_script), DEFAULT_NETWORK_DOWN_SCRIPT);
  1471 + }
  1472 + ret = net_tap_init(vlan, ifname, setup_script, down_script);
  1473 + }
  1474 + } else
  1475 +#endif
  1476 + if (!strcmp(device, "socket")) {
  1477 + if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
  1478 + int fd;
  1479 + fd = strtol(buf, NULL, 0);
  1480 + ret = -1;
  1481 + if (net_socket_fd_init(vlan, fd, 1))
  1482 + ret = 0;
  1483 + } else if (get_param_value(buf, sizeof(buf), "listen", p) > 0) {
  1484 + ret = net_socket_listen_init(vlan, buf);
  1485 + } else if (get_param_value(buf, sizeof(buf), "connect", p) > 0) {
  1486 + ret = net_socket_connect_init(vlan, buf);
  1487 + } else if (get_param_value(buf, sizeof(buf), "mcast", p) > 0) {
  1488 + ret = net_socket_mcast_init(vlan, buf);
  1489 + } else {
  1490 + fprintf(stderr, "Unknown socket options: %s\n", p);
  1491 + return -1;
  1492 + }
  1493 + vlan->nb_host_devs++;
  1494 + } else
  1495 +#ifdef CONFIG_VDE
  1496 + if (!strcmp(device, "vde")) {
  1497 + char vde_sock[1024], vde_group[512];
  1498 + int vde_port, vde_mode;
  1499 + vlan->nb_host_devs++;
  1500 + if (get_param_value(vde_sock, sizeof(vde_sock), "sock", p) <= 0) {
  1501 + vde_sock[0] = '\0';
  1502 + }
  1503 + if (get_param_value(buf, sizeof(buf), "port", p) > 0) {
  1504 + vde_port = strtol(buf, NULL, 10);
  1505 + } else {
  1506 + vde_port = 0;
  1507 + }
  1508 + if (get_param_value(vde_group, sizeof(vde_group), "group", p) <= 0) {
  1509 + vde_group[0] = '\0';
  1510 + }
  1511 + if (get_param_value(buf, sizeof(buf), "mode", p) > 0) {
  1512 + vde_mode = strtol(buf, NULL, 8);
  1513 + } else {
  1514 + vde_mode = 0700;
  1515 + }
  1516 + ret = net_vde_init(vlan, vde_sock, vde_port, vde_group, vde_mode);
  1517 + } else
  1518 +#endif
  1519 + {
  1520 + fprintf(stderr, "Unknown network device: %s\n", device);
  1521 + return -1;
  1522 + }
  1523 + if (ret < 0) {
  1524 + fprintf(stderr, "Could not initialize device '%s'\n", device);
  1525 + }
  1526 +
  1527 + return ret;
  1528 +}
  1529 +
  1530 +int net_client_parse(const char *str)
  1531 +{
  1532 + const char *p;
  1533 + char *q;
  1534 + char device[64];
  1535 +
  1536 + p = str;
  1537 + q = device;
  1538 + while (*p != '\0' && *p != ',') {
  1539 + if ((q - device) < sizeof(device) - 1)
  1540 + *q++ = *p;
  1541 + p++;
  1542 + }
  1543 + *q = '\0';
  1544 + if (*p == ',')
  1545 + p++;
  1546 +
  1547 + return net_client_init(device, p);
  1548 +}
  1549 +
  1550 +void do_info_network(void)
  1551 +{
  1552 + VLANState *vlan;
  1553 + VLANClientState *vc;
  1554 +
  1555 + for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
  1556 + term_printf("VLAN %d devices:\n", vlan->id);
  1557 + for(vc = vlan->first_client; vc != NULL; vc = vc->next)
  1558 + term_printf(" %s\n", vc->info_str);
  1559 + }
  1560 +}
  1561 +
  1562 +void net_cleanup(void)
  1563 +{
  1564 + VLANState *vlan;
  1565 +
  1566 +#if !defined(_WIN32)
  1567 + /* close network clients */
  1568 + for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
  1569 + VLANClientState *vc;
  1570 +
  1571 + for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
  1572 + if (vc->fd_read == tap_receive) {
  1573 + char ifname[64];
  1574 + TAPState *s = vc->opaque;
  1575 +
  1576 + if (sscanf(vc->info_str, "tap: ifname=%63s ", ifname) == 1 &&
  1577 + s->down_script[0])
  1578 + launch_script(s->down_script, ifname, s->fd);
  1579 + }
  1580 +#if defined(CONFIG_VDE)
  1581 + if (vc->fd_read == vde_from_qemu) {
  1582 + VDEState *s = vc->opaque;
  1583 + vde_close(s->vde);
  1584 + }
  1585 +#endif
  1586 + }
  1587 + }
  1588 +#endif
  1589 +}
  1590 +
  1591 +void net_client_check(void)
  1592 +{
  1593 + VLANState *vlan;
  1594 +
  1595 + for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
  1596 + if (vlan->nb_guest_devs == 0 && vlan->nb_host_devs == 0)
  1597 + continue;
  1598 + if (vlan->nb_guest_devs == 0)
  1599 + fprintf(stderr, "Warning: vlan %d with no nics\n", vlan->id);
  1600 + if (vlan->nb_host_devs == 0)
  1601 + fprintf(stderr,
  1602 + "Warning: vlan %d is not connected to host network\n",
  1603 + vlan->id);
  1604 + }
  1605 +}
... ...
... ... @@ -69,4 +69,13 @@ uint16_t net_checksum_tcpudp(uint16_t length, uint16_t proto,
69 69 uint8_t *addrs, uint8_t *buf);
70 70 void net_checksum_calculate(uint8_t *data, int length);
71 71  
  72 +/* from net.c */
  73 +int net_client_init(const char *device, const char *p);
  74 +int net_client_parse(const char *str);
  75 +void net_slirp_smb(const char *exported_dir);
  76 +void net_slirp_redir(const char *redir_str);
  77 +void net_cleanup(void);
  78 +int slirp_is_inited(void);
  79 +void net_client_check(void);
  80 +
72 81 #endif
... ...
sysemu.h
... ... @@ -193,4 +193,11 @@ void do_usb_add(const char *devname);
193 193 void do_usb_del(const char *devname);
194 194 void usb_info(void);
195 195  
  196 +const char *get_opt_name(char *buf, int buf_size, const char *p);
  197 +const char *get_opt_value(char *buf, int buf_size, const char *p);
  198 +int get_param_value(char *buf, int buf_size,
  199 + const char *tag, const char *str);
  200 +int check_params(char *buf, int buf_size,
  201 + const char * const *params, const char *str);
  202 +
196 203 #endif
... ...
... ... @@ -210,7 +210,6 @@ CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
210 210 int win2k_install_hack = 0;
211 211 #endif
212 212 int usb_enabled = 0;
213   -static VLANState *first_vlan;
214 213 int smp_cpus = 1;
215 214 const char *vnc_display;
216 215 int acpi_enabled = 1;
... ... @@ -1757,1244 +1756,7 @@ static int socket_init(void)
1757 1756 }
1758 1757 #endif
1759 1758  
1760   -/***********************************************************/
1761   -/* network device redirectors */
1762   -
1763   -
1764   -#if defined(DEBUG_NET) || defined(DEBUG_SLIRP)
1765   -static void hex_dump(FILE *f, const uint8_t *buf, int size)
1766   -{
1767   - int len, i, j, c;
1768   -
1769   - for(i=0;i<size;i+=16) {
1770   - len = size - i;
1771   - if (len > 16)
1772   - len = 16;
1773   - fprintf(f, "%08x ", i);
1774   - for(j=0;j<16;j++) {
1775   - if (j < len)
1776   - fprintf(f, " %02x", buf[i+j]);
1777   - else
1778   - fprintf(f, " ");
1779   - }
1780   - fprintf(f, " ");
1781   - for(j=0;j<len;j++) {
1782   - c = buf[i+j];
1783   - if (c < ' ' || c > '~')
1784   - c = '.';
1785   - fprintf(f, "%c", c);
1786   - }
1787   - fprintf(f, "\n");
1788   - }
1789   -}
1790   -#endif
1791   -
1792   -static int parse_macaddr(uint8_t *macaddr, const char *p)
1793   -{
1794   - int i;
1795   - char *last_char;
1796   - long int offset;
1797   -
1798   - errno = 0;
1799   - offset = strtol(p, &last_char, 0);
1800   - if (0 == errno && '\0' == *last_char &&
1801   - offset >= 0 && offset <= 0xFFFFFF) {
1802   - macaddr[3] = (offset & 0xFF0000) >> 16;
1803   - macaddr[4] = (offset & 0xFF00) >> 8;
1804   - macaddr[5] = offset & 0xFF;
1805   - return 0;
1806   - } else {
1807   - for(i = 0; i < 6; i++) {
1808   - macaddr[i] = strtol(p, (char **)&p, 16);
1809   - if (i == 5) {
1810   - if (*p != '\0')
1811   - return -1;
1812   - } else {
1813   - if (*p != ':' && *p != '-')
1814   - return -1;
1815   - p++;
1816   - }
1817   - }
1818   - return 0;
1819   - }
1820   -
1821   - return -1;
1822   -}
1823   -
1824   -static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
1825   -{
1826   - const char *p, *p1;
1827   - int len;
1828   - p = *pp;
1829   - p1 = strchr(p, sep);
1830   - if (!p1)
1831   - return -1;
1832   - len = p1 - p;
1833   - p1++;
1834   - if (buf_size > 0) {
1835   - if (len > buf_size - 1)
1836   - len = buf_size - 1;
1837   - memcpy(buf, p, len);
1838   - buf[len] = '\0';
1839   - }
1840   - *pp = p1;
1841   - return 0;
1842   -}
1843   -
1844   -int parse_host_src_port(struct sockaddr_in *haddr,
1845   - struct sockaddr_in *saddr,
1846   - const char *input_str)
1847   -{
1848   - char *str = strdup(input_str);
1849   - char *host_str = str;
1850   - char *src_str;
1851   - const char *src_str2;
1852   - char *ptr;
1853   -
1854   - /*
1855   - * Chop off any extra arguments at the end of the string which
1856   - * would start with a comma, then fill in the src port information
1857   - * if it was provided else use the "any address" and "any port".
1858   - */
1859   - if ((ptr = strchr(str,',')))
1860   - *ptr = '\0';
1861   -
1862   - if ((src_str = strchr(input_str,'@'))) {
1863   - *src_str = '\0';
1864   - src_str++;
1865   - }
1866   -
1867   - if (parse_host_port(haddr, host_str) < 0)
1868   - goto fail;
1869   -
1870   - src_str2 = src_str;
1871   - if (!src_str || *src_str == '\0')
1872   - src_str2 = ":0";
1873   -
1874   - if (parse_host_port(saddr, src_str2) < 0)
1875   - goto fail;
1876   -
1877   - free(str);
1878   - return(0);
1879   -
1880   -fail:
1881   - free(str);
1882   - return -1;
1883   -}
1884   -
1885   -int parse_host_port(struct sockaddr_in *saddr, const char *str)
1886   -{
1887   - char buf[512];
1888   - struct hostent *he;
1889   - const char *p, *r;
1890   - int port;
1891   -
1892   - p = str;
1893   - if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
1894   - return -1;
1895   - saddr->sin_family = AF_INET;
1896   - if (buf[0] == '\0') {
1897   - saddr->sin_addr.s_addr = 0;
1898   - } else {
1899   - if (isdigit(buf[0])) {
1900   - if (!inet_aton(buf, &saddr->sin_addr))
1901   - return -1;
1902   - } else {
1903   - if ((he = gethostbyname(buf)) == NULL)
1904   - return - 1;
1905   - saddr->sin_addr = *(struct in_addr *)he->h_addr;
1906   - }
1907   - }
1908   - port = strtol(p, (char **)&r, 0);
1909   - if (r == p)
1910   - return -1;
1911   - saddr->sin_port = htons(port);
1912   - return 0;
1913   -}
1914   -
1915   -#ifndef _WIN32
1916   -int parse_unix_path(struct sockaddr_un *uaddr, const char *str)
1917   -{
1918   - const char *p;
1919   - int len;
1920   -
1921   - len = MIN(108, strlen(str));
1922   - p = strchr(str, ',');
1923   - if (p)
1924   - len = MIN(len, p - str);
1925   -
1926   - memset(uaddr, 0, sizeof(*uaddr));
1927   -
1928   - uaddr->sun_family = AF_UNIX;
1929   - memcpy(uaddr->sun_path, str, len);
1930   -
1931   - return 0;
1932   -}
1933   -#endif
1934   -
1935   -/* find or alloc a new VLAN */
1936   -VLANState *qemu_find_vlan(int id)
1937   -{
1938   - VLANState **pvlan, *vlan;
1939   - for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
1940   - if (vlan->id == id)
1941   - return vlan;
1942   - }
1943   - vlan = qemu_mallocz(sizeof(VLANState));
1944   - if (!vlan)
1945   - return NULL;
1946   - vlan->id = id;
1947   - vlan->next = NULL;
1948   - pvlan = &first_vlan;
1949   - while (*pvlan != NULL)
1950   - pvlan = &(*pvlan)->next;
1951   - *pvlan = vlan;
1952   - return vlan;
1953   -}
1954   -
1955   -VLANClientState *qemu_new_vlan_client(VLANState *vlan,
1956   - IOReadHandler *fd_read,
1957   - IOCanRWHandler *fd_can_read,
1958   - void *opaque)
1959   -{
1960   - VLANClientState *vc, **pvc;
1961   - vc = qemu_mallocz(sizeof(VLANClientState));
1962   - if (!vc)
1963   - return NULL;
1964   - vc->fd_read = fd_read;
1965   - vc->fd_can_read = fd_can_read;
1966   - vc->opaque = opaque;
1967   - vc->vlan = vlan;
1968   -
1969   - vc->next = NULL;
1970   - pvc = &vlan->first_client;
1971   - while (*pvc != NULL)
1972   - pvc = &(*pvc)->next;
1973   - *pvc = vc;
1974   - return vc;
1975   -}
1976   -
1977   -void qemu_del_vlan_client(VLANClientState *vc)
1978   -{
1979   - VLANClientState **pvc = &vc->vlan->first_client;
1980   -
1981   - while (*pvc != NULL)
1982   - if (*pvc == vc) {
1983   - *pvc = vc->next;
1984   - free(vc);
1985   - break;
1986   - } else
1987   - pvc = &(*pvc)->next;
1988   -}
1989   -
1990   -int qemu_can_send_packet(VLANClientState *vc1)
1991   -{
1992   - VLANState *vlan = vc1->vlan;
1993   - VLANClientState *vc;
1994   -
1995   - for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
1996   - if (vc != vc1) {
1997   - if (vc->fd_can_read && vc->fd_can_read(vc->opaque))
1998   - return 1;
1999   - }
2000   - }
2001   - return 0;
2002   -}
2003   -
2004   -void qemu_send_packet(VLANClientState *vc1, const uint8_t *buf, int size)
2005   -{
2006   - VLANState *vlan = vc1->vlan;
2007   - VLANClientState *vc;
2008   -
2009   -#ifdef DEBUG_NET
2010   - printf("vlan %d send:\n", vlan->id);
2011   - hex_dump(stdout, buf, size);
2012   -#endif
2013   - for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
2014   - if (vc != vc1) {
2015   - vc->fd_read(vc->opaque, buf, size);
2016   - }
2017   - }
2018   -}
2019   -
2020   -#if defined(CONFIG_SLIRP)
2021   -
2022   -/* slirp network adapter */
2023   -
2024   -static int slirp_inited;
2025   -static VLANClientState *slirp_vc;
2026   -
2027   -int slirp_can_output(void)
2028   -{
2029   - return !slirp_vc || qemu_can_send_packet(slirp_vc);
2030   -}
2031   -
2032   -void slirp_output(const uint8_t *pkt, int pkt_len)
2033   -{
2034   -#ifdef DEBUG_SLIRP
2035   - printf("slirp output:\n");
2036   - hex_dump(stdout, pkt, pkt_len);
2037   -#endif
2038   - if (!slirp_vc)
2039   - return;
2040   - qemu_send_packet(slirp_vc, pkt, pkt_len);
2041   -}
2042   -
2043   -static void slirp_receive(void *opaque, const uint8_t *buf, int size)
2044   -{
2045   -#ifdef DEBUG_SLIRP
2046   - printf("slirp input:\n");
2047   - hex_dump(stdout, buf, size);
2048   -#endif
2049   - slirp_input(buf, size);
2050   -}
2051   -
2052   -static int net_slirp_init(VLANState *vlan)
2053   -{
2054   - if (!slirp_inited) {
2055   - slirp_inited = 1;
2056   - slirp_init();
2057   - }
2058   - slirp_vc = qemu_new_vlan_client(vlan,
2059   - slirp_receive, NULL, NULL);
2060   - snprintf(slirp_vc->info_str, sizeof(slirp_vc->info_str), "user redirector");
2061   - return 0;
2062   -}
2063   -
2064   -static void net_slirp_redir(const char *redir_str)
2065   -{
2066   - int is_udp;
2067   - char buf[256], *r;
2068   - const char *p;
2069   - struct in_addr guest_addr;
2070   - int host_port, guest_port;
2071   -
2072   - if (!slirp_inited) {
2073   - slirp_inited = 1;
2074   - slirp_init();
2075   - }
2076   -
2077   - p = redir_str;
2078   - if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
2079   - goto fail;
2080   - if (!strcmp(buf, "tcp")) {
2081   - is_udp = 0;
2082   - } else if (!strcmp(buf, "udp")) {
2083   - is_udp = 1;
2084   - } else {
2085   - goto fail;
2086   - }
2087   -
2088   - if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
2089   - goto fail;
2090   - host_port = strtol(buf, &r, 0);
2091   - if (r == buf)
2092   - goto fail;
2093   -
2094   - if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
2095   - goto fail;
2096   - if (buf[0] == '\0') {
2097   - pstrcpy(buf, sizeof(buf), "10.0.2.15");
2098   - }
2099   - if (!inet_aton(buf, &guest_addr))
2100   - goto fail;
2101   -
2102   - guest_port = strtol(p, &r, 0);
2103   - if (r == p)
2104   - goto fail;
2105   -
2106   - if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) {
2107   - fprintf(stderr, "qemu: could not set up redirection\n");
2108   - exit(1);
2109   - }
2110   - return;
2111   - fail:
2112   - fprintf(stderr, "qemu: syntax: -redir [tcp|udp]:host-port:[guest-host]:guest-port\n");
2113   - exit(1);
2114   -}
2115   -
2116   -#ifndef _WIN32
2117   -
2118   -static char smb_dir[1024];
2119   -
2120   -static void erase_dir(char *dir_name)
2121   -{
2122   - DIR *d;
2123   - struct dirent *de;
2124   - char filename[1024];
2125   -
2126   - /* erase all the files in the directory */
2127   - if ((d = opendir(dir_name)) != 0) {
2128   - for(;;) {
2129   - de = readdir(d);
2130   - if (!de)
2131   - break;
2132   - if (strcmp(de->d_name, ".") != 0 &&
2133   - strcmp(de->d_name, "..") != 0) {
2134   - snprintf(filename, sizeof(filename), "%s/%s",
2135   - smb_dir, de->d_name);
2136   - if (unlink(filename) != 0) /* is it a directory? */
2137   - erase_dir(filename);
2138   - }
2139   - }
2140   - closedir(d);
2141   - rmdir(dir_name);
2142   - }
2143   -}
2144   -
2145   -/* automatic user mode samba server configuration */
2146   -static void smb_exit(void)
2147   -{
2148   - erase_dir(smb_dir);
2149   -}
2150   -
2151   -/* automatic user mode samba server configuration */
2152   -static void net_slirp_smb(const char *exported_dir)
2153   -{
2154   - char smb_conf[1024];
2155   - char smb_cmdline[1024];
2156   - FILE *f;
2157   -
2158   - if (!slirp_inited) {
2159   - slirp_inited = 1;
2160   - slirp_init();
2161   - }
2162   -
2163   - /* XXX: better tmp dir construction */
2164   - snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%d", getpid());
2165   - if (mkdir(smb_dir, 0700) < 0) {
2166   - fprintf(stderr, "qemu: could not create samba server dir '%s'\n", smb_dir);
2167   - exit(1);
2168   - }
2169   - snprintf(smb_conf, sizeof(smb_conf), "%s/%s", smb_dir, "smb.conf");
2170   -
2171   - f = fopen(smb_conf, "w");
2172   - if (!f) {
2173   - fprintf(stderr, "qemu: could not create samba server configuration file '%s'\n", smb_conf);
2174   - exit(1);
2175   - }
2176   - fprintf(f,
2177   - "[global]\n"
2178   - "private dir=%s\n"
2179   - "smb ports=0\n"
2180   - "socket address=127.0.0.1\n"
2181   - "pid directory=%s\n"
2182   - "lock directory=%s\n"
2183   - "log file=%s/log.smbd\n"
2184   - "smb passwd file=%s/smbpasswd\n"
2185   - "security = share\n"
2186   - "[qemu]\n"
2187   - "path=%s\n"
2188   - "read only=no\n"
2189   - "guest ok=yes\n",
2190   - smb_dir,
2191   - smb_dir,
2192   - smb_dir,
2193   - smb_dir,
2194   - smb_dir,
2195   - exported_dir
2196   - );
2197   - fclose(f);
2198   - atexit(smb_exit);
2199   -
2200   - snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s",
2201   - SMBD_COMMAND, smb_conf);
2202   -
2203   - slirp_add_exec(0, smb_cmdline, 4, 139);
2204   -}
2205   -
2206   -#endif /* !defined(_WIN32) */
2207   -void do_info_slirp(void)
2208   -{
2209   - slirp_stats();
2210   -}
2211   -
2212   -#endif /* CONFIG_SLIRP */
2213   -
2214   -#if !defined(_WIN32)
2215   -
2216   -typedef struct TAPState {
2217   - VLANClientState *vc;
2218   - int fd;
2219   - char down_script[1024];
2220   -} TAPState;
2221   -
2222   -static void tap_receive(void *opaque, const uint8_t *buf, int size)
2223   -{
2224   - TAPState *s = opaque;
2225   - int ret;
2226   - for(;;) {
2227   - ret = write(s->fd, buf, size);
2228   - if (ret < 0 && (errno == EINTR || errno == EAGAIN)) {
2229   - } else {
2230   - break;
2231   - }
2232   - }
2233   -}
2234   -
2235   -static void tap_send(void *opaque)
2236   -{
2237   - TAPState *s = opaque;
2238   - uint8_t buf[4096];
2239   - int size;
2240   -
2241   -#ifdef __sun__
2242   - struct strbuf sbuf;
2243   - int f = 0;
2244   - sbuf.maxlen = sizeof(buf);
2245   - sbuf.buf = buf;
2246   - size = getmsg(s->fd, NULL, &sbuf, &f) >=0 ? sbuf.len : -1;
2247   -#else
2248   - size = read(s->fd, buf, sizeof(buf));
2249   -#endif
2250   - if (size > 0) {
2251   - qemu_send_packet(s->vc, buf, size);
2252   - }
2253   -}
2254   -
2255   -/* fd support */
2256   -
2257   -static TAPState *net_tap_fd_init(VLANState *vlan, int fd)
2258   -{
2259   - TAPState *s;
2260   -
2261   - s = qemu_mallocz(sizeof(TAPState));
2262   - if (!s)
2263   - return NULL;
2264   - s->fd = fd;
2265   - s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s);
2266   - qemu_set_fd_handler(s->fd, tap_send, NULL, s);
2267   - snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: fd=%d", fd);
2268   - return s;
2269   -}
2270   -
2271   -#if defined (_BSD) || defined (__FreeBSD_kernel__)
2272   -static int tap_open(char *ifname, int ifname_size)
2273   -{
2274   - int fd;
2275   - char *dev;
2276   - struct stat s;
2277   -
2278   - TFR(fd = open("/dev/tap", O_RDWR));
2279   - if (fd < 0) {
2280   - fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n");
2281   - return -1;
2282   - }
2283   -
2284   - fstat(fd, &s);
2285   - dev = devname(s.st_rdev, S_IFCHR);
2286   - pstrcpy(ifname, ifname_size, dev);
2287   -
2288   - fcntl(fd, F_SETFL, O_NONBLOCK);
2289   - return fd;
2290   -}
2291   -#elif defined(__sun__)
2292   -#define TUNNEWPPA (('T'<<16) | 0x0001)
2293   -/*
2294   - * Allocate TAP device, returns opened fd.
2295   - * Stores dev name in the first arg(must be large enough).
2296   - */
2297   -int tap_alloc(char *dev, size_t dev_size)
2298   -{
2299   - int tap_fd, if_fd, ppa = -1;
2300   - static int ip_fd = 0;
2301   - char *ptr;
2302   -
2303   - static int arp_fd = 0;
2304   - int ip_muxid, arp_muxid;
2305   - struct strioctl strioc_if, strioc_ppa;
2306   - int link_type = I_PLINK;;
2307   - struct lifreq ifr;
2308   - char actual_name[32] = "";
2309   -
2310   - memset(&ifr, 0x0, sizeof(ifr));
2311   -
2312   - if( *dev ){
2313   - ptr = dev;
2314   - while( *ptr && !isdigit((int)*ptr) ) ptr++;
2315   - ppa = atoi(ptr);
2316   - }
2317   -
2318   - /* Check if IP device was opened */
2319   - if( ip_fd )
2320   - close(ip_fd);
2321   -
2322   - TFR(ip_fd = open("/dev/udp", O_RDWR, 0));
2323   - if (ip_fd < 0) {
2324   - syslog(LOG_ERR, "Can't open /dev/ip (actually /dev/udp)");
2325   - return -1;
2326   - }
2327   -
2328   - TFR(tap_fd = open("/dev/tap", O_RDWR, 0));
2329   - if (tap_fd < 0) {
2330   - syslog(LOG_ERR, "Can't open /dev/tap");
2331   - return -1;
2332   - }
2333   -
2334   - /* Assign a new PPA and get its unit number. */
2335   - strioc_ppa.ic_cmd = TUNNEWPPA;
2336   - strioc_ppa.ic_timout = 0;
2337   - strioc_ppa.ic_len = sizeof(ppa);
2338   - strioc_ppa.ic_dp = (char *)&ppa;
2339   - if ((ppa = ioctl (tap_fd, I_STR, &strioc_ppa)) < 0)
2340   - syslog (LOG_ERR, "Can't assign new interface");
2341   -
2342   - TFR(if_fd = open("/dev/tap", O_RDWR, 0));
2343   - if (if_fd < 0) {
2344   - syslog(LOG_ERR, "Can't open /dev/tap (2)");
2345   - return -1;
2346   - }
2347   - if(ioctl(if_fd, I_PUSH, "ip") < 0){
2348   - syslog(LOG_ERR, "Can't push IP module");
2349   - return -1;
2350   - }
2351   -
2352   - if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
2353   - syslog(LOG_ERR, "Can't get flags\n");
2354   -
2355   - snprintf (actual_name, 32, "tap%d", ppa);
2356   - pstrcpy(ifr.lifr_name, sizeof(ifr.lifr_name), actual_name);
2357   -
2358   - ifr.lifr_ppa = ppa;
2359   - /* Assign ppa according to the unit number returned by tun device */
2360   -
2361   - if (ioctl (if_fd, SIOCSLIFNAME, &ifr) < 0)
2362   - syslog (LOG_ERR, "Can't set PPA %d", ppa);
2363   - if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0)
2364   - syslog (LOG_ERR, "Can't get flags\n");
2365   - /* Push arp module to if_fd */
2366   - if (ioctl (if_fd, I_PUSH, "arp") < 0)
2367   - syslog (LOG_ERR, "Can't push ARP module (2)");
2368   -
2369   - /* Push arp module to ip_fd */
2370   - if (ioctl (ip_fd, I_POP, NULL) < 0)
2371   - syslog (LOG_ERR, "I_POP failed\n");
2372   - if (ioctl (ip_fd, I_PUSH, "arp") < 0)
2373   - syslog (LOG_ERR, "Can't push ARP module (3)\n");
2374   - /* Open arp_fd */
2375   - TFR(arp_fd = open ("/dev/tap", O_RDWR, 0));
2376   - if (arp_fd < 0)
2377   - syslog (LOG_ERR, "Can't open %s\n", "/dev/tap");
2378   -
2379   - /* Set ifname to arp */
2380   - strioc_if.ic_cmd = SIOCSLIFNAME;
2381   - strioc_if.ic_timout = 0;
2382   - strioc_if.ic_len = sizeof(ifr);
2383   - strioc_if.ic_dp = (char *)&ifr;
2384   - if (ioctl(arp_fd, I_STR, &strioc_if) < 0){
2385   - syslog (LOG_ERR, "Can't set ifname to arp\n");
2386   - }
2387   -
2388   - if((ip_muxid = ioctl(ip_fd, I_LINK, if_fd)) < 0){
2389   - syslog(LOG_ERR, "Can't link TAP device to IP");
2390   - return -1;
2391   - }
2392   -
2393   - if ((arp_muxid = ioctl (ip_fd, link_type, arp_fd)) < 0)
2394   - syslog (LOG_ERR, "Can't link TAP device to ARP");
2395   -
2396   - close (if_fd);
2397   -
2398   - memset(&ifr, 0x0, sizeof(ifr));
2399   - pstrcpy(ifr.lifr_name, sizeof(ifr.lifr_name), actual_name);
2400   - ifr.lifr_ip_muxid = ip_muxid;
2401   - ifr.lifr_arp_muxid = arp_muxid;
2402   -
2403   - if (ioctl (ip_fd, SIOCSLIFMUXID, &ifr) < 0)
2404   - {
2405   - ioctl (ip_fd, I_PUNLINK , arp_muxid);
2406   - ioctl (ip_fd, I_PUNLINK, ip_muxid);
2407   - syslog (LOG_ERR, "Can't set multiplexor id");
2408   - }
2409   -
2410   - snprintf(dev, dev_size, "tap%d", ppa);
2411   - return tap_fd;
2412   -}
2413   -
2414   -static int tap_open(char *ifname, int ifname_size)
2415   -{
2416   - char dev[10]="";
2417   - int fd;
2418   - if( (fd = tap_alloc(dev, sizeof(dev))) < 0 ){
2419   - fprintf(stderr, "Cannot allocate TAP device\n");
2420   - return -1;
2421   - }
2422   - pstrcpy(ifname, ifname_size, dev);
2423   - fcntl(fd, F_SETFL, O_NONBLOCK);
2424   - return fd;
2425   -}
2426   -#else
2427   -static int tap_open(char *ifname, int ifname_size)
2428   -{
2429   - struct ifreq ifr;
2430   - int fd, ret;
2431   -
2432   - TFR(fd = open("/dev/net/tun", O_RDWR));
2433   - if (fd < 0) {
2434   - fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
2435   - return -1;
2436   - }
2437   - memset(&ifr, 0, sizeof(ifr));
2438   - ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
2439   - if (ifname[0] != '\0')
2440   - pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname);
2441   - else
2442   - pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d");
2443   - ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
2444   - if (ret != 0) {
2445   - fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
2446   - close(fd);
2447   - return -1;
2448   - }
2449   - pstrcpy(ifname, ifname_size, ifr.ifr_name);
2450   - fcntl(fd, F_SETFL, O_NONBLOCK);
2451   - return fd;
2452   -}
2453   -#endif
2454   -
2455   -static int launch_script(const char *setup_script, const char *ifname, int fd)
2456   -{
2457   - int pid, status;
2458   - char *args[3];
2459   - char **parg;
2460   -
2461   - /* try to launch network script */
2462   - pid = fork();
2463   - if (pid >= 0) {
2464   - if (pid == 0) {
2465   - int open_max = sysconf (_SC_OPEN_MAX), i;
2466   - for (i = 0; i < open_max; i++)
2467   - if (i != STDIN_FILENO &&
2468   - i != STDOUT_FILENO &&
2469   - i != STDERR_FILENO &&
2470   - i != fd)
2471   - close(i);
2472   -
2473   - parg = args;
2474   - *parg++ = (char *)setup_script;
2475   - *parg++ = (char *)ifname;
2476   - *parg++ = NULL;
2477   - execv(setup_script, args);
2478   - _exit(1);
2479   - }
2480   - while (waitpid(pid, &status, 0) != pid);
2481   - if (!WIFEXITED(status) ||
2482   - WEXITSTATUS(status) != 0) {
2483   - fprintf(stderr, "%s: could not launch network script\n",
2484   - setup_script);
2485   - return -1;
2486   - }
2487   - }
2488   - return 0;
2489   -}
2490   -
2491   -static int net_tap_init(VLANState *vlan, const char *ifname1,
2492   - const char *setup_script, const char *down_script)
2493   -{
2494   - TAPState *s;
2495   - int fd;
2496   - char ifname[128];
2497   -
2498   - if (ifname1 != NULL)
2499   - pstrcpy(ifname, sizeof(ifname), ifname1);
2500   - else
2501   - ifname[0] = '\0';
2502   - TFR(fd = tap_open(ifname, sizeof(ifname)));
2503   - if (fd < 0)
2504   - return -1;
2505   -
2506   - if (!setup_script || !strcmp(setup_script, "no"))
2507   - setup_script = "";
2508   - if (setup_script[0] != '\0') {
2509   - if (launch_script(setup_script, ifname, fd))
2510   - return -1;
2511   - }
2512   - s = net_tap_fd_init(vlan, fd);
2513   - if (!s)
2514   - return -1;
2515   - snprintf(s->vc->info_str, sizeof(s->vc->info_str),
2516   - "tap: ifname=%s setup_script=%s", ifname, setup_script);
2517   - if (down_script && strcmp(down_script, "no"))
2518   - snprintf(s->down_script, sizeof(s->down_script), "%s", down_script);
2519   - return 0;
2520   -}
2521   -
2522   -#endif /* !_WIN32 */
2523   -
2524   -#if defined(CONFIG_VDE)
2525   -typedef struct VDEState {
2526   - VLANClientState *vc;
2527   - VDECONN *vde;
2528   -} VDEState;
2529   -
2530   -static void vde_to_qemu(void *opaque)
2531   -{
2532   - VDEState *s = opaque;
2533   - uint8_t buf[4096];
2534   - int size;
2535   -
2536   - size = vde_recv(s->vde, buf, sizeof(buf), 0);
2537   - if (size > 0) {
2538   - qemu_send_packet(s->vc, buf, size);
2539   - }
2540   -}
2541   -
2542   -static void vde_from_qemu(void *opaque, const uint8_t *buf, int size)
2543   -{
2544   - VDEState *s = opaque;
2545   - int ret;
2546   - for(;;) {
2547   - ret = vde_send(s->vde, buf, size, 0);
2548   - if (ret < 0 && errno == EINTR) {
2549   - } else {
2550   - break;
2551   - }
2552   - }
2553   -}
2554   -
2555   -static int net_vde_init(VLANState *vlan, const char *sock, int port,
2556   - const char *group, int mode)
2557   -{
2558   - VDEState *s;
2559   - char *init_group = strlen(group) ? (char *)group : NULL;
2560   - char *init_sock = strlen(sock) ? (char *)sock : NULL;
2561   -
2562   - struct vde_open_args args = {
2563   - .port = port,
2564   - .group = init_group,
2565   - .mode = mode,
2566   - };
2567   -
2568   - s = qemu_mallocz(sizeof(VDEState));
2569   - if (!s)
2570   - return -1;
2571   - s->vde = vde_open(init_sock, "QEMU", &args);
2572   - if (!s->vde){
2573   - free(s);
2574   - return -1;
2575   - }
2576   - s->vc = qemu_new_vlan_client(vlan, vde_from_qemu, NULL, s);
2577   - qemu_set_fd_handler(vde_datafd(s->vde), vde_to_qemu, NULL, s);
2578   - snprintf(s->vc->info_str, sizeof(s->vc->info_str), "vde: sock=%s fd=%d",
2579   - sock, vde_datafd(s->vde));
2580   - return 0;
2581   -}
2582   -#endif
2583   -
2584   -/* network connection */
2585   -typedef struct NetSocketState {
2586   - VLANClientState *vc;
2587   - int fd;
2588   - int state; /* 0 = getting length, 1 = getting data */
2589   - int index;
2590   - int packet_len;
2591   - uint8_t buf[4096];
2592   - struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
2593   -} NetSocketState;
2594   -
2595   -typedef struct NetSocketListenState {
2596   - VLANState *vlan;
2597   - int fd;
2598   -} NetSocketListenState;
2599   -
2600   -/* XXX: we consider we can send the whole packet without blocking */
2601   -static void net_socket_receive(void *opaque, const uint8_t *buf, int size)
2602   -{
2603   - NetSocketState *s = opaque;
2604   - uint32_t len;
2605   - len = htonl(size);
2606   -
2607   - send_all(s->fd, (const uint8_t *)&len, sizeof(len));
2608   - send_all(s->fd, buf, size);
2609   -}
2610   -
2611   -static void net_socket_receive_dgram(void *opaque, const uint8_t *buf, int size)
2612   -{
2613   - NetSocketState *s = opaque;
2614   - sendto(s->fd, buf, size, 0,
2615   - (struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));
2616   -}
2617   -
2618   -static void net_socket_send(void *opaque)
2619   -{
2620   - NetSocketState *s = opaque;
2621   - int l, size, err;
2622   - uint8_t buf1[4096];
2623   - const uint8_t *buf;
2624   -
2625   - size = recv(s->fd, buf1, sizeof(buf1), 0);
2626   - if (size < 0) {
2627   - err = socket_error();
2628   - if (err != EWOULDBLOCK)
2629   - goto eoc;
2630   - } else if (size == 0) {
2631   - /* end of connection */
2632   - eoc:
2633   - qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
2634   - closesocket(s->fd);
2635   - return;
2636   - }
2637   - buf = buf1;
2638   - while (size > 0) {
2639   - /* reassemble a packet from the network */
2640   - switch(s->state) {
2641   - case 0:
2642   - l = 4 - s->index;
2643   - if (l > size)
2644   - l = size;
2645   - memcpy(s->buf + s->index, buf, l);
2646   - buf += l;
2647   - size -= l;
2648   - s->index += l;
2649   - if (s->index == 4) {
2650   - /* got length */
2651   - s->packet_len = ntohl(*(uint32_t *)s->buf);
2652   - s->index = 0;
2653   - s->state = 1;
2654   - }
2655   - break;
2656   - case 1:
2657   - l = s->packet_len - s->index;
2658   - if (l > size)
2659   - l = size;
2660   - memcpy(s->buf + s->index, buf, l);
2661   - s->index += l;
2662   - buf += l;
2663   - size -= l;
2664   - if (s->index >= s->packet_len) {
2665   - qemu_send_packet(s->vc, s->buf, s->packet_len);
2666   - s->index = 0;
2667   - s->state = 0;
2668   - }
2669   - break;
2670   - }
2671   - }
2672   -}
2673   -
2674   -static void net_socket_send_dgram(void *opaque)
2675   -{
2676   - NetSocketState *s = opaque;
2677   - int size;
2678   -
2679   - size = recv(s->fd, s->buf, sizeof(s->buf), 0);
2680   - if (size < 0)
2681   - return;
2682   - if (size == 0) {
2683   - /* end of connection */
2684   - qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
2685   - return;
2686   - }
2687   - qemu_send_packet(s->vc, s->buf, size);
2688   -}
2689   -
2690   -static int net_socket_mcast_create(struct sockaddr_in *mcastaddr)
2691   -{
2692   - struct ip_mreq imr;
2693   - int fd;
2694   - int val, ret;
2695   - if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) {
2696   - fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) does not contain a multicast address\n",
2697   - inet_ntoa(mcastaddr->sin_addr),
2698   - (int)ntohl(mcastaddr->sin_addr.s_addr));
2699   - return -1;
2700   -
2701   - }
2702   - fd = socket(PF_INET, SOCK_DGRAM, 0);
2703   - if (fd < 0) {
2704   - perror("socket(PF_INET, SOCK_DGRAM)");
2705   - return -1;
2706   - }
2707   -
2708   - val = 1;
2709   - ret=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
2710   - (const char *)&val, sizeof(val));
2711   - if (ret < 0) {
2712   - perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)");
2713   - goto fail;
2714   - }
2715   -
2716   - ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
2717   - if (ret < 0) {
2718   - perror("bind");
2719   - goto fail;
2720   - }
2721   -
2722   - /* Add host to multicast group */
2723   - imr.imr_multiaddr = mcastaddr->sin_addr;
2724   - imr.imr_interface.s_addr = htonl(INADDR_ANY);
2725   -
2726   - ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
2727   - (const char *)&imr, sizeof(struct ip_mreq));
2728   - if (ret < 0) {
2729   - perror("setsockopt(IP_ADD_MEMBERSHIP)");
2730   - goto fail;
2731   - }
2732   -
2733   - /* Force mcast msgs to loopback (eg. several QEMUs in same host */
2734   - val = 1;
2735   - ret=setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
2736   - (const char *)&val, sizeof(val));
2737   - if (ret < 0) {
2738   - perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)");
2739   - goto fail;
2740   - }
2741   -
2742   - socket_set_nonblock(fd);
2743   - return fd;
2744   -fail:
2745   - if (fd >= 0)
2746   - closesocket(fd);
2747   - return -1;
2748   -}
2749   -
2750   -static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan, int fd,
2751   - int is_connected)
2752   -{
2753   - struct sockaddr_in saddr;
2754   - int newfd;
2755   - socklen_t saddr_len;
2756   - NetSocketState *s;
2757   -
2758   - /* fd passed: multicast: "learn" dgram_dst address from bound address and save it
2759   - * Because this may be "shared" socket from a "master" process, datagrams would be recv()
2760   - * by ONLY ONE process: we must "clone" this dgram socket --jjo
2761   - */
2762   -
2763   - if (is_connected) {
2764   - if (getsockname(fd, (struct sockaddr *) &saddr, &saddr_len) == 0) {
2765   - /* must be bound */
2766   - if (saddr.sin_addr.s_addr==0) {
2767   - fprintf(stderr, "qemu: error: init_dgram: fd=%d unbound, cannot setup multicast dst addr\n",
2768   - fd);
2769   - return NULL;
2770   - }
2771   - /* clone dgram socket */
2772   - newfd = net_socket_mcast_create(&saddr);
2773   - if (newfd < 0) {
2774   - /* error already reported by net_socket_mcast_create() */
2775   - close(fd);
2776   - return NULL;
2777   - }
2778   - /* clone newfd to fd, close newfd */
2779   - dup2(newfd, fd);
2780   - close(newfd);
2781   -
2782   - } else {
2783   - fprintf(stderr, "qemu: error: init_dgram: fd=%d failed getsockname(): %s\n",
2784   - fd, strerror(errno));
2785   - return NULL;
2786   - }
2787   - }
2788   -
2789   - s = qemu_mallocz(sizeof(NetSocketState));
2790   - if (!s)
2791   - return NULL;
2792   - s->fd = fd;
2793   -
2794   - s->vc = qemu_new_vlan_client(vlan, net_socket_receive_dgram, NULL, s);
2795   - qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
2796   -
2797   - /* mcast: save bound address as dst */
2798   - if (is_connected) s->dgram_dst=saddr;
2799   -
2800   - snprintf(s->vc->info_str, sizeof(s->vc->info_str),
2801   - "socket: fd=%d (%s mcast=%s:%d)",
2802   - fd, is_connected? "cloned" : "",
2803   - inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
2804   - return s;
2805   -}
2806   -
2807   -static void net_socket_connect(void *opaque)
2808   -{
2809   - NetSocketState *s = opaque;
2810   - qemu_set_fd_handler(s->fd, net_socket_send, NULL, s);
2811   -}
2812   -
2813   -static NetSocketState *net_socket_fd_init_stream(VLANState *vlan, int fd,
2814   - int is_connected)
2815   -{
2816   - NetSocketState *s;
2817   - s = qemu_mallocz(sizeof(NetSocketState));
2818   - if (!s)
2819   - return NULL;
2820   - s->fd = fd;
2821   - s->vc = qemu_new_vlan_client(vlan,
2822   - net_socket_receive, NULL, s);
2823   - snprintf(s->vc->info_str, sizeof(s->vc->info_str),
2824   - "socket: fd=%d", fd);
2825   - if (is_connected) {
2826   - net_socket_connect(s);
2827   - } else {
2828   - qemu_set_fd_handler(s->fd, NULL, net_socket_connect, s);
2829   - }
2830   - return s;
2831   -}
2832   -
2833   -static NetSocketState *net_socket_fd_init(VLANState *vlan, int fd,
2834   - int is_connected)
2835   -{
2836   - int so_type=-1, optlen=sizeof(so_type);
2837   -
2838   - if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type,
2839   - (socklen_t *)&optlen)< 0) {
2840   - fprintf(stderr, "qemu: error: getsockopt(SO_TYPE) for fd=%d failed\n", fd);
2841   - return NULL;
2842   - }
2843   - switch(so_type) {
2844   - case SOCK_DGRAM:
2845   - return net_socket_fd_init_dgram(vlan, fd, is_connected);
2846   - case SOCK_STREAM:
2847   - return net_socket_fd_init_stream(vlan, fd, is_connected);
2848   - default:
2849   - /* who knows ... this could be a eg. a pty, do warn and continue as stream */
2850   - fprintf(stderr, "qemu: warning: socket type=%d for fd=%d is not SOCK_DGRAM or SOCK_STREAM\n", so_type, fd);
2851   - return net_socket_fd_init_stream(vlan, fd, is_connected);
2852   - }
2853   - return NULL;
2854   -}
2855   -
2856   -static void net_socket_accept(void *opaque)
2857   -{
2858   - NetSocketListenState *s = opaque;
2859   - NetSocketState *s1;
2860   - struct sockaddr_in saddr;
2861   - socklen_t len;
2862   - int fd;
2863   -
2864   - for(;;) {
2865   - len = sizeof(saddr);
2866   - fd = accept(s->fd, (struct sockaddr *)&saddr, &len);
2867   - if (fd < 0 && errno != EINTR) {
2868   - return;
2869   - } else if (fd >= 0) {
2870   - break;
2871   - }
2872   - }
2873   - s1 = net_socket_fd_init(s->vlan, fd, 1);
2874   - if (!s1) {
2875   - closesocket(fd);
2876   - } else {
2877   - snprintf(s1->vc->info_str, sizeof(s1->vc->info_str),
2878   - "socket: connection from %s:%d",
2879   - inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
2880   - }
2881   -}
2882   -
2883   -static int net_socket_listen_init(VLANState *vlan, const char *host_str)
2884   -{
2885   - NetSocketListenState *s;
2886   - int fd, val, ret;
2887   - struct sockaddr_in saddr;
2888   -
2889   - if (parse_host_port(&saddr, host_str) < 0)
2890   - return -1;
2891   -
2892   - s = qemu_mallocz(sizeof(NetSocketListenState));
2893   - if (!s)
2894   - return -1;
2895   -
2896   - fd = socket(PF_INET, SOCK_STREAM, 0);
2897   - if (fd < 0) {
2898   - perror("socket");
2899   - return -1;
2900   - }
2901   - socket_set_nonblock(fd);
2902   -
2903   - /* allow fast reuse */
2904   - val = 1;
2905   - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
2906   -
2907   - ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
2908   - if (ret < 0) {
2909   - perror("bind");
2910   - return -1;
2911   - }
2912   - ret = listen(fd, 0);
2913   - if (ret < 0) {
2914   - perror("listen");
2915   - return -1;
2916   - }
2917   - s->vlan = vlan;
2918   - s->fd = fd;
2919   - qemu_set_fd_handler(fd, net_socket_accept, NULL, s);
2920   - return 0;
2921   -}
2922   -
2923   -static int net_socket_connect_init(VLANState *vlan, const char *host_str)
2924   -{
2925   - NetSocketState *s;
2926   - int fd, connected, ret, err;
2927   - struct sockaddr_in saddr;
2928   -
2929   - if (parse_host_port(&saddr, host_str) < 0)
2930   - return -1;
2931   -
2932   - fd = socket(PF_INET, SOCK_STREAM, 0);
2933   - if (fd < 0) {
2934   - perror("socket");
2935   - return -1;
2936   - }
2937   - socket_set_nonblock(fd);
2938   -
2939   - connected = 0;
2940   - for(;;) {
2941   - ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
2942   - if (ret < 0) {
2943   - err = socket_error();
2944   - if (err == EINTR || err == EWOULDBLOCK) {
2945   - } else if (err == EINPROGRESS) {
2946   - break;
2947   -#ifdef _WIN32
2948   - } else if (err == WSAEALREADY) {
2949   - break;
2950   -#endif
2951   - } else {
2952   - perror("connect");
2953   - closesocket(fd);
2954   - return -1;
2955   - }
2956   - } else {
2957   - connected = 1;
2958   - break;
2959   - }
2960   - }
2961   - s = net_socket_fd_init(vlan, fd, connected);
2962   - if (!s)
2963   - return -1;
2964   - snprintf(s->vc->info_str, sizeof(s->vc->info_str),
2965   - "socket: connect to %s:%d",
2966   - inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
2967   - return 0;
2968   -}
2969   -
2970   -static int net_socket_mcast_init(VLANState *vlan, const char *host_str)
2971   -{
2972   - NetSocketState *s;
2973   - int fd;
2974   - struct sockaddr_in saddr;
2975   -
2976   - if (parse_host_port(&saddr, host_str) < 0)
2977   - return -1;
2978   -
2979   -
2980   - fd = net_socket_mcast_create(&saddr);
2981   - if (fd < 0)
2982   - return -1;
2983   -
2984   - s = net_socket_fd_init(vlan, fd, 0);
2985   - if (!s)
2986   - return -1;
2987   -
2988   - s->dgram_dst = saddr;
2989   -
2990   - snprintf(s->vc->info_str, sizeof(s->vc->info_str),
2991   - "socket: mcast=%s:%d",
2992   - inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
2993   - return 0;
2994   -
2995   -}
2996   -
2997   -static const char *get_opt_name(char *buf, int buf_size, const char *p)
  1759 +const char *get_opt_name(char *buf, int buf_size, const char *p)
2998 1760 {
2999 1761 char *q;
3000 1762  
... ... @@ -3010,7 +1772,7 @@ static const char *get_opt_name(char *buf, int buf_size, const char *p)
3010 1772 return p;
3011 1773 }
3012 1774  
3013   -static const char *get_opt_value(char *buf, int buf_size, const char *p)
  1775 +const char *get_opt_value(char *buf, int buf_size, const char *p)
3014 1776 {
3015 1777 char *q;
3016 1778  
... ... @@ -3031,8 +1793,8 @@ static const char *get_opt_value(char *buf, int buf_size, const char *p)
3031 1793 return p;
3032 1794 }
3033 1795  
3034   -static int get_param_value(char *buf, int buf_size,
3035   - const char *tag, const char *str)
  1796 +int get_param_value(char *buf, int buf_size,
  1797 + const char *tag, const char *str)
3036 1798 {
3037 1799 const char *p;
3038 1800 char option[128];
... ... @@ -3056,8 +1818,8 @@ static int get_param_value(char *buf, int buf_size,
3056 1818 return 0;
3057 1819 }
3058 1820  
3059   -static int check_params(char *buf, int buf_size,
3060   - const char * const *params, const char *str)
  1821 +int check_params(char *buf, int buf_size,
  1822 + const char * const *params, const char *str)
3061 1823 {
3062 1824 const char *p;
3063 1825 int i;
... ... @@ -3081,188 +1843,6 @@ static int check_params(char *buf, int buf_size,
3081 1843 return 0;
3082 1844 }
3083 1845  
3084   -static int net_client_init(const char *device, const char *p)
3085   -{
3086   - char buf[1024];
3087   - int vlan_id, ret;
3088   - VLANState *vlan;
3089   -
3090   - vlan_id = 0;
3091   - if (get_param_value(buf, sizeof(buf), "vlan", p)) {
3092   - vlan_id = strtol(buf, NULL, 0);
3093   - }
3094   - vlan = qemu_find_vlan(vlan_id);
3095   - if (!vlan) {
3096   - fprintf(stderr, "Could not create vlan %d\n", vlan_id);
3097   - return -1;
3098   - }
3099   - if (!strcmp(device, "nic")) {
3100   - NICInfo *nd;
3101   - uint8_t *macaddr;
3102   -
3103   - if (nb_nics >= MAX_NICS) {
3104   - fprintf(stderr, "Too Many NICs\n");
3105   - return -1;
3106   - }
3107   - nd = &nd_table[nb_nics];
3108   - macaddr = nd->macaddr;
3109   - macaddr[0] = 0x52;
3110   - macaddr[1] = 0x54;
3111   - macaddr[2] = 0x00;
3112   - macaddr[3] = 0x12;
3113   - macaddr[4] = 0x34;
3114   - macaddr[5] = 0x56 + nb_nics;
3115   -
3116   - if (get_param_value(buf, sizeof(buf), "macaddr", p)) {
3117   - if (parse_macaddr(macaddr, buf) < 0) {
3118   - fprintf(stderr, "invalid syntax for ethernet address\n");
3119   - return -1;
3120   - }
3121   - }
3122   - if (get_param_value(buf, sizeof(buf), "model", p)) {
3123   - nd->model = strdup(buf);
3124   - }
3125   - nd->vlan = vlan;
3126   - nb_nics++;
3127   - vlan->nb_guest_devs++;
3128   - ret = 0;
3129   - } else
3130   - if (!strcmp(device, "none")) {
3131   - /* does nothing. It is needed to signal that no network cards
3132   - are wanted */
3133   - ret = 0;
3134   - } else
3135   -#ifdef CONFIG_SLIRP
3136   - if (!strcmp(device, "user")) {
3137   - if (get_param_value(buf, sizeof(buf), "hostname", p)) {
3138   - pstrcpy(slirp_hostname, sizeof(slirp_hostname), buf);
3139   - }
3140   - vlan->nb_host_devs++;
3141   - ret = net_slirp_init(vlan);
3142   - } else
3143   -#endif
3144   -#ifdef _WIN32
3145   - if (!strcmp(device, "tap")) {
3146   - char ifname[64];
3147   - if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
3148   - fprintf(stderr, "tap: no interface name\n");
3149   - return -1;
3150   - }
3151   - vlan->nb_host_devs++;
3152   - ret = tap_win32_init(vlan, ifname);
3153   - } else
3154   -#else
3155   - if (!strcmp(device, "tap")) {
3156   - char ifname[64];
3157   - char setup_script[1024], down_script[1024];
3158   - int fd;
3159   - vlan->nb_host_devs++;
3160   - if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
3161   - fd = strtol(buf, NULL, 0);
3162   - fcntl(fd, F_SETFL, O_NONBLOCK);
3163   - ret = -1;
3164   - if (net_tap_fd_init(vlan, fd))
3165   - ret = 0;
3166   - } else {
3167   - if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
3168   - ifname[0] = '\0';
3169   - }
3170   - if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) {
3171   - pstrcpy(setup_script, sizeof(setup_script), DEFAULT_NETWORK_SCRIPT);
3172   - }
3173   - if (get_param_value(down_script, sizeof(down_script), "downscript", p) == 0) {
3174   - pstrcpy(down_script, sizeof(down_script), DEFAULT_NETWORK_DOWN_SCRIPT);
3175   - }
3176   - ret = net_tap_init(vlan, ifname, setup_script, down_script);
3177   - }
3178   - } else
3179   -#endif
3180   - if (!strcmp(device, "socket")) {
3181   - if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
3182   - int fd;
3183   - fd = strtol(buf, NULL, 0);
3184   - ret = -1;
3185   - if (net_socket_fd_init(vlan, fd, 1))
3186   - ret = 0;
3187   - } else if (get_param_value(buf, sizeof(buf), "listen", p) > 0) {
3188   - ret = net_socket_listen_init(vlan, buf);
3189   - } else if (get_param_value(buf, sizeof(buf), "connect", p) > 0) {
3190   - ret = net_socket_connect_init(vlan, buf);
3191   - } else if (get_param_value(buf, sizeof(buf), "mcast", p) > 0) {
3192   - ret = net_socket_mcast_init(vlan, buf);
3193   - } else {
3194   - fprintf(stderr, "Unknown socket options: %s\n", p);
3195   - return -1;
3196   - }
3197   - vlan->nb_host_devs++;
3198   - } else
3199   -#ifdef CONFIG_VDE
3200   - if (!strcmp(device, "vde")) {
3201   - char vde_sock[1024], vde_group[512];
3202   - int vde_port, vde_mode;
3203   - vlan->nb_host_devs++;
3204   - if (get_param_value(vde_sock, sizeof(vde_sock), "sock", p) <= 0) {
3205   - vde_sock[0] = '\0';
3206   - }
3207   - if (get_param_value(buf, sizeof(buf), "port", p) > 0) {
3208   - vde_port = strtol(buf, NULL, 10);
3209   - } else {
3210   - vde_port = 0;
3211   - }
3212   - if (get_param_value(vde_group, sizeof(vde_group), "group", p) <= 0) {
3213   - vde_group[0] = '\0';
3214   - }
3215   - if (get_param_value(buf, sizeof(buf), "mode", p) > 0) {
3216   - vde_mode = strtol(buf, NULL, 8);
3217   - } else {
3218   - vde_mode = 0700;
3219   - }
3220   - ret = net_vde_init(vlan, vde_sock, vde_port, vde_group, vde_mode);
3221   - } else
3222   -#endif
3223   - {
3224   - fprintf(stderr, "Unknown network device: %s\n", device);
3225   - return -1;
3226   - }
3227   - if (ret < 0) {
3228   - fprintf(stderr, "Could not initialize device '%s'\n", device);
3229   - }
3230   -
3231   - return ret;
3232   -}
3233   -
3234   -static int net_client_parse(const char *str)
3235   -{
3236   - const char *p;
3237   - char *q;
3238   - char device[64];
3239   -
3240   - p = str;
3241   - q = device;
3242   - while (*p != '\0' && *p != ',') {
3243   - if ((q - device) < sizeof(device) - 1)
3244   - *q++ = *p;
3245   - p++;
3246   - }
3247   - *q = '\0';
3248   - if (*p == ',')
3249   - p++;
3250   -
3251   - return net_client_init(device, p);
3252   -}
3253   -
3254   -void do_info_network(void)
3255   -{
3256   - VLANState *vlan;
3257   - VLANClientState *vc;
3258   -
3259   - for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
3260   - term_printf("VLAN %d devices:\n", vlan->id);
3261   - for(vc = vlan->first_client; vc != NULL; vc = vc->next)
3262   - term_printf(" %s\n", vc->info_str);
3263   - }
3264   -}
3265   -
3266 1846 /***********************************************************/
3267 1847 /* Bluetooth support */
3268 1848 static int nb_hcis;
... ... @@ -5877,7 +4457,7 @@ void main_loop_wait(int timeout)
5877 4457 tv.tv_usec = (timeout % 1000) * 1000;
5878 4458  
5879 4459 #if defined(CONFIG_SLIRP)
5880   - if (slirp_inited) {
  4460 + if (slirp_is_inited()) {
5881 4461 slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
5882 4462 }
5883 4463 #endif
... ... @@ -5906,7 +4486,7 @@ void main_loop_wait(int timeout)
5906 4486 }
5907 4487 }
5908 4488 #if defined(CONFIG_SLIRP)
5909   - if (slirp_inited) {
  4489 + if (slirp_is_inited()) {
5910 4490 if (ret < 0) {
5911 4491 FD_ZERO(&rfds);
5912 4492 FD_ZERO(&wfds);
... ... @@ -6739,7 +5319,6 @@ int main(int argc, char **argv)
6739 5319 int fds[2];
6740 5320 int tb_size;
6741 5321 const char *pid_file = NULL;
6742   - VLANState *vlan;
6743 5322 int autostart;
6744 5323 const char *incoming = NULL;
6745 5324  
... ... @@ -7481,16 +6060,7 @@ int main(int argc, char **argv)
7481 6060 if (net_client_parse(net_clients[i]) < 0)
7482 6061 exit(1);
7483 6062 }
7484   - for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
7485   - if (vlan->nb_guest_devs == 0 && vlan->nb_host_devs == 0)
7486   - continue;
7487   - if (vlan->nb_guest_devs == 0)
7488   - fprintf(stderr, "Warning: vlan %d with no nics\n", vlan->id);
7489   - if (vlan->nb_host_devs == 0)
7490   - fprintf(stderr,
7491   - "Warning: vlan %d is not connected to host network\n",
7492   - vlan->id);
7493   - }
  6063 + net_client_check();
7494 6064  
7495 6065 #ifdef TARGET_I386
7496 6066 /* XXX: this should be moved in the PC machine instantiation code */
... ... @@ -7739,29 +6309,7 @@ int main(int argc, char **argv)
7739 6309  
7740 6310 main_loop();
7741 6311 quit_timers();
  6312 + net_cleanup();
7742 6313  
7743   -#if !defined(_WIN32)
7744   - /* close network clients */
7745   - for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
7746   - VLANClientState *vc;
7747   -
7748   - for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
7749   - if (vc->fd_read == tap_receive) {
7750   - char ifname[64];
7751   - TAPState *s = vc->opaque;
7752   -
7753   - if (sscanf(vc->info_str, "tap: ifname=%63s ", ifname) == 1 &&
7754   - s->down_script[0])
7755   - launch_script(s->down_script, ifname, s->fd);
7756   - }
7757   -#if defined(CONFIG_VDE)
7758   - if (vc->fd_read == vde_from_qemu) {
7759   - VDEState *s = vc->opaque;
7760   - vde_close(s->vde);
7761   - }
7762   -#endif
7763   - }
7764   - }
7765   -#endif
7766 6314 return 0;
7767 6315 }
... ...