Commit 7c9d8e07e188597e570a311efc46cb1ab013e5e7

Authored by bellard
1 parent 868bfe2b

new network emulation


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1622 c046a42c-6fe2-441c-8c8c-71466251a162
gdbstub.c
... ... @@ -704,19 +704,19 @@ void gdb_exit(CPUState *env, int code)
704 704 }
705 705  
706 706 #else
707   -static int gdb_can_read(void *opaque)
708   -{
709   - return 256;
710   -}
711   -
712   -static void gdb_read(void *opaque, const uint8_t *buf, int size)
  707 +static void gdb_read(void *opaque)
713 708 {
714 709 GDBState *s = opaque;
715   - int i;
  710 + int i, size;
  711 + uint8_t buf[4096];
  712 +
  713 + size = read(s->fd, buf, sizeof(buf));
  714 + if (size < 0)
  715 + return;
716 716 if (size == 0) {
717 717 /* end of connection */
718 718 qemu_del_vm_stop_handler(gdb_vm_stopped, s);
719   - qemu_del_fd_read_handler(s->fd);
  719 + qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
720 720 qemu_free(s);
721 721 vm_start();
722 722 } else {
... ... @@ -727,7 +727,7 @@ static void gdb_read(void *opaque, const uint8_t *buf, int size)
727 727  
728 728 #endif
729 729  
730   -static void gdb_accept(void *opaque, const uint8_t *buf, int size)
  730 +static void gdb_accept(void *opaque)
731 731 {
732 732 GDBState *s;
733 733 struct sockaddr_in sockaddr;
... ... @@ -768,7 +768,7 @@ static void gdb_accept(void *opaque, const uint8_t *buf, int size)
768 768 vm_stop(EXCP_INTERRUPT);
769 769  
770 770 /* start handling I/O */
771   - qemu_add_fd_read_handler(s->fd, gdb_can_read, gdb_read, s);
  771 + qemu_set_fd_handler(s->fd, gdb_read, NULL, s);
772 772 /* when the VM is stopped, the following callback is called */
773 773 qemu_add_vm_stop_handler(gdb_vm_stopped, s);
774 774 #endif
... ... @@ -815,9 +815,9 @@ int gdbserver_start(int port)
815 815 return -1;
816 816 /* accept connections */
817 817 #ifdef CONFIG_USER_ONLY
818   - gdb_accept (NULL, NULL, 0);
  818 + gdb_accept (NULL);
819 819 #else
820   - qemu_add_fd_read_handler(gdbserver_fd, NULL, gdb_accept, NULL);
  820 + qemu_set_fd_handler(gdbserver_fd, gdb_accept, NULL, NULL);
821 821 #endif
822 822 return 0;
823 823 }
... ...
hw/lance.c
... ... @@ -154,7 +154,8 @@ struct lance_init_block {
154 154 #define LEDMA_MAXADDR (LEDMA_REGS * 4 - 1)
155 155  
156 156 typedef struct LANCEState {
157   - NetDriverState *nd;
  157 + VLANClientState *vc;
  158 + uint8_t macaddr[6]; /* init mac address */
158 159 uint32_t leptr;
159 160 uint16_t addr;
160 161 uint16_t regs[LE_NREGS];
... ... @@ -169,7 +170,7 @@ static void lance_send(void *opaque);
169 170 static void lance_reset(void *opaque)
170 171 {
171 172 LANCEState *s = opaque;
172   - memcpy(s->phys, s->nd->macaddr, 6);
  173 + memcpy(s->phys, s->macaddr, 6);
173 174 s->rxptr = 0;
174 175 s->txptr = 0;
175 176 memset(s->regs, 0, LE_NREGS * 2);
... ... @@ -280,31 +281,6 @@ static CPUWriteMemoryFunc *lance_mem_write[3] = {
280 281 };
281 282  
282 283  
283   -/* return the max buffer size if the LANCE can receive more data */
284   -static int lance_can_receive(void *opaque)
285   -{
286   - LANCEState *s = opaque;
287   - uint32_t dmaptr = s->leptr + s->ledmaregs[3];
288   - struct lance_init_block *ib;
289   - int i;
290   - uint8_t temp8;
291   -
292   - if ((s->regs[LE_CSR0] & LE_C0_STOP) == LE_C0_STOP)
293   - return 0;
294   -
295   - ib = (void *) iommu_translate(dmaptr);
296   -
297   - for (i = 0; i < RX_RING_SIZE; i++) {
298   - cpu_physical_memory_read((uint32_t)&ib->brx_ring[i].rmd1_bits, (void *) &temp8, 1);
299   - if (temp8 == (LE_R1_OWN)) {
300   - DPRINTF("can receive %d\n", RX_BUFF_SIZE);
301   - return RX_BUFF_SIZE;
302   - }
303   - }
304   - DPRINTF("cannot receive\n");
305   - return 0;
306   -}
307   -
308 284 #define MIN_BUF_SIZE 60
309 285  
310 286 static void lance_receive(void *opaque, const uint8_t *buf, int size)
... ... @@ -368,7 +344,7 @@ static void lance_send(void *opaque)
368 344 temp16 = (~temp16) + 1;
369 345 cpu_physical_memory_read((uint32_t)&ib->tx_buf[i], pkt_buf, temp16);
370 346 DPRINTF("sending packet, len %d\n", temp16);
371   - qemu_send_packet(s->nd, pkt_buf, temp16);
  347 + qemu_send_packet(s->vc, pkt_buf, temp16);
372 348 temp8 = LE_T1_POK;
373 349 cpu_physical_memory_write((uint32_t)&ib->btx_ring[i].tmd1_bits, (void *) &temp8, 1);
374 350 s->txptr = (s->txptr + 1) & TX_RING_MOD_MASK;
... ... @@ -443,7 +419,7 @@ static int lance_load(QEMUFile *f, void *opaque, int version_id)
443 419 return 0;
444 420 }
445 421  
446   -void lance_init(NetDriverState *nd, int irq, uint32_t leaddr, uint32_t ledaddr)
  422 +void lance_init(NICInfo *nd, int irq, uint32_t leaddr, uint32_t ledaddr)
447 423 {
448 424 LANCEState *s;
449 425 int lance_io_memory, ledma_io_memory;
... ... @@ -452,7 +428,6 @@ void lance_init(NetDriverState *nd, int irq, uint32_t leaddr, uint32_t ledaddr)
452 428 if (!s)
453 429 return;
454 430  
455   - s->nd = nd;
456 431 s->irq = irq;
457 432  
458 433 lance_io_memory = cpu_register_io_memory(0, lance_mem_read, lance_mem_write, s);
... ... @@ -461,8 +436,21 @@ void lance_init(NetDriverState *nd, int irq, uint32_t leaddr, uint32_t ledaddr)
461 436 ledma_io_memory = cpu_register_io_memory(0, ledma_mem_read, ledma_mem_write, s);
462 437 cpu_register_physical_memory(ledaddr, 16, ledma_io_memory);
463 438  
  439 + memcpy(s->macaddr, nd->macaddr, 6);
  440 +
464 441 lance_reset(s);
465   - qemu_add_read_packet(nd, lance_can_receive, lance_receive, s);
  442 +
  443 + s->vc = qemu_new_vlan_client(nd->vlan, lance_receive, s);
  444 +
  445 + snprintf(s->vc->info_str, sizeof(s->vc->info_str),
  446 + "lance macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
  447 + s->macaddr[0],
  448 + s->macaddr[1],
  449 + s->macaddr[2],
  450 + s->macaddr[3],
  451 + s->macaddr[4],
  452 + s->macaddr[5]);
  453 +
466 454 register_savevm("lance", leaddr, 1, lance_save, lance_load, s);
467 455 qemu_register_reset(lance_reset, s);
468 456 }
... ...
hw/ne2000.c
... ... @@ -122,6 +122,7 @@ typedef struct NE2000State {
122 122 uint16_t rcnt;
123 123 uint32_t rsar;
124 124 uint8_t rsr;
  125 + uint8_t rxcr;
125 126 uint8_t isr;
126 127 uint8_t dcfg;
127 128 uint8_t imr;
... ... @@ -130,7 +131,8 @@ typedef struct NE2000State {
130 131 uint8_t mult[8]; /* multicast mask array */
131 132 int irq;
132 133 PCIDevice *pci_dev;
133   - NetDriverState *nd;
  134 + VLANClientState *vc;
  135 + uint8_t macaddr[6];
134 136 uint8_t mem[NE2000_MEM_SIZE];
135 137 } NE2000State;
136 138  
... ... @@ -139,7 +141,7 @@ static void ne2000_reset(NE2000State *s)
139 141 int i;
140 142  
141 143 s->isr = ENISR_RESET;
142   - memcpy(s->mem, s->nd->macaddr, 6);
  144 + memcpy(s->mem, s->macaddr, 6);
143 145 s->mem[14] = 0x57;
144 146 s->mem[15] = 0x57;
145 147  
... ... @@ -167,6 +169,30 @@ static void ne2000_update_irq(NE2000State *s)
167 169 }
168 170 }
169 171  
  172 +#define POLYNOMIAL 0x04c11db6
  173 +
  174 +/* From FreeBSD */
  175 +/* XXX: optimize */
  176 +static int compute_mcast_idx(const uint8_t *ep)
  177 +{
  178 + uint32_t crc;
  179 + int carry, i, j;
  180 + uint8_t b;
  181 +
  182 + crc = 0xffffffff;
  183 + for (i = 0; i < 6; i++) {
  184 + b = *ep++;
  185 + for (j = 0; j < 8; j++) {
  186 + carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01);
  187 + crc <<= 1;
  188 + b >>= 1;
  189 + if (carry)
  190 + crc = ((crc ^ POLYNOMIAL) | carry);
  191 + }
  192 + }
  193 + return (crc >> 26);
  194 +}
  195 +
170 196 /* return the max buffer size if the NE2000 can receive more data */
171 197 static int ne2000_can_receive(void *opaque)
172 198 {
... ... @@ -192,13 +218,46 @@ static void ne2000_receive(void *opaque, const uint8_t *buf, int size)
192 218 {
193 219 NE2000State *s = opaque;
194 220 uint8_t *p;
195   - int total_len, next, avail, len, index;
  221 + int total_len, next, avail, len, index, mcast_idx;
196 222 uint8_t buf1[60];
  223 + static const uint8_t broadcast_macaddr[6] =
  224 + { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
197 225  
198 226 #if defined(DEBUG_NE2000)
199 227 printf("NE2000: received len=%d\n", size);
200 228 #endif
201 229  
  230 + if (!ne2000_can_receive(s))
  231 + return;
  232 +
  233 + /* XXX: check this */
  234 + if (s->rxcr & 0x10) {
  235 + /* promiscuous: receive all */
  236 + } else {
  237 + if (!memcmp(buf, broadcast_macaddr, 6)) {
  238 + /* broadcast address */
  239 + if (!(s->rxcr & 0x04))
  240 + return;
  241 + } else if (buf[0] & 0x01) {
  242 + /* multicast */
  243 + if (!(s->rxcr & 0x08))
  244 + return;
  245 + mcast_idx = compute_mcast_idx(buf);
  246 + if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))))
  247 + return;
  248 + } else if (s->mem[0] == buf[0] &&
  249 + s->mem[2] == buf[1] &&
  250 + s->mem[4] == buf[2] &&
  251 + s->mem[6] == buf[3] &&
  252 + s->mem[8] == buf[4] &&
  253 + s->mem[10] == buf[5]) {
  254 + /* match */
  255 + } else {
  256 + return;
  257 + }
  258 + }
  259 +
  260 +
202 261 /* if too small buffer, then expand it */
203 262 if (size < MIN_BUF_SIZE) {
204 263 memcpy(buf1, buf, size);
... ... @@ -273,7 +332,7 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
273 332 index -= NE2000_PMEM_SIZE;
274 333 /* fail safe: check range on the transmitted length */
275 334 if (index + s->tcnt <= NE2000_PMEM_END) {
276   - qemu_send_packet(s->nd, s->mem + index, s->tcnt);
  335 + qemu_send_packet(s->vc, s->mem + index, s->tcnt);
277 336 }
278 337 /* signal end of transfert */
279 338 s->tsr = ENTSR_PTX;
... ... @@ -320,6 +379,9 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
320 379 case EN0_RCNTHI:
321 380 s->rcnt = (s->rcnt & 0x00ff) | (val << 8);
322 381 break;
  382 + case EN0_RXCR:
  383 + s->rxcr = val;
  384 + break;
323 385 case EN0_DCFG:
324 386 s->dcfg = val;
325 387 break;
... ... @@ -608,10 +670,10 @@ static int ne2000_load(QEMUFile* f,void* opaque,int version_id)
608 670 return 0;
609 671 }
610 672  
611   -void isa_ne2000_init(int base, int irq, NetDriverState *nd)
  673 +void isa_ne2000_init(int base, int irq, NICInfo *nd)
612 674 {
613 675 NE2000State *s;
614   -
  676 +
615 677 s = qemu_mallocz(sizeof(NE2000State));
616 678 if (!s)
617 679 return;
... ... @@ -627,14 +689,22 @@ void isa_ne2000_init(int base, int irq, NetDriverState *nd)
627 689 register_ioport_write(base + 0x1f, 1, 1, ne2000_reset_ioport_write, s);
628 690 register_ioport_read(base + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
629 691 s->irq = irq;
630   - s->nd = nd;
  692 + memcpy(s->macaddr, nd->macaddr, 6);
631 693  
632 694 ne2000_reset(s);
633 695  
634   - qemu_add_read_packet(nd, ne2000_can_receive, ne2000_receive, s);
635   -
  696 + s->vc = qemu_new_vlan_client(nd->vlan, ne2000_receive, s);
  697 +
  698 + snprintf(s->vc->info_str, sizeof(s->vc->info_str),
  699 + "ne2000 macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
  700 + s->macaddr[0],
  701 + s->macaddr[1],
  702 + s->macaddr[2],
  703 + s->macaddr[3],
  704 + s->macaddr[4],
  705 + s->macaddr[5]);
  706 +
636 707 register_savevm("ne2000", 0, 1, ne2000_save, ne2000_load, s);
637   -
638 708 }
639 709  
640 710 /***********************************************************/
... ... @@ -665,7 +735,7 @@ static void ne2000_map(PCIDevice *pci_dev, int region_num,
665 735 register_ioport_read(addr + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
666 736 }
667 737  
668   -void pci_ne2000_init(PCIBus *bus, NetDriverState *nd)
  738 +void pci_ne2000_init(PCIBus *bus, NICInfo *nd)
669 739 {
670 740 PCINE2000State *d;
671 741 NE2000State *s;
... ... @@ -690,10 +760,19 @@ void pci_ne2000_init(PCIBus *bus, NetDriverState *nd)
690 760 s = &d->ne2000;
691 761 s->irq = 16; // PCI interrupt
692 762 s->pci_dev = (PCIDevice *)d;
693   - s->nd = nd;
  763 + memcpy(s->macaddr, nd->macaddr, 6);
694 764 ne2000_reset(s);
695   - qemu_add_read_packet(nd, ne2000_can_receive, ne2000_receive, s);
696   -
  765 + s->vc = qemu_new_vlan_client(nd->vlan, ne2000_receive, s);
  766 +
  767 + snprintf(s->vc->info_str, sizeof(s->vc->info_str),
  768 + "ne2000 pci macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
  769 + s->macaddr[0],
  770 + s->macaddr[1],
  771 + s->macaddr[2],
  772 + s->macaddr[3],
  773 + s->macaddr[4],
  774 + s->macaddr[5]);
  775 +
697 776 /* XXX: instance number ? */
698 777 register_savevm("ne2000", 0, 1, ne2000_save, ne2000_load, s);
699 778 register_savevm("ne2000_pci", 0, 1, generic_pci_save, generic_pci_load,
... ...
hw/parallel.c
... ... @@ -154,27 +154,6 @@ static uint32_t parallel_ioport_read(void *opaque, uint32_t addr)
154 154 return ret;
155 155 }
156 156  
157   -static int parallel_can_receive(ParallelState *s)
158   -{
159   - return 0;
160   -}
161   -
162   -static void parallel_receive_byte(ParallelState *s, int ch)
163   -{
164   -}
165   -
166   -static int parallel_can_receive1(void *opaque)
167   -{
168   - ParallelState *s = opaque;
169   - return parallel_can_receive(s);
170   -}
171   -
172   -static void parallel_receive1(void *opaque, const uint8_t *buf, int size)
173   -{
174   - ParallelState *s = opaque;
175   - parallel_receive_byte(s, buf[0]);
176   -}
177   -
178 157 /* If fd is zero, it means that the parallel device uses the console */
179 158 ParallelState *parallel_init(int base, int irq, CharDriverState *chr)
180 159 {
... ... @@ -200,6 +179,5 @@ ParallelState *parallel_init(int base, int irq, CharDriverState *chr)
200 179  
201 180 register_ioport_write(base, 8, 1, parallel_ioport_write, s);
202 181 register_ioport_read(base, 8, 1, parallel_ioport_read, s);
203   - qemu_chr_add_read_handler(chr, parallel_can_receive1, parallel_receive1, s);
204 182 return s;
205 183 }
... ...
monitor.c
... ... @@ -196,23 +196,6 @@ static void do_info_version(void)
196 196 term_printf("%s\n", QEMU_VERSION);
197 197 }
198 198  
199   -static void do_info_network(void)
200   -{
201   - int i, j;
202   - NetDriverState *nd;
203   -
204   - for(i = 0; i < nb_nics; i++) {
205   - nd = &nd_table[i];
206   - term_printf("%d: ifname=%s macaddr=", i, nd->ifname);
207   - for(j = 0; j < 6; j++) {
208   - if (j > 0)
209   - term_printf(":");
210   - term_printf("%02x", nd->macaddr[j]);
211   - }
212   - term_printf("\n");
213   - }
214   -}
215   -
216 199 static void do_info_block(void)
217 200 {
218 201 bdrv_info();
... ...
... ... @@ -40,6 +40,7 @@
40 40 #include <sys/socket.h>
41 41 #include <netinet/in.h>
42 42 #include <dirent.h>
  43 +#include <netdb.h>
43 44 #ifdef _BSD
44 45 #include <sys/stat.h>
45 46 #ifndef __APPLE__
... ... @@ -122,10 +123,9 @@ const char* keyboard_layout = NULL;
122 123 int64_t ticks_per_sec;
123 124 int boot_device = 'c';
124 125 int ram_size;
125   -static char network_script[1024];
126 126 int pit_min_timer_count = 0;
127 127 int nb_nics;
128   -NetDriverState nd_table[MAX_NICS];
  128 +NICInfo nd_table[MAX_NICS];
129 129 QEMUTimer *gui_timer;
130 130 int vm_running;
131 131 #ifdef HAS_AUDIO
... ... @@ -155,6 +155,7 @@ int win2k_install_hack = 0;
155 155 int usb_enabled = 0;
156 156 USBPort *vm_usb_ports[MAX_VM_USB_PORTS];
157 157 USBDevice *vm_usb_hub;
  158 +static VLANState *first_vlan;
158 159  
159 160 /***********************************************************/
160 161 /* x86 ISA bus support */
... ... @@ -1076,10 +1077,10 @@ CharDriverState *qemu_chr_open_null(void)
1076 1077  
1077 1078 typedef struct {
1078 1079 int fd_in, fd_out;
1079   - /* for nographic stdio only */
1080 1080 IOCanRWHandler *fd_can_read;
1081 1081 IOReadHandler *fd_read;
1082 1082 void *fd_opaque;
  1083 + int max_size;
1083 1084 } FDCharDriver;
1084 1085  
1085 1086 #define STDIO_MAX_CLIENTS 2
... ... @@ -1113,6 +1114,33 @@ static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
1113 1114 return unix_write(s->fd_out, buf, len);
1114 1115 }
1115 1116  
  1117 +static int fd_chr_read_poll(void *opaque)
  1118 +{
  1119 + CharDriverState *chr = opaque;
  1120 + FDCharDriver *s = chr->opaque;
  1121 +
  1122 + s->max_size = s->fd_can_read(s->fd_opaque);
  1123 + return s->max_size;
  1124 +}
  1125 +
  1126 +static void fd_chr_read(void *opaque)
  1127 +{
  1128 + CharDriverState *chr = opaque;
  1129 + FDCharDriver *s = chr->opaque;
  1130 + int size, len;
  1131 + uint8_t buf[1024];
  1132 +
  1133 + len = sizeof(buf);
  1134 + if (len > s->max_size)
  1135 + len = s->max_size;
  1136 + if (len == 0)
  1137 + return;
  1138 + size = read(s->fd_in, buf, len);
  1139 + if (size > 0) {
  1140 + s->fd_read(s->fd_opaque, buf, size);
  1141 + }
  1142 +}
  1143 +
1116 1144 static void fd_chr_add_read_handler(CharDriverState *chr,
1117 1145 IOCanRWHandler *fd_can_read,
1118 1146 IOReadHandler *fd_read, void *opaque)
... ... @@ -1120,12 +1148,13 @@ static void fd_chr_add_read_handler(CharDriverState *chr,
1120 1148 FDCharDriver *s = chr->opaque;
1121 1149  
1122 1150 if (s->fd_in >= 0) {
  1151 + s->fd_can_read = fd_can_read;
  1152 + s->fd_read = fd_read;
  1153 + s->fd_opaque = opaque;
1123 1154 if (nographic && s->fd_in == 0) {
1124   - s->fd_can_read = fd_can_read;
1125   - s->fd_read = fd_read;
1126   - s->fd_opaque = opaque;
1127 1155 } else {
1128   - qemu_add_fd_read_handler(s->fd_in, fd_can_read, fd_read, opaque);
  1156 + qemu_set_fd_handler2(s->fd_in, fd_chr_read_poll,
  1157 + fd_chr_read, NULL, chr);
1129 1158 }
1130 1159 }
1131 1160 }
... ... @@ -1261,7 +1290,7 @@ static void stdio_received_byte(int ch)
1261 1290 }
1262 1291 }
1263 1292  
1264   -static int stdio_can_read(void *opaque)
  1293 +static int stdio_read_poll(void *opaque)
1265 1294 {
1266 1295 CharDriverState *chr;
1267 1296 FDCharDriver *s;
... ... @@ -1284,11 +1313,14 @@ static int stdio_can_read(void *opaque)
1284 1313 }
1285 1314 }
1286 1315  
1287   -static void stdio_read(void *opaque, const uint8_t *buf, int size)
  1316 +static void stdio_read(void *opaque)
