/[qemu]/qemu/vl.c
ViewVC logotype

Diff of /qemu/vl.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.145 by bellard, Fri Nov 11 00:00:38 2005 UTC revision 1.146 by bellard, Tue Nov 15 22:16:05 2005 UTC
# Line 40  Line 40 
40  #include <sys/socket.h>  #include <sys/socket.h>
41  #include <netinet/in.h>  #include <netinet/in.h>
42  #include <dirent.h>  #include <dirent.h>
43    #include <netdb.h>
44  #ifdef _BSD  #ifdef _BSD
45  #include <sys/stat.h>  #include <sys/stat.h>
46  #ifndef __APPLE__  #ifndef __APPLE__
# Line 122  const char* keyboard_layout = NULL; Line 123  const char* keyboard_layout = NULL;
123  int64_t ticks_per_sec;  int64_t ticks_per_sec;
124  int boot_device = 'c';  int boot_device = 'c';
125  int ram_size;  int ram_size;
 static char network_script[1024];  
126  int pit_min_timer_count = 0;  int pit_min_timer_count = 0;
127  int nb_nics;  int nb_nics;
128  NetDriverState nd_table[MAX_NICS];  NICInfo nd_table[MAX_NICS];
129  QEMUTimer *gui_timer;  QEMUTimer *gui_timer;
130  int vm_running;  int vm_running;
131  #ifdef HAS_AUDIO  #ifdef HAS_AUDIO
# Line 155  int win2k_install_hack = 0; Line 155  int win2k_install_hack = 0;
155  int usb_enabled = 0;  int usb_enabled = 0;
156  USBPort *vm_usb_ports[MAX_VM_USB_PORTS];  USBPort *vm_usb_ports[MAX_VM_USB_PORTS];
157  USBDevice *vm_usb_hub;  USBDevice *vm_usb_hub;
158    static VLANState *first_vlan;
159    
160  /***********************************************************/  /***********************************************************/
161  /* x86 ISA bus support */  /* x86 ISA bus support */
# Line 1076  CharDriverState *qemu_chr_open_null(void Line 1077  CharDriverState *qemu_chr_open_null(void
1077    
1078  typedef struct {  typedef struct {
1079      int fd_in, fd_out;      int fd_in, fd_out;
     /* for nographic stdio only */  
1080      IOCanRWHandler *fd_can_read;      IOCanRWHandler *fd_can_read;
1081      IOReadHandler *fd_read;      IOReadHandler *fd_read;
1082      void *fd_opaque;      void *fd_opaque;
1083        int max_size;
1084  } FDCharDriver;  } FDCharDriver;
1085    
1086  #define STDIO_MAX_CLIENTS 2  #define STDIO_MAX_CLIENTS 2
# Line 1113  static int fd_chr_write(CharDriverState Line 1114  static int fd_chr_write(CharDriverState
1114      return unix_write(s->fd_out, buf, len);      return unix_write(s->fd_out, buf, len);
1115  }  }
1116    
1117    static int fd_chr_read_poll(void *opaque)
1118    {
1119        CharDriverState *chr = opaque;
1120        FDCharDriver *s = chr->opaque;
1121    
1122        s->max_size = s->fd_can_read(s->fd_opaque);
1123        return s->max_size;
1124    }
1125    
1126    static void fd_chr_read(void *opaque)
1127    {
1128        CharDriverState *chr = opaque;
1129        FDCharDriver *s = chr->opaque;
1130        int size, len;
1131        uint8_t buf[1024];
1132        
1133        len = sizeof(buf);
1134        if (len > s->max_size)
1135            len = s->max_size;
1136        if (len == 0)
1137            return;
1138        size = read(s->fd_in, buf, len);
1139        if (size > 0) {
1140            s->fd_read(s->fd_opaque, buf, size);
1141        }
1142    }
1143    
1144  static void fd_chr_add_read_handler(CharDriverState *chr,  static void fd_chr_add_read_handler(CharDriverState *chr,
1145                                      IOCanRWHandler *fd_can_read,                                      IOCanRWHandler *fd_can_read,
1146                                      IOReadHandler *fd_read, void *opaque)                                      IOReadHandler *fd_read, void *opaque)
# Line 1120  static void fd_chr_add_read_handler(Char Line 1148  static void fd_chr_add_read_handler(Char
1148      FDCharDriver *s = chr->opaque;      FDCharDriver *s = chr->opaque;
1149    
1150      if (s->fd_in >= 0) {      if (s->fd_in >= 0) {
1151            s->fd_can_read = fd_can_read;
1152            s->fd_read = fd_read;
1153            s->fd_opaque = opaque;
1154          if (nographic && s->fd_in == 0) {          if (nographic && s->fd_in == 0) {
             s->fd_can_read = fd_can_read;  
             s->fd_read = fd_read;  
             s->fd_opaque = opaque;  
1155          } else {          } else {
1156              qemu_add_fd_read_handler(s->fd_in, fd_can_read, fd_read, opaque);              qemu_set_fd_handler2(s->fd_in, fd_chr_read_poll,
1157                                     fd_chr_read, NULL, chr);
1158          }          }
1159      }      }
1160  }  }
# Line 1261  static void stdio_received_byte(int ch) Line 1290  static void stdio_received_byte(int ch)
1290      }      }
1291  }  }
1292    
1293  static int stdio_can_read(void *opaque)  static int stdio_read_poll(void *opaque)
1294  {  {
1295      CharDriverState *chr;      CharDriverState *chr;
1296      FDCharDriver *s;      FDCharDriver *s;
# Line 1284  static int stdio_can_read(void *opaque) Line 1313  static int stdio_can_read(void *opaque)
1313      }      }
1314  }  }
1315    
1316  static void stdio_read(void *opaque, const uint8_t *buf, int size)  static void stdio_read(void *opaque)
1317  {  {
1318      int i;      int size;
1319      for(i = 0; i < size; i++)      uint8_t buf[1];
1320          stdio_received_byte(buf[i]);      
1321        size = read(0, buf, 1);
1322        if (size > 0)
1323            stdio_received_byte(buf[0]);
1324  }  }
1325    
1326  /* init terminal so that we can grab keys */  /* init terminal so that we can grab keys */
# Line 1337  CharDriverState *qemu_chr_open_stdio(voi Line 1369  CharDriverState *qemu_chr_open_stdio(voi
1369              return NULL;              return NULL;
1370          chr = qemu_chr_open_fd(0, 1);          chr = qemu_chr_open_fd(0, 1);
1371          if (stdio_nb_clients == 0)          if (stdio_nb_clients == 0)
1372              qemu_add_fd_read_handler(0, stdio_can_read, stdio_read, NULL);              qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, NULL);
1373          client_index = stdio_nb_clients;          client_index = stdio_nb_clients;
1374      } else {      } else {
1375          if (stdio_nb_clients != 0)          if (stdio_nb_clients != 0)
# Line 1603  CharDriverState *qemu_chr_open(const cha Line 1635  CharDriverState *qemu_chr_open(const cha
1635  }  }
1636    
1637  /***********************************************************/  /***********************************************************/
1638  /* Linux network device redirectors */  /* network device redirectors */
1639    
1640  void hex_dump(FILE *f, const uint8_t *buf, int size)  void hex_dump(FILE *f, const uint8_t *buf, int size)
1641  {  {
# Line 1631  void hex_dump(FILE *f, const uint8_t *bu Line 1663  void hex_dump(FILE *f, const uint8_t *bu
1663      }      }
1664  }  }
1665    
1666  void qemu_send_packet(NetDriverState *nd, const uint8_t *buf, int size)  static int parse_macaddr(uint8_t *macaddr, const char *p)
1667  {  {
1668      nd->send_packet(nd, buf, size);      int i;
1669        for(i = 0; i < 6; i++) {
1670            macaddr[i] = strtol(p, (char **)&p, 16);
1671            if (i == 5) {
1672                if (*p != '\0')
1673                    return -1;
1674            } else {
1675                if (*p != ':')
1676                    return -1;
1677                p++;
1678            }
1679        }
1680        return 0;
1681  }  }
1682    
1683  void qemu_add_read_packet(NetDriverState *nd, IOCanRWHandler *fd_can_read,  static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
                           IOReadHandler *fd_read, void *opaque)  
