Commit c20709aa32045c79e21905c4c009aae53d008af5

Authored by bellard
1 parent 92cb7d54

initial user mode network support


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@730 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 3 changed files with 266 additions and 84 deletions
configure
... ... @@ -71,6 +71,7 @@ bigendian="no"
71 71 mingw32="no"
72 72 EXESUF=""
73 73 gdbstub="yes"
  74 +slirp="no"
74 75  
75 76 # OS specific
76 77 targetos=`uname -s`
... ... @@ -124,6 +125,8 @@ for opt do
124 125 ;;
125 126 --enable-mingw32) mingw32="yes" ; cross_prefix="i386-mingw32-"
126 127 ;;
  128 + --enable-slirp) slirp="yes"
  129 + ;;
127 130 esac
128 131 done
129 132  
... ... @@ -378,6 +381,10 @@ if test "$sdl" = "yes" ; then
378 381 fi
379 382 echo "" >> $config_mak
380 383 fi
  384 +if test "$slirp" = "yes" ; then
  385 + echo "CONFIG_SLIRP=yes" >> $config_mak
  386 + echo "#define CONFIG_SLIRP 1" >> $config_h
  387 +fi
381 388 echo -n "VERSION=" >>$config_mak
382 389 head $source_path/VERSION >>$config_mak
383 390 echo "" >>$config_mak
... ...
... ... @@ -45,6 +45,10 @@
45 45 #include <linux/if_tun.h>
46 46 #endif
47 47  
  48 +#if defined(CONFIG_SLIRP)
  49 +#include "libslirp.h"
  50 +#endif
  51 +
48 52 #ifdef _WIN32
49 53 #include <sys/timeb.h>
50 54 #include <windows.h>
... ... @@ -750,20 +754,121 @@ int serial_open_device(void)
750 754 #endif
751 755  
752 756 /***********************************************************/
753   -/* Linux network device redirector */
  757 +/* Linux network device redirectors */
754 758  
755   -#ifdef _WIN32
  759 +void hex_dump(FILE *f, const uint8_t *buf, int size)
  760 +{
  761 + int len, i, j, c;
  762 +
  763 + for(i=0;i<size;i+=16) {
  764 + len = size - i;
  765 + if (len > 16)
  766 + len = 16;
  767 + fprintf(f, "%08x ", i);
  768 + for(j=0;j<16;j++) {
  769 + if (j < len)
  770 + fprintf(f, " %02x", buf[i+j]);
  771 + else
  772 + fprintf(f, " ");
  773 + }
  774 + fprintf(f, " ");
  775 + for(j=0;j<len;j++) {
  776 + c = buf[i+j];
  777 + if (c < ' ' || c > '~')
  778 + c = '.';
  779 + fprintf(f, "%c", c);
  780 + }
  781 + fprintf(f, "\n");
  782 + }
  783 +}
  784 +
  785 +void qemu_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
  786 +{
  787 + nd->send_packet(nd, buf, size);
  788 +}
756 789  
757   -static int net_init(void)
  790 +void qemu_add_read_packet(NetDriverState *nd, IOCanRWHandler *fd_can_read,
  791 + IOReadHandler *fd_read, void *opaque)
758 792 {
  793 + nd->add_read_packet(nd, fd_can_read, fd_read, opaque);
  794 +}
  795 +
  796 +/* dummy network adapter */
  797 +
  798 +static void dummy_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
  799 +{
  800 +}
  801 +
  802 +static void dummy_add_read_packet(NetDriverState *nd,
  803 + IOCanRWHandler *fd_can_read,
  804 + IOReadHandler *fd_read, void *opaque)
  805 +{
  806 +}
  807 +
  808 +static int net_dummy_init(NetDriverState *nd)
  809 +{
  810 + nd->send_packet = dummy_send_packet;
  811 + nd->add_read_packet = dummy_add_read_packet;
  812 + pstrcpy(nd->ifname, sizeof(nd->ifname), "dummy");
759 813 return 0;
760 814 }
761 815  
762   -void net_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
  816 +#if defined(CONFIG_SLIRP)
  817 +
  818 +/* slirp network adapter */
  819 +
  820 +static void *slirp_fd_opaque;
  821 +static IOCanRWHandler *slirp_fd_can_read;
  822 +static IOReadHandler *slirp_fd_read;
  823 +static int slirp_inited;
  824 +
  825 +int slirp_can_output(void)
  826 +{
  827 + return slirp_fd_can_read(slirp_fd_opaque);
  828 +}
  829 +
  830 +void slirp_output(const uint8_t *pkt, int pkt_len)