1288 1317 {
1289   - int i;
1290   - for(i = 0; i < size; i++)
1291   - stdio_received_byte(buf[i]);
  1318 + int size;
  1319 + uint8_t buf[1];
  1320 +
  1321 + size = read(0, buf, 1);
  1322 + if (size > 0)
  1323 + stdio_received_byte(buf[0]);
1292 1324 }
1293 1325  
1294 1326 /* init terminal so that we can grab keys */
... ... @@ -1337,7 +1369,7 @@ CharDriverState *qemu_chr_open_stdio(void)
1337 1369 return NULL;
1338 1370 chr = qemu_chr_open_fd(0, 1);
1339 1371 if (stdio_nb_clients == 0)
1340   - qemu_add_fd_read_handler(0, stdio_can_read, stdio_read, NULL);
  1372 + qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, NULL);
1341 1373 client_index = stdio_nb_clients;
1342 1374 } else {
1343 1375 if (stdio_nb_clients != 0)
... ... @@ -1603,7 +1635,7 @@ CharDriverState *qemu_chr_open(const char *filename)
1603 1635 }
1604 1636  
1605 1637 /***********************************************************/
1606   -/* Linux network device redirectors */
  1638 +/* network device redirectors */
1607 1639  
1608 1640 void hex_dump(FILE *f, const uint8_t *buf, int size)
1609 1641 {
... ... @@ -1631,107 +1663,171 @@ void hex_dump(FILE *f, const uint8_t *buf, int size)
1631 1663 }
1632 1664 }
1633 1665  
1634   -void qemu_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
  1666 +static int parse_macaddr(uint8_t *macaddr, const char *p)