1684  {  {
1685      nd->add_read_packet(nd, fd_can_read, fd_read, opaque);      const char *p, *p1;
1686        int len;
1687        p = *pp;
1688        p1 = strchr(p, sep);
1689        if (!p1)
1690            return -1;
1691        len = p1 - p;
1692        p1++;
1693        if (buf_size > 0) {
1694            if (len > buf_size - 1)
1695                len = buf_size - 1;
1696            memcpy(buf, p, len);
1697            buf[len] = '\0';
1698        }
1699        *pp = p1;
1700        return 0;
1701  }  }
1702    
1703  /* dummy network adapter */  int parse_host_port(struct sockaddr_in *saddr, const char *str)
   
 static void dummy_send_packet(NetDriverState *nd, const uint8_t *buf, int size)  
1704  {  {
1705        char buf[512];
1706        struct hostent *he;
1707        const char *p, *r;
1708        int port;
1709    
1710        p = str;
1711        if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
1712            return -1;
1713        saddr->sin_family = AF_INET;
1714        if (buf[0] == '\0') {
1715            saddr->sin_addr.s_addr = 0;
1716        } else {
1717            if (isdigit(buf[0])) {
1718                if (!inet_aton(buf, &saddr->sin_addr))
1719                    return -1;
1720            } else {
1721    #ifdef _WIN32
1722                return -1;
1723    #else
1724                if ((he = gethostbyname(buf)) == NULL)
1725                    return - 1;
1726                saddr->sin_addr = *(struct in_addr *)he->h_addr;
1727    #endif
1728            }
1729        }
1730        port = strtol(p, (char **)&r, 0);
1731        if (r == p)
1732            return -1;
1733        saddr->sin_port = htons(port);
1734        return 0;
1735  }  }
1736    
1737  static void dummy_add_read_packet(NetDriverState *nd,  /* find or alloc a new VLAN */
1738                                    IOCanRWHandler *fd_can_read,  VLANState *qemu_find_vlan(int id)
                                   IOReadHandler *fd_read, void *opaque)  
1739  {  {
1740        VLANState **pvlan, *vlan;
1741        for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
1742            if (vlan->id == id)
1743                return vlan;
1744        }
1745        vlan = qemu_mallocz(sizeof(VLANState));
1746        if (!vlan)
1747            return NULL;
1748        vlan->id = id;
1749        vlan->next = NULL;
1750        pvlan = &first_vlan;
1751        while (*pvlan != NULL)
1752            pvlan = &(*pvlan)->next;
1753        *pvlan = vlan;
1754        return vlan;
1755    }
1756    
1757    VLANClientState *qemu_new_vlan_client(VLANState *vlan,
1758                                          IOReadHandler *fd_read, void *opaque)
1759    {
1760        VLANClientState *vc, **pvc;
1761        vc = qemu_mallocz(sizeof(VLANClientState));
1762        if (!vc)
1763            return NULL;
1764        vc->fd_read = fd_read;
1765        vc->opaque = opaque;
1766        vc->vlan = vlan;
1767    
1768        vc->next = NULL;
1769        pvc = &vlan->first_client;
1770        while (*pvc != NULL)
1771            pvc = &(*pvc)->next;
1772        *pvc = vc;
1773        return vc;
1774  }  }
1775    
1776  static int net_dummy_init(NetDriverState *nd)  void qemu_send_packet(VLANClientState *vc1, const uint8_t *buf, int size)
1777  {  {
1778      nd->send_packet = dummy_send_packet;      VLANState *vlan = vc1->vlan;
1779      nd->add_read_packet = dummy_add_read_packet;      VLANClientState *vc;
1780      pstrcpy(nd->ifname, sizeof(nd->ifname), "dummy");  
1781      return 0;  #if 0
1782        printf("vlan %d send:\n", vlan->id);
1783        hex_dump(stdout, buf, size);
1784    #endif
1785        for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
1786            if (vc != vc1) {
1787                vc->fd_read(vc->opaque, buf, size);
1788            }
1789        }
1790  }  }
1791    
1792  #if defined(CONFIG_SLIRP)  #if defined(CONFIG_SLIRP)
1793    
1794  /* slirp network adapter */  /* slirp network adapter */
1795    
 static void *slirp_fd_opaque;  
 static IOCanRWHandler *slirp_fd_can_read;  
 static IOReadHandler *slirp_fd_read;  
1796  static int slirp_inited;  static int slirp_inited;
1797    static VLANClientState *slirp_vc;
1798    
1799  int slirp_can_output(void)  int slirp_can_output(void)
1800  {  {
1801      return slirp_fd_can_read(slirp_fd_opaque);      return 1;
1802  }  }
1803    
1804  void slirp_output(const uint8_t *pkt, int pkt_len)  void slirp_output(const uint8_t *pkt, int pkt_len)
1805  {  {
1806  #if 0  #if 0
1807      printf("output:\n");      printf("slirp output:\n");
1808      hex_dump(stdout, pkt, pkt_len);      hex_dump(stdout, pkt, pkt_len);
1809  #endif  #endif
1810      slirp_fd_read(slirp_fd_opaque, pkt, pkt_len);      qemu_send_packet(slirp_vc, pkt, pkt_len);
1811  }  }
1812    
1813  static void slirp_send_packet(NetDriverState *nd, const uint8_t *buf, int size)  static void slirp_receive(void *opaque, const uint8_t *buf, int size)
1814  {  {
1815  #if 0  #if 0
1816      printf("input:\n");      printf("slirp input:\n");
1817      hex_dump(stdout, buf, size);      hex_dump(stdout, buf, size);
1818  #endif  #endif
1819      slirp_input(buf, size);      slirp_input(buf, size);
1820  }  }
1821    
1822  static void slirp_add_read_packet(NetDriverState *nd,  static int net_slirp_init(VLANState *vlan)
                                   IOCanRWHandler *fd_can_read,  
                                   IOReadHandler *fd_read, void *opaque)  
 {  
     slirp_fd_opaque = opaque;  
     slirp_fd_can_read = fd_can_read;  
     slirp_fd_read = fd_read;  
 }  
   
 static int net_slirp_init(NetDriverState *nd)  