763 831 {
  832 +#if 0
  833 + printf("output:\n");
  834 + hex_dump(stdout, pkt, pkt_len);
  835 +#endif
  836 + slirp_fd_read(slirp_fd_opaque, pkt, pkt_len);
764 837 }
765 838  
766   -#else
  839 +static void slirp_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
  840 +{
  841 +#if 0
  842 + printf("input:\n");
  843 + hex_dump(stdout, buf, size);
  844 +#endif
  845 + slirp_input(buf, size);
  846 +}
  847 +
  848 +static void slirp_add_read_packet(NetDriverState *nd,
  849 + IOCanRWHandler *fd_can_read,
  850 + IOReadHandler *fd_read, void *opaque)
  851 +{
  852 + slirp_fd_opaque = opaque;
  853 + slirp_fd_can_read = fd_can_read;
  854 + slirp_fd_read = fd_read;
  855 +}
  856 +
  857 +static int net_slirp_init(NetDriverState *nd)
  858 +{
  859 + if (!slirp_inited) {
  860 + slirp_inited = 1;
  861 + slirp_init();
  862 + }
  863 + nd->send_packet = slirp_send_packet;
  864 + nd->add_read_packet = slirp_add_read_packet;
  865 + pstrcpy(nd->ifname, sizeof(nd->ifname), "slirp");
  866 + return 0;
  867 +}
  868 +
  869 +#endif /* CONFIG_SLIRP */
  870 +
  871 +#if !defined(_WIN32)
767 872  
768 873 static int tun_open(char *ifname, int ifname_size)
769 874 {
... ... @@ -790,60 +895,61 @@ static int tun_open(char *ifname, int ifname_size)
790 895 return fd;
791 896 }
792 897  
793   -static int net_init(void)
  898 +static void tun_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
  899 +{
  900 + write(nd->fd, buf, size);
  901 +}
  902 +
  903 +static void tun_add_read_packet(NetDriverState *nd,
  904 + IOCanRWHandler *fd_can_read,
  905 + IOReadHandler *fd_read, void *opaque)
