Revision c20709aa

b/configure
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 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 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
b/vl.c
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 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 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 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 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 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 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 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 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 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 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 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 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 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 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
                }
b/vl.h
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 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

  

Also available in: Unified diff