1823  {  {
1824      if (!slirp_inited) {      if (!slirp_inited) {
1825          slirp_inited = 1;          slirp_inited = 1;
1826          slirp_init();          slirp_init();
1827      }      }
1828      nd->send_packet = slirp_send_packet;      slirp_vc = qemu_new_vlan_client(vlan,
1829      nd->add_read_packet = slirp_add_read_packet;                                      slirp_receive, NULL);
1830      pstrcpy(nd->ifname, sizeof(nd->ifname), "slirp");      snprintf(slirp_vc->info_str, sizeof(slirp_vc->info_str), "user redirector");
     return 0;  
 }  
   
 static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)  
 {  
     const char *p, *p1;  
     int len;  
     p = *pp;  
     p1 = strchr(p, sep);  
     if (!p1)  
         return -1;  
     len = p1 - p;  
     p1++;  
     if (buf_size > 0) {  
         if (len > buf_size - 1)  
             len = buf_size - 1;  
         memcpy(buf, p, len);  
         buf[len] = '\0';  
     }  
     *pp = p1;  
1831      return 0;      return 0;
1832  }  }
1833    
# Line 1874  void net_slirp_smb(const char *exported_ Line 1970  void net_slirp_smb(const char *exported_
1970  #endif /* CONFIG_SLIRP */  #endif /* CONFIG_SLIRP */
1971    
1972  #if !defined(_WIN32)  #if !defined(_WIN32)
1973    
1974    typedef struct TAPState {
1975        VLANClientState *vc;
1976        int fd;
1977    } TAPState;
1978    
1979    static void tap_receive(void *opaque, const uint8_t *buf, int size)
1980    {
1981        TAPState *s = opaque;
1982        int ret;
1983        for(;;) {
1984            ret = write(s->fd, buf, size);
1985            if (ret < 0 && (errno == EINTR || errno == EAGAIN)) {
1986            } else {
1987                break;
1988            }
1989        }
1990    }
1991    
1992    static void tap_send(void *opaque)
1993    {
1994        TAPState *s = opaque;
1995        uint8_t buf[4096];
1996        int size;
1997    
1998        size = read(s->fd, buf, sizeof(buf));
1999        if (size > 0) {
2000            qemu_send_packet(s->vc, buf, size);
2001        }
2002    }
2003    
2004    /* fd support */
2005    
2006    static TAPState *net_tap_fd_init(VLANState *vlan, int fd)
2007    {
2008        TAPState *s;
2009    
2010        s = qemu_mallocz(sizeof(TAPState));
2011        if (!s)
2012            return NULL;
2013        s->fd = fd;
2014        s->vc = qemu_new_vlan_client(vlan, tap_receive, s);
2015        qemu_set_fd_handler(s->fd, tap_send, NULL, s);
2016        snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: fd=%d", fd);
2017        return s;
2018    }
2019    
2020  #ifdef _BSD  #ifdef _BSD
2021  static int tun_open(char *ifname, int ifname_size)  static int tap_open(char *ifname, int ifname_size)
2022  {  {
2023      int fd;      int fd;
2024      char *dev;      char *dev;
# Line 1895  static int tun_open(char *ifname, int if Line 2038  static int tun_open(char *ifname, int if
2038      return fd;      return fd;
2039  }  }
2040  #else  #else
2041  static int tun_open(char *ifname, int ifname_size)  static int tap_open(char *ifname, int ifname_size)
2042  {  {
2043      struct ifreq ifr;      struct ifreq ifr;
2044      int fd, ret;      int fd, ret;
# Line 1907  static int tun_open(char *ifname, int if Line 2050  static int tun_open(char *ifname, int if
2050      }      }
2051      memset(&ifr, 0, sizeof(ifr));      memset(&ifr, 0, sizeof(ifr));
2052      ifr.ifr_flags = IFF_TAP | IFF_NO_PI;      ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
2053      pstrcpy(ifr.ifr_name, IFNAMSIZ, "tun%d");      if (ifname[0] != '\0')
2054            pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname);
2055        else
2056            pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d");
2057      ret = ioctl(fd, TUNSETIFF, (void *) &ifr);      ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
2058      if (ret != 0) {      if (ret != 0) {
2059          fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");          fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
2060          close(fd);          close(fd);
2061          return -1;          return -1;
2062      }      }
     printf("Connected to host network interface: %s\n", ifr.ifr_name);  
2063      pstrcpy(ifname, ifname_size, ifr.ifr_name);      pstrcpy(ifname, ifname_size, ifr.ifr_name);
2064      fcntl(fd, F_SETFL, O_NONBLOCK);      fcntl(fd, F_SETFL, O_NONBLOCK);
2065      return fd;      return fd;
2066  }  }
2067  #endif  #endif
2068    
2069  static void tun_send_packet(NetDriverState *nd, const uint8_t *buf, int size)  static int net_tap_init(VLANState *vlan, const char *ifname1,
2070                            const char *setup_script)
2071    {
2072        TAPState *s;
2073        int pid, status, fd;
2074        char *args[3];
2075        char **parg;
2076        char ifname[128];
2077    
2078        if (ifname1 != NULL)
2079            pstrcpy(ifname, sizeof(ifname), ifname1);
2080        else
2081            ifname[0] = '\0';
2082        fd = tap_open(ifname, sizeof(ifname));
2083        if (fd < 0)
2084            return -1;
2085    
2086        if (!setup_script)
2087            setup_script = "";
2088        if (setup_script[0] != '\0') {
2089            /* try to launch network init script */
2090            pid = fork();
2091            if (pid >= 0) {
2092                if (pid == 0) {
2093                    parg = args;
2094                    *parg++ = (char *)setup_script;
2095                    *parg++ = ifname;
2096                    *parg++ = NULL;
2097                    execv(setup_script, args);
2098                    exit(1);
2099                }
2100                while (waitpid(pid, &status, 0) != pid);
2101                if (!WIFEXITED(status) ||
2102                    WEXITSTATUS(status) != 0) {
2103                    fprintf(stderr, "%s: could not launch network script\n",
2104                            setup_script);
2105                    return -1;
2106                }
2107            }
2108        }
2109        s = net_tap_fd_init(vlan, fd);
2110        if (!s)
2111            return -1;
2112        snprintf(s->vc->info_str, sizeof(s->vc->info_str),
2113                 "tap: ifname=%s setup_script=%s", ifname, setup_script);
2114        return 0;
2115    }
2116    
2117    /* network connection */
2118    typedef struct NetSocketState {
2119        VLANClientState *vc;
2120        int fd;
2121        int state; /* 0 = getting length, 1 = getting data */
2122        int index;
2123        int packet_len;
2124        uint8_t buf[4096];
2125    } NetSocketState;
2126    
2127    typedef struct NetSocketListenState {
2128        VLANState *vlan;
2129        int fd;
2130    } NetSocketListenState;
2131    
2132    /* XXX: we consider we can send the whole packet without blocking */
2133    static void net_socket_receive(void *opaque, const uint8_t *buf, int size)
2134  {  {
2135      write(nd->fd, buf, size);      NetSocketState *s = opaque;
2136        uint32_t len;
2137        len = htonl(size);
2138    
2139        unix_write(s->fd, (const uint8_t *)&len, sizeof(len));
2140        unix_write(s->fd, buf, size);
2141  }  }
2142    
2143  static void tun_add_read_packet(NetDriverState *nd,  static void net_socket_send(void *opaque)
                                 IOCanRWHandler *fd_can_read,  
                                 IOReadHandler *fd_read, void *opaque)  
