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,6 +580,7 @@ ifndef CONFIG_USER_ONLY
580 580
581 OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o machine.o net-checksum.o 581 OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o machine.o net-checksum.o
582 OBJS+=fw_cfg.o aio.o buffered_file.o migration.o migration-tcp.o qemu-char.o 582 OBJS+=fw_cfg.o aio.o buffered_file.o migration.o migration-tcp.o qemu-char.o
  583 +OBJS+=net.o
583 ifdef CONFIG_WIN32 584 ifdef CONFIG_WIN32
584 OBJS+=block-raw-win32.o 585 OBJS+=block-raw-win32.o
585 else 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,4 +69,13 @@ uint16_t net_checksum_tcpudp(uint16_t length, uint16_t proto,
69 uint8_t *addrs, uint8_t *buf); 69 uint8_t *addrs, uint8_t *buf);
70 void net_checksum_calculate(uint8_t *data, int length); 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 #endif 81 #endif
sysemu.h
@@ -193,4 +193,11 @@ void do_usb_add(const char *devname); @@ -193,4 +193,11 @@ void do_usb_add(const char *devname);
193 void do_usb_del(const char *devname); 193 void do_usb_del(const char *devname);
194 void usb_info(void); 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 #endif 203 #endif
@@ -210,7 +210,6 @@ CharDriverState *parallel_hds[MAX_PARALLEL_PORTS]; @@ -210,7 +210,6 @@ CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
210 int win2k_install_hack = 0; 210 int win2k_install_hack = 0;
211 #endif 211 #endif
212 int usb_enabled = 0; 212 int usb_enabled = 0;
213 -static VLANState *first_vlan;  
214 int smp_cpus = 1; 213 int smp_cpus = 1;
215 const char *vnc_display; 214 const char *vnc_display;
216 int acpi_enabled = 1; 215 int acpi_enabled = 1;
@@ -1757,1244 +1756,7 @@ static int socket_init(void) @@ -1757,1244 +1756,7 @@ static int socket_init(void)
1757 } 1756 }
1758 #endif 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 char *q; 1761 char *q;
3000 1762
@@ -3010,7 +1772,7 @@ static const char *get_opt_name(char *buf, int buf_size, const char *p) @@ -3010,7 +1772,7 @@ static const char *get_opt_name(char *buf, int buf_size, const char *p)
3010 return p; 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 char *q; 1777 char *q;
3016 1778
@@ -3031,8 +1793,8 @@ static const char *get_opt_value(char *buf, int buf_size, const char *p) @@ -3031,8 +1793,8 @@ static const char *get_opt_value(char *buf, int buf_size, const char *p)
3031 return p; 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 const char *p; 1799 const char *p;
3038 char option[128]; 1800 char option[128];
@@ -3056,8 +1818,8 @@ static int get_param_value(char *buf, int buf_size, @@ -3056,8 +1818,8 @@ static int get_param_value(char *buf, int buf_size,
3056 return 0; 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 const char *p; 1824 const char *p;
3063 int i; 1825 int i;
@@ -3081,188 +1843,6 @@ static int check_params(char *buf, int buf_size, @@ -3081,188 +1843,6 @@ static int check_params(char *buf, int buf_size,
3081 return 0; 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 /* Bluetooth support */ 1847 /* Bluetooth support */
3268 static int nb_hcis; 1848 static int nb_hcis;
@@ -5877,7 +4457,7 @@ void main_loop_wait(int timeout) @@ -5877,7 +4457,7 @@ void main_loop_wait(int timeout)
5877 tv.tv_usec = (timeout % 1000) * 1000; 4457 tv.tv_usec = (timeout % 1000) * 1000;
5878 4458
5879 #if defined(CONFIG_SLIRP) 4459 #if defined(CONFIG_SLIRP)
5880 - if (slirp_inited) { 4460 + if (slirp_is_inited()) {
5881 slirp_select_fill(&nfds, &rfds, &wfds, &xfds); 4461 slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
5882 } 4462 }
5883 #endif 4463 #endif
@@ -5906,7 +4486,7 @@ void main_loop_wait(int timeout) @@ -5906,7 +4486,7 @@ void main_loop_wait(int timeout)
5906 } 4486 }
5907 } 4487 }
5908 #if defined(CONFIG_SLIRP) 4488 #if defined(CONFIG_SLIRP)
5909 - if (slirp_inited) { 4489 + if (slirp_is_inited()) {
5910 if (ret < 0) { 4490 if (ret < 0) {
5911 FD_ZERO(&rfds); 4491 FD_ZERO(&rfds);
5912 FD_ZERO(&wfds); 4492 FD_ZERO(&wfds);
@@ -6739,7 +5319,6 @@ int main(int argc, char **argv) @@ -6739,7 +5319,6 @@ int main(int argc, char **argv)
6739 int fds[2]; 5319 int fds[2];
6740 int tb_size; 5320 int tb_size;
6741 const char *pid_file = NULL; 5321 const char *pid_file = NULL;
6742 - VLANState *vlan;  
6743 int autostart; 5322 int autostart;
6744 const char *incoming = NULL; 5323 const char *incoming = NULL;
6745 5324
@@ -7481,16 +6060,7 @@ int main(int argc, char **argv) @@ -7481,16 +6060,7 @@ int main(int argc, char **argv)
7481 if (net_client_parse(net_clients[i]) < 0) 6060 if (net_client_parse(net_clients[i]) < 0)
7482 exit(1); 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 #ifdef TARGET_I386 6065 #ifdef TARGET_I386
7496 /* XXX: this should be moved in the PC machine instantiation code */ 6066 /* XXX: this should be moved in the PC machine instantiation code */
@@ -7739,29 +6309,7 @@ int main(int argc, char **argv) @@ -7739,29 +6309,7 @@ int main(int argc, char **argv)
7739 6309
7740 main_loop(); 6310 main_loop();
7741 quit_timers(); 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 return 0; 6314 return 0;
7767 } 6315 }