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,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
@@ -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 }
@@ -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