2144  {  {
2145      qemu_add_fd_read_handler(nd->fd, fd_can_read, fd_read, opaque);      NetSocketState *s = opaque;
2146        int l, size;
2147        uint8_t buf1[4096];
2148        const uint8_t *buf;
2149    
2150        size = read(s->fd, buf1, sizeof(buf1));
2151        if (size < 0)
2152            return;
2153        if (size == 0) {
2154            /* end of connection */
2155            qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
2156            return;
2157        }
2158        buf = buf1;
2159        while (size > 0) {
2160            /* reassemble a packet from the network */
2161            switch(s->state) {
2162            case 0:
2163                l = 4 - s->index;
2164                if (l > size)
2165                    l = size;
2166                memcpy(s->buf + s->index, buf, l);
2167                buf += l;
2168                size -= l;
2169                s->index += l;
2170                if (s->index == 4) {
2171                    /* got length */
2172                    s->packet_len = ntohl(*(uint32_t *)s->buf);
2173                    s->index = 0;
2174                    s->state = 1;
2175                }
2176                break;
2177            case 1:
2178                l = s->packet_len - s->index;
2179                if (l > size)
2180                    l = size;
2181                memcpy(s->buf + s->index, buf, l);
2182                s->index += l;
2183                buf += l;
2184                size -= l;
2185                if (s->index >= s->packet_len) {
2186                    qemu_send_packet(s->vc, s->buf, s->packet_len);
2187                    s->index = 0;
2188                    s->state = 0;
2189                }
2190                break;
2191            }
2192        }
2193  }  }
2194    
2195  static int net_tun_init(NetDriverState *nd)  static void net_socket_connect(void *opaque)
2196  {  {
2197      int pid, status;      NetSocketState *s = opaque;
2198      char *args[3];      qemu_set_fd_handler(s->fd, net_socket_send, NULL, s);
2199      char **parg;  }
2200    
2201      nd->fd = tun_open(nd->ifname, sizeof(nd->ifname));  static NetSocketState *net_socket_fd_init(VLANState *vlan, int fd,
2202      if (nd->fd < 0)                                            int is_connected)
2203          return -1;  {
2204        NetSocketState *s;
2205        s = qemu_mallocz(sizeof(NetSocketState));
2206        if (!s)
2207            return NULL;
2208        s->fd = fd;
2209        s->vc = qemu_new_vlan_client(vlan,
2210                                     net_socket_receive, s);
2211        snprintf(s->vc->info_str, sizeof(s->vc->info_str),
2212                 "socket: fd=%d", fd);
2213        if (is_connected) {
2214            net_socket_connect(s);
2215        } else {
2216            qemu_set_fd_handler(s->fd, NULL, net_socket_connect, s);
2217        }
2218        return s;
2219    }
2220    
2221      /* try to launch network init script */  static void net_socket_accept(void *opaque)
2222      pid = fork();  {
2223      if (pid >= 0) {      NetSocketListenState *s = opaque;    
2224          if (pid == 0) {      NetSocketState *s1;
2225              parg = args;      struct sockaddr_in saddr;
2226              *parg++ = network_script;      socklen_t len;
2227              *parg++ = nd->ifname;      int fd;
2228              *parg++ = NULL;  
2229              execv(network_script, args);      for(;;) {
2230              exit(1);          len = sizeof(saddr);
2231          }          fd = accept(s->fd, (struct sockaddr *)&saddr, &len);
2232          while (waitpid(pid, &status, 0) != pid);          if (fd < 0 && errno != EINTR) {
2233          if (!WIFEXITED(status) ||              return;
2234              WEXITSTATUS(status) != 0) {          } else if (fd >= 0) {
2235              fprintf(stderr, "%s: could not launch network script\n",              break;
                     network_script);  
2236          }          }
2237      }      }
2238      nd->send_packet = tun_send_packet;      s1 = net_socket_fd_init(s->vlan, fd, 1);
2239      nd->add_read_packet = tun_add_read_packet;      if (!s1) {
2240            close(fd);
2241        } else {
2242            snprintf(s1->vc->info_str, sizeof(s1->vc->info_str),
2243                     "socket: connection from %s:%d",
2244                     inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
2245        }
2246    }
2247    
2248    static int net_socket_listen_init(VLANState *vlan, const char *host_str)
2249    {
2250        NetSocketListenState *s;
2251        int fd, val, ret;
2252        struct sockaddr_in saddr;
2253    
2254        if (parse_host_port(&saddr, host_str) < 0)
2255            return -1;
2256        
2257        s = qemu_mallocz(sizeof(NetSocketListenState));
2258        if (!s)
2259            return -1;
2260    
2261        fd = socket(PF_INET, SOCK_STREAM, 0);
2262        if (fd < 0) {
2263            perror("socket");
2264            return -1;
2265        }
2266        fcntl(fd, F_SETFL, O_NONBLOCK);
2267    
2268        /* allow fast reuse */
2269        val = 1;
2270        setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
2271        
2272        ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
2273        if (ret < 0) {
2274            perror("bind");
2275            return -1;
2276        }
2277        ret = listen(fd, 0);
2278        if (ret < 0) {
2279            perror("listen");
2280            return -1;
2281        }
2282        s->vlan = vlan;
2283        s->fd = fd;
2284        qemu_set_fd_handler(fd, net_socket_accept, NULL, s);
2285      return 0;      return 0;
2286  }  }
2287    
2288  static int net_fd_init(NetDriverState *nd, int fd)  static int net_socket_connect_init(VLANState *vlan, const char *host_str)
2289  {  {
2290      nd->fd = fd;      NetSocketState *s;
2291      nd->send_packet = tun_send_packet;      int fd, connected, ret;
2292      nd->add_read_packet = tun_add_read_packet;      struct sockaddr_in saddr;
2293      pstrcpy(nd->ifname, sizeof(nd->ifname), "tunfd");  
2294        if (parse_host_port(&saddr, host_str) < 0)
2295            return -1;
2296    
2297        fd = socket(PF_INET, SOCK_STREAM, 0);
2298        if (fd < 0) {
2299            perror("socket");
2300            return -1;
2301        }
2302        fcntl(fd, F_SETFL, O_NONBLOCK);
2303    
2304        connected = 0;
2305        for(;;) {
2306            ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
2307            if (ret < 0) {
2308                if (errno == EINTR || errno == EAGAIN) {
2309                } else if (errno == EINPROGRESS) {
2310                    break;
2311                } else {
2312                    perror("connect");
2313                    close(fd);
2314                    return -1;
2315                }
2316            } else {
2317                connected = 1;
2318                break;
2319            }
2320        }
2321        s = net_socket_fd_init(vlan, fd, connected);
2322        if (!s)
2323            return -1;
2324        snprintf(s->vc->info_str, sizeof(s->vc->info_str),
2325                 "socket: connect to %s:%d",
2326                 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
2327      return 0;      return 0;
2328  }  }
2329    
2330  #endif /* !_WIN32 */  #endif /* !_WIN32 */
2331    
2332    static int get_param_value(char *buf, int buf_size,
2333                               const char *tag, const char *str)
2334    {
2335        const char *p;
2336        char *q;
2337        char option[128];
2338    
2339        p = str;
2340        for(;;) {
2341            q = option;
2342            while (*p != '\0' && *p != '=') {
2343                if ((q - option) < sizeof(option) - 1)
2344                    *q++ = *p;
2345                p++;
2346            }
2347            *q = '\0';
2348            if (*p != '=')
2349                break;
2350            p++;
2351            if (!strcmp(tag, option)) {
2352                q = buf;
2353                while (*p != '\0' && *p != ',') {
2354                    if ((q - buf) < buf_size - 1)
2355                        *q++ = *p;
2356                    p++;
2357                }
2358                *q = '\0';
2359                return q - buf;
2360            } else {
2361                while (*p != '\0' && *p != ',') {
2362                    p++;
2363                }
2364            }
2365            if (*p != ',')
2366                break;
2367            p++;
2368        }
2369        return 0;
2370    }
2371    
2372    int net_client_init(const char *str)
2373    {
2374        const char *p;
2375        char *q;
2376        char device[64];
2377        char buf[1024];
2378        int vlan_id, ret;
2379        VLANState *vlan;
2380    
2381        p = str;
2382        q = device;
2383        while (*p != '\0' && *p != ',') {
2384            if ((q - device) < sizeof(device) - 1)
2385                *q++ = *p;
2386            p++;
2387        }
2388        *q = '\0';
2389        if (*p == ',')
2390            p++;
2391        vlan_id = 0;
2392        if (get_param_value(buf, sizeof(buf), "vlan", p)) {
2393            vlan_id = strtol(buf, NULL, 0);
2394        }
2395        vlan = qemu_find_vlan(vlan_id);
2396        if (!vlan) {
2397            fprintf(stderr, "Could not create vlan %d\n", vlan_id);
2398            return -1;
2399        }
2400        if (!strcmp(device, "nic")) {
2401            NICInfo *nd;
2402            uint8_t *macaddr;
2403    
2404            if (nb_nics >= MAX_NICS) {
2405                fprintf(stderr, "Too Many NICs\n");
2406                return -1;
2407            }
2408            nd = &nd_table[nb_nics];
2409            macaddr = nd->macaddr;
2410            macaddr[0] = 0x52;
2411            macaddr[1] = 0x54;
2412            macaddr[2] = 0x00;
2413            macaddr[3] = 0x12;
2414            macaddr[4] = 0x34;
2415            macaddr[5] = 0x56 + nb_nics;
2416    
2417            if (get_param_value(buf, sizeof(buf), "macaddr", p)) {
2418                if (parse_macaddr(macaddr, buf) < 0) {
2419                    fprintf(stderr, "invalid syntax for ethernet address\n");
2420                    return -1;
2421                }
2422            }
2423            nd->vlan = vlan;
2424            nb_nics++;
2425            ret = 0;
2426        } else
2427        if (!strcmp(device, "none")) {
2428            /* does nothing. It is needed to signal that no network cards
2429               are wanted */
2430            ret = 0;
2431        } else
2432    #ifdef CONFIG_SLIRP
2433        if (!strcmp(device, "user")) {
2434            ret = net_slirp_init(vlan);
2435        } else
2436    #endif
2437    #ifndef _WIN32
2438        if (!strcmp(device, "tap")) {
2439            char ifname[64];
2440            char setup_script[1024];
2441            int fd;
2442            if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
2443                fd = strtol(buf, NULL, 0);
2444                ret = -1;
2445                if (net_tap_fd_init(vlan, fd))
2446                    ret = 0;
2447            } else {
2448                get_param_value(ifname, sizeof(ifname), "ifname", p);
2449                if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) {
2450                    pstrcpy(setup_script, sizeof(setup_script), DEFAULT_NETWORK_SCRIPT);
2451                }
2452                ret = net_tap_init(vlan, ifname, setup_script);
2453            }
2454        } else
2455        if (!strcmp(device, "socket")) {
2456            if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
2457                int fd;
2458                fd = strtol(buf, NULL, 0);
2459                ret = -1;
2460                if (net_socket_fd_init(vlan, fd, 1))
2461                    ret = 0;
2462            } else if (get_param_value(buf, sizeof(buf), "listen", p) > 0) {
2463                ret = net_socket_listen_init(vlan, buf);
2464            } else if (get_param_value(buf, sizeof(buf), "connect", p) > 0) {
2465                ret = net_socket_connect_init(vlan, buf);
2466            } else {
2467                fprintf(stderr, "Unknown socket options: %s\n", p);
2468                return -1;
2469            }
2470        } else
2471    #endif
2472        {
2473            fprintf(stderr, "Unknown network device: %s\n", device);
2474            return -1;
2475        }
2476        if (ret < 0) {
2477            fprintf(stderr, "Could not initialize device '%s'\n", device);
2478        }
2479        
2480        return ret;
2481    }
2482    
2483    void do_info_network(void)
2484    {
2485        VLANState *vlan;
2486        VLANClientState *vc;
2487    
2488        for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
2489            term_printf("VLAN %d devices:\n", vlan->id);
2490            for(vc = vlan->first_client; vc != NULL; vc = vc->next)
2491                term_printf("  %s\n", vc->info_str);
2492        }
2493    }
2494    
2495  /***********************************************************/  /***********************************************************/
2496  /* USB devices */  /* USB devices */
2497    
# Line 2175  static void host_segv_handler(int host_s Line 2690  static void host_segv_handler(int host_s
2690    
2691  typedef struct IOHandlerRecord {  typedef struct IOHandlerRecord {
2692      int fd;      int fd;
2693      IOCanRWHandler *fd_can_read;      IOCanRWHandler *fd_read_poll;
2694      IOReadHandler *fd_read;      IOHandler *fd_read;
2695        IOHandler *fd_write;
2696      void *opaque;      void *opaque;
2697      /* temporary data */      /* temporary data */
2698      struct pollfd *ufd;      struct pollfd *ufd;
     int max_size;  
2699      struct IOHandlerRecord *next;      struct IOHandlerRecord *next;
2700  } IOHandlerRecord;  } IOHandlerRecord;
2701    
2702  static IOHandlerRecord *first_io_handler;  static IOHandlerRecord *first_io_handler;
2703    
2704  int qemu_add_fd_read_handler(int fd, IOCanRWHandler *fd_can_read,  /* XXX: fd_read_poll should be suppressed, but an API change is
2705                               IOReadHandler *fd_read, void *opaque)     necessary in the character devices to suppress fd_can_read(). */
2706    int qemu_set_fd_handler2(int fd,
2707                             IOCanRWHandler *fd_read_poll,
2708                             IOHandler *fd_read,
2709                             IOHandler *fd_write,
2710                             void *opaque)
2711  {  {
2712      IOHandlerRecord *ioh;      IOHandlerRecord **pioh, *ioh;
2713    
2714      ioh = qemu_mallocz(sizeof(IOHandlerRecord));      if (!fd_read && !fd_write) {
2715      if (!ioh)          pioh = &first_io_handler;
2716          return -1;          for(;;) {
2717      ioh->fd = fd;              ioh = *pioh;
2718      ioh->fd_can_read = fd_can_read;              if (ioh == NULL)
2719      ioh->fd_read = fd_read;                  break;
2720      ioh->opaque = opaque;              if (ioh->fd == fd) {
2721      ioh->next = first_io_handler;                  *pioh = ioh->next;
2722      first_io_handler = ioh;                  break;
2723                }
2724                pioh = &ioh->next;
2725            }
2726        } else {
2727            for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
2728                if (ioh->fd == fd)
2729                    goto found;
2730            }
2731            ioh = qemu_mallocz(sizeof(IOHandlerRecord));
2732            if (!ioh)
2733                return -1;
2734            ioh->next = first_io_handler;
2735            first_io_handler = ioh;
2736        found:
2737            ioh->fd = fd;
2738            ioh->fd_read_poll = fd_read_poll;
2739            ioh->fd_read = fd_read;
2740            ioh->fd_write = fd_write;
2741            ioh->opaque = opaque;
2742        }
2743      return 0;      return 0;
2744  }  }
2745    
2746  void qemu_del_fd_read_handler(int fd)  int qemu_set_fd_handler(int fd,
2747                            IOHandler *fd_read,
2748                            IOHandler *fd_write,
2749                            void *opaque)
2750  {  {
2751      IOHandlerRecord **pioh, *ioh;      return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
   
     pioh = &first_io_handler;  
     for(;;) {  
         ioh = *pioh;  
         if (ioh == NULL)  
             break;  
         if (ioh->fd == fd) {  
             *pioh = ioh->next;  
             break;  
         }  
         pioh = &ioh->next;  
     }  
2752  }  }
2753    
2754  /***********************************************************/  /***********************************************************/
# Line 3080  void main_loop_wait(int timeout) Line 3611  void main_loop_wait(int timeout)
3611  #ifndef _WIN32  #ifndef _WIN32
3612      struct pollfd ufds[MAX_IO_HANDLERS + 1], *pf;      struct pollfd ufds[MAX_IO_HANDLERS + 1], *pf;
3613      IOHandlerRecord *ioh, *ioh_next;      IOHandlerRecord *ioh, *ioh_next;
     uint8_t buf[4096];  
     int n, max_size;  