1635 1667 {
1636   - nd->send_packet(nd, buf, size);
  1668 + int i;
  1669 + for(i = 0; i < 6; i++) {
  1670 + macaddr[i] = strtol(p, (char **)&p, 16);
  1671 + if (i == 5) {
  1672 + if (*p != '\0')
  1673 + return -1;
  1674 + } else {
  1675 + if (*p != ':')
  1676 + return -1;
  1677 + p++;
  1678 + }
  1679 + }
  1680 + return 0;
1637 1681 }
1638 1682  
1639   -void qemu_add_read_packet(NetDriverState *nd, IOCanRWHandler *fd_can_read,
1640   - IOReadHandler *fd_read, void *opaque)
  1683 +static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
1641 1684 {
1642   - nd->add_read_packet(nd, fd_can_read, fd_read, opaque);
  1685 + const char *p, *p1;
  1686 + int len;
  1687 + p = *pp;
  1688 + p1 = strchr(p, sep);
  1689 + if (!p1)
  1690 + return -1;
  1691 + len = p1 - p;
  1692 + p1++;
  1693 + if (buf_size > 0) {
  1694 + if (len > buf_size - 1)
  1695 + len = buf_size - 1;
  1696 + memcpy(buf, p, len);
  1697 + buf[len] = '\0';
  1698 + }
  1699 + *pp = p1;
  1700 + return 0;
1643 1701 }
1644 1702  
1645   -/* dummy network adapter */
  1703 +int parse_host_port(struct sockaddr_in *saddr, const char *str)
  1704 +{
  1705 + char buf[512];
  1706 + struct hostent *he;
  1707 + const char *p, *r;
  1708 + int port;
  1709 +
  1710 + p = str;
  1711 + if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
  1712 + return -1;
  1713 + saddr->sin_family = AF_INET;
  1714 + if (buf[0] == '\0') {
  1715 + saddr->sin_addr.s_addr = 0;
  1716 + } else {
  1717 + if (isdigit(buf[0])) {
  1718 + if (!inet_aton(buf, &saddr->sin_addr))
  1719 + return -1;
  1720 + } else {
  1721 +#ifdef _WIN32
  1722 + return -1;
  1723 +#else
  1724 + if ((he = gethostbyname(buf)) == NULL)
  1725 + return - 1;
  1726 + saddr->sin_addr = *(struct in_addr *)he->h_addr;
  1727 +#endif
  1728 + }
  1729 + }
  1730 + port = strtol(p, (char **)&r, 0);
  1731 + if (r == p)
  1732 + return -1;
  1733 + saddr->sin_port = htons(port);
  1734 + return 0;
  1735 +}
1646 1736  
1647   -static void dummy_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
  1737 +/* find or alloc a new VLAN */
  1738 +VLANState *qemu_find_vlan(int id)
1648 1739 {
  1740 + VLANState **pvlan, *vlan;
  1741 + for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
  1742 + if (vlan->id == id)
  1743 + return vlan;
  1744 + }
  1745 + vlan = qemu_mallocz(sizeof(VLANState));
  1746 + if (!vlan)
  1747 + return NULL;
  1748 + vlan->id = id;
  1749 + vlan->next = NULL;
  1750 + pvlan = &first_vlan;
  1751 + while (*pvlan != NULL)
  1752 + pvlan = &(*pvlan)->next;
  1753 + *pvlan = vlan;
  1754 + return vlan;
1649 1755 }
1650 1756  
1651   -static void dummy_add_read_packet(NetDriverState *nd,
1652   - IOCanRWHandler *fd_can_read,
1653   - IOReadHandler *fd_read, void *opaque)
  1757 +VLANClientState *qemu_new_vlan_client(VLANState *vlan,
  1758 + IOReadHandler *fd_read, void *opaque)
1654 1759 {
  1760 + VLANClientState *vc, **pvc;
  1761 + vc = qemu_mallocz(sizeof(VLANClientState));
  1762 + if (!vc)
  1763 + return NULL;
  1764 + vc->fd_read = fd_read;
  1765 + vc->opaque = opaque;
  1766 + vc->vlan = vlan;
  1767 +
  1768 + vc->next = NULL;
  1769 + pvc = &vlan->first_client;
  1770 + while (*pvc != NULL)
  1771 + pvc = &(*pvc)->next;
  1772 + *pvc = vc;
  1773 + return vc;
1655 1774 }
1656 1775  
1657   -static int net_dummy_init(NetDriverState *nd)
  1776 +void qemu_send_packet(VLANClientState *vc1, const uint8_t *buf, int size)
1658 1777 {
1659   - nd->send_packet = dummy_send_packet;
1660   - nd->add_read_packet = dummy_add_read_packet;
1661   - pstrcpy(nd->ifname, sizeof(nd->ifname), "dummy");
1662   - return 0;
  1778 + VLANState *vlan = vc1->vlan;
  1779 + VLANClientState *vc;
  1780 +
  1781 +#if 0
  1782 + printf("vlan %d send:\n", vlan->id);
  1783 + hex_dump(stdout, buf, size);
  1784 +#endif
  1785 + for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
  1786 + if (vc != vc1) {
  1787 + vc->fd_read(vc->opaque, buf, size);
  1788 + }
  1789 + }
