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 |