3614  #endif  #endif
3615      int ret;      int ret;
3616    
# Line 3093  void main_loop_wait(int timeout) Line 3622  void main_loop_wait(int timeout)
3622          /* XXX: separate device handlers from system ones */          /* XXX: separate device handlers from system ones */
3623          pf = ufds;          pf = ufds;
3624          for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {          for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
3625              if (!ioh->fd_can_read) {              pf->events = 0;
3626                  max_size = 0;              pf->fd = ioh->fd;
3627                  pf->fd = ioh->fd;              if (ioh->fd_read &&
3628                  pf->events = POLLIN;                  (!ioh->fd_read_poll ||
3629                  ioh->ufd = pf;                   ioh->fd_read_poll(ioh->opaque) != 0)) {
3630                  pf++;                  pf->events |= POLLIN;
             } else {  
                 max_size = ioh->fd_can_read(ioh->opaque);  
                 if (max_size > 0) {  
                     if (max_size > sizeof(buf))  
                         max_size = sizeof(buf);  
                     pf->fd = ioh->fd;  
                     pf->events = POLLIN;  
                     ioh->ufd = pf;  
                     pf++;  
                 } else {  
                     ioh->ufd = NULL;  
                 }  
3631              }              }
3632              ioh->max_size = max_size;              if (ioh->fd_write) {
3633                    pf->events |= POLLOUT;
3634                }
3635                ioh->ufd = pf;
3636                pf++;
3637          }          }
3638                    
3639          ret = poll(ufds, pf - ufds, timeout);          ret = poll(ufds, pf - ufds, timeout);
# Line 3121  void main_loop_wait(int timeout) Line 3642  void main_loop_wait(int timeout)
3642              for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) {              for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) {
3643                  ioh_next = ioh->next;                  ioh_next = ioh->next;
3644                  pf = ioh->ufd;                  pf = ioh->ufd;
3645                  if (pf) {                  if (pf->revents & POLLIN) {
3646                      if (pf->revents & POLLIN) {                      ioh->fd_read(ioh->opaque);
3647                          if (ioh->max_size == 0) {                  }
3648                              /* just a read event */                  if (pf->revents & POLLOUT) {
3649                              ioh->fd_read(ioh->opaque, NULL, 0);                      ioh->fd_write(ioh->opaque);
                         } else {  
                             n = read(ioh->fd, buf, ioh->max_size);  
                             if (n >= 0) {  
                                 ioh->fd_read(ioh->opaque, buf, n);  
                             } else if (errno != EAGAIN) {  
                                 ioh->fd_read(ioh->opaque, NULL, -errno);  
                             }  
                         }  
                     }  
3650                  }                  }
3651              }              }
3652          }          }
# Line 3251  void help(void) Line 3763  void help(void)
3763  #endif  #endif
3764             "\n"             "\n"
3765             "Network options:\n"             "Network options:\n"
3766             "-nics n         simulate 'n' network cards [default=1]\n"             "-net nic[,vlan=n][,macaddr=addr]\n"
3767             "-macaddr addr   set the mac address of the first interface\n"             "                create a new Network Interface Card and connect it to VLAN 'n'\n"
3768             "-n script       set tap/tun network init script [default=%s]\n"  #ifdef CONFIG_SLIRP
3769             "-tun-fd fd      use this fd as already opened tap/tun interface\n"             "-net user[,vlan=n]\n"
3770               "                connect the user mode network stack to VLAN 'n'\n"
3771    #endif
3772    #ifndef _WIN32
3773               "-net tap[,vlan=n][,fd=h][,ifname=name][,script=file]\n"
3774               "                connect the host TAP network interface to VLAN 'n' and use\n"
3775               "                the network script 'file' (default=%s);\n"
3776               "                use 'fd=h' to connect to an already opened TAP interface\n"
3777               "-net socket[,vlan=n][,fd=x][,listen=[host]:port][,connect=host:port]\n"
3778               "                connect the vlan 'n' to another VLAN using a socket connection\n"
3779    #endif
3780               "-net none       use it alone to have zero network devices; if no -net option\n"
3781               "                is provided, the default is '-net nic -net user'\n"
3782               "\n"
3783  #ifdef CONFIG_SLIRP  #ifdef CONFIG_SLIRP
3784             "-user-net       use user mode network stack [default if no tap/tun script]\n"             "-tftp prefix    allow tftp access to files starting with prefix [-net user]\n"
            "-tftp prefix    allow tftp access to files starting with prefix [-user-net]\n"  