1663 1790 }
1664 1791  
1665 1792 #if defined(CONFIG_SLIRP)
1666 1793  
1667 1794 /* slirp network adapter */
1668 1795  
1669   -static void *slirp_fd_opaque;
1670   -static IOCanRWHandler *slirp_fd_can_read;
1671   -static IOReadHandler *slirp_fd_read;
1672 1796 static int slirp_inited;
  1797 +static VLANClientState *slirp_vc;
1673 1798  
1674 1799 int slirp_can_output(void)
1675 1800 {
1676   - return slirp_fd_can_read(slirp_fd_opaque);
  1801 + return 1;
1677 1802 }
1678 1803  
1679 1804 void slirp_output(const uint8_t *pkt, int pkt_len)
1680 1805 {
1681 1806 #if 0
1682   - printf("output:\n");
  1807 + printf("slirp output:\n");
1683 1808 hex_dump(stdout, pkt, pkt_len);
1684 1809 #endif
1685   - slirp_fd_read(slirp_fd_opaque, pkt, pkt_len);
  1810 + qemu_send_packet(slirp_vc, pkt, pkt_len);
1686 1811 }
1687 1812  
1688   -static void slirp_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
  1813 +static void slirp_receive(void *opaque, const uint8_t *buf, int size)
1689 1814 {
1690 1815 #if 0
1691   - printf("input:\n");
  1816 + printf("slirp input:\n");
1692 1817 hex_dump(stdout, buf, size);
1693 1818 #endif
1694 1819 slirp_input(buf, size);
1695 1820 }
1696 1821  
1697   -static void slirp_add_read_packet(NetDriverState *nd,
1698   - IOCanRWHandler *fd_can_read,
1699   - IOReadHandler *fd_read, void *opaque)
1700   -{
1701   - slirp_fd_opaque = opaque;
1702   - slirp_fd_can_read = fd_can_read;
1703   - slirp_fd_read = fd_read;
1704   -}
1705   -
1706   -static int net_slirp_init(NetDriverState *nd)
  1822 +static int net_slirp_init(VLANState *vlan)
1707 1823 {
1708 1824 if (!slirp_inited) {
1709 1825 slirp_inited = 1;
1710 1826 slirp_init();
1711 1827 }
1712   - nd->send_packet = slirp_send_packet;
1713   - nd->add_read_packet = slirp_add_read_packet;
1714   - pstrcpy(nd->ifname, sizeof(nd->ifname), "slirp");
1715   - return 0;
1716   -}
1717   -
1718   -static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
1719   -{
1720   - const char *p, *p1;
1721   - int len;
1722   - p = *pp;
1723   - p1 = strchr(p, sep);
1724   - if (!p1)
1725   - return -1;
1726   - len = p1 - p;
1727   - p1++;
1728   - if (buf_size > 0) {
1729   - if (len > buf_size - 1)
1730   - len = buf_size - 1;
1731   - memcpy(buf, p, len);
1732   - buf[len] = '\0';
1733   - }
1734   - *pp = p1;
  1828 + slirp_vc = qemu_new_vlan_client(vlan,
  1829 + slirp_receive, NULL);
  1830 + snprintf(slirp_vc->info_str, sizeof(slirp_vc->info_str), "user redirector");
1735 1831 return 0;
1736 1832 }
1737 1833  
... ... @@ -1874,8 +1970,55 @@ void net_slirp_smb(const char *exported_dir)
1874 1970 #endif /* CONFIG_SLIRP */
1875 1971  
1876 1972 #if !defined(_WIN32)
  1973 +
  1974 +typedef struct TAPState {
  1975 + VLANClientState *vc;
  1976 + int fd;
  1977 +} TAPState;
  1978 +
  1979 +static void tap_receive(void *opaque, const uint8_t *buf, int size)
  1980 +{
  1981 + TAPState *s = opaque;
  1982 + int ret;
  1983 + for(;;) {
  1984 + ret = write(s->fd, buf, size);
  1985 + if (ret < 0 && (errno == EINTR || errno == EAGAIN)) {
  1986 + } else {
  1987 + break;
  1988 + }
  1989 + }
  1990 +}
  1991 +
  1992 +static void tap_send(void *opaque)
  1993 +{
  1994 + TAPState *s = opaque;
  1995 + uint8_t buf[4096];
  1996 + int size;
  1997 +
  1998 + size = read(s->fd, buf, sizeof(buf));
  1999 + if (size > 0) {
  2000 + qemu_send_packet(s->vc, buf, size);
  2001 + }
  2002 +}
  2003 +
  2004 +/* fd support */
  2005 +
  2006 +static TAPState *net_tap_fd_init(VLANState *vlan, int fd)
  2007 +{
  2008 + TAPState *s;
  2009 +
  2010 + s = qemu_mallocz(sizeof(TAPState));
  2011 + if (!s)
  2012 + return NULL;
  2013 + s->fd = fd;
  2014 + s->vc = qemu_new_vlan_client(vlan, tap_receive, s);
  2015 + qemu_set_fd_handler(s->fd, tap_send, NULL, s);
  2016 + snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: fd=%d", fd);
  2017 + return s;
  2018 +}
  2019 +
1877 2020 #ifdef _BSD
1878   -static int tun_open(char *ifname, int ifname_size)
  2021 +static int tap_open(char *ifname, int ifname_size)
1879 2022 {
1880 2023 int fd;
1881 2024 char *dev;
... ... @@ -1895,7 +2038,7 @@ static int tun_open(char *ifname, int ifname_size)
1895 2038 return fd;
1896 2039 }
1897 2040 #else
1898   -static int tun_open(char *ifname, int ifname_size)
  2041 +static int tap_open(char *ifname, int ifname_size)
1899 2042 {
1900 2043 struct ifreq ifr;
1901 2044 int fd, ret;
... ... @@ -1907,76 +2050,448 @@ static int tun_open(char *ifname, int ifname_size)
1907 2050 }
1908 2051 memset(&ifr, 0, sizeof(ifr));
1909 2052 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
1910   - pstrcpy(ifr.ifr_name, IFNAMSIZ, "tun%d");
  2053 + if (ifname[0] != '\0')
  2054 + pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname);
  2055 + else
  2056 + pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d");
1911 2057 ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
1912 2058 if (ret != 0) {
1913 2059 fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
1914 2060 close(fd);
1915 2061 return -1;
1916 2062 }
1917   - printf("Connected to host network interface: %s\n", ifr.ifr_name);
1918 2063 pstrcpy(ifname, ifname_size, ifr.ifr_name);
1919 2064 fcntl(fd, F_SETFL, O_NONBLOCK);
1920 2065 return fd;
1921 2066 }
1922 2067 #endif
1923 2068  
1924   -static void tun_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
  2069 +static int net_tap_init(VLANState *vlan, const char *ifname1,
  2070 + const char *setup_script)
  2071 +{
  2072 + TAPState *s;
  2073 + int pid, status, fd;
  2074 + char *args[3];
  2075 + char **parg;
  2076 + char ifname[128];
  2077 +
  2078 + if (ifname1 != NULL)
  2079 + pstrcpy(ifname, sizeof(ifname), ifname1);
  2080 + else
  2081 + ifname[0] = '\0';
  2082 + fd = tap_open(ifname, sizeof(ifname));
  2083 + if (fd < 0)
  2084 + return -1;
  2085 +
  2086 + if (!setup_script)
  2087 + setup_script = "";
  2088 + if (setup_script[0] != '\0') {
  2089 + /* try to launch network init script */
  2090 + pid = fork();
  2091 + if (pid >= 0) {
  2092 + if (pid == 0) {
  2093 + parg = args;
  2094 + *parg++ = (char *)setup_script;
  2095 + *parg++ = ifname;
  2096 + *parg++ = NULL;
  2097 + execv(setup_script, args);
  2098 + exit(1);
  2099 + }
  2100 + while (waitpid(pid, &status, 0) != pid);
  2101 + if (!WIFEXITED(status) ||
  2102 + WEXITSTATUS(status) != 0) {
  2103 + fprintf(stderr, "%s: could not launch network script\n",
  2104 + setup_script);
  2105 + return -1;
  2106 + }
  2107 + }
  2108 + }
  2109 + s = net_tap_fd_init(vlan, fd);
  2110 + if (!s)
  2111 + return -1;
  2112 + snprintf(s->vc->info_str, sizeof(s->vc->info_str),
  2113 + "tap: ifname=%s setup_script=%s", ifname, setup_script);
  2114 + return 0;
  2115 +}
  2116 +
  2117 +/* network connection */
  2118 +typedef struct NetSocketState {
  2119 + VLANClientState *vc;
  2120 + int fd;
  2121 + int state; /* 0 = getting length, 1 = getting data */
  2122 + int index;
  2123 + int packet_len;
  2124 + uint8_t buf[4096];
  2125 +} NetSocketState;
  2126 +
  2127 +typedef struct NetSocketListenState {
  2128 + VLANState *vlan;
  2129 + int fd;
  2130 +} NetSocketListenState;
  2131 +
  2132 +/* XXX: we consider we can send the whole packet without blocking */
  2133 +static void net_socket_receive(void *opaque, const uint8_t *buf, int size)
1925 2134 {
1926   - write(nd->fd, buf, size);
  2135 + NetSocketState *s = opaque;
  2136 + uint32_t len;
  2137 + len = htonl(size);
  2138 +
  2139 + unix_write(s->fd, (const uint8_t *)&len, sizeof(len));
  2140 + unix_write(s->fd, buf, size);
1927 2141 }
1928 2142  
1929   -static void tun_add_read_packet(NetDriverState *nd,
1930   - IOCanRWHandler *fd_can_read,
1931   - IOReadHandler *fd_read, void *opaque)
  2143 +static void net_socket_send(void *opaque)