794 906 {
795   - int pid, status, launch_script, i;
796   - NetDriverState *nd;
797   - char *args[MAX_NICS + 2];
  907 + qemu_add_fd_read_handler(nd->fd, fd_can_read, fd_read, opaque);
  908 +}
  909 +
  910 +static int net_tun_init(NetDriverState *nd)
  911 +{
  912 + int pid, status;
  913 + char *args[3];
798 914 char **parg;
799 915  
800   - launch_script = 0;
801   - for(i = 0; i < nb_nics; i++) {
802   - nd = &nd_table[i];
803   - if (nd->fd < 0) {
804   - nd->fd = tun_open(nd->ifname, sizeof(nd->ifname));
805   - if (nd->fd >= 0)
806   - launch_script = 1;
807   - }
808   - }
  916 + nd->fd = tun_open(nd->ifname, sizeof(nd->ifname));
  917 + if (nd->fd < 0)
  918 + return -1;
809 919  
810   - if (launch_script) {
811   - /* try to launch network init script */
812   - pid = fork();
813   - if (pid >= 0) {
814   - if (pid == 0) {
815   - parg = args;
816   - *parg++ = network_script;
817   - for(i = 0; i < nb_nics; i++) {
818   - nd = &nd_table[i];
819   - if (nd->fd >= 0) {
820   - *parg++ = nd->ifname;
821   - }
822   - }
823   - *parg++ = NULL;
824   - execv(network_script, args);
825   - exit(1);
826   - }
827   - while (waitpid(pid, &status, 0) != pid);
828   - if (!WIFEXITED(status) ||
829   - WEXITSTATUS(status) != 0) {
830   - fprintf(stderr, "%s: could not launch network script\n",
831   - network_script);
832   - }
  920 + /* try to launch network init script */
  921 + pid = fork();
  922 + if (pid >= 0) {
  923 + if (pid == 0) {
  924 + parg = args;
  925 + *parg++ = network_script;
  926 + *parg++ = nd->ifname;
  927 + *parg++ = NULL;
  928 + execv(network_script, args);
  929 + exit(1);
  930 + }
  931 + while (waitpid(pid, &status, 0) != pid);
  932 + if (!WIFEXITED(status) ||
  933 + WEXITSTATUS(status) != 0) {
  934 + fprintf(stderr, "%s: could not launch network script\n",
  935 + network_script);
833 936 }
834 937 }
  938 + nd->send_packet = tun_send_packet;
  939 + nd->add_read_packet = tun_add_read_packet;
835 940 return 0;
836 941 }
837 942  
838   -void net_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
  943 +static int net_fd_init(NetDriverState *nd, int fd)
839 944 {
840   -#ifdef DEBUG_NE2000
841   - printf("NE2000: sending packet size=%d\n", size);
842   -#endif
843   - write(nd->fd, buf, size);
  945 + nd->fd = fd;
  946 + nd->send_packet = tun_send_packet;
  947 + nd->add_read_packet = tun_add_read_packet;
  948 + pstrcpy(nd->ifname, sizeof(nd->ifname), "tunfd");
  949 + return 0;
844 950 }
845 951  
846   -#endif
  952 +#endif /* !_WIN32 */
847 953  
848 954 /***********************************************************/
849 955 /* dumb display */
... ... @@ -1597,6 +1703,28 @@ int main_loop(void)
1597 1703 }
1598 1704 }
1599 1705 }
  1706 +
  1707 +#if defined(CONFIG_SLIRP)
  1708 + /* XXX: merge with poll() */
  1709 + if (slirp_inited) {
  1710 + fd_set rfds, wfds, xfds;
  1711 + int nfds;
  1712 + struct timeval tv;
  1713 +
  1714 + nfds = -1;
  1715 + FD_ZERO(&rfds);
  1716 + FD_ZERO(&wfds);
  1717 + FD_ZERO(&xfds);
  1718 + slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
  1719 + tv.tv_sec = 0;
  1720 + tv.tv_usec = 0;
  1721 + ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
  1722 + if (ret >= 0) {
  1723 + slirp_select_poll(&rfds, &wfds, &xfds);
  1724 + }
  1725 + }
  1726 +#endif
  1727 +