3785  #ifndef _WIN32  #ifndef _WIN32
3786             "-smb dir        allow SMB access to files in 'dir' [-user-net]\n"             "-smb dir        allow SMB access to files in 'dir' [-net user]\n"
3787  #endif  #endif
3788             "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n"             "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n"
3789             "                redirect TCP or UDP connections from host to guest [-user-net]\n"             "                redirect TCP or UDP connections from host to guest [-net user]\n"
3790  #endif  #endif
            "-dummy-net      use dummy network stack\n"  
3791             "\n"             "\n"
3792             "Linux boot specific:\n"             "Linux boot specific:\n"
3793             "-kernel bzImage use 'bzImage' as kernel image\n"             "-kernel bzImage use 'bzImage' as kernel image\n"
# Line 3308  void help(void) Line 3831  void help(void)
3831             "qemu-fast",             "qemu-fast",
3832  #endif  #endif
3833             DEFAULT_RAM_SIZE,             DEFAULT_RAM_SIZE,
3834    #ifndef _WIN32
3835             DEFAULT_NETWORK_SCRIPT,             DEFAULT_NETWORK_SCRIPT,
3836    #endif
3837             DEFAULT_GDBSTUB_PORT,             DEFAULT_GDBSTUB_PORT,
3838             "/tmp/qemu.log");             "/tmp/qemu.log");
3839  #ifndef CONFIG_SOFTMMU  #ifndef CONFIG_SOFTMMU
# Line 3343  enum { Line 3868  enum {
3868      QEMU_OPTION_soundhw,      QEMU_OPTION_soundhw,
3869  #endif  #endif
3870    
3871      QEMU_OPTION_nics,      QEMU_OPTION_net,
     QEMU_OPTION_macaddr,  
     QEMU_OPTION_n,  
     QEMU_OPTION_tun_fd,  
     QEMU_OPTION_user_net,  