1932 2144 {
1933   - qemu_add_fd_read_handler(nd->fd, fd_can_read, fd_read, opaque);
  2145 + NetSocketState *s = opaque;
  2146 + int l, size;
  2147 + uint8_t buf1[4096];
  2148 + const uint8_t *buf;
  2149 +
  2150 + size = read(s->fd, buf1, sizeof(buf1));
  2151 + if (size < 0)
  2152 + return;
  2153 + if (size == 0) {
  2154 + /* end of connection */
  2155 + qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
  2156 + return;
  2157 + }
  2158 + buf = buf1;
  2159 + while (size > 0) {
  2160 + /* reassemble a packet from the network */
  2161 + switch(s->state) {
  2162 + case 0:
  2163 + l = 4 - s->index;
  2164 + if (l > size)
  2165 + l = size;
  2166 + memcpy(s->buf + s->index, buf, l);
  2167 + buf += l;
  2168 + size -= l;
  2169 + s->index += l;
  2170 + if (s->index == 4) {
  2171 + /* got length */
  2172 + s->packet_len = ntohl(*(uint32_t *)s->buf);
  2173 + s->index = 0;
  2174 + s->state = 1;
  2175 + }
  2176 + break;
  2177 + case 1:
  2178 + l = s->packet_len - s->index;
  2179 + if (l > size)
  2180 + l = size;
  2181 + memcpy(s->buf + s->index, buf, l);
  2182 + s->index += l;
  2183 + buf += l;
  2184 + size -= l;
  2185 + if (s->index >= s->packet_len) {
  2186 + qemu_send_packet(s->vc, s->buf, s->packet_len);
  2187 + s->index = 0;
  2188 + s->state = 0;
  2189 + }
  2190 + break;
  2191 + }
  2192 + }
1934 2193 }
1935 2194  
1936   -static int net_tun_init(NetDriverState *nd)
  2195 +static void net_socket_connect(void *opaque)
1937 2196 {
1938   - int pid, status;
1939   - char *args[3];
1940   - char **parg;
  2197 + NetSocketState *s = opaque;
  2198 + qemu_set_fd_handler(s->fd, net_socket_send, NULL, s);
  2199 +}
1941 2200  
1942   - nd->fd = tun_open(nd->ifname, sizeof(nd->ifname));
1943   - if (nd->fd < 0)
1944   - return -1;
  2201 +static NetSocketState *net_socket_fd_init(VLANState *vlan, int fd,
  2202 + int is_connected)
  2203 +{
  2204 + NetSocketState *s;
  2205 + s = qemu_mallocz(sizeof(NetSocketState));
  2206 + if (!s)
  2207 + return NULL;
  2208 + s->fd = fd;
  2209 + s->vc = qemu_new_vlan_client(vlan,
  2210 + net_socket_receive, s);
  2211 + snprintf(s->vc->info_str, sizeof(s->vc->info_str),
  2212 + "socket: fd=%d", fd);
  2213 + if (is_connected) {
  2214 + net_socket_connect(s);
  2215 + } else {
  2216 + qemu_set_fd_handler(s->fd, NULL, net_socket_connect, s);
  2217 + }
  2218 + return s;
  2219 +}
1945 2220  
1946   - /* try to launch network init script */
1947   - pid = fork();
1948   - if (pid >= 0) {
1949   - if (pid == 0) {
1950   - parg = args;
1951   - *parg++ = network_script;
1952   - *parg++ = nd->ifname;
1953   - *parg++ = NULL;
1954   - execv(network_script, args);
1955   - exit(1);
1956   - }
1957   - while (waitpid(pid, &status, 0) != pid);
1958   - if (!WIFEXITED(status) ||
1959   - WEXITSTATUS(status) != 0) {
1960   - fprintf(stderr, "%s: could not launch network script\n",
1961   - network_script);
  2221 +static void net_socket_accept(void *opaque)
  2222 +{
  2223 + NetSocketListenState *s = opaque;
  2224 + NetSocketState *s1;
  2225 + struct sockaddr_in saddr;
  2226 + socklen_t len;
  2227 + int fd;
  2228 +
  2229 + for(;;) {
  2230 + len = sizeof(saddr);
  2231 + fd = accept(s->fd, (struct sockaddr *)&saddr, &len);
  2232 + if (fd < 0 && errno != EINTR) {
  2233 + return;
  2234 + } else if (fd >= 0) {
  2235 + break;
1962 2236 }
1963 2237 }
1964   - nd->send_packet = tun_send_packet;
1965   - nd->add_read_packet = tun_add_read_packet;
  2238 + s1 = net_socket_fd_init(s->vlan, fd, 1);
  2239 + if (!s1) {
  2240 + close(fd);
  2241 + } else {
  2242 + snprintf(s1->vc->info_str, sizeof(s1->vc->info_str),
  2243 + "socket: connection from %s:%d",
  2244 + inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
  2245 + }
  2246 +}
  2247 +
  2248 +static int net_socket_listen_init(VLANState *vlan, const char *host_str)
  2249 +{
  2250 + NetSocketListenState *s;
  2251 + int fd, val, ret;
  2252 + struct sockaddr_in saddr;
  2253 +
  2254 + if (parse_host_port(&saddr, host_str) < 0)
  2255 + return -1;
  2256 +
  2257 + s = qemu_mallocz(sizeof(NetSocketListenState));
  2258 + if (!s)
  2259 + return -1;
  2260 +
  2261 + fd = socket(PF_INET, SOCK_STREAM, 0);
  2262 + if (fd < 0) {
  2263 + perror("socket");
  2264 + return -1;
  2265 + }
  2266 + fcntl(fd, F_SETFL, O_NONBLOCK);
  2267 +
  2268 + /* allow fast reuse */
  2269 + val = 1;
  2270 + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
  2271 +
  2272 + ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
  2273 + if (ret < 0) {
  2274 + perror("bind");
  2275 + return -1;
  2276 + }
  2277 + ret = listen(fd, 0);
  2278 + if (ret < 0) {
  2279 + perror("listen");
  2280 + return -1;
  2281 + }
  2282 + s->vlan = vlan;
  2283 + s->fd = fd;
  2284 + qemu_set_fd_handler(fd, net_socket_accept, NULL, s);
1966 2285 return 0;
1967 2286 }
1968 2287  
1969   -static int net_fd_init(NetDriverState *nd, int fd)
  2288 +static int net_socket_connect_init(VLANState *vlan, const char *host_str)
1970 2289 {
1971   - nd->fd = fd;
1972   - nd->send_packet = tun_send_packet;
1973   - nd->add_read_packet = tun_add_read_packet;
1974   - pstrcpy(nd->ifname, sizeof(nd->ifname), "tunfd");
  2290 + NetSocketState *s;
  2291 + int fd, connected, ret;
  2292 + struct sockaddr_in saddr;
  2293 +
  2294 + if (parse_host_port(&saddr, host_str) < 0)
  2295 + return -1;
  2296 +
  2297 + fd = socket(PF_INET, SOCK_STREAM, 0);
  2298 + if (fd < 0) {
  2299 + perror("socket");
  2300 + return -1;
  2301 + }
  2302 + fcntl(fd, F_SETFL, O_NONBLOCK);
  2303 +
  2304 + connected = 0;
  2305 + for(;;) {
  2306 + ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
  2307 + if (ret < 0) {
  2308 + if (errno == EINTR || errno == EAGAIN) {
  2309 + } else if (errno == EINPROGRESS) {
  2310 + break;
  2311 + } else {
  2312 + perror("connect");
  2313 + close(fd);
  2314 + return -1;
  2315 + }
  2316 + } else {
  2317 + connected = 1;
  2318 + break;
  2319 + }
  2320 + }
  2321 + s = net_socket_fd_init(vlan, fd, connected);
  2322 + if (!s)
  2323 + return -1;
  2324 + snprintf(s->vc->info_str, sizeof(s->vc->info_str),
  2325 + "socket: connect to %s:%d",
  2326 + inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
1975 2327 return 0;
1976 2328 }
1977 2329  
1978 2330 #endif /* !_WIN32 */
1979 2331  
  2332 +static int get_param_value(char *buf, int buf_size,
  2333 + const char *tag, const char *str)
  2334 +{
  2335 + const char *p;
  2336 + char *q;
  2337 + char option[128];
  2338 +
  2339 + p = str;
  2340 + for(;;) {
  2341 + q = option;
  2342 + while (*p != '\0' && *p != '=') {
  2343 + if ((q - option) < sizeof(option) - 1)
  2344 + *q++ = *p;
  2345 + p++;
  2346 + }
  2347 + *q = '\0';
  2348 + if (*p != '=')
  2349 + break;
  2350 + p++;
  2351 + if (!strcmp(tag, option)) {
  2352 + q = buf;
  2353 + while (*p != '\0' && *p != ',') {
  2354 + if ((q - buf) < buf_size - 1)
  2355 + *q++ = *p;
  2356 + p++;
  2357 + }
  2358 + *q = '\0';
  2359 + return q - buf;
  2360 + } else {
  2361 + while (*p != '\0' && *p != ',') {
  2362 + p++;
  2363 + }
  2364 + }
  2365 + if (*p != ',')
  2366 + break;
  2367 + p++;
  2368 + }
  2369 + return 0;
  2370 +}
  2371 +
  2372 +int net_client_init(const char *str)
  2373 +{
  2374 + const char *p;
  2375 + char *q;
  2376 + char device[64];
  2377 + char buf[1024];
  2378 + int vlan_id, ret;
  2379 + VLANState *vlan;
  2380 +
  2381 + p = str;
  2382 + q = device;
  2383 + while (*p != '\0' && *p != ',') {
  2384 + if ((q - device) < sizeof(device) - 1)
  2385 + *q++ = *p;
  2386 + p++;
  2387 + }
  2388 + *q = '\0';
  2389 + if (*p == ',')
  2390 + p++;
  2391 + vlan_id = 0;
  2392 + if (get_param_value(buf, sizeof(buf), "vlan", p)) {
  2393 + vlan_id = strtol(buf, NULL, 0);
  2394 + }
  2395 + vlan = qemu_find_vlan(vlan_id);
  2396 + if (!vlan) {
  2397 + fprintf(stderr, "Could not create vlan %d\n", vlan_id);
  2398 + return -1;
  2399 + }
  2400 + if (!strcmp(device, "nic")) {
  2401 + NICInfo *nd;
  2402 + uint8_t *macaddr;
  2403 +
  2404 + if (nb_nics >= MAX_NICS) {
  2405 + fprintf(stderr, "Too Many NICs\n");
  2406 + return -1;
  2407 + }
  2408 + nd = &nd_table[nb_nics];
  2409 + macaddr = nd->macaddr;
  2410 + macaddr[0] = 0x52;
  2411 + macaddr[1] = 0x54;
  2412 + macaddr[2] = 0x00;
  2413 + macaddr[3] = 0x12;
  2414 + macaddr[4] = 0x34;
  2415 + macaddr[5] = 0x56 + nb_nics;
  2416 +
  2417 + if (get_param_value(buf, sizeof(buf), "macaddr", p)) {
  2418 + if (parse_macaddr(macaddr, buf) < 0) {
  2419 + fprintf(stderr, "invalid syntax for ethernet address\n");
  2420 + return -1;
  2421 + }
  2422 + }
  2423 + nd->vlan = vlan;
  2424 + nb_nics++;
  2425 + ret = 0;
  2426 + } else
  2427 + if (!strcmp(device, "none")) {
  2428 + /* does nothing. It is needed to signal that no network cards
  2429 + are wanted */
  2430 + ret = 0;
  2431 + } else
  2432 +#ifdef CONFIG_SLIRP
  2433 + if (!strcmp(device, "user")) {
  2434 + ret = net_slirp_init(vlan);
  2435 + } else
  2436 +#endif
  2437 +#ifndef _WIN32
  2438 + if (!strcmp(device, "tap")) {
  2439 + char ifname[64];
  2440 + char setup_script[1024];
  2441 + int fd;
  2442 + if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
  2443 + fd = strtol(buf, NULL, 0);
  2444 + ret = -1;
  2445 + if (net_tap_fd_init(vlan, fd))
  2446 + ret = 0;
  2447 + } else {
  2448 + get_param_value(ifname, sizeof(ifname), "ifname", p);
  2449 + if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) {
  2450 + pstrcpy(setup_script, sizeof(setup_script), DEFAULT_NETWORK_SCRIPT);
  2451 + }
  2452 + ret = net_tap_init(vlan, ifname, setup_script);
  2453 + }
  2454 + } else
  2455 + if (!strcmp(device, "socket")) {
  2456 + if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
  2457 + int fd;
  2458 + fd = strtol(buf, NULL, 0);
  2459 + ret = -1;
  2460 + if (net_socket_fd_init(vlan, fd, 1))
  2461 + ret = 0;
  2462 + } else if (get_param_value(buf, sizeof(buf), "listen", p) > 0) {
  2463 + ret = net_socket_listen_init(vlan, buf);
  2464 + } else if (get_param_value(buf, sizeof(buf), "connect", p) > 0) {
  2465 + ret = net_socket_connect_init(vlan, buf);
  2466 + } else {
  2467 + fprintf(stderr, "Unknown socket options: %s\n", p);
  2468 + return -1;
  2469 + }
  2470 + } else
  2471 +#endif
  2472 + {
  2473 + fprintf(stderr, "Unknown network device: %s\n", device);
  2474 + return -1;
  2475 + }
  2476 + if (ret < 0) {
  2477 + fprintf(stderr, "Could not initialize device '%s'\n", device);
  2478 + }
  2479 +
  2480 + return ret;
  2481 +}
  2482 +
  2483 +void do_info_network(void)
  2484 +{
  2485 + VLANState *vlan;
  2486 + VLANClientState *vc;
  2487 +
  2488 + for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
  2489 + term_printf("VLAN %d devices:\n", vlan->id);
  2490 + for(vc = vlan->first_client; vc != NULL; vc = vc->next)
  2491 + term_printf(" %s\n", vc->info_str);
  2492 + }
  2493 +}
  2494 +