1600 1728 #endif
1601 1729  
1602 1730 if (vm_running) {
... ... @@ -1636,10 +1764,14 @@ void help(void)
1636 1764 "-nographic disable graphical output and redirect serial I/Os to console\n"
1637 1765 "\n"
1638 1766 "Network options:\n"
1639   - "-n script set network init script [default=%s]\n"
1640   - "-nics n simulate 'n' network interfaces [default=1]\n"
  1767 + "-nics n simulate 'n' network cards [default=1]\n"
1641 1768 "-macaddr addr set the mac address of the first interface\n"
1642   - "-tun-fd fd0[,...] use these fds as already opened tap/tun interfaces\n"
  1769 + "-n script set tap/tun network init script [default=%s]\n"
  1770 + "-tun-fd fd use this fd as already opened tap/tun interface\n"
  1771 +#ifdef CONFIG_SLIRP
  1772 + "-user-net use user mode network stack [default if no tap/tun script]\n"
  1773 +#endif
  1774 + "-dummy-net use dummy network stack\n"
1643 1775 "\n"
1644 1776 "Linux boot specific:\n"
1645 1777 "-kernel bzImage use 'bzImage' as kernel image\n"
... ... @@ -1695,6 +1827,8 @@ struct option long_options[] = {
1695 1827 { "no-code-copy", 0, NULL, 0 },
1696 1828 { "nics", 1, NULL, 0 },
1697 1829 { "macaddr", 1, NULL, 0 },
  1830 + { "user-net", 1, NULL, 0 },
  1831 + { "dummy-net", 1, NULL, 0 },
1698 1832 { NULL, 0, NULL, 0 },
1699 1833 };
1700 1834  
... ... @@ -1707,6 +1841,10 @@ static uint8_t *signal_stack;
1707 1841  
1708 1842 #endif
1709 1843  
  1844 +#define NET_IF_TUN 0
  1845 +#define NET_IF_USER 1
  1846 +#define NET_IF_DUMMY 2
  1847 +
1710 1848 int main(int argc, char **argv)
1711 1849 {
1712 1850 #ifdef CONFIG_GDBSTUB
... ... @@ -1722,7 +1860,8 @@ int main(int argc, char **argv)
1722 1860 int cyls, heads, secs;
1723 1861 int start_emulation = 1;
1724 1862 uint8_t macaddr[6];
1725   -
  1863 + int net_if_type, nb_tun_fds, tun_fds[MAX_NICS];
  1864 +
1726 1865 #if !defined(CONFIG_SOFTMMU)
1727 1866 /* we never want that malloc() uses mmap() */
1728 1867 mallopt(M_MMAP_THRESHOLD, 4096 * 1024);
... ... @@ -1746,6 +1885,8 @@ int main(int argc, char **argv)
1746 1885 has_cdrom = 1;
1747 1886 cyls = heads = secs = 0;
1748 1887  
  1888 + nb_tun_fds = 0;
  1889 + net_if_type = -1;
1749 1890 nb_nics = 1;
1750 1891 /* default mac address of the first network interface */
1751 1892 macaddr[0] = 0x52;
... ... @@ -1754,10 +1895,8 @@ int main(int argc, char **argv)
1754 1895 macaddr[3] = 0x12;
1755 1896 macaddr[4] = 0x34;
1756 1897 macaddr[5] = 0x56;
1757   -
1758   - for(i = 0; i < MAX_NICS; i++)
1759   - nd_table[i].fd = -1;
1760   -
  1898 +
  1899 +
1761 1900 for(;;) {
1762 1901 c = getopt_long_only(argc, argv, "hm:d:n:sp:L:S", long_options, &long_index);
1763 1902 if (c == -1)
... ... @@ -1809,23 +1948,13 @@ int main(int argc, char **argv)
1809 1948 {
1810 1949 const char *p;
1811 1950 int fd;
1812   - p = optarg;
1813   - nb_nics = 0;
1814   - for(;;) {
1815   - fd = strtol(p, (char **)&p, 0);
1816   - nd_table[nb_nics].fd = fd;
1817   - snprintf(nd_table[nb_nics].ifname,
1818   - sizeof(nd_table[nb_nics].ifname),
1819   - "fd%d", nb_nics);
1820   - nb_nics++;
1821   - if (*p == ',') {
1822   - p++;
1823   - } else if (*p != '\0') {
1824   - fprintf(stderr, "qemu: invalid fd for network interface %d\n", nb_nics);
  1951 + if (nb_tun_fds < MAX_NICS) {
  1952 + fd = strtol(optarg, (char **)&p, 0);
  1953 + if (*p != '\0') {
  1954 + fprintf(stderr, "qemu: invalid fd for network interface %d\n", nb_tun_fds);
1825 1955 exit(1);
1826   - } else {
1827   - break;
1828 1956 }
  1957 + tun_fds[nb_tun_fds++] = fd;
1829 1958 }
1830 1959 }
1831 1960 break;
... ... @@ -1885,6 +2014,12 @@ int main(int argc, char **argv)
1885 2014 }
1886 2015 }
1887 2016 break;
  2017 + case 18:
  2018 + net_if_type = NET_IF_USER;
  2019 + break;
  2020 + case 19:
  2021 + net_if_type = NET_IF_DUMMY;
  2022 + break;
1888 2023 }
1889 2024 break;
1890 2025 case 'h':
... ... @@ -1965,8 +2100,18 @@ int main(int argc, char **argv)
1965 2100 #endif
1966 2101  
1967 2102 /* init host network redirectors */
1968   - for(i = 0; i < MAX_NICS; i++) {
  2103 + if (net_if_type == -1) {
  2104 + net_if_type = NET_IF_TUN;
  2105 +#if defined(CONFIG_SLIRP)
  2106 + if (access(network_script, R_OK) < 0) {
  2107 + net_if_type = NET_IF_USER;
  2108 + }
  2109 +#endif
  2110 + }
  2111 +
  2112 + for(i = 0; i < nb_nics; i++) {
1969 2113 NetDriverState *nd = &nd_table[i];
  2114 + nd->index = i;
1970 2115 /* init virtual mac address */
1971 2116 nd->macaddr[0] = macaddr[0];
1972 2117 nd->macaddr[1] = macaddr[1];
... ... @@ -1974,8 +2119,27 @@ int main(int argc, char **argv)
1974 2119 nd->macaddr[3] = macaddr[3];
1975 2120 nd->macaddr[4] = macaddr[4];
1976 2121 nd->macaddr[5] = macaddr[5] + i;
  2122 + switch(net_if_type) {
  2123 +#if defined(CONFIG_SLIRP)
  2124 + case NET_IF_USER:
  2125 + net_slirp_init(nd);
  2126 + break;
  2127 +#endif
  2128 +#if !defined(_WIN32)
  2129 + case NET_IF_TUN:
  2130 + if (i < nb_tun_fds) {
  2131 + net_fd_init(nd, tun_fds[i]);
  2132 + } else {
  2133 + net_tun_init(nd);
  2134 + }
  2135 + break;
  2136 +#endif
  2137 + case NET_IF_DUMMY:
  2138 + default:
  2139 + net_dummy_init(nd);
  2140 + break;
  2141 + }
1977 2142 }
1978   - net_init();
1979 2143  
1980 2144 /* init the memory */
1981 2145 phys_ram_size = ram_size + vga_ram_size;
... ... @@ -2058,7 +2222,7 @@ int main(int argc, char **argv)
2058 2222 }
2059 2223 if (fd_filename[i] != '\0') {
2060 2224 if (bdrv_open(fd_table[i], fd_filename[i], snapshot) < 0) {
2061   - fprintf(stderr, "qemu: could not open floppy disk image '%s\n",
  2225 + fprintf(stderr, "qemu: could not open floppy disk image '%s'\n",
2062 2226 fd_filename[i]);
2063 2227 exit(1);
2064 2228 }
... ...
... ... @@ -132,29 +132,39 @@ void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque);
132 132 void vm_start(void);
133 133 void vm_stop(int reason);
134 134  
  135 +/* async I/O support */
  136 +
  137 +typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size);
  138 +typedef int IOCanRWHandler(void *opaque);
  139 +
  140 +int qemu_add_fd_read_handler(int fd, IOCanRWHandler *fd_can_read,
  141 + IOReadHandler *fd_read, void *opaque);
  142 +void qemu_del_fd_read_handler(int fd);
  143 +
135 144 /* network redirectors support */
136 145  
137 146 #define MAX_NICS 8
138 147  
139 148 typedef struct NetDriverState {
140   - int fd;
  149 + int index; /* index number in QEMU */
141 150 uint8_t macaddr[6];
142 151 char ifname[16];
  152 + void (*send_packet)(struct NetDriverState *nd,
  153 + const uint8_t *buf, int size);
  154 + void (*add_read_packet)(struct NetDriverState *nd,
  155 + IOCanRWHandler *fd_can_read,
  156 + IOReadHandler *fd_read, void *opaque);
  157 + /* tun specific data */
  158 + int fd;
  159 + /* slirp specific data */
143 160 } NetDriverState;
144 161  
145 162 extern int nb_nics;
146 163 extern NetDriverState nd_table[MAX_NICS];
147 164  
148   -void net_send_packet(NetDriverState *nd, const uint8_t *buf, int size);
149   -
150   -/* async I/O support */
151   -
152   -typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size);
153   -typedef int IOCanRWHandler(void *opaque);
154   -
155   -int qemu_add_fd_read_handler(int fd, IOCanRWHandler *fd_can_read,
156   - IOReadHandler *fd_read, void *opaque);
157   -void qemu_del_fd_read_handler(int fd);
  165 +void qemu_send_packet(NetDriverState *nd, const uint8_t *buf, int size);
  166 +void qemu_add_read_packet(NetDriverState *nd, IOCanRWHandler *fd_can_read,
  167 + IOReadHandler *fd_read, void *opaque);
158 168  
159 169 /* timers */
160 170  
... ... @@ -417,6 +427,7 @@ void serial_receive_break(SerialState *s);
417 427 void pic_set_irq(int irq, int level);
418 428 void pic_init(void);
419 429 uint32_t pic_intack_read(CPUState *env);
  430 +void pic_info(void);
420 431  
421 432 /* i8254.c */
422 433  
... ...