3872      QEMU_OPTION_tftp,      QEMU_OPTION_tftp,
3873      QEMU_OPTION_smb,      QEMU_OPTION_smb,
3874      QEMU_OPTION_redir,      QEMU_OPTION_redir,
     QEMU_OPTION_dummy_net,  
3875    
3876      QEMU_OPTION_kernel,      QEMU_OPTION_kernel,
3877      QEMU_OPTION_append,      QEMU_OPTION_append,
# Line 3409  const QEMUOption qemu_options[] = { Line 3929  const QEMUOption qemu_options[] = {
3929      { "soundhw", HAS_ARG, QEMU_OPTION_soundhw },      { "soundhw", HAS_ARG, QEMU_OPTION_soundhw },
3930  #endif  #endif
3931    
3932      { "nics", HAS_ARG, QEMU_OPTION_nics},      { "net", HAS_ARG, QEMU_OPTION_net},
     { "macaddr", HAS_ARG, QEMU_OPTION_macaddr},  
     { "n", HAS_ARG, QEMU_OPTION_n },  
     { "tun-fd", HAS_ARG, QEMU_OPTION_tun_fd },  
3933  #ifdef CONFIG_SLIRP  #ifdef CONFIG_SLIRP
     { "user-net", 0, QEMU_OPTION_user_net },  
3934      { "tftp", HAS_ARG, QEMU_OPTION_tftp },      { "tftp", HAS_ARG, QEMU_OPTION_tftp },
3935  #ifndef _WIN32  #ifndef _WIN32
3936      { "smb", HAS_ARG, QEMU_OPTION_smb },      { "smb", HAS_ARG, QEMU_OPTION_smb },
3937  #endif  #endif
3938      { "redir", HAS_ARG, QEMU_OPTION_redir },      { "redir", HAS_ARG, QEMU_OPTION_redir },
3939  #endif  #endif
     { "dummy-net", 0, QEMU_OPTION_dummy_net },  
3940    
3941      { "kernel", HAS_ARG, QEMU_OPTION_kernel },      { "kernel", HAS_ARG, QEMU_OPTION_kernel },
3942      { "append", HAS_ARG, QEMU_OPTION_append },      { "append", HAS_ARG, QEMU_OPTION_append },
# Line 3596  static void select_soundhw (const char * Line 4111  static void select_soundhw (const char *
4111  }  }
4112  #endif  #endif
4113    
4114  #define NET_IF_TUN   0  #define MAX_NET_CLIENTS 32
 #define NET_IF_USER  1  
 #define NET_IF_DUMMY 2  