1980 2495 /***********************************************************/
1981 2496 /* USB devices */
1982 2497  
... ... @@ -2175,49 +2690,65 @@ static void host_segv_handler(int host_signum, siginfo_t *info,
2175 2690  
2176 2691 typedef struct IOHandlerRecord {
2177 2692 int fd;
2178   - IOCanRWHandler *fd_can_read;
2179   - IOReadHandler *fd_read;
  2693 + IOCanRWHandler *fd_read_poll;
  2694 + IOHandler *fd_read;
  2695 + IOHandler *fd_write;
2180 2696 void *opaque;
2181 2697 /* temporary data */
2182 2698 struct pollfd *ufd;
2183   - int max_size;
2184 2699 struct IOHandlerRecord *next;
2185 2700 } IOHandlerRecord;
2186 2701  
2187 2702 static IOHandlerRecord *first_io_handler;
2188 2703  
2189   -int qemu_add_fd_read_handler(int fd, IOCanRWHandler *fd_can_read,
2190   - IOReadHandler *fd_read, void *opaque)
  2704 +/* XXX: fd_read_poll should be suppressed, but an API change is
  2705 + necessary in the character devices to suppress fd_can_read(). */
  2706 +int qemu_set_fd_handler2(int fd,
  2707 + IOCanRWHandler *fd_read_poll,
  2708 + IOHandler *fd_read,
  2709 + IOHandler *fd_write,
  2710 + void *opaque)
2191 2711 {
2192   - IOHandlerRecord *ioh;
  2712 + IOHandlerRecord **pioh, *ioh;
2193 2713  
2194   - ioh = qemu_mallocz(sizeof(IOHandlerRecord));
2195   - if (!ioh)
2196   - return -1;
2197   - ioh->fd = fd;
2198   - ioh->fd_can_read = fd_can_read;
2199   - ioh->fd_read = fd_read;
2200   - ioh->opaque = opaque;
2201   - ioh->next = first_io_handler;
2202   - first_io_handler = ioh;
  2714 + if (!fd_read && !fd_write) {
  2715 + pioh = &first_io_handler;
  2716 + for(;;) {
  2717 + ioh = *pioh;
  2718 + if (ioh == NULL)
  2719 + break;
  2720 + if (ioh->fd == fd) {
  2721 + *pioh = ioh->next;
  2722 + break;
  2723 + }
  2724 + pioh = &ioh->next;
  2725 + }
  2726 + } else {
  2727 + for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
  2728 + if (ioh->fd == fd)
  2729 + goto found;
  2730 + }
  2731 + ioh = qemu_mallocz(sizeof(IOHandlerRecord));
  2732 + if (!ioh)
  2733 + return -1;
  2734 + ioh->next = first_io_handler;
  2735 + first_io_handler = ioh;
  2736 + found:
  2737 + ioh->fd = fd;
  2738 + ioh->fd_read_poll = fd_read_poll;
  2739 + ioh->fd_read = fd_read;
  2740 + ioh->fd_write = fd_write;
  2741 + ioh->opaque = opaque;
  2742 + }
2203 2743 return 0;
2204 2744 }
2205 2745  
2206   -void qemu_del_fd_read_handler(int fd)
  2746 +int qemu_set_fd_handler(int fd,
  2747 + IOHandler *fd_read,
  2748 + IOHandler *fd_write,
  2749 + void *opaque)
