Commit c20709aa32045c79e21905c4c009aae53d008af5
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,6 +71,7 @@ bigendian="no" | ||
| 71 | mingw32="no" | 71 | mingw32="no" |
| 72 | EXESUF="" | 72 | EXESUF="" |
| 73 | gdbstub="yes" | 73 | gdbstub="yes" |
| 74 | +slirp="no" | ||
| 74 | 75 | ||
| 75 | # OS specific | 76 | # OS specific |
| 76 | targetos=`uname -s` | 77 | targetos=`uname -s` |
| @@ -124,6 +125,8 @@ for opt do | @@ -124,6 +125,8 @@ for opt do | ||
| 124 | ;; | 125 | ;; |
| 125 | --enable-mingw32) mingw32="yes" ; cross_prefix="i386-mingw32-" | 126 | --enable-mingw32) mingw32="yes" ; cross_prefix="i386-mingw32-" |
| 126 | ;; | 127 | ;; |
| 128 | + --enable-slirp) slirp="yes" | ||
| 129 | + ;; | ||
| 127 | esac | 130 | esac |
| 128 | done | 131 | done |
| 129 | 132 | ||
| @@ -378,6 +381,10 @@ if test "$sdl" = "yes" ; then | @@ -378,6 +381,10 @@ if test "$sdl" = "yes" ; then | ||
| 378 | fi | 381 | fi |
| 379 | echo "" >> $config_mak | 382 | echo "" >> $config_mak |
| 380 | fi | 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 | echo -n "VERSION=" >>$config_mak | 388 | echo -n "VERSION=" >>$config_mak |
| 382 | head $source_path/VERSION >>$config_mak | 389 | head $source_path/VERSION >>$config_mak |
| 383 | echo "" >>$config_mak | 390 | echo "" >>$config_mak |
vl.c
| @@ -45,6 +45,10 @@ | @@ -45,6 +45,10 @@ | ||
| 45 | #include <linux/if_tun.h> | 45 | #include <linux/if_tun.h> |
| 46 | #endif | 46 | #endif |
| 47 | 47 | ||
| 48 | +#if defined(CONFIG_SLIRP) | ||
| 49 | +#include "libslirp.h" | ||
| 50 | +#endif | ||
| 51 | + | ||
| 48 | #ifdef _WIN32 | 52 | #ifdef _WIN32 |
| 49 | #include <sys/timeb.h> | 53 | #include <sys/timeb.h> |
| 50 | #include <windows.h> | 54 | #include <windows.h> |
| @@ -750,20 +754,121 @@ int serial_open_device(void) | @@ -750,20 +754,121 @@ int serial_open_device(void) | ||
| 750 | #endif | 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 | return 0; | 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 | static int tun_open(char *ifname, int ifname_size) | 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,60 +895,61 @@ static int tun_open(char *ifname, int ifname_size) | ||
| 790 | return fd; | 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 | char **parg; | 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 | return 0; | 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 | /* dumb display */ | 955 | /* dumb display */ |
| @@ -1597,6 +1703,28 @@ int main_loop(void) | @@ -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 | #endif | 1728 | #endif |
| 1601 | 1729 | ||
| 1602 | if (vm_running) { | 1730 | if (vm_running) { |
| @@ -1636,10 +1764,14 @@ void help(void) | @@ -1636,10 +1764,14 @@ void help(void) | ||
| 1636 | "-nographic disable graphical output and redirect serial I/Os to console\n" | 1764 | "-nographic disable graphical output and redirect serial I/Os to console\n" |
| 1637 | "\n" | 1765 | "\n" |
| 1638 | "Network options:\n" | 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 | "-macaddr addr set the mac address of the first interface\n" | 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 | "\n" | 1775 | "\n" |
| 1644 | "Linux boot specific:\n" | 1776 | "Linux boot specific:\n" |
| 1645 | "-kernel bzImage use 'bzImage' as kernel image\n" | 1777 | "-kernel bzImage use 'bzImage' as kernel image\n" |
| @@ -1695,6 +1827,8 @@ struct option long_options[] = { | @@ -1695,6 +1827,8 @@ struct option long_options[] = { | ||
| 1695 | { "no-code-copy", 0, NULL, 0 }, | 1827 | { "no-code-copy", 0, NULL, 0 }, |
| 1696 | { "nics", 1, NULL, 0 }, | 1828 | { "nics", 1, NULL, 0 }, |
| 1697 | { "macaddr", 1, NULL, 0 }, | 1829 | { "macaddr", 1, NULL, 0 }, |
| 1830 | + { "user-net", 1, NULL, 0 }, | ||
| 1831 | + { "dummy-net", 1, NULL, 0 }, | ||
| 1698 | { NULL, 0, NULL, 0 }, | 1832 | { NULL, 0, NULL, 0 }, |
| 1699 | }; | 1833 | }; |
| 1700 | 1834 | ||
| @@ -1707,6 +1841,10 @@ static uint8_t *signal_stack; | @@ -1707,6 +1841,10 @@ static uint8_t *signal_stack; | ||
| 1707 | 1841 | ||
| 1708 | #endif | 1842 | #endif |
| 1709 | 1843 | ||
| 1844 | +#define NET_IF_TUN 0 | ||
| 1845 | +#define NET_IF_USER 1 | ||
| 1846 | +#define NET_IF_DUMMY 2 | ||
| 1847 | + | ||
| 1710 | int main(int argc, char **argv) | 1848 | int main(int argc, char **argv) |
| 1711 | { | 1849 | { |
| 1712 | #ifdef CONFIG_GDBSTUB | 1850 | #ifdef CONFIG_GDBSTUB |
| @@ -1722,7 +1860,8 @@ int main(int argc, char **argv) | @@ -1722,7 +1860,8 @@ int main(int argc, char **argv) | ||
| 1722 | int cyls, heads, secs; | 1860 | int cyls, heads, secs; |
| 1723 | int start_emulation = 1; | 1861 | int start_emulation = 1; |
| 1724 | uint8_t macaddr[6]; | 1862 | uint8_t macaddr[6]; |
| 1725 | - | 1863 | + int net_if_type, nb_tun_fds, tun_fds[MAX_NICS]; |
| 1864 | + | ||
| 1726 | #if !defined(CONFIG_SOFTMMU) | 1865 | #if !defined(CONFIG_SOFTMMU) |
| 1727 | /* we never want that malloc() uses mmap() */ | 1866 | /* we never want that malloc() uses mmap() */ |
| 1728 | mallopt(M_MMAP_THRESHOLD, 4096 * 1024); | 1867 | mallopt(M_MMAP_THRESHOLD, 4096 * 1024); |
| @@ -1746,6 +1885,8 @@ int main(int argc, char **argv) | @@ -1746,6 +1885,8 @@ int main(int argc, char **argv) | ||
| 1746 | has_cdrom = 1; | 1885 | has_cdrom = 1; |
| 1747 | cyls = heads = secs = 0; | 1886 | cyls = heads = secs = 0; |
| 1748 | 1887 | ||
| 1888 | + nb_tun_fds = 0; | ||
| 1889 | + net_if_type = -1; | ||
| 1749 | nb_nics = 1; | 1890 | nb_nics = 1; |
| 1750 | /* default mac address of the first network interface */ | 1891 | /* default mac address of the first network interface */ |
| 1751 | macaddr[0] = 0x52; | 1892 | macaddr[0] = 0x52; |
| @@ -1754,10 +1895,8 @@ int main(int argc, char **argv) | @@ -1754,10 +1895,8 @@ int main(int argc, char **argv) | ||
| 1754 | macaddr[3] = 0x12; | 1895 | macaddr[3] = 0x12; |
| 1755 | macaddr[4] = 0x34; | 1896 | macaddr[4] = 0x34; |
| 1756 | macaddr[5] = 0x56; | 1897 | macaddr[5] = 0x56; |
| 1757 | - | ||
| 1758 | - for(i = 0; i < MAX_NICS; i++) | ||
| 1759 | - nd_table[i].fd = -1; | ||
| 1760 | - | 1898 | + |
| 1899 | + | ||
| 1761 | for(;;) { | 1900 | for(;;) { |
| 1762 | c = getopt_long_only(argc, argv, "hm:d:n:sp:L:S", long_options, &long_index); | 1901 | c = getopt_long_only(argc, argv, "hm:d:n:sp:L:S", long_options, &long_index); |
| 1763 | if (c == -1) | 1902 | if (c == -1) |
| @@ -1809,23 +1948,13 @@ int main(int argc, char **argv) | @@ -1809,23 +1948,13 @@ int main(int argc, char **argv) | ||
| 1809 | { | 1948 | { |
| 1810 | const char *p; | 1949 | const char *p; |
| 1811 | int fd; | 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 | exit(1); | 1955 | exit(1); |
| 1826 | - } else { | ||
| 1827 | - break; | ||
| 1828 | } | 1956 | } |
| 1957 | + tun_fds[nb_tun_fds++] = fd; | ||
| 1829 | } | 1958 | } |
| 1830 | } | 1959 | } |
| 1831 | break; | 1960 | break; |
| @@ -1885,6 +2014,12 @@ int main(int argc, char **argv) | @@ -1885,6 +2014,12 @@ int main(int argc, char **argv) | ||
| 1885 | } | 2014 | } |
| 1886 | } | 2015 | } |
| 1887 | break; | 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 | break; | 2024 | break; |
| 1890 | case 'h': | 2025 | case 'h': |
| @@ -1965,8 +2100,18 @@ int main(int argc, char **argv) | @@ -1965,8 +2100,18 @@ int main(int argc, char **argv) | ||
| 1965 | #endif | 2100 | #endif |
| 1966 | 2101 | ||
| 1967 | /* init host network redirectors */ | 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 | NetDriverState *nd = &nd_table[i]; | 2113 | NetDriverState *nd = &nd_table[i]; |
| 2114 | + nd->index = i; | ||
| 1970 | /* init virtual mac address */ | 2115 | /* init virtual mac address */ |
| 1971 | nd->macaddr[0] = macaddr[0]; | 2116 | nd->macaddr[0] = macaddr[0]; |
| 1972 | nd->macaddr[1] = macaddr[1]; | 2117 | nd->macaddr[1] = macaddr[1]; |
| @@ -1974,8 +2119,27 @@ int main(int argc, char **argv) | @@ -1974,8 +2119,27 @@ int main(int argc, char **argv) | ||
| 1974 | nd->macaddr[3] = macaddr[3]; | 2119 | nd->macaddr[3] = macaddr[3]; |
| 1975 | nd->macaddr[4] = macaddr[4]; | 2120 | nd->macaddr[4] = macaddr[4]; |
| 1976 | nd->macaddr[5] = macaddr[5] + i; | 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 | /* init the memory */ | 2144 | /* init the memory */ |
| 1981 | phys_ram_size = ram_size + vga_ram_size; | 2145 | phys_ram_size = ram_size + vga_ram_size; |
| @@ -2058,7 +2222,7 @@ int main(int argc, char **argv) | @@ -2058,7 +2222,7 @@ int main(int argc, char **argv) | ||
| 2058 | } | 2222 | } |
| 2059 | if (fd_filename[i] != '\0') { | 2223 | if (fd_filename[i] != '\0') { |
| 2060 | if (bdrv_open(fd_table[i], fd_filename[i], snapshot) < 0) { | 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 | fd_filename[i]); | 2226 | fd_filename[i]); |
| 2063 | exit(1); | 2227 | exit(1); |
| 2064 | } | 2228 | } |
vl.h
| @@ -132,29 +132,39 @@ void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque); | @@ -132,29 +132,39 @@ void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque); | ||
| 132 | void vm_start(void); | 132 | void vm_start(void); |
| 133 | void vm_stop(int reason); | 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 | /* network redirectors support */ | 144 | /* network redirectors support */ |
| 136 | 145 | ||
| 137 | #define MAX_NICS 8 | 146 | #define MAX_NICS 8 |
| 138 | 147 | ||
| 139 | typedef struct NetDriverState { | 148 | typedef struct NetDriverState { |
| 140 | - int fd; | 149 | + int index; /* index number in QEMU */ |
| 141 | uint8_t macaddr[6]; | 150 | uint8_t macaddr[6]; |
| 142 | char ifname[16]; | 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 | } NetDriverState; | 160 | } NetDriverState; |
| 144 | 161 | ||
| 145 | extern int nb_nics; | 162 | extern int nb_nics; |
| 146 | extern NetDriverState nd_table[MAX_NICS]; | 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 | /* timers */ | 169 | /* timers */ |
| 160 | 170 | ||
| @@ -417,6 +427,7 @@ void serial_receive_break(SerialState *s); | @@ -417,6 +427,7 @@ void serial_receive_break(SerialState *s); | ||
| 417 | void pic_set_irq(int irq, int level); | 427 | void pic_set_irq(int irq, int level); |
| 418 | void pic_init(void); | 428 | void pic_init(void); |
| 419 | uint32_t pic_intack_read(CPUState *env); | 429 | uint32_t pic_intack_read(CPUState *env); |
| 430 | +void pic_info(void); | ||
| 420 | 431 | ||
| 421 | /* i8254.c */ | 432 | /* i8254.c */ |
| 422 | 433 |