4115    
4116  int main(int argc, char **argv)  int main(int argc, char **argv)
4117  {  {
# Line 3614  int main(int argc, char **argv) Line 4127  int main(int argc, char **argv)
4127      DisplayState *ds = &display_state;      DisplayState *ds = &display_state;
4128      int cyls, heads, secs, translation;      int cyls, heads, secs, translation;
4129      int start_emulation = 1;      int start_emulation = 1;
4130      uint8_t macaddr[6];      char net_clients[MAX_NET_CLIENTS][256];
4131      int net_if_type, nb_tun_fds, tun_fds[MAX_NICS];      int nb_net_clients;
4132      int optind;      int optind;
4133      const char *r, *optarg;      const char *r, *optarg;
4134      CharDriverState *monitor_hd;      CharDriverState *monitor_hd;
# Line 3644  int main(int argc, char **argv) Line 4157  int main(int argc, char **argv)
4157      ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;      ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
4158      vga_ram_size = VGA_RAM_SIZE;      vga_ram_size = VGA_RAM_SIZE;
4159      bios_size = BIOS_SIZE;      bios_size = BIOS_SIZE;
     pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT);  
4160  #ifdef CONFIG_GDBSTUB  #ifdef CONFIG_GDBSTUB
4161      use_gdbstub = 0;      use_gdbstub = 0;
4162      gdbstub_port = DEFAULT_GDBSTUB_PORT;      gdbstub_port = DEFAULT_GDBSTUB_PORT;
# Line 3674  int main(int argc, char **argv) Line 4186  int main(int argc, char **argv)
4186            
4187      usb_devices_index = 0;      usb_devices_index = 0;
4188            
4189      nb_tun_fds = 0;      nb_net_clients = 0;
4190      net_if_type = -1;  
4191      nb_nics = 1;      nb_nics = 0;
4192      /* default mac address of the first network interface */      /* default mac address of the first network interface */
     macaddr[0] = 0x52;  
     macaddr[1] = 0x54;  
     macaddr[2] = 0x00;  
     macaddr[3] = 0x12;  
     macaddr[4] = 0x34;  
     macaddr[5] = 0x56;  
4193            
4194      optind = 1;      optind = 1;
4195      for(;;) {      for(;;) {
# Line 3797  int main(int argc, char **argv) Line 4303  int main(int argc, char **argv)
4303              case QEMU_OPTION_append:              case QEMU_OPTION_append:
4304                  kernel_cmdline = optarg;                  kernel_cmdline = optarg;
4305                  break;                  break;
             case QEMU_OPTION_tun_fd:  
                 {  
                     const char *p;  
                     int fd;  
                     net_if_type = NET_IF_TUN;  
                     if (nb_tun_fds < MAX_NICS) {  
                         fd = strtol(optarg, (char **)&p, 0);  
                         if (*p != '\0') {  
                             fprintf(stderr, "qemu: invalid fd for network interface %d\n", nb_tun_fds);  
                             exit(1);  
                         }  
                         tun_fds[nb_tun_fds++] = fd;  
                     }  
                 }  
                 break;  
4306              case QEMU_OPTION_cdrom:              case QEMU_OPTION_cdrom:
4307                  if (cdrom_index >= 0) {                  if (cdrom_index >= 0) {
4308                      hd_filename[cdrom_index] = optarg;                      hd_filename[cdrom_index] = optarg;
# Line 3838  int main(int argc, char **argv) Line 4329  int main(int argc, char **argv)
4329              case QEMU_OPTION_no_code_copy:              case QEMU_OPTION_no_code_copy:
4330                  code_copy_enabled = 0;                  code_copy_enabled = 0;
4331                  break;                  break;
4332              case QEMU_OPTION_nics:              case QEMU_OPTION_net:
4333                  nb_nics = atoi(optarg);                  if (nb_net_clients >= MAX_NET_CLIENTS) {
4334                  if (nb_nics < 0 || nb_nics > MAX_NICS) {                      fprintf(stderr, "qemu: too many network clients\n");
                     fprintf(stderr, "qemu: invalid number of network interfaces\n");  
4335                      exit(1);                      exit(1);
4336                  }                  }
4337                  break;                  pstrcpy(net_clients[nb_net_clients],
4338              case QEMU_OPTION_macaddr:                          sizeof(net_clients[0]),
4339                  {                          optarg);
4340                      const char *p;                  nb_net_clients++;
                     int i;  
                     p = optarg;  
                     for(i = 0; i < 6; i++) {  
                         macaddr[i] = strtol(p, (char **)&p, 16);  
                         if (i == 5) {  
                             if (*p != '\0')  
                                 goto macaddr_error;  
                         } else {  
                             if (*p != ':') {  
                             macaddr_error:  
                                 fprintf(stderr, "qemu: invalid syntax for ethernet address\n");  
                                 exit(1);  
                             }  
                             p++;  
                         }  
                     }  
                 }  
4341                  break;                  break;
4342  #ifdef CONFIG_SLIRP  #ifdef CONFIG_SLIRP
4343              case QEMU_OPTION_tftp:              case QEMU_OPTION_tftp:
# Line 3875  int main(int argc, char **argv) Line 4348  int main(int argc, char **argv)
4348                  net_slirp_smb(optarg);                  net_slirp_smb(optarg);
4349                  break;                  break;
4350  #endif  #endif
             case QEMU_OPTION_user_net:  
                 net_if_type = NET_IF_USER;  
                 break;  
4351              case QEMU_OPTION_redir:              case QEMU_OPTION_redir:
4352                  net_slirp_redir(optarg);                                  net_slirp_redir(optarg);                
4353                  break;                  break;
4354  #endif  #endif
             case QEMU_OPTION_dummy_net:  
                 net_if_type = NET_IF_DUMMY;  
                 break;  
4355  #ifdef HAS_AUDIO  #ifdef HAS_AUDIO
4356              case QEMU_OPTION_enable_audio:              case QEMU_OPTION_enable_audio:
4357                  audio_enabled = 1;                  audio_enabled = 1;
# Line 3930  int main(int argc, char **argv) Line 4397  int main(int argc, char **argv)
4397                      cpu_set_log(mask);                      cpu_set_log(mask);
4398                  }                  }
4399                  break;                  break;
             case QEMU_OPTION_n:  
                 pstrcpy(network_script, sizeof(network_script), optarg);  
                 break;  
4400  #ifdef CONFIG_GDBSTUB  #ifdef CONFIG_GDBSTUB
4401              case QEMU_OPTION_s:              case QEMU_OPTION_s:
4402                  use_gdbstub = 1;                  use_gdbstub = 1;
# Line 4076  int main(int argc, char **argv) Line 4540  int main(int argc, char **argv)
4540  #else  #else
4541      setvbuf(stdout, NULL, _IOLBF, 0);      setvbuf(stdout, NULL, _IOLBF, 0);
4542  #endif  #endif
4543        
4544      /* init host network redirectors */      /* init network clients */
4545      if (net_if_type == -1) {      if (nb_net_clients == 0) {
4546          net_if_type = NET_IF_TUN;          /* if no clients, we use a default config */
4547  #if defined(CONFIG_SLIRP)          pstrcpy(net_clients[0], sizeof(net_clients[0]),
4548          if (access(network_script, R_OK) < 0) {                  "nic");
4549              net_if_type = NET_IF_USER;          pstrcpy(net_clients[1], sizeof(net_clients[0]),
4550          }                  "user");
4551  #endif          nb_net_clients = 2;
4552      }      }
4553    
4554      for(i = 0; i < nb_nics; i++) {      for(i = 0;i < nb_net_clients; i++) {
4555          NetDriverState *nd = &nd_table[i];          if (net_client_init(net_clients[i]) < 0)
4556          nd->index = i;              exit(1);
         /* init virtual mac address */  
         nd->macaddr[0] = macaddr[0];  
         nd->macaddr[1] = macaddr[1];  
         nd->macaddr[2] = macaddr[2];  
         nd->macaddr[3] = macaddr[3];  
         nd->macaddr[4] = macaddr[4];  
         nd->macaddr[5] = macaddr[5] + i;  
         switch(net_if_type) {  
 #if defined(CONFIG_SLIRP)  
         case NET_IF_USER:  
             net_slirp_init(nd);  
             break;  
 #endif  
 #if !defined(_WIN32)  
         case NET_IF_TUN:  
             if (i < nb_tun_fds) {  
                 net_fd_init(nd, tun_fds[i]);  
             } else {  
                 if (net_tun_init(nd) < 0)  
                     net_dummy_init(nd);  
             }  
             break;  
 #endif  
         case NET_IF_DUMMY:  
         default:  
             net_dummy_init(nd);  
             break;  
         }  
4557      }      }
4558    
4559      /* init the memory */      /* init the memory */

Legend:
Removed from v.1.145  
changed lines
  Added in v.1.146

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26