2207 2750 {
2208   - IOHandlerRecord **pioh, *ioh;
2209   -
2210   - pioh = &first_io_handler;
2211   - for(;;) {
2212   - ioh = *pioh;
2213   - if (ioh == NULL)
2214   - break;
2215   - if (ioh->fd == fd) {
2216   - *pioh = ioh->next;
2217   - break;
2218   - }
2219   - pioh = &ioh->next;
2220   - }
  2751 + return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
2221 2752 }
2222 2753  
2223 2754 /***********************************************************/
... ... @@ -3080,8 +3611,6 @@ void main_loop_wait(int timeout)
3080 3611 #ifndef _WIN32
3081 3612 struct pollfd ufds[MAX_IO_HANDLERS + 1], *pf;
3082 3613 IOHandlerRecord *ioh, *ioh_next;
3083   - uint8_t buf[4096];
3084   - int n, max_size;
3085 3614 #endif
3086 3615 int ret;
3087 3616  
... ... @@ -3093,26 +3622,18 @@ void main_loop_wait(int timeout)
3093 3622 /* XXX: separate device handlers from system ones */
3094 3623 pf = ufds;
3095 3624 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
3096   - if (!ioh->fd_can_read) {
3097   - max_size = 0;
3098   - pf->fd = ioh->fd;
3099   - pf->events = POLLIN;
3100   - ioh->ufd = pf;
3101   - pf++;
3102   - } else {
3103   - max_size = ioh->fd_can_read(ioh->opaque);
3104   - if (max_size > 0) {
3105   - if (max_size > sizeof(buf))
3106   - max_size = sizeof(buf);
3107   - pf->fd = ioh->fd;
3108   - pf->events = POLLIN;
3109   - ioh->ufd = pf;
3110   - pf++;
3111   - } else {
3112   - ioh->ufd = NULL;
3113   - }
  3625 + pf->events = 0;
  3626 + pf->fd = ioh->fd;
  3627 + if (ioh->fd_read &&
  3628 + (!ioh->fd_read_poll ||
  3629 + ioh->fd_read_poll(ioh->opaque) != 0)) {
  3630 + pf->events |= POLLIN;
  3631 + }
  3632 + if (ioh->fd_write) {
  3633 + pf->events |= POLLOUT;
3114 3634 }
3115   - ioh->max_size = max_size;
  3635 + ioh->ufd = pf;
  3636 + pf++;
3116 3637 }
3117 3638  
3118 3639 ret = poll(ufds, pf - ufds, timeout);
... ... @@ -3121,20 +3642,11 @@ void main_loop_wait(int timeout)
3121 3642 for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) {
3122 3643 ioh_next = ioh->next;
3123 3644 pf = ioh->ufd;
3124   - if (pf) {
3125   - if (pf->revents & POLLIN) {
3126   - if (ioh->max_size == 0) {
3127   - /* just a read event */
3128   - ioh->fd_read(ioh->opaque, NULL, 0);
3129   - } else {
3130   - n = read(ioh->fd, buf, ioh->max_size);
3131   - if (n >= 0) {
3132   - ioh->fd_read(ioh->opaque, buf, n);
3133   - } else if (errno != EAGAIN) {
3134   - ioh->fd_read(ioh->opaque, NULL, -errno);
3135   - }
3136   - }
3137   - }
  3645 + if (pf->revents & POLLIN) {
  3646 + ioh->fd_read(ioh->opaque);
  3647 + }
  3648 + if (pf->revents & POLLOUT) {
  3649 + ioh->fd_write(ioh->opaque);
3138 3650 }
3139 3651 }
3140 3652 }
... ... @@ -3251,20 +3763,31 @@ void help(void)
3251 3763 #endif
3252 3764 "\n"
3253 3765 "Network options:\n"
3254   - "-nics n simulate 'n' network cards [default=1]\n"
3255   - "-macaddr addr set the mac address of the first interface\n"
3256   - "-n script set tap/tun network init script [default=%s]\n"
3257   - "-tun-fd fd use this fd as already opened tap/tun interface\n"
  3766 + "-net nic[,vlan=n][,macaddr=addr]\n"
  3767 + " create a new Network Interface Card and connect it to VLAN 'n'\n"
3258 3768 #ifdef CONFIG_SLIRP
3259   - "-user-net use user mode network stack [default if no tap/tun script]\n"
3260   - "-tftp prefix allow tftp access to files starting with prefix [-user-net]\n"
  3769 + "-net user[,vlan=n]\n"
  3770 + " connect the user mode network stack to VLAN 'n'\n"
  3771 +#endif
3261 3772 #ifndef _WIN32
3262   - "-smb dir allow SMB access to files in 'dir' [-user-net]\n"
  3773 + "-net tap[,vlan=n][,fd=h][,ifname=name][,script=file]\n"
  3774 + " connect the host TAP network interface to VLAN 'n' and use\n"
  3775 + " the network script 'file' (default=%s);\n"
  3776 + " use 'fd=h' to connect to an already opened TAP interface\n"
  3777 + "-net socket[,vlan=n][,fd=x][,listen=[host]:port][,connect=host:port]\n"
  3778 + " connect the vlan 'n' to another VLAN using a socket connection\n"
  3779 +#endif
  3780 + "-net none use it alone to have zero network devices; if no -net option\n"
  3781 + " is provided, the default is '-net nic -net user'\n"
  3782 + "\n"
  3783 +#ifdef CONFIG_SLIRP
  3784 + "-tftp prefix allow tftp access to files starting with prefix [-net user]\n"
  3785 +#ifndef _WIN32
  3786 + "-smb dir allow SMB access to files in 'dir' [-net user]\n"
3263 3787 #endif
3264 3788 "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n"
3265   - " redirect TCP or UDP connections from host to guest [-user-net]\n"
  3789 + " redirect TCP or UDP connections from host to guest [-net user]\n"
3266 3790 #endif
3267   - "-dummy-net use dummy network stack\n"
3268 3791 "\n"
3269 3792 "Linux boot specific:\n"
3270 3793 "-kernel bzImage use 'bzImage' as kernel image\n"
... ... @@ -3308,7 +3831,9 @@ void help(void)
3308 3831 "qemu-fast",
3309 3832 #endif
3310 3833 DEFAULT_RAM_SIZE,
  3834 +#ifndef _WIN32
3311 3835 DEFAULT_NETWORK_SCRIPT,
  3836 +#endif
3312 3837 DEFAULT_GDBSTUB_PORT,
3313 3838 "/tmp/qemu.log");
3314 3839 #ifndef CONFIG_SOFTMMU
... ... @@ -3343,15 +3868,10 @@ enum {
3343 3868 QEMU_OPTION_soundhw,
3344 3869 #endif
3345 3870  
3346   - QEMU_OPTION_nics,
3347   - QEMU_OPTION_macaddr,
3348   - QEMU_OPTION_n,
3349   - QEMU_OPTION_tun_fd,
3350   - QEMU_OPTION_user_net,
  3871 + QEMU_OPTION_net,
3351 3872 QEMU_OPTION_tftp,
3352 3873 QEMU_OPTION_smb,
3353 3874 QEMU_OPTION_redir,
3354   - QEMU_OPTION_dummy_net,
3355 3875  
3356 3876 QEMU_OPTION_kernel,
3357 3877 QEMU_OPTION_append,
... ... @@ -3409,19 +3929,14 @@ const QEMUOption qemu_options[] = {
3409 3929 { "soundhw", HAS_ARG, QEMU_OPTION_soundhw },
3410 3930 #endif
3411 3931  
3412   - { "nics", HAS_ARG, QEMU_OPTION_nics},
3413   - { "macaddr", HAS_ARG, QEMU_OPTION_macaddr},
3414   - { "n", HAS_ARG, QEMU_OPTION_n },
3415   - { "tun-fd", HAS_ARG, QEMU_OPTION_tun_fd },
  3932 + { "net", HAS_ARG, QEMU_OPTION_net},
3416 3933 #ifdef CONFIG_SLIRP
3417   - { "user-net", 0, QEMU_OPTION_user_net },
3418 3934 { "tftp", HAS_ARG, QEMU_OPTION_tftp },
3419 3935 #ifndef _WIN32
3420 3936 { "smb", HAS_ARG, QEMU_OPTION_smb },
3421 3937 #endif
3422 3938 { "redir", HAS_ARG, QEMU_OPTION_redir },
3423 3939 #endif
3424   - { "dummy-net", 0, QEMU_OPTION_dummy_net },
3425 3940  
3426 3941 { "kernel", HAS_ARG, QEMU_OPTION_kernel },
3427 3942 { "append", HAS_ARG, QEMU_OPTION_append },
... ... @@ -3596,9 +4111,7 @@ static void select_soundhw (const char *optarg)
3596 4111 }
3597 4112 #endif
3598 4113  
3599   -#define NET_IF_TUN 0
3600   -#define NET_IF_USER 1
3601   -#define NET_IF_DUMMY 2
  4114 +#define MAX_NET_CLIENTS 32
3602 4115  
3603 4116 int main(int argc, char **argv)
3604 4117 {
... ... @@ -3614,8 +4127,8 @@ int main(int argc, char **argv)
3614 4127 DisplayState *ds = &display_state;
3615 4128 int cyls, heads, secs, translation;
3616 4129 int start_emulation = 1;
3617   - uint8_t macaddr[6];
3618   - int net_if_type, nb_tun_fds, tun_fds[MAX_NICS];
  4130 + char net_clients[MAX_NET_CLIENTS][256];
  4131 + int nb_net_clients;
3619 4132 int optind;
3620 4133 const char *r, *optarg;
3621 4134 CharDriverState *monitor_hd;
... ... @@ -3644,7 +4157,6 @@ int main(int argc, char **argv)
3644 4157 ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
3645 4158 vga_ram_size = VGA_RAM_SIZE;
3646 4159 bios_size = BIOS_SIZE;
3647   - pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT);
3648 4160 #ifdef CONFIG_GDBSTUB
3649 4161 use_gdbstub = 0;
3650 4162 gdbstub_port = DEFAULT_GDBSTUB_PORT;
... ... @@ -3674,16 +4186,10 @@ int main(int argc, char **argv)
3674 4186  
3675 4187 usb_devices_index = 0;
3676 4188  
3677   - nb_tun_fds = 0;
3678   - net_if_type = -1;
3679   - nb_nics = 1;
  4189 + nb_net_clients = 0;
  4190 +
  4191 + nb_nics = 0;
3680 4192 /* default mac address of the first network interface */
3681   - macaddr[0] = 0x52;
3682   - macaddr[1] = 0x54;
3683   - macaddr[2] = 0x00;
3684   - macaddr[3] = 0x12;
3685   - macaddr[4] = 0x34;
3686   - macaddr[5] = 0x56;
3687 4193  
3688 4194 optind = 1;
3689 4195 for(;;) {
... ... @@ -3797,21 +4303,6 @@ int main(int argc, char **argv)
3797 4303 case QEMU_OPTION_append:
3798 4304 kernel_cmdline = optarg;
3799 4305 break;
3800   - case QEMU_OPTION_tun_fd:
3801   - {
3802   - const char *p;
3803   - int fd;
3804   - net_if_type = NET_IF_TUN;
3805   - if (nb_tun_fds < MAX_NICS) {
3806   - fd = strtol(optarg, (char **)&p, 0);
3807   - if (*p != '\0') {
3808   - fprintf(stderr, "qemu: invalid fd for network interface %d\n", nb_tun_fds);
3809   - exit(1);
3810   - }
3811   - tun_fds[nb_tun_fds++] = fd;
3812   - }
3813   - }
3814   - break;
3815 4306 case QEMU_OPTION_cdrom:
3816 4307 if (cdrom_index >= 0) {
3817 4308 hd_filename[cdrom_index] = optarg;
... ... @@ -3838,33 +4329,15 @@ int main(int argc, char **argv)
3838 4329 case QEMU_OPTION_no_code_copy:
3839 4330 code_copy_enabled = 0;
3840 4331 break;
3841   - case QEMU_OPTION_nics:
3842   - nb_nics = atoi(optarg);
3843   - if (nb_nics < 0 || nb_nics > MAX_NICS) {
3844   - fprintf(stderr, "qemu: invalid number of network interfaces\n");
  4332 + case QEMU_OPTION_net:
  4333 + if (nb_net_clients >= MAX_NET_CLIENTS) {
  4334 + fprintf(stderr, "qemu: too many network clients\n");
3845 4335 exit(1);
3846 4336 }
3847   - break;
3848   - case QEMU_OPTION_macaddr:
3849   - {
3850   - const char *p;
3851   - int i;
3852   - p = optarg;
3853   - for(i = 0; i < 6; i++) {
3854   - macaddr[i] = strtol(p, (char **)&p, 16);
3855   - if (i == 5) {
3856   - if (*p != '\0')
3857   - goto macaddr_error;
3858   - } else {
3859   - if (*p != ':') {
3860   - macaddr_error:
3861   - fprintf(stderr, "qemu: invalid syntax for ethernet address\n");
3862   - exit(1);
3863   - }
3864   - p++;
3865   - }
3866   - }
3867   - }
  4337 + pstrcpy(net_clients[nb_net_clients],
  4338 + sizeof(net_clients[0]),
  4339 + optarg);
  4340 + nb_net_clients++;
3868 4341 break;
3869 4342 #ifdef CONFIG_SLIRP
3870 4343 case QEMU_OPTION_tftp:
... ... @@ -3875,16 +4348,10 @@ int main(int argc, char **argv)
3875 4348 net_slirp_smb(optarg);
3876 4349 break;
3877 4350 #endif
3878   - case QEMU_OPTION_user_net:
3879   - net_if_type = NET_IF_USER;
3880   - break;
3881 4351 case QEMU_OPTION_redir:
3882 4352 net_slirp_redir(optarg);
3883 4353 break;
3884 4354 #endif
3885   - case QEMU_OPTION_dummy_net:
3886   - net_if_type = NET_IF_DUMMY;
3887   - break;
3888 4355 #ifdef HAS_AUDIO
3889 4356 case QEMU_OPTION_enable_audio:
3890 4357 audio_enabled = 1;
... ... @@ -3930,9 +4397,6 @@ int main(int argc, char **argv)
3930 4397 cpu_set_log(mask);
3931 4398 }
3932 4399 break;
3933   - case QEMU_OPTION_n:
3934   - pstrcpy(network_script, sizeof(network_script), optarg);
3935   - break;
3936 4400 #ifdef CONFIG_GDBSTUB
3937 4401 case QEMU_OPTION_s:
3938 4402 use_gdbstub = 1;
... ... @@ -4076,48 +4540,20 @@ int main(int argc, char **argv)
4076 4540 #else
4077 4541 setvbuf(stdout, NULL, _IOLBF, 0);
4078 4542 #endif
4079   -
4080   - /* init host network redirectors */
4081   - if (net_if_type == -1) {
4082   - net_if_type = NET_IF_TUN;
4083   -#if defined(CONFIG_SLIRP)
4084   - if (access(network_script, R_OK) < 0) {
4085   - net_if_type = NET_IF_USER;
4086   - }
4087   -#endif
  4543 +
  4544 + /* init network clients */
  4545 + if (nb_net_clients == 0) {
  4546 + /* if no clients, we use a default config */
  4547 + pstrcpy(net_clients[0], sizeof(net_clients[0]),
  4548 + "nic");
  4549 + pstrcpy(net_clients[1], sizeof(net_clients[0]),
  4550 + "user");
  4551 + nb_net_clients = 2;
4088 4552 }
4089 4553  
4090   - for(i = 0; i < nb_nics; i++) {
4091   - NetDriverState *nd = &nd_table[i];
4092   - nd->index = i;
4093   - /* init virtual mac address */
4094   - nd->macaddr[0] = macaddr[0];
4095   - nd->macaddr[1] = macaddr[1];
4096   - nd->macaddr[2] = macaddr[2];
4097   - nd->macaddr[3] = macaddr[3];
4098   - nd->macaddr[4] = macaddr[4];
4099   - nd->macaddr[5] = macaddr[5] + i;
4100   - switch(net_if_type) {
4101   -#if defined(CONFIG_SLIRP)
4102   - case NET_IF_USER:
4103   - net_slirp_init(nd);
4104   - break;
4105   -#endif
4106   -#if !defined(_WIN32)
4107   - case NET_IF_TUN:
4108   - if (i < nb_tun_fds) {
4109   - net_fd_init(nd, tun_fds[i]);
4110   - } else {
4111   - if (net_tun_init(nd) < 0)
4112   - net_dummy_init(nd);
4113   - }
4114   - break;
4115   -#endif
4116   - case NET_IF_DUMMY:
4117   - default:
4118   - net_dummy_init(nd);
4119   - break;
4120   - }
  4554 + for(i = 0;i < nb_net_clients; i++) {
  4555 + if (net_client_init(net_clients[i]) < 0)
  4556 + exit(1);
4121 4557 }
4122 4558  
4123 4559 /* init the memory */
... ...
... ... @@ -196,10 +196,17 @@ void kbd_put_keysym(int keysym);
196 196  
197 197 typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size);
198 198 typedef int IOCanRWHandler(void *opaque);
  199 +typedef void IOHandler(void *opaque);
199 200  
200   -int qemu_add_fd_read_handler(int fd, IOCanRWHandler *fd_can_read,
201   - IOReadHandler *fd_read, void *opaque);
202   -void qemu_del_fd_read_handler(int fd);
  201 +int qemu_set_fd_handler2(int fd,
  202 + IOCanRWHandler *fd_read_poll,
  203 + IOHandler *fd_read,
  204 + IOHandler *fd_write,
  205 + void *opaque);
  206 +int qemu_set_fd_handler(int fd,
  207 + IOHandler *fd_read,
  208 + IOHandler *fd_write,
  209 + void *opaque);
203 210  
204 211 /* character device */
205 212  
... ... @@ -270,30 +277,42 @@ extern CharDriverState *serial_hds[MAX_SERIAL_PORTS];
270 277  
271 278 extern CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
272 279  
273   -/* network redirectors support */
  280 +/* VLANs support */
  281 +
  282 +typedef struct VLANClientState VLANClientState;
  283 +
  284 +struct VLANClientState {
  285 + IOReadHandler *fd_read;
  286 + void *opaque;
  287 + struct VLANClientState *next;
  288 + struct VLANState *vlan;
  289 + char info_str[256];
  290 +};
  291 +
  292 +typedef struct VLANState {
  293 + int id;
  294 + VLANClientState *first_client;
  295 + struct VLANState *next;
  296 +} VLANState;
  297 +
  298 +VLANState *qemu_find_vlan(int id);
  299 +VLANClientState *qemu_new_vlan_client(VLANState *vlan,
  300 + IOReadHandler *fd_read, void *opaque);
  301 +void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size);
  302 +
  303 +void do_info_network(void);
  304 +
  305 +/* NIC info */
274 306  
275 307 #define MAX_NICS 8
276 308  
277   -typedef struct NetDriverState {
278   - int index; /* index number in QEMU */
  309 +typedef struct NICInfo {
279 310 uint8_t macaddr[6];
280   - char ifname[16];
281   - void (*send_packet)(struct NetDriverState *nd,
282   - const uint8_t *buf, int size);
283   - void (*add_read_packet)(struct NetDriverState *nd,
284   - IOCanRWHandler *fd_can_read,
285   - IOReadHandler *fd_read, void *opaque);
286   - /* tun specific data */
287   - int fd;
288   - /* slirp specific data */
289   -} NetDriverState;
  311 + VLANState *vlan;
  312 +} NICInfo;
290 313  
291 314 extern int nb_nics;
292   -extern NetDriverState nd_table[MAX_NICS];
293   -
294   -void qemu_send_packet(NetDriverState *nd, const uint8_t *buf, int size);
295   -void qemu_add_read_packet(NetDriverState *nd, IOCanRWHandler *fd_can_read,
296   - IOReadHandler *fd_read, void *opaque);
  315 +extern NICInfo nd_table[MAX_NICS];
297 316  
298 317 /* timers */
299 318  
... ... @@ -692,8 +711,8 @@ int fdctrl_get_drive_type(fdctrl_t *fdctrl, int drive_num);
692 711  
693 712 /* ne2000.c */
694 713  
695   -void isa_ne2000_init(int base, int irq, NetDriverState *nd);
696   -void pci_ne2000_init(PCIBus *bus, NetDriverState *nd);
  714 +void isa_ne2000_init(int base, int irq, NICInfo *nd);
  715 +void pci_ne2000_init(PCIBus *bus, NICInfo *nd);
697 716  
698 717 /* pckbd.c */
699 718  
... ... @@ -781,7 +800,7 @@ void *iommu_init(uint32_t addr);
781 800 uint32_t iommu_translate_local(void *opaque, uint32_t addr);
782 801  
783 802 /* lance.c */
784   -void lance_init(NetDriverState *nd, int irq, uint32_t leaddr, uint32_t ledaddr);
  803 +void lance_init(NICInfo *nd, int irq, uint32_t leaddr, uint32_t ledaddr);
785 804  
786 805 /* tcx.c */
787 806 void *tcx_init(DisplayState *ds, uint32_t addr, uint8_t *vram_base,
... ...