clang-format in src/network/

This commit is contained in:
Jasmine Iwanek
2022-09-18 17:18:20 -04:00
parent 4685da3fca
commit 3c76dbbde5
11 changed files with 3768 additions and 4025 deletions

View File

@@ -63,131 +63,124 @@
#include <86box/bswap.h> #include <86box/bswap.h>
typedef struct { typedef struct {
dp8390_t *dp8390; dp8390_t *dp8390;
mem_mapping_t ram_mapping; mem_mapping_t ram_mapping;
uint32_t base_address; uint32_t base_address;
int base_irq; int base_irq;
uint32_t bios_addr; uint32_t bios_addr;
uint8_t maclocal[6]; /* configured MAC (local) address */ uint8_t maclocal[6]; /* configured MAC (local) address */
struct { struct {
uint8_t pstr; uint8_t pstr;
uint8_t pspr; uint8_t pspr;
uint8_t dqtr; uint8_t dqtr;
uint8_t bcfr; uint8_t bcfr;
uint8_t pcfr; uint8_t pcfr;
uint8_t gacfr; uint8_t gacfr;
uint8_t ctrl; uint8_t ctrl;
uint8_t streg; uint8_t streg;
uint8_t idcfr; uint8_t idcfr;
uint16_t da; uint16_t da;
uint32_t vptr; uint32_t vptr;
uint8_t rfmsb; uint8_t rfmsb;
uint8_t rflsb; uint8_t rflsb;
} regs; } regs;
int dma_channel; int dma_channel;
} threec503_t; } threec503_t;
#ifdef ENABLE_3COM503_LOG #ifdef ENABLE_3COM503_LOG
int threec503_do_log = ENABLE_3COM503_LOG; int threec503_do_log = ENABLE_3COM503_LOG;
static void static void
threec503_log(const char *fmt, ...) threec503_log(const char *fmt, ...)
{ {
va_list ap; va_list ap;
if (threec503_do_log) { if (threec503_do_log) {
va_start(ap, fmt); va_start(ap, fmt);
pclog_ex(fmt, ap); pclog_ex(fmt, ap);
va_end(ap); va_end(ap);
} }
} }
#else #else
#define threec503_log(fmt, ...) # define threec503_log(fmt, ...)
#endif #endif
static void static void
threec503_interrupt(void *priv, int set) threec503_interrupt(void *priv, int set)
{ {
threec503_t *dev = (threec503_t *) priv; threec503_t *dev = (threec503_t *) priv;
switch (dev->base_irq) { switch (dev->base_irq) {
case 2: case 2:
dev->regs.idcfr = 0x10; dev->regs.idcfr = 0x10;
break; break;
case 3: case 3:
dev->regs.idcfr = 0x20; dev->regs.idcfr = 0x20;
break; break;
case 4: case 4:
dev->regs.idcfr = 0x40; dev->regs.idcfr = 0x40;
break; break;
case 5: case 5:
dev->regs.idcfr = 0x80; dev->regs.idcfr = 0x80;
break; break;
} }
if (set) if (set)
picint(1 << dev->base_irq); picint(1 << dev->base_irq);
else else
picintc(1 << dev->base_irq); picintc(1 << dev->base_irq);
} }
static void static void
threec503_ram_write(uint32_t addr, uint8_t val, void *priv) threec503_ram_write(uint32_t addr, uint8_t val, void *priv)
{ {
threec503_t *dev = (threec503_t *)priv; threec503_t *dev = (threec503_t *) priv;
if ((addr & 0x3fff) >= 0x2000) if ((addr & 0x3fff) >= 0x2000)
return; return;
dev->dp8390->mem[addr & 0x1fff] = val; dev->dp8390->mem[addr & 0x1fff] = val;
} }
static uint8_t static uint8_t
threec503_ram_read(uint32_t addr, void *priv) threec503_ram_read(uint32_t addr, void *priv)
{ {
threec503_t *dev = (threec503_t *)priv; threec503_t *dev = (threec503_t *) priv;
if ((addr & 0x3fff) >= 0x2000) if ((addr & 0x3fff) >= 0x2000)
return 0xff; return 0xff;
return dev->dp8390->mem[addr & 0x1fff]; return dev->dp8390->mem[addr & 0x1fff];
} }
static void static void
threec503_set_drq(threec503_t *dev) threec503_set_drq(threec503_t *dev)
{ {
switch (dev->dma_channel) { switch (dev->dma_channel) {
case 1: case 1:
dev->regs.idcfr = 1; dev->regs.idcfr = 1;
break; break;
case 2: case 2:
dev->regs.idcfr = 2; dev->regs.idcfr = 2;
break; break;
case 3: case 3:
dev->regs.idcfr = 4; dev->regs.idcfr = 4;
break; break;
} }
} }
/* reset - restore state to power-up, cancelling all i/o */ /* reset - restore state to power-up, cancelling all i/o */
static void static void
threec503_reset(void *priv) threec503_reset(void *priv)
{ {
threec503_t *dev = (threec503_t *)priv; threec503_t *dev = (threec503_t *) priv;
#ifdef ENABLE_3COM503_LOG #ifdef ENABLE_3COM503_LOG
threec503_log("3Com503: reset\n"); threec503_log("3Com503: reset\n");
@@ -200,374 +193,370 @@ threec503_reset(void *priv)
dev->regs.ctrl = 0x0a; dev->regs.ctrl = 0x0a;
} }
static uint8_t static uint8_t
threec503_nic_lo_read(uint16_t addr, void *priv) threec503_nic_lo_read(uint16_t addr, void *priv)
{ {
threec503_t *dev = (threec503_t *)priv; threec503_t *dev = (threec503_t *) priv;
uint8_t retval = 0; uint8_t retval = 0;
int off = addr - dev->base_address; int off = addr - dev->base_address;
switch ((dev->regs.ctrl >> 2) & 3) { switch ((dev->regs.ctrl >> 2) & 3) {
case 0x00: case 0x00:
threec503_log("Read offset=%04x\n", off); threec503_log("Read offset=%04x\n", off);
if (off == 0x00) if (off == 0x00)
retval = dp8390_read_cr(dev->dp8390); retval = dp8390_read_cr(dev->dp8390);
else switch(dev->dp8390->CR.pgsel) { else
case 0x00: switch (dev->dp8390->CR.pgsel) {
retval = dp8390_page0_read(dev->dp8390, off, 1); case 0x00:
break; retval = dp8390_page0_read(dev->dp8390, off, 1);
break;
case 0x01: case 0x01:
retval = dp8390_page1_read(dev->dp8390, off, 1); retval = dp8390_page1_read(dev->dp8390, off, 1);
break; break;
case 0x02: case 0x02:
retval = dp8390_page2_read(dev->dp8390, off, 1); retval = dp8390_page2_read(dev->dp8390, off, 1);
break; break;
case 0x03: case 0x03:
retval = 0xff; retval = 0xff;
break; break;
} }
break; break;
case 0x01: case 0x01:
retval = dev->dp8390->macaddr[off]; retval = dev->dp8390->macaddr[off];
break; break;
case 0x02: case 0x02:
retval = dev->dp8390->macaddr[off + 0x10]; retval = dev->dp8390->macaddr[off + 0x10];
break; break;
case 0x03: case 0x03:
retval = 0xff; retval = 0xff;
break; break;
} }
return(retval); return (retval);
} }
static void static void
threec503_nic_lo_write(uint16_t addr, uint8_t val, void *priv) threec503_nic_lo_write(uint16_t addr, uint8_t val, void *priv)
{ {
threec503_t *dev = (threec503_t *)priv; threec503_t *dev = (threec503_t *) priv;
int off = addr - dev->base_address; int off = addr - dev->base_address;
switch ((dev->regs.ctrl >> 2) & 3) { switch ((dev->regs.ctrl >> 2) & 3) {
case 0x00: case 0x00:
/* The high 16 bytes of i/o space are for the ne2000 asic - /* The high 16 bytes of i/o space are for the ne2000 asic -
the low 16 bytes are for the DS8390, with the current the low 16 bytes are for the DS8390, with the current
page being selected by the PS0,PS1 registers in the page being selected by the PS0,PS1 registers in the
command register */ command register */
if (off == 0x00) if (off == 0x00)
dp8390_write_cr(dev->dp8390, val); dp8390_write_cr(dev->dp8390, val);
else switch(dev->dp8390->CR.pgsel) { else
case 0x00: switch (dev->dp8390->CR.pgsel) {
dp8390_page0_write(dev->dp8390, off, val, 1); case 0x00:
break; dp8390_page0_write(dev->dp8390, off, val, 1);
break;
case 0x01: case 0x01:
dp8390_page1_write(dev->dp8390, off, val, 1); dp8390_page1_write(dev->dp8390, off, val, 1);
break; break;
case 0x02: case 0x02:
dp8390_page2_write(dev->dp8390, off, val, 1); dp8390_page2_write(dev->dp8390, off, val, 1);
break; break;
case 0x03: case 0x03:
break; break;
} }
break; break;
case 0x01: case 0x01:
case 0x02: case 0x02:
case 0x03: case 0x03:
break; break;
} }
threec503_log("3Com503: write addr %x, value %x\n", addr, val); threec503_log("3Com503: write addr %x, value %x\n", addr, val);
} }
static uint8_t static uint8_t
threec503_nic_hi_read(uint16_t addr, void *priv) threec503_nic_hi_read(uint16_t addr, void *priv)
{ {
threec503_t *dev = (threec503_t *)priv; threec503_t *dev = (threec503_t *) priv;
threec503_log("3Com503: Read GA address=%04x\n", addr); threec503_log("3Com503: Read GA address=%04x\n", addr);
switch (addr & 0x0f) { switch (addr & 0x0f) {
case 0x00: case 0x00:
return dev->regs.pstr; return dev->regs.pstr;
case 0x01: case 0x01:
return dev->regs.pspr; return dev->regs.pspr;
case 0x02: case 0x02:
return dev->regs.dqtr; return dev->regs.dqtr;
case 0x03: case 0x03:
switch (dev->base_address) { switch (dev->base_address) {
default: default:
case 0x300: case 0x300:
dev->regs.bcfr = 0x80; dev->regs.bcfr = 0x80;
break; break;
case 0x310: case 0x310:
dev->regs.bcfr = 0x40; dev->regs.bcfr = 0x40;
break; break;
case 0x330: case 0x330:
dev->regs.bcfr = 0x20; dev->regs.bcfr = 0x20;
break; break;
case 0x350: case 0x350:
dev->regs.bcfr = 0x10; dev->regs.bcfr = 0x10;
break; break;
case 0x250: case 0x250:
dev->regs.bcfr = 0x08; dev->regs.bcfr = 0x08;
break; break;
case 0x280: case 0x280:
dev->regs.bcfr = 0x04; dev->regs.bcfr = 0x04;
break; break;
case 0x2a0: case 0x2a0:
dev->regs.bcfr = 0x02; dev->regs.bcfr = 0x02;
break; break;
case 0x2e0: case 0x2e0:
dev->regs.bcfr = 0x01; dev->regs.bcfr = 0x01;
break; break;
} }
return dev->regs.bcfr; return dev->regs.bcfr;
break; break;
case 0x04: case 0x04:
switch (dev->bios_addr) { switch (dev->bios_addr) {
case 0xdc000: case 0xdc000:
dev->regs.pcfr = 0x80; dev->regs.pcfr = 0x80;
break; break;
case 0xd8000: case 0xd8000:
dev->regs.pcfr = 0x40; dev->regs.pcfr = 0x40;
break; break;
case 0xcc000: case 0xcc000:
dev->regs.pcfr = 0x20; dev->regs.pcfr = 0x20;
break; break;
case 0xc8000: case 0xc8000:
dev->regs.pcfr = 0x10; dev->regs.pcfr = 0x10;
break; break;
} }
return dev->regs.pcfr; return dev->regs.pcfr;
break; break;
case 0x05: case 0x05:
return dev->regs.gacfr; return dev->regs.gacfr;
case 0x06: case 0x06:
return dev->regs.ctrl; return dev->regs.ctrl;
case 0x07: case 0x07:
return dev->regs.streg; return dev->regs.streg;
case 0x08: case 0x08:
return dev->regs.idcfr; return dev->regs.idcfr;
case 0x09: case 0x09:
return (dev->regs.da >> 8); return (dev->regs.da >> 8);
case 0x0a: case 0x0a:
return (dev->regs.da & 0xff); return (dev->regs.da & 0xff);
case 0x0b: case 0x0b:
return (dev->regs.vptr >> 12) & 0xff; return (dev->regs.vptr >> 12) & 0xff;
case 0x0c: case 0x0c:
return (dev->regs.vptr >> 4) & 0xff; return (dev->regs.vptr >> 4) & 0xff;
case 0x0d: case 0x0d:
return (dev->regs.vptr & 0x0f) << 4; return (dev->regs.vptr & 0x0f) << 4;
case 0x0e: case 0x0e:
case 0x0f: case 0x0f:
if (!(dev->regs.ctrl & 0x80)) if (!(dev->regs.ctrl & 0x80))
return 0xff; return 0xff;
threec503_set_drq(dev); threec503_set_drq(dev);
return dp8390_chipmem_read(dev->dp8390, dev->regs.da++, 1); return dp8390_chipmem_read(dev->dp8390, dev->regs.da++, 1);
} }
return 0; return 0;
} }
static void static void
threec503_nic_hi_write(uint16_t addr, uint8_t val, void *priv) threec503_nic_hi_write(uint16_t addr, uint8_t val, void *priv)
{ {
threec503_t *dev = (threec503_t *)priv; threec503_t *dev = (threec503_t *) priv;
threec503_log("3Com503: Write GA address=%04x, val=%04x\n", addr, val); threec503_log("3Com503: Write GA address=%04x, val=%04x\n", addr, val);
switch (addr & 0x0f) { switch (addr & 0x0f) {
case 0x00: case 0x00:
dev->regs.pstr = val; dev->regs.pstr = val;
break; break;
case 0x01: case 0x01:
dev->regs.pspr = val; dev->regs.pspr = val;
break; break;
case 0x02: case 0x02:
dev->regs.dqtr = val; dev->regs.dqtr = val;
break; break;
case 0x05: case 0x05:
if ((dev->regs.gacfr & 0x0f) != (val & 0x0f)) { if ((dev->regs.gacfr & 0x0f) != (val & 0x0f)) {
switch (val & 0x0f) { switch (val & 0x0f) {
case 0: /*ROM mapping*/ case 0: /*ROM mapping*/
/* FIXME: Implement this when a BIOS is found/generated. */ /* FIXME: Implement this when a BIOS is found/generated. */
mem_mapping_disable(&dev->ram_mapping); mem_mapping_disable(&dev->ram_mapping);
break; break;
case 9: /*RAM mapping*/ case 9: /*RAM mapping*/
mem_mapping_enable(&dev->ram_mapping); mem_mapping_enable(&dev->ram_mapping);
break; break;
default: /*No ROM mapping*/ default: /*No ROM mapping*/
mem_mapping_disable(&dev->ram_mapping); mem_mapping_disable(&dev->ram_mapping);
break; break;
} }
} }
if (!(val & 0x80)) if (!(val & 0x80))
threec503_interrupt(dev, 1); threec503_interrupt(dev, 1);
else else
threec503_interrupt(dev, 0); threec503_interrupt(dev, 0);
dev->regs.gacfr = val; dev->regs.gacfr = val;
break; break;
case 0x06: case 0x06:
if (val & 1) { if (val & 1) {
threec503_reset(dev); threec503_reset(dev);
dev->dp8390->ISR.reset = 1; dev->dp8390->ISR.reset = 1;
dev->regs.ctrl = 0x0b; dev->regs.ctrl = 0x0b;
return; return;
} }
if ((val & 0x80) != (dev->regs.ctrl & 0x80)) { if ((val & 0x80) != (dev->regs.ctrl & 0x80)) {
if (val & 0x80) if (val & 0x80)
dev->regs.streg |= 0x88; dev->regs.streg |= 0x88;
else else
dev->regs.streg &= ~0x88; dev->regs.streg &= ~0x88;
dev->regs.streg &= ~0x10; dev->regs.streg &= ~0x10;
} }
dev->regs.ctrl = val; dev->regs.ctrl = val;
break; break;
case 0x08: case 0x08:
switch (val & 0xf0) { switch (val & 0xf0) {
case 0x00: case 0x00:
case 0x10: case 0x10:
case 0x20: case 0x20:
case 0x40: case 0x40:
case 0x80: case 0x80:
dev->regs.idcfr = (dev->regs.idcfr & 0x0f) | (val & 0xf0); dev->regs.idcfr = (dev->regs.idcfr & 0x0f) | (val & 0xf0);
break; break;
default: default:
threec503_log("Trying to set multiple IRQs: %02x\n", val); threec503_log("Trying to set multiple IRQs: %02x\n", val);
break; break;
} }
switch (val & 0x0f) { switch (val & 0x0f) {
case 0x00: case 0x00:
case 0x01: case 0x01:
case 0x02: case 0x02:
case 0x04: case 0x04:
dev->regs.idcfr = (dev->regs.idcfr & 0xf0) | (val & 0x0f); dev->regs.idcfr = (dev->regs.idcfr & 0xf0) | (val & 0x0f);
break; break;
case 0x08: case 0x08:
break; break;
default: default:
threec503_log("Trying to set multiple DMA channels: %02x\n", val); threec503_log("Trying to set multiple DMA channels: %02x\n", val);
break; break;
} }
break; break;
case 0x09: case 0x09:
dev->regs.da = (val << 8) | (dev->regs.da & 0xff); dev->regs.da = (val << 8) | (dev->regs.da & 0xff);
break; break;
case 0x0a: case 0x0a:
dev->regs.da = (dev->regs.da & 0xff00) | val; dev->regs.da = (dev->regs.da & 0xff00) | val;
break; break;
case 0x0b: case 0x0b:
dev->regs.vptr = (val << 12) | (dev->regs.vptr & 0xfff); dev->regs.vptr = (val << 12) | (dev->regs.vptr & 0xfff);
break; break;
case 0x0c: case 0x0c:
dev->regs.vptr = (val << 4) | (dev->regs.vptr & 0xff00f); dev->regs.vptr = (val << 4) | (dev->regs.vptr & 0xff00f);
break; break;
case 0x0d: case 0x0d:
dev->regs.vptr = (val << 4) | (dev->regs.vptr & 0xffff0); dev->regs.vptr = (val << 4) | (dev->regs.vptr & 0xffff0);
break; break;
case 0x0e: case 0x0e:
case 0x0f: case 0x0f:
if (!(dev->regs.ctrl & 0x80)) if (!(dev->regs.ctrl & 0x80))
return; return;
threec503_set_drq(dev); threec503_set_drq(dev);
dp8390_chipmem_write(dev->dp8390, dev->regs.da++, val, 1); dp8390_chipmem_write(dev->dp8390, dev->regs.da++, val, 1);
break; break;
} }
} }
static void static void
threec503_nic_ioset(threec503_t *dev, uint16_t addr) threec503_nic_ioset(threec503_t *dev, uint16_t addr)
{ {
io_sethandler(addr, 0x10, io_sethandler(addr, 0x10,
threec503_nic_lo_read, NULL, NULL, threec503_nic_lo_read, NULL, NULL,
threec503_nic_lo_write, NULL, NULL, dev); threec503_nic_lo_write, NULL, NULL, dev);
io_sethandler(addr+0x400, 0x10, io_sethandler(addr + 0x400, 0x10,
threec503_nic_hi_read, NULL, NULL, threec503_nic_hi_read, NULL, NULL,
threec503_nic_hi_write, NULL, NULL, dev); threec503_nic_hi_write, NULL, NULL, dev);
} }
static void * static void *
threec503_nic_init(const device_t *info) threec503_nic_init(const device_t *info)
{ {
uint32_t mac; uint32_t mac;
threec503_t *dev; threec503_t *dev;
dev = malloc(sizeof(threec503_t)); dev = malloc(sizeof(threec503_t));
memset(dev, 0x00, sizeof(threec503_t)); memset(dev, 0x00, sizeof(threec503_t));
dev->maclocal[0] = 0x02; /* 02:60:8C (3Com OID) */ dev->maclocal[0] = 0x02; /* 02:60:8C (3Com OID) */
dev->maclocal[1] = 0x60; dev->maclocal[1] = 0x60;
dev->maclocal[2] = 0x8C; dev->maclocal[2] = 0x8C;
dev->base_address = device_get_config_hex16("base"); dev->base_address = device_get_config_hex16("base");
dev->base_irq = device_get_config_int("irq"); dev->base_irq = device_get_config_int("irq");
dev->dma_channel = device_get_config_int("dma"); dev->dma_channel = device_get_config_int("dma");
dev->bios_addr = device_get_config_hex20("bios_addr"); dev->bios_addr = device_get_config_hex20("bios_addr");
/* See if we have a local MAC address configured. */ /* See if we have a local MAC address configured. */
mac = device_get_config_mac("mac", -1); mac = device_get_config_mac("mac", -1);
@@ -580,22 +569,22 @@ threec503_nic_init(const device_t *info)
/* Set up our BIA. */ /* Set up our BIA. */
if (mac & 0xff000000) { if (mac & 0xff000000) {
/* Generate new local MAC. */ /* Generate new local MAC. */
dev->maclocal[3] = random_generate(); dev->maclocal[3] = random_generate();
dev->maclocal[4] = random_generate(); dev->maclocal[4] = random_generate();
dev->maclocal[5] = random_generate(); dev->maclocal[5] = random_generate();
mac = (((int) dev->maclocal[3]) << 16); mac = (((int) dev->maclocal[3]) << 16);
mac |= (((int) dev->maclocal[4]) << 8); mac |= (((int) dev->maclocal[4]) << 8);
mac |= ((int) dev->maclocal[5]); mac |= ((int) dev->maclocal[5]);
device_set_config_mac("mac", mac); device_set_config_mac("mac", mac);
} else { } else {
dev->maclocal[3] = (mac>>16) & 0xff; dev->maclocal[3] = (mac >> 16) & 0xff;
dev->maclocal[4] = (mac>>8) & 0xff; dev->maclocal[4] = (mac >> 8) & 0xff;
dev->maclocal[5] = (mac & 0xff); dev->maclocal[5] = (mac & 0xff);
} }
dev->dp8390 = device_add_inst(&dp8390_device, dp3890_inst++); dev->dp8390 = device_add_inst(&dp8390_device, dp3890_inst++);
dev->dp8390->priv = dev; dev->dp8390->priv = dev;
dev->dp8390->interrupt = threec503_interrupt; dev->dp8390->interrupt = threec503_interrupt;
dp8390_set_defaults(dev->dp8390, DP8390_FLAG_CHECK_CR | DP8390_FLAG_CLEAR_IRQ); dp8390_set_defaults(dev->dp8390, DP8390_FLAG_CHECK_CR | DP8390_FLAG_CLEAR_IRQ);
dp8390_mem_alloc(dev->dp8390, 0x2000, 0x2000); dp8390_mem_alloc(dev->dp8390, 0x2000, 0x2000);
@@ -603,32 +592,31 @@ threec503_nic_init(const device_t *info)
memcpy(dev->dp8390->physaddr, dev->maclocal, sizeof(dev->maclocal)); memcpy(dev->dp8390->physaddr, dev->maclocal, sizeof(dev->maclocal));
threec503_log("I/O=%04x, IRQ=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", threec503_log("I/O=%04x, IRQ=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n",
dev->base_address, dev->base_irq, dev->base_address, dev->base_irq,
dev->dp8390->physaddr[0], dev->dp8390->physaddr[1], dev->dp8390->physaddr[2], dev->dp8390->physaddr[0], dev->dp8390->physaddr[1], dev->dp8390->physaddr[2],
dev->dp8390->physaddr[3], dev->dp8390->physaddr[4], dev->dp8390->physaddr[5]); dev->dp8390->physaddr[3], dev->dp8390->physaddr[4], dev->dp8390->physaddr[5]);
/* Reset the board. */ /* Reset the board. */
threec503_reset(dev); threec503_reset(dev);
/* Map this system into the memory map. */ /* Map this system into the memory map. */
mem_mapping_add(&dev->ram_mapping, dev->bios_addr, 0x4000, mem_mapping_add(&dev->ram_mapping, dev->bios_addr, 0x4000,
threec503_ram_read, NULL, NULL, threec503_ram_read, NULL, NULL,
threec503_ram_write, NULL, NULL, threec503_ram_write, NULL, NULL,
NULL, MEM_MAPPING_EXTERNAL, dev); NULL, MEM_MAPPING_EXTERNAL, dev);
// mem_mapping_disable(&dev->ram_mapping); // mem_mapping_disable(&dev->ram_mapping);
dev->regs.gacfr = 0x09; /* Start with RAM mapping enabled. */ dev->regs.gacfr = 0x09; /* Start with RAM mapping enabled. */
/* Attach ourselves to the network module. */ /* Attach ourselves to the network module. */
dev->dp8390->card = network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL); dev->dp8390->card = network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL);
return(dev); return (dev);
} }
static void static void
threec503_nic_close(void *priv) threec503_nic_close(void *priv)
{ {
threec503_t *dev = (threec503_t *)priv; threec503_t *dev = (threec503_t *) priv;
#ifdef ENABLE_3COM503_LOG #ifdef ENABLE_3COM503_LOG
threec503_log("3Com503: closed\n"); threec503_log("3Com503: closed\n");
@@ -638,7 +626,7 @@ threec503_nic_close(void *priv)
} }
static const device_config_t threec503_config[] = { static const device_config_t threec503_config[] = {
// clang-format off // clang-format off
{ {
.name = "base", .name = "base",
.description = "Address", .description = "Address",

File diff suppressed because it is too large Load Diff

View File

@@ -1,19 +1,19 @@
#ifdef _WIN32 #ifdef _WIN32
#define WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN
#include <windows.h> # include <windows.h>
#else #else
#include <unistd.h> # include <unistd.h>
#include <fcntl.h> # include <fcntl.h>
#endif #endif
#include <86box/net_event.h> #include <86box/net_event.h>
#ifndef _WIN32 #ifndef _WIN32
static void setup_fd(int fd) static void
setup_fd(int fd)
{ {
fcntl(fd, F_SETFD, FD_CLOEXEC); fcntl(fd, F_SETFD, FD_CLOEXEC);
fcntl(fd, F_SETFL, O_NONBLOCK); fcntl(fd, F_SETFL, O_NONBLOCK);
} }
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@@ -52,14 +52,14 @@
#include <wchar.h> #include <wchar.h>
#include <stdbool.h> #include <stdbool.h>
#ifdef _WIN32 #ifdef _WIN32
#define WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN
#include <windows.h> # include <windows.h>
#include <winsock2.h> # include <winsock2.h>
#else #else
#include <poll.h> # include <poll.h>
#include <unistd.h> # include <unistd.h>
#include <fcntl.h> # include <fcntl.h>
#include <sys/select.h> # include <sys/select.h>
#endif #endif
#define HAVE_STDARG_H #define HAVE_STDARG_H
@@ -82,45 +82,45 @@ enum {
}; };
#ifdef __APPLE__ #ifdef __APPLE__
#include <pcap/pcap.h> # include <pcap/pcap.h>
#else #else
typedef int bpf_int32; typedef int bpf_int32;
typedef unsigned int bpf_u_int32; typedef unsigned int bpf_u_int32;
/* /*
* The instruction data structure. * The instruction data structure.
*/ */
struct bpf_insn { struct bpf_insn {
unsigned short code; unsigned short code;
unsigned char jt; unsigned char jt;
unsigned char jf; unsigned char jf;
bpf_u_int32 k; bpf_u_int32 k;
}; };
/* /*
* Structure for "pcap_compile()", "pcap_setfilter()", etc.. * Structure for "pcap_compile()", "pcap_setfilter()", etc..
*/ */
struct bpf_program { struct bpf_program {
unsigned int bf_len; unsigned int bf_len;
struct bpf_insn *bf_insns; struct bpf_insn *bf_insns;
}; };
typedef struct pcap_if pcap_if_t; typedef struct pcap_if pcap_if_t;
#define PCAP_ERRBUF_SIZE 256 # define PCAP_ERRBUF_SIZE 256
struct pcap_pkthdr { struct pcap_pkthdr {
struct timeval ts; struct timeval ts;
bpf_u_int32 caplen; bpf_u_int32 caplen;
bpf_u_int32 len; bpf_u_int32 len;
}; };
struct pcap_if { struct pcap_if {
struct pcap_if *next; struct pcap_if *next;
char *name; char *name;
char *description; char *description;
void *addresses; void *addresses;
bpf_u_int32 flags; bpf_u_int32 flags;
}; };
struct pcap_send_queue { struct pcap_send_queue {
@@ -154,39 +154,39 @@ typedef struct {
uint8_t *mac_addr; uint8_t *mac_addr;
} net_pcap_params_t; } net_pcap_params_t;
static volatile void *libpcap_handle; /* handle to WinPcap DLL */ static volatile void *libpcap_handle; /* handle to WinPcap DLL */
/* Pointers to the real functions. */ /* Pointers to the real functions. */
static const char *(*f_pcap_lib_version)(void); static const char *(*f_pcap_lib_version)(void);
static int (*f_pcap_findalldevs)(pcap_if_t **,char *); static int (*f_pcap_findalldevs)(pcap_if_t **, char *);
static void (*f_pcap_freealldevs)(void *); static void (*f_pcap_freealldevs)(void *);
static void *(*f_pcap_open_live)(const char *,int,int,int,char *); static void *(*f_pcap_open_live)(const char *, int, int, int, char *);
static int (*f_pcap_compile)(void *,void *, const char *,int,bpf_u_int32); static int (*f_pcap_compile)(void *, void *, const char *, int, bpf_u_int32);
static int (*f_pcap_setfilter)(void *,void *); static int (*f_pcap_setfilter)(void *, void *);
static const unsigned char static const unsigned char
*(*f_pcap_next)(void *,void *); *(*f_pcap_next)(void *, void *);
static int (*f_pcap_sendpacket)(void *,const unsigned char *,int); static int (*f_pcap_sendpacket)(void *, const unsigned char *, int);
static void (*f_pcap_close)(void *); static void (*f_pcap_close)(void *);
static int (*f_pcap_setnonblock)(void*, int, char*); static int (*f_pcap_setnonblock)(void *, int, char *);
static int (*f_pcap_set_immediate_mode)(void *, int); static int (*f_pcap_set_immediate_mode)(void *, int);
static int (*f_pcap_set_promisc)(void *, int); static int (*f_pcap_set_promisc)(void *, int);
static int (*f_pcap_set_snaplen)(void *, int); static int (*f_pcap_set_snaplen)(void *, int);
static int (*f_pcap_dispatch)(void *, int, pcap_handler callback, u_char *user); static int (*f_pcap_dispatch)(void *, int, pcap_handler callback, u_char *user);
static void *(*f_pcap_create)(const char *, char*); static void *(*f_pcap_create)(const char *, char *);
static int (*f_pcap_activate)(void *); static int (*f_pcap_activate)(void *);
static void *(*f_pcap_geterr)(void *); static void *(*f_pcap_geterr)(void *);
#ifdef _WIN32 #ifdef _WIN32
static HANDLE (*f_pcap_getevent)(void *); static HANDLE (*f_pcap_getevent)(void *);
static int (*f_pcap_sendqueue_queue)(void *, void *, void *); static int (*f_pcap_sendqueue_queue)(void *, void *, void *);
static u_int (*f_pcap_sendqueue_transmit)(void *, void *, int sync); static u_int (*f_pcap_sendqueue_transmit)(void *, void *, int sync);
static void *(*f_pcap_sendqueue_alloc)(u_int memsize); static void *(*f_pcap_sendqueue_alloc)(u_int memsize);
static void (*f_pcap_sendqueue_destroy)(void *); static void (*f_pcap_sendqueue_destroy)(void *);
#else #else
static int (*f_pcap_get_selectable_fd)(void *); static int (*f_pcap_get_selectable_fd)(void *);
#endif #endif
static dllimp_t pcap_imports[] = { static dllimp_t pcap_imports[] = {
{ "pcap_lib_version", &f_pcap_lib_version }, {"pcap_lib_version", &f_pcap_lib_version },
{ "pcap_findalldevs", &f_pcap_findalldevs }, { "pcap_findalldevs", &f_pcap_findalldevs },
{ "pcap_freealldevs", &f_pcap_freealldevs }, { "pcap_freealldevs", &f_pcap_freealldevs },
{ "pcap_open_live", &f_pcap_open_live }, { "pcap_open_live", &f_pcap_open_live },
@@ -210,7 +210,7 @@ static dllimp_t pcap_imports[] = {
{ "pcap_sendqueue_alloc", &f_pcap_sendqueue_alloc }, { "pcap_sendqueue_alloc", &f_pcap_sendqueue_alloc },
{ "pcap_sendqueue_destroy", &f_pcap_sendqueue_destroy }, { "pcap_sendqueue_destroy", &f_pcap_sendqueue_destroy },
#else #else
{ "pcap_get_selectable_fd", &f_pcap_get_selectable_fd }, { "pcap_get_selectable_fd", &f_pcap_get_selectable_fd },
#endif #endif
{ NULL, NULL }, { NULL, NULL },
}; };
@@ -224,20 +224,19 @@ pcap_log(const char *fmt, ...)
va_list ap; va_list ap;
if (pcap_do_log) { if (pcap_do_log) {
va_start(ap, fmt); va_start(ap, fmt);
pclog_ex(fmt, ap); pclog_ex(fmt, ap);
va_end(ap); va_end(ap);
} }
} }
#else #else
#define pcap_log(fmt, ...) # define pcap_log(fmt, ...)
#endif #endif
static void static void
net_pcap_rx_handler(uint8_t *user, const struct pcap_pkthdr *h, const uint8_t *bytes) net_pcap_rx_handler(uint8_t *user, const struct pcap_pkthdr *h, const uint8_t *bytes)
{ {
net_pcap_t *pcap = (net_pcap_t*)user; net_pcap_t *pcap = (net_pcap_t *) user;
memcpy(pcap->pkt.data, bytes, h->caplen); memcpy(pcap->pkt.data, bytes, h->caplen);
pcap->pkt.len = h->caplen; pcap->pkt.len = h->caplen;
network_rx_put_pkt(pcap->card, &pcap->pkt); network_rx_put_pkt(pcap->card, &pcap->pkt);
@@ -248,15 +247,15 @@ void
net_pcap_in(void *pcap, uint8_t *bufp, int len) net_pcap_in(void *pcap, uint8_t *bufp, int len)
{ {
if (pcap == NULL) if (pcap == NULL)
return; return;
f_pcap_sendpacket((void *)pcap, bufp, len); f_pcap_sendpacket((void *) pcap, bufp, len);
} }
void void
net_pcap_in_available(void *priv) net_pcap_in_available(void *priv)
{ {
net_pcap_t *pcap = (net_pcap_t *)priv; net_pcap_t *pcap = (net_pcap_t *) priv;
net_event_set(&pcap->tx_event); net_event_set(&pcap->tx_event);
} }
@@ -264,14 +263,14 @@ net_pcap_in_available(void *priv)
static void static void
net_pcap_thread(void *priv) net_pcap_thread(void *priv)
{ {
net_pcap_t *pcap = (net_pcap_t*)priv; net_pcap_t *pcap = (net_pcap_t *) priv;
pcap_log("PCAP: polling started.\n"); pcap_log("PCAP: polling started.\n");
HANDLE events[NET_EVENT_MAX]; HANDLE events[NET_EVENT_MAX];
events[NET_EVENT_STOP] = net_event_get_handle(&pcap->stop_event); events[NET_EVENT_STOP] = net_event_get_handle(&pcap->stop_event);
events[NET_EVENT_TX] = net_event_get_handle(&pcap->tx_event); events[NET_EVENT_TX] = net_event_get_handle(&pcap->tx_event);
events[NET_EVENT_RX] = f_pcap_getevent((void *)pcap->pcap); events[NET_EVENT_RX] = f_pcap_getevent((void *) pcap->pcap);
bool run = true; bool run = true;
@@ -297,7 +296,7 @@ net_pcap_thread(void *priv)
break; break;
case NET_EVENT_RX: case NET_EVENT_RX:
f_pcap_dispatch(pcap->pcap, PCAP_PKT_BATCH, net_pcap_rx_handler, (u_char *)pcap); f_pcap_dispatch(pcap->pcap, PCAP_PKT_BATCH, net_pcap_rx_handler, (u_char *) pcap);
break; break;
} }
} }
@@ -308,7 +307,7 @@ net_pcap_thread(void *priv)
static void static void
net_pcap_thread(void *priv) net_pcap_thread(void *priv)
{ {
net_pcap_t *pcap = (net_pcap_t*)priv; net_pcap_t *pcap = (net_pcap_t *) priv;
pcap_log("PCAP: polling started.\n"); pcap_log("PCAP: polling started.\n");
@@ -341,9 +340,8 @@ net_pcap_thread(void *priv)
} }
if (pfd[NET_EVENT_RX].revents & POLLIN) { if (pfd[NET_EVENT_RX].revents & POLLIN) {
f_pcap_dispatch(pcap->pcap, PCAP_PKT_BATCH, net_pcap_rx_handler, (u_char *)pcap); f_pcap_dispatch(pcap->pcap, PCAP_PKT_BATCH, net_pcap_rx_handler, (u_char *) pcap);
} }
} }
pcap_log("PCAP: polling stopped.\n"); pcap_log("PCAP: polling stopped.\n");
@@ -360,9 +358,9 @@ net_pcap_thread(void *priv)
int int
net_pcap_prepare(netdev_t *list) net_pcap_prepare(netdev_t *list)
{ {
char errbuf[PCAP_ERRBUF_SIZE]; char errbuf[PCAP_ERRBUF_SIZE];
pcap_if_t *devlist, *dev; pcap_if_t *devlist, *dev;
int i = 0; int i = 0;
/* Try loading the DLL. */ /* Try loading the DLL. */
#ifdef _WIN32 #ifdef _WIN32
@@ -374,44 +372,44 @@ net_pcap_prepare(netdev_t *list)
#endif #endif
if (libpcap_handle == NULL) { if (libpcap_handle == NULL) {
pcap_log("PCAP: error loading pcap module\n"); pcap_log("PCAP: error loading pcap module\n");
return(-1); return (-1);
} }
/* Retrieve the device list from the local machine */ /* Retrieve the device list from the local machine */
if (f_pcap_findalldevs(&devlist, errbuf) == -1) { if (f_pcap_findalldevs(&devlist, errbuf) == -1) {
pcap_log("PCAP: error in pcap_findalldevs: %s\n", errbuf); pcap_log("PCAP: error in pcap_findalldevs: %s\n", errbuf);
return(-1); return (-1);
} }
for (dev=devlist; dev!=NULL; dev=dev->next) { for (dev = devlist; dev != NULL; dev = dev->next) {
if (i >= (NET_HOST_INTF_MAX - 1)) if (i >= (NET_HOST_INTF_MAX - 1))
break; break;
/** /**
* we initialize the strings to NULL first for strncpy * we initialize the strings to NULL first for strncpy
*/ */
memset(list->device, '\0', sizeof(list->device)); memset(list->device, '\0', sizeof(list->device));
memset(list->description, '\0', sizeof(list->description)); memset(list->description, '\0', sizeof(list->description));
strncpy(list->device, dev->name, sizeof(list->device) - 1); strncpy(list->device, dev->name, sizeof(list->device) - 1);
if (dev->description) { if (dev->description) {
strncpy(list->description, dev->description, sizeof(list->description) - 1); strncpy(list->description, dev->description, sizeof(list->description) - 1);
} else { } else {
/* if description is NULL, set the name. This allows pcap to display *something* useful under WINE */ /* if description is NULL, set the name. This allows pcap to display *something* useful under WINE */
strncpy(list->description, dev->name, sizeof(list->description) - 1); strncpy(list->description, dev->name, sizeof(list->description) - 1);
} }
list++; i++; list++;
i++;
} }
/* Release the memory. */ /* Release the memory. */
f_pcap_freealldevs(devlist); f_pcap_freealldevs(devlist);
return(i); return (i);
} }
/* /*
* Initialize (Win)Pcap for use. * Initialize (Win)Pcap for use.
* *
@@ -422,12 +420,12 @@ net_pcap_prepare(netdev_t *list)
void * void *
net_pcap_init(const netcard_t *card, const uint8_t *mac_addr, void *priv) net_pcap_init(const netcard_t *card, const uint8_t *mac_addr, void *priv)
{ {
char errbuf[PCAP_ERRBUF_SIZE]; char errbuf[PCAP_ERRBUF_SIZE];
char *str; char *str;
char filter_exp[255]; char filter_exp[255];
struct bpf_program fp; struct bpf_program fp;
char *intf_name = (char*)priv; char *intf_name = (char *) priv;
/* Did we already load the library? */ /* Did we already load the library? */
if (libpcap_handle == NULL) { if (libpcap_handle == NULL) {
@@ -451,7 +449,7 @@ net_pcap_init(const netcard_t *card, const uint8_t *mac_addr, void *priv)
pcap_log("PCAP: interface: %s\n", intf_name); pcap_log("PCAP: interface: %s\n", intf_name);
net_pcap_t *pcap = calloc(1, sizeof(net_pcap_t)); net_pcap_t *pcap = calloc(1, sizeof(net_pcap_t));
pcap->card = (netcard_t *)card; pcap->card = (netcard_t *) card;
memcpy(pcap->mac_addr, mac_addr, sizeof(pcap->mac_addr)); memcpy(pcap->mac_addr, mac_addr, sizeof(pcap->mac_addr));
if ((pcap->pcap = f_pcap_create(intf_name, errbuf)) == NULL) { if ((pcap->pcap = f_pcap_create(intf_name, errbuf)) == NULL) {
@@ -494,7 +492,7 @@ net_pcap_init(const netcard_t *card, const uint8_t *mac_addr, void *priv)
return NULL; return NULL;
} }
} else { } else {
pcap_log("PCAP: could not compile filter (%s) : %s!\n", filter_exp, f_pcap_geterr((void*)pcap->pcap)); pcap_log("PCAP: could not compile filter (%s) : %s!\n", filter_exp, f_pcap_geterr((void *) pcap->pcap));
f_pcap_close((void *) pcap->pcap); f_pcap_close((void *) pcap->pcap);
free(pcap); free(pcap);
return NULL; return NULL;
@@ -523,7 +521,7 @@ net_pcap_close(void *priv)
if (!priv) if (!priv)
return; return;
net_pcap_t *pcap = (net_pcap_t *)priv; net_pcap_t *pcap = (net_pcap_t *) priv;
pcap_log("PCAP: closing.\n"); pcap_log("PCAP: closing.\n");
@@ -541,10 +539,10 @@ net_pcap_close(void *priv)
free(pcap->pkt.data); free(pcap->pkt.data);
#ifdef _WIN32 #ifdef _WIN32
f_pcap_sendqueue_destroy((void*)pcap->pcap_queue); f_pcap_sendqueue_destroy((void *) pcap->pcap_queue);
#endif #endif
/* OK, now shut down Pcap itself. */ /* OK, now shut down Pcap itself. */
f_pcap_close((void*)pcap->pcap); f_pcap_close((void *) pcap->pcap);
net_event_close(&pcap->tx_event); net_event_close(&pcap->tx_event);
net_event_close(&pcap->stop_event); net_event_close(&pcap->stop_event);

File diff suppressed because it is too large Load Diff

View File

@@ -36,9 +36,8 @@
#include <86box/network.h> #include <86box/network.h>
#include <86box/net_plip.h> #include <86box/net_plip.h>
enum { enum {
PLIP_START = 0x00, PLIP_START = 0x00,
PLIP_TX_LEN_LSB_LOW = 0x10, PLIP_TX_LEN_LSB_LOW = 0x10,
PLIP_TX_LEN_LSB_HIGH, PLIP_TX_LEN_LSB_HIGH,
PLIP_TX_LEN_MSB_LOW, PLIP_TX_LEN_MSB_LOW,
@@ -60,26 +59,24 @@ enum {
typedef struct typedef struct
{ {
uint8_t mac[6]; uint8_t mac[6];
void *lpt; void *lpt;
pc_timer_t rx_timer; pc_timer_t rx_timer;
pc_timer_t timeout_timer; pc_timer_t timeout_timer;
uint8_t status, ctrl; uint8_t status, ctrl;
uint8_t state, ack, tx_checksum, tx_checksum_calc, *tx_pkt; uint8_t state, ack, tx_checksum, tx_checksum_calc, *tx_pkt;
uint16_t tx_len, tx_ptr; uint16_t tx_len, tx_ptr;
uint8_t *rx_pkt, rx_checksum, rx_return_state; uint8_t *rx_pkt, rx_checksum, rx_return_state;
uint16_t rx_len, rx_ptr; uint16_t rx_len, rx_ptr;
netcard_t *card; netcard_t *card;
} plip_t; } plip_t;
static void plip_receive_packet(plip_t *dev);
static void plip_receive_packet(plip_t *dev); plip_t *instance;
plip_t *instance;
#ifdef ENABLE_PLIP_LOG #ifdef ENABLE_PLIP_LOG
int plip_do_log = ENABLE_PLIP_LOG; int plip_do_log = ENABLE_PLIP_LOG;
@@ -90,16 +87,15 @@ plip_log(uint8_t lvl, const char *fmt, ...)
va_list ap; va_list ap;
if (plip_do_log >= lvl) { if (plip_do_log >= lvl) {
va_start(ap, fmt); va_start(ap, fmt);
pclog_ex(fmt, ap); pclog_ex(fmt, ap);
va_end(ap); va_end(ap);
} }
} }
#else #else
#define plip_log(lvl, fmt, ...) # define plip_log(lvl, fmt, ...)
#endif #endif
static void static void
timeout_timer(void *priv) timeout_timer(void *priv)
{ {
@@ -108,22 +104,21 @@ timeout_timer(void *priv)
plip_log(1, "PLIP: timeout at state %d status %02X\n", dev->state, dev->status); plip_log(1, "PLIP: timeout at state %d status %02X\n", dev->state, dev->status);
/* Throw everything out the window. */ /* Throw everything out the window. */
dev->state = PLIP_START; dev->state = PLIP_START;
dev->status = 0x80; dev->status = 0x80;
if (dev->tx_pkt) { if (dev->tx_pkt) {
free(dev->tx_pkt); free(dev->tx_pkt);
dev->tx_pkt = NULL; dev->tx_pkt = NULL;
} }
if (dev->rx_pkt) { if (dev->rx_pkt) {
free(dev->rx_pkt); free(dev->rx_pkt);
dev->rx_pkt = NULL; dev->rx_pkt = NULL;
} }
timer_disable(&dev->timeout_timer); timer_disable(&dev->timeout_timer);
} }
static void static void
plip_write_data(uint8_t val, void *priv) plip_write_data(uint8_t val, void *priv)
{ {
@@ -132,220 +127,219 @@ plip_write_data(uint8_t val, void *priv)
plip_log(3, "PLIP: write_data(%02X)\n", val); plip_log(3, "PLIP: write_data(%02X)\n", val);
switch (dev->state) { switch (dev->state) {
case PLIP_START: case PLIP_START:
if (val == 0x08) { /* D3/ACK wakes us up */ if (val == 0x08) { /* D3/ACK wakes us up */
plip_log(2, "PLIP: ACK wakeup\n"); plip_log(2, "PLIP: ACK wakeup\n");
dev->state = PLIP_TX_LEN_LSB_LOW; dev->state = PLIP_TX_LEN_LSB_LOW;
dev->status = 0x08; dev->status = 0x08;
break; break;
} }
return; return;
case PLIP_TX_LEN_LSB_LOW: case PLIP_TX_LEN_LSB_LOW:
if (!(val & 0x10)) if (!(val & 0x10))
return; /* D4/BUSY not high yet */ return; /* D4/BUSY not high yet */
dev->tx_len = val & 0xf; dev->tx_len = val & 0xf;
plip_log(2, "PLIP: tx_len = %04X (1/4)\n", dev->tx_len); plip_log(2, "PLIP: tx_len = %04X (1/4)\n", dev->tx_len);
dev->state = PLIP_TX_LEN_LSB_HIGH; dev->state = PLIP_TX_LEN_LSB_HIGH;
dev->status &= ~0x88; dev->status &= ~0x88;
break; break;
case PLIP_TX_LEN_LSB_HIGH: case PLIP_TX_LEN_LSB_HIGH:
if (val & 0x10) if (val & 0x10)
return; /* D4/BUSY not low yet */ return; /* D4/BUSY not low yet */
dev->tx_len |= (val & 0xf) << 4; dev->tx_len |= (val & 0xf) << 4;
plip_log(2, "PLIP: tx_len = %04X (2/4)\n", dev->tx_len); plip_log(2, "PLIP: tx_len = %04X (2/4)\n", dev->tx_len);
dev->state = PLIP_TX_LEN_MSB_LOW; dev->state = PLIP_TX_LEN_MSB_LOW;
dev->status |= 0x80; dev->status |= 0x80;
break; break;
case PLIP_TX_LEN_MSB_LOW: case PLIP_TX_LEN_MSB_LOW:
if (!(val & 0x10)) if (!(val & 0x10))
return; /* D4/BUSY not high yet */ return; /* D4/BUSY not high yet */
dev->tx_len |= (val & 0xf) << 8; dev->tx_len |= (val & 0xf) << 8;
plip_log(2, "PLIP: tx_len = %04X (3/4)\n", dev->tx_len); plip_log(2, "PLIP: tx_len = %04X (3/4)\n", dev->tx_len);
dev->state = PLIP_TX_LEN_MSB_HIGH; dev->state = PLIP_TX_LEN_MSB_HIGH;
dev->status &= ~0x80; dev->status &= ~0x80;
break; break;
case PLIP_TX_LEN_MSB_HIGH: case PLIP_TX_LEN_MSB_HIGH:
if (val & 0x10) if (val & 0x10)
return; /* D4/BUSY not low yet */ return; /* D4/BUSY not low yet */
dev->tx_len |= (val & 0xf) << 12; dev->tx_len |= (val & 0xf) << 12;
plip_log(2, "PLIP: tx_len = %04X (4/4)\n", dev->tx_len); plip_log(2, "PLIP: tx_len = %04X (4/4)\n", dev->tx_len);
/* We have the length, allocate a packet. */ /* We have the length, allocate a packet. */
if (!(dev->tx_pkt = malloc(dev->tx_len))) /* unlikely */ if (!(dev->tx_pkt = malloc(dev->tx_len))) /* unlikely */
fatal("PLIP: unable to allocate tx_pkt\n"); fatal("PLIP: unable to allocate tx_pkt\n");
dev->tx_ptr = 0; dev->tx_ptr = 0;
dev->tx_checksum_calc = 0; dev->tx_checksum_calc = 0;
dev->state = PLIP_TX_DATA_LOW; dev->state = PLIP_TX_DATA_LOW;
dev->status |= 0x80; dev->status |= 0x80;
break; break;
case PLIP_TX_DATA_LOW: case PLIP_TX_DATA_LOW:
if (!(val & 0x10)) if (!(val & 0x10))
return; /* D4/BUSY not high yet */ return; /* D4/BUSY not high yet */
dev->tx_pkt[dev->tx_ptr] = val & 0x0f; dev->tx_pkt[dev->tx_ptr] = val & 0x0f;
plip_log(2, "PLIP: tx_pkt[%d] = %02X (1/2)\n", dev->tx_ptr, dev->tx_pkt[dev->tx_ptr]); plip_log(2, "PLIP: tx_pkt[%d] = %02X (1/2)\n", dev->tx_ptr, dev->tx_pkt[dev->tx_ptr]);
dev->state = PLIP_TX_DATA_HIGH; dev->state = PLIP_TX_DATA_HIGH;
dev->status &= ~0x80; dev->status &= ~0x80;
break; break;
case PLIP_TX_DATA_HIGH: case PLIP_TX_DATA_HIGH:
if (val & 0x10) if (val & 0x10)
return; /* D4/BUSY not low yet */ return; /* D4/BUSY not low yet */
dev->tx_pkt[dev->tx_ptr] |= (val & 0x0f) << 4; dev->tx_pkt[dev->tx_ptr] |= (val & 0x0f) << 4;
plip_log(2, "PLIP: tx_pkt[%d] = %02X (2/2)\n", dev->tx_ptr, dev->tx_pkt[dev->tx_ptr]); plip_log(2, "PLIP: tx_pkt[%d] = %02X (2/2)\n", dev->tx_ptr, dev->tx_pkt[dev->tx_ptr]);
dev->tx_checksum_calc += dev->tx_pkt[dev->tx_ptr++]; dev->tx_checksum_calc += dev->tx_pkt[dev->tx_ptr++];
/* Are we done yet? */ /* Are we done yet? */
if (dev->tx_ptr < dev->tx_len) /* no, receive another byte */ if (dev->tx_ptr < dev->tx_len) /* no, receive another byte */
dev->state = PLIP_TX_DATA_LOW; dev->state = PLIP_TX_DATA_LOW;
else /* yes, move on to checksum */ else /* yes, move on to checksum */
dev->state = PLIP_TX_CHECKSUM_LOW; dev->state = PLIP_TX_CHECKSUM_LOW;
dev->status |= 0x80; dev->status |= 0x80;
break; break;
case PLIP_TX_CHECKSUM_LOW: case PLIP_TX_CHECKSUM_LOW:
if (!(val & 0x10)) if (!(val & 0x10))
return; /* D4/BUSY not high yet */ return; /* D4/BUSY not high yet */
dev->tx_checksum = val & 0x0f; dev->tx_checksum = val & 0x0f;
plip_log(2, "PLIP: tx_checksum = %02X (1/2)\n", dev->tx_checksum); plip_log(2, "PLIP: tx_checksum = %02X (1/2)\n", dev->tx_checksum);
dev->state = PLIP_TX_CHECKSUM_HIGH; dev->state = PLIP_TX_CHECKSUM_HIGH;
dev->status &= ~0x80; dev->status &= ~0x80;
break; break;
case PLIP_TX_CHECKSUM_HIGH: case PLIP_TX_CHECKSUM_HIGH:
if (val & 0x10) if (val & 0x10)
return; /* D4/BUSY not low yet */ return; /* D4/BUSY not low yet */
dev->tx_checksum |= (val & 0x0f) << 4; dev->tx_checksum |= (val & 0x0f) << 4;
plip_log(2, "PLIP: tx_checksum = %02X (2/2)\n", dev->tx_checksum); plip_log(2, "PLIP: tx_checksum = %02X (2/2)\n", dev->tx_checksum);
/* Verify checksum. */ /* Verify checksum. */
if (dev->tx_checksum_calc == dev->tx_checksum) { if (dev->tx_checksum_calc == dev->tx_checksum) {
/* Make sure we know the other end's MAC address. */ /* Make sure we know the other end's MAC address. */
memcpy(dev->mac, dev->tx_pkt + 6, 6); memcpy(dev->mac, dev->tx_pkt + 6, 6);
/* Transmit packet. */ /* Transmit packet. */
plip_log(2, "PLIP: transmitting %d-byte packet\n", dev->tx_len); plip_log(2, "PLIP: transmitting %d-byte packet\n", dev->tx_len);
network_tx(dev->card, dev->tx_pkt, dev->tx_len); network_tx(dev->card, dev->tx_pkt, dev->tx_len);
} else { } else {
plip_log(1, "PLIP: checksum error: expected %02X, got %02X\n", dev->tx_checksum_calc, dev->tx_checksum); plip_log(1, "PLIP: checksum error: expected %02X, got %02X\n", dev->tx_checksum_calc, dev->tx_checksum);
} }
/* We're done with this packet. */ /* We're done with this packet. */
free(dev->tx_pkt); free(dev->tx_pkt);
dev->tx_pkt = NULL; dev->tx_pkt = NULL;
dev->tx_len = 0; dev->tx_len = 0;
dev->state = PLIP_END; dev->state = PLIP_END;
dev->status |= 0x80; dev->status |= 0x80;
break; break;
case PLIP_RX_LEN_LSB_LOW: case PLIP_RX_LEN_LSB_LOW:
if (!(val & 0x01)) if (!(val & 0x01))
return; /* D3/ACK not high yet */ return; /* D3/ACK not high yet */
plip_log(2, "PLIP: rx_len = %04X (1/4)\n", dev->rx_len); plip_log(2, "PLIP: rx_len = %04X (1/4)\n", dev->rx_len);
dev->status = (dev->rx_len & 0x0f) << 3; dev->status = (dev->rx_len & 0x0f) << 3;
dev->state = PLIP_RX_LEN_LSB_HIGH; dev->state = PLIP_RX_LEN_LSB_HIGH;
break; break;
case PLIP_RX_LEN_LSB_HIGH: case PLIP_RX_LEN_LSB_HIGH:
if (!(val & 0x10)) if (!(val & 0x10))
return; /* D4/BUSY not high yet */ return; /* D4/BUSY not high yet */
plip_log(2, "PLIP: rx_len = %04X (2/4)\n", dev->rx_len); plip_log(2, "PLIP: rx_len = %04X (2/4)\n", dev->rx_len);
dev->status = ((dev->rx_len >> 4) & 0x0f) << 3; dev->status = ((dev->rx_len >> 4) & 0x0f) << 3;
dev->status |= 0x80; dev->status |= 0x80;
dev->state = PLIP_RX_LEN_MSB_LOW; dev->state = PLIP_RX_LEN_MSB_LOW;
break; break;
case PLIP_RX_LEN_MSB_LOW: case PLIP_RX_LEN_MSB_LOW:
if (val & 0x10) if (val & 0x10)
return; /* D4/BUSY not low yet */ return; /* D4/BUSY not low yet */
plip_log(2, "PLIP: rx_len = %04X (3/4)\n", dev->rx_len); plip_log(2, "PLIP: rx_len = %04X (3/4)\n", dev->rx_len);
dev->status = ((dev->rx_len >> 8) & 0x0f) << 3; dev->status = ((dev->rx_len >> 8) & 0x0f) << 3;
dev->state = PLIP_RX_LEN_MSB_HIGH; dev->state = PLIP_RX_LEN_MSB_HIGH;
break; break;
case PLIP_RX_LEN_MSB_HIGH: case PLIP_RX_LEN_MSB_HIGH:
if (!(val & 0x10)) if (!(val & 0x10))
return; /* D4/BUSY not high yet */ return; /* D4/BUSY not high yet */
plip_log(2, "PLIP: rx_len = %04X (4/4)\n", dev->rx_len); plip_log(2, "PLIP: rx_len = %04X (4/4)\n", dev->rx_len);
dev->status = ((dev->rx_len >> 12) & 0x0f) << 3; dev->status = ((dev->rx_len >> 12) & 0x0f) << 3;
dev->status |= 0x80; dev->status |= 0x80;
dev->rx_ptr = 0; dev->rx_ptr = 0;
dev->rx_checksum = 0; dev->rx_checksum = 0;
dev->state = PLIP_RX_DATA_LOW; dev->state = PLIP_RX_DATA_LOW;
break; break;
case PLIP_RX_DATA_LOW: case PLIP_RX_DATA_LOW:
if (val & 0x10) if (val & 0x10)
return; /* D4/BUSY not low yet */ return; /* D4/BUSY not low yet */
plip_log(2, "PLIP: rx_pkt[%d] = %02X (1/2)\n", dev->rx_ptr, dev->rx_pkt[dev->rx_ptr]); plip_log(2, "PLIP: rx_pkt[%d] = %02X (1/2)\n", dev->rx_ptr, dev->rx_pkt[dev->rx_ptr]);
dev->status = (dev->rx_pkt[dev->rx_ptr] & 0x0f) << 3; dev->status = (dev->rx_pkt[dev->rx_ptr] & 0x0f) << 3;
dev->state = PLIP_RX_DATA_HIGH; dev->state = PLIP_RX_DATA_HIGH;
break; break;
case PLIP_RX_DATA_HIGH: case PLIP_RX_DATA_HIGH:
if (!(val & 0x10)) if (!(val & 0x10))
return; /* D4/BUSY not high yet */ return; /* D4/BUSY not high yet */
plip_log(2, "PLIP: rx_pkt[%d] = %02X (2/2)\n", dev->rx_ptr, dev->rx_pkt[dev->rx_ptr]); plip_log(2, "PLIP: rx_pkt[%d] = %02X (2/2)\n", dev->rx_ptr, dev->rx_pkt[dev->rx_ptr]);
dev->status = ((dev->rx_pkt[dev->rx_ptr] >> 4) & 0x0f) << 3; dev->status = ((dev->rx_pkt[dev->rx_ptr] >> 4) & 0x0f) << 3;
dev->status |= 0x80; dev->status |= 0x80;
dev->rx_checksum += dev->rx_pkt[dev->rx_ptr++]; dev->rx_checksum += dev->rx_pkt[dev->rx_ptr++];
/* Are we done yet? */ /* Are we done yet? */
if (dev->rx_ptr < dev->rx_len) /* no, send another byte */ if (dev->rx_ptr < dev->rx_len) /* no, send another byte */
dev->state = PLIP_RX_DATA_LOW; dev->state = PLIP_RX_DATA_LOW;
else /* yes, move on to checksum */ else /* yes, move on to checksum */
dev->state = PLIP_RX_CHECKSUM_LOW; dev->state = PLIP_RX_CHECKSUM_LOW;
break; break;
case PLIP_RX_CHECKSUM_LOW: case PLIP_RX_CHECKSUM_LOW:
if (val & 0x10) if (val & 0x10)
return; /* D4/BUSY not low yet */ return; /* D4/BUSY not low yet */
plip_log(2, "PLIP: rx_checksum = %02X (1/2)\n", dev->rx_checksum); plip_log(2, "PLIP: rx_checksum = %02X (1/2)\n", dev->rx_checksum);
dev->status = (dev->rx_checksum & 0x0f) << 3; dev->status = (dev->rx_checksum & 0x0f) << 3;
dev->state = PLIP_RX_CHECKSUM_HIGH; dev->state = PLIP_RX_CHECKSUM_HIGH;
break; break;
case PLIP_RX_CHECKSUM_HIGH: case PLIP_RX_CHECKSUM_HIGH:
if (!(val & 0x10)) if (!(val & 0x10))
return; /* D4/BUSY not high yet */ return; /* D4/BUSY not high yet */
plip_log(2, "PLIP: rx_checksum = %02X (2/2)\n", dev->rx_checksum); plip_log(2, "PLIP: rx_checksum = %02X (2/2)\n", dev->rx_checksum);
dev->status = ((dev->rx_checksum >> 4) & 0x0f) << 3; dev->status = ((dev->rx_checksum >> 4) & 0x0f) << 3;
dev->status |= 0x80; dev->status |= 0x80;
/* We're done with this packet. */ /* We're done with this packet. */
free(dev->rx_pkt); free(dev->rx_pkt);
dev->rx_pkt = NULL; dev->rx_pkt = NULL;
dev->rx_len = 0; dev->rx_len = 0;
dev->state = PLIP_END; dev->state = PLIP_END;
break; break;
case PLIP_END: case PLIP_END:
if (val == 0x00) { /* written after TX or RX is done */ if (val == 0x00) { /* written after TX or RX is done */
plip_log(2, "PLIP: end\n"); plip_log(2, "PLIP: end\n");
dev->status = 0x80; dev->status = 0x80;
dev->state = PLIP_START; dev->state = PLIP_START;
timer_set_delay_u64(&dev->rx_timer, ISACONST); /* for DOS */ timer_set_delay_u64(&dev->rx_timer, ISACONST); /* for DOS */
} }
/* Disengage timeout timer. */ /* Disengage timeout timer. */
timer_disable(&dev->timeout_timer); timer_disable(&dev->timeout_timer);
return; return;
} }
/* Engage timeout timer unless otherwise specified. */ /* Engage timeout timer unless otherwise specified. */
timer_set_delay_u64(&dev->timeout_timer, 1000000 * TIMER_USEC); timer_set_delay_u64(&dev->timeout_timer, 1000000 * TIMER_USEC);
} }
static void static void
plip_write_ctrl(uint8_t val, void *priv) plip_write_ctrl(uint8_t val, void *priv)
{ {
@@ -356,10 +350,9 @@ plip_write_ctrl(uint8_t val, void *priv)
dev->ctrl = val; dev->ctrl = val;
if (val & 0x10) /* for Linux */ if (val & 0x10) /* for Linux */
timer_set_delay_u64(&dev->rx_timer, ISACONST); timer_set_delay_u64(&dev->rx_timer, ISACONST);
} }
static uint8_t static uint8_t
plip_read_status(void *priv) plip_read_status(void *priv)
{ {
@@ -370,31 +363,30 @@ plip_read_status(void *priv)
return dev->status; return dev->status;
} }
static void static void
plip_receive_packet(plip_t *dev) plip_receive_packet(plip_t *dev)
{ {
/* At least the Linux driver supports being interrupted /* At least the Linux driver supports being interrupted
in the PLIP_TX_LEN_LSB_LOW state, but let's be safe. */ in the PLIP_TX_LEN_LSB_LOW state, but let's be safe. */
if (dev->state > PLIP_START) { if (dev->state > PLIP_START) {
plip_log(3, "PLIP: cannot receive, operation already in progress\n"); plip_log(3, "PLIP: cannot receive, operation already in progress\n");
return; return;
} }
if (!dev->rx_pkt || !dev->rx_len) { /* unpause RX queue if there's no packet to receive */ if (!dev->rx_pkt || !dev->rx_len) { /* unpause RX queue if there's no packet to receive */
return; return;
} }
if (!(dev->ctrl & 0x10)) { /* checking this is essential to avoid collisions */ if (!(dev->ctrl & 0x10)) { /* checking this is essential to avoid collisions */
plip_log(3, "PLIP: cannot receive, interrupts are off\n"); plip_log(3, "PLIP: cannot receive, interrupts are off\n");
return; return;
} }
plip_log(2, "PLIP: receiving %d-byte packet\n", dev->rx_len); plip_log(2, "PLIP: receiving %d-byte packet\n", dev->rx_len);
/* Set up to receive a packet. */ /* Set up to receive a packet. */
dev->status = 0xc7; /* DOS expects exactly 0xc7, while Linux masks the 7 off */ dev->status = 0xc7; /* DOS expects exactly 0xc7, while Linux masks the 7 off */
dev->state = PLIP_RX_LEN_LSB_LOW; dev->state = PLIP_RX_LEN_LSB_LOW;
/* Engage timeout timer. */ /* Engage timeout timer. */
timer_set_delay_u64(&dev->timeout_timer, 1000000 * TIMER_USEC); timer_set_delay_u64(&dev->timeout_timer, 1000000 * TIMER_USEC);
@@ -403,7 +395,6 @@ plip_receive_packet(plip_t *dev)
lpt_irq(dev->lpt, 1); lpt_irq(dev->lpt, 1);
} }
/* This timer defers a call to plip_receive_packet to /* This timer defers a call to plip_receive_packet to
the next ISA clock, in order to avoid IRQ weirdness. */ the next ISA clock, in order to avoid IRQ weirdness. */
static void static void
@@ -416,7 +407,6 @@ rx_timer(void *priv)
timer_disable(&dev->rx_timer); timer_disable(&dev->rx_timer);
} }
static int static int
plip_rx(void *priv, uint8_t *buf, int io_len) plip_rx(void *priv, uint8_t *buf, int io_len)
{ {
@@ -425,12 +415,12 @@ plip_rx(void *priv, uint8_t *buf, int io_len)
plip_log(2, "PLIP: incoming %d-byte packet\n", io_len); plip_log(2, "PLIP: incoming %d-byte packet\n", io_len);
if (dev->rx_pkt) { /* shouldn't really happen with the RX queue paused */ if (dev->rx_pkt) { /* shouldn't really happen with the RX queue paused */
plip_log(3, "PLIP: already have a packet to receive"); plip_log(3, "PLIP: already have a packet to receive");
return 0; return 0;
} }
if (!(dev->rx_pkt = malloc(io_len))) /* unlikely */ if (!(dev->rx_pkt = malloc(io_len))) /* unlikely */
fatal("PLIP: unable to allocate rx_pkt\n"); fatal("PLIP: unable to allocate rx_pkt\n");
/* Copy this packet to our buffer. */ /* Copy this packet to our buffer. */
dev->rx_len = io_len; dev->rx_len = io_len;
@@ -442,7 +432,6 @@ plip_rx(void *priv, uint8_t *buf, int io_len)
return 1; return 1;
} }
static void * static void *
plip_lpt_init(void *lpt) plip_lpt_init(void *lpt)
{ {
@@ -464,15 +453,14 @@ plip_lpt_init(void *lpt)
return dev; return dev;
} }
static void * static void *
plip_net_init(const device_t *info) plip_net_init(const device_t *info)
{ {
plip_log(1, "PLIP: net_init()"); plip_log(1, "PLIP: net_init()");
if (!instance) { if (!instance) {
plip_log(1, " (not attached to LPT)\n"); plip_log(1, " (not attached to LPT)\n");
return NULL; return NULL;
} }
plip_log(1, " (attached to LPT)\n"); plip_log(1, " (attached to LPT)\n");
@@ -481,38 +469,37 @@ plip_net_init(const device_t *info)
return instance; return instance;
} }
static void static void
plip_close(void *priv) plip_close(void *priv)
{ {
if (instance->card) { if (instance->card) {
netcard_close(instance->card); netcard_close(instance->card);
} }
free(priv); free(priv);
} }
const lpt_device_t lpt_plip_device = { const lpt_device_t lpt_plip_device = {
.name = "Parallel Line Internet Protocol", .name = "Parallel Line Internet Protocol",
.internal_name = "plip", .internal_name = "plip",
.init = plip_lpt_init, .init = plip_lpt_init,
.close = plip_close, .close = plip_close,
.write_data = plip_write_data, .write_data = plip_write_data,
.write_ctrl = plip_write_ctrl, .write_ctrl = plip_write_ctrl,
.read_data = NULL, .read_data = NULL,
.read_status = plip_read_status, .read_status = plip_read_status,
.read_ctrl = NULL .read_ctrl = NULL
}; };
const device_t plip_device = { const device_t plip_device = {
.name = "Parallel Line Internet Protocol", .name = "Parallel Line Internet Protocol",
.internal_name = "plip", .internal_name = "plip",
.flags = DEVICE_LPT, .flags = DEVICE_LPT,
.local = 0, .local = 0,
.init = plip_net_init, .init = plip_net_init,
.close = NULL, .close = NULL,
.reset = NULL, .reset = NULL,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };

View File

@@ -39,10 +39,10 @@
#include <86box/config.h> #include <86box/config.h>
#include <86box/video.h> #include <86box/video.h>
#ifdef _WIN32 #ifdef _WIN32
#define WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN
#include <windows.h> # include <windows.h>
#else #else
#include <poll.h> # include <poll.h>
#endif #endif
#include <86box/net_event.h> #include <86box/net_event.h>
@@ -75,37 +75,33 @@ typedef struct {
#ifdef ENABLE_SLIRP_LOG #ifdef ENABLE_SLIRP_LOG
int slirp_do_log = ENABLE_SLIRP_LOG; int slirp_do_log = ENABLE_SLIRP_LOG;
static void static void
slirp_log(const char *fmt, ...) slirp_log(const char *fmt, ...)
{ {
va_list ap; va_list ap;
if (slirp_do_log) { if (slirp_do_log) {
va_start(ap, fmt); va_start(ap, fmt);
pclog_ex(fmt, ap); pclog_ex(fmt, ap);
va_end(ap); va_end(ap);
} }
} }
#else #else
#define slirp_log(fmt, ...) # define slirp_log(fmt, ...)
#endif #endif
static void static void
net_slirp_guest_error(const char *msg, void *opaque) net_slirp_guest_error(const char *msg, void *opaque)
{ {
slirp_log("SLiRP: guest_error(): %s\n", msg); slirp_log("SLiRP: guest_error(): %s\n", msg);
} }
static int64_t static int64_t
net_slirp_clock_get_ns(void *opaque) net_slirp_clock_get_ns(void *opaque)
{ {
return (int64_t)((double)tsc / cpuclock * 1000000000.0); return (int64_t) ((double) tsc / cpuclock * 1000000000.0);
} }
static void * static void *
net_slirp_timer_new(SlirpTimerCb cb, void *cb_opaque, void *opaque) net_slirp_timer_new(SlirpTimerCb cb, void *cb_opaque, void *opaque)
{ {
@@ -114,7 +110,6 @@ net_slirp_timer_new(SlirpTimerCb cb, void *cb_opaque, void *opaque)
return timer; return timer;
} }
static void static void
net_slirp_timer_free(void *timer, void *opaque) net_slirp_timer_free(void *timer, void *opaque)
{ {
@@ -122,14 +117,12 @@ net_slirp_timer_free(void *timer, void *opaque)
free(timer); free(timer);
} }
static void static void
net_slirp_timer_mod(void *timer, int64_t expire_timer, void *opaque) net_slirp_timer_mod(void *timer, int64_t expire_timer, void *opaque)
{ {
timer_on_auto(timer, expire_timer * 1000); timer_on_auto(timer, expire_timer * 1000);
} }
static void static void
net_slirp_register_poll_fd(int fd, void *opaque) net_slirp_register_poll_fd(int fd, void *opaque)
{ {
@@ -137,7 +130,6 @@ net_slirp_register_poll_fd(int fd, void *opaque)
(void) opaque; (void) opaque;
} }
static void static void
net_slirp_unregister_poll_fd(int fd, void *opaque) net_slirp_unregister_poll_fd(int fd, void *opaque)
{ {
@@ -145,14 +137,12 @@ net_slirp_unregister_poll_fd(int fd, void *opaque)
(void) opaque; (void) opaque;
} }
static void static void
net_slirp_notify(void *opaque) net_slirp_notify(void *opaque)
{ {
(void) opaque; (void) opaque;
} }
ssize_t ssize_t
net_slirp_send_packet(const void *qp, size_t pkt_len, void *opaque) net_slirp_send_packet(const void *qp, size_t pkt_len, void *opaque)
{ {
@@ -160,20 +150,19 @@ net_slirp_send_packet(const void *qp, size_t pkt_len, void *opaque)
slirp_log("SLiRP: received %d-byte packet\n", pkt_len); slirp_log("SLiRP: received %d-byte packet\n", pkt_len);
memcpy(slirp->pkt.data, (uint8_t*) qp, pkt_len); memcpy(slirp->pkt.data, (uint8_t *) qp, pkt_len);
slirp->pkt.len = pkt_len; slirp->pkt.len = pkt_len;
network_rx_put_pkt(slirp->card, &slirp->pkt); network_rx_put_pkt(slirp->card, &slirp->pkt);
return pkt_len; return pkt_len;
} }
#ifdef _WIN32 #ifdef _WIN32
static int static int
net_slirp_add_poll(int fd, int events, void *opaque) net_slirp_add_poll(int fd, int events, void *opaque)
{ {
net_slirp_t *slirp = (net_slirp_t *) opaque; net_slirp_t *slirp = (net_slirp_t *) opaque;
long bitmask = 0; long bitmask = 0;
if (events & SLIRP_POLL_IN) if (events & SLIRP_POLL_IN)
bitmask |= FD_READ | FD_ACCEPT; bitmask |= FD_READ | FD_ACCEPT;
if (events & SLIRP_POLL_OUT) if (events & SLIRP_POLL_OUT)
@@ -193,17 +182,17 @@ net_slirp_add_poll(int fd, int events, void *opaque)
net_slirp_t *slirp = (net_slirp_t *) opaque; net_slirp_t *slirp = (net_slirp_t *) opaque;
if (slirp->pfd_len >= slirp->pfd_size) { if (slirp->pfd_len >= slirp->pfd_size) {
int newsize = slirp->pfd_size + 16; int newsize = slirp->pfd_size + 16;
struct pollfd *new = realloc(slirp->pfd, newsize * sizeof(struct pollfd)); struct pollfd *new = realloc(slirp->pfd, newsize * sizeof(struct pollfd));
if (new) { if (new) {
slirp->pfd = new; slirp->pfd = new;
slirp->pfd_size = newsize; slirp->pfd_size = newsize;
} }
} }
if ((slirp->pfd_len < slirp->pfd_size)) { if ((slirp->pfd_len < slirp->pfd_size)) {
int idx = slirp->pfd_len++; int idx = slirp->pfd_len++;
slirp->pfd[idx].fd = fd; slirp->pfd[idx].fd = fd;
int pevents = 0; int pevents = 0;
if (events & SLIRP_POLL_IN) if (events & SLIRP_POLL_IN)
pevents |= POLLIN; pevents |= POLLIN;
if (events & SLIRP_POLL_OUT) if (events & SLIRP_POLL_OUT)
@@ -225,8 +214,8 @@ net_slirp_add_poll(int fd, int events, void *opaque)
static int static int
net_slirp_get_revents(int idx, void *opaque) net_slirp_get_revents(int idx, void *opaque)
{ {
net_slirp_t *slirp = (net_slirp_t *) opaque; net_slirp_t *slirp = (net_slirp_t *) opaque;
int ret = 0; int ret = 0;
WSANETWORKEVENTS ev; WSANETWORKEVENTS ev;
if (WSAEnumNetworkEvents(idx, slirp->sock_event, &ev) != 0) { if (WSAEnumNetworkEvents(idx, slirp->sock_event, &ev) != 0) {
return ret; return ret;
@@ -242,9 +231,9 @@ net_slirp_get_revents(int idx, void *opaque)
} \ } \
} while (0) } while (0)
WSA_TO_POLL(FD_READ, SLIRP_POLL_IN); WSA_TO_POLL(FD_READ, SLIRP_POLL_IN);
WSA_TO_POLL(FD_ACCEPT, SLIRP_POLL_IN); WSA_TO_POLL(FD_ACCEPT, SLIRP_POLL_IN);
WSA_TO_POLL(FD_WRITE, SLIRP_POLL_OUT); WSA_TO_POLL(FD_WRITE, SLIRP_POLL_OUT);
WSA_TO_POLL(FD_CONNECT, SLIRP_POLL_OUT); WSA_TO_POLL(FD_CONNECT, SLIRP_POLL_OUT);
WSA_TO_POLL(FD_OOB, SLIRP_POLL_PRI); WSA_TO_POLL(FD_OOB, SLIRP_POLL_PRI);
WSA_TO_POLL(FD_CLOSE, SLIRP_POLL_HUP); WSA_TO_POLL(FD_CLOSE, SLIRP_POLL_HUP);
@@ -255,9 +244,9 @@ net_slirp_get_revents(int idx, void *opaque)
static int static int
net_slirp_get_revents(int idx, void *opaque) net_slirp_get_revents(int idx, void *opaque)
{ {
net_slirp_t *slirp = (net_slirp_t *) opaque; net_slirp_t *slirp = (net_slirp_t *) opaque;
int ret = 0; int ret = 0;
int events = slirp->pfd[idx].revents; int events = slirp->pfd[idx].revents;
if (events & POLLIN) if (events & POLLIN)
ret |= SLIRP_POLL_IN; ret |= SLIRP_POLL_IN;
if (events & POLLOUT) if (events & POLLOUT)
@@ -273,15 +262,15 @@ net_slirp_get_revents(int idx, void *opaque)
#endif #endif
static const SlirpCb slirp_cb = { static const SlirpCb slirp_cb = {
.send_packet = net_slirp_send_packet, .send_packet = net_slirp_send_packet,
.guest_error = net_slirp_guest_error, .guest_error = net_slirp_guest_error,
.clock_get_ns = net_slirp_clock_get_ns, .clock_get_ns = net_slirp_clock_get_ns,
.timer_new = net_slirp_timer_new, .timer_new = net_slirp_timer_new,
.timer_free = net_slirp_timer_free, .timer_free = net_slirp_timer_free,
.timer_mod = net_slirp_timer_mod, .timer_mod = net_slirp_timer_mod,
.register_poll_fd = net_slirp_register_poll_fd, .register_poll_fd = net_slirp_register_poll_fd,
.unregister_poll_fd = net_slirp_unregister_poll_fd, .unregister_poll_fd = net_slirp_unregister_poll_fd,
.notify = net_slirp_notify .notify = net_slirp_notify
}; };
/* Send a packet to the SLiRP interface. */ /* Send a packet to the SLiRP interface. */
@@ -299,7 +288,7 @@ net_slirp_in(net_slirp_t *slirp, uint8_t *pkt, int pkt_len)
void void
net_slirp_in_available(void *priv) net_slirp_in_available(void *priv)
{ {
net_slirp_t *slirp = (net_slirp_t *)priv; net_slirp_t *slirp = (net_slirp_t *) priv;
net_event_set(&slirp->tx_event); net_event_set(&slirp->tx_event);
} }
@@ -314,16 +303,16 @@ net_slirp_thread(void *priv)
HANDLE events[3]; HANDLE events[3];
events[NET_EVENT_STOP] = net_event_get_handle(&slirp->stop_event); events[NET_EVENT_STOP] = net_event_get_handle(&slirp->stop_event);
events[NET_EVENT_TX] = net_event_get_handle(&slirp->tx_event); events[NET_EVENT_TX] = net_event_get_handle(&slirp->tx_event);
events[NET_EVENT_RX] = slirp->sock_event; events[NET_EVENT_RX] = slirp->sock_event;
bool run = true; bool run = true;
while (run) { while (run) {
uint32_t timeout = -1; uint32_t timeout = -1;
slirp_pollfds_fill(slirp->slirp, &timeout, net_slirp_add_poll, slirp); slirp_pollfds_fill(slirp->slirp, &timeout, net_slirp_add_poll, slirp);
if (timeout < 0) if (timeout < 0)
timeout = INFINITE; timeout = INFINITE;
int ret = WaitForMultipleObjects(3, events, FALSE, (DWORD)timeout); int ret = WaitForMultipleObjects(3, events, FALSE, (DWORD) timeout);
switch (ret - WAIT_OBJECT_0) { switch (ret - WAIT_OBJECT_0) {
case NET_EVENT_STOP: case NET_EVENT_STOP:
run = false; run = false;
@@ -341,7 +330,6 @@ net_slirp_thread(void *priv)
default: default:
slirp_pollfds_poll(slirp->slirp, ret == WAIT_FAILED, net_slirp_get_revents, slirp); slirp_pollfds_poll(slirp->slirp, ret == WAIT_FAILED, net_slirp_get_revents, slirp);
break; break;
} }
} }
@@ -398,11 +386,11 @@ net_slirp_init(const netcard_t *card, const uint8_t *mac_addr, void *priv)
slirp_log("SLiRP: initializing...\n"); slirp_log("SLiRP: initializing...\n");
net_slirp_t *slirp = calloc(1, sizeof(net_slirp_t)); net_slirp_t *slirp = calloc(1, sizeof(net_slirp_t));
memcpy(slirp->mac_addr, mac_addr, sizeof(slirp->mac_addr)); memcpy(slirp->mac_addr, mac_addr, sizeof(slirp->mac_addr));
slirp->card = (netcard_t*)card; slirp->card = (netcard_t *) card;
#ifndef _WIN32 #ifndef _WIN32
slirp->pfd_size = 16 * sizeof(struct pollfd); slirp->pfd_size = 16 * sizeof(struct pollfd);
slirp->pfd = malloc(slirp->pfd_size); slirp->pfd = malloc(slirp->pfd_size);
memset(slirp->pfd, 0, slirp->pfd_size); memset(slirp->pfd, 0, slirp->pfd_size);
#endif #endif
@@ -412,7 +400,7 @@ net_slirp_init(const netcard_t *card, const uint8_t *mac_addr, void *priv)
struct in_addr host = { .s_addr = htonl(0x0a000002 | (slirp_card_num << 8)) }; /* 10.0.x.2 */ struct in_addr host = { .s_addr = htonl(0x0a000002 | (slirp_card_num << 8)) }; /* 10.0.x.2 */
struct in_addr dhcp = { .s_addr = htonl(0x0a00000f | (slirp_card_num << 8)) }; /* 10.0.x.15 */ struct in_addr dhcp = { .s_addr = htonl(0x0a00000f | (slirp_card_num << 8)) }; /* 10.0.x.15 */
struct in_addr dns = { .s_addr = htonl(0x0a000003 | (slirp_card_num << 8)) }; /* 10.0.x.3 */ struct in_addr dns = { .s_addr = htonl(0x0a000003 | (slirp_card_num << 8)) }; /* 10.0.x.3 */
struct in_addr bind = { .s_addr = htonl(0x00000000) }; /* 0.0.0.0 */ struct in_addr bind = { .s_addr = htonl(0x00000000) }; /* 0.0.0.0 */
struct in6_addr ipv6_dummy = { 0 }; /* contents don't matter; we're not using IPv6 */ struct in6_addr ipv6_dummy = { 0 }; /* contents don't matter; we're not using IPv6 */
/* Initialize SLiRP. */ /* Initialize SLiRP. */
@@ -424,10 +412,10 @@ net_slirp_init(const netcard_t *card, const uint8_t *mac_addr, void *priv)
} }
/* Set up port forwarding. */ /* Set up port forwarding. */
int udp, external, internal, i = 0; int udp, external, internal, i = 0;
char category[32]; char category[32];
snprintf(category, sizeof(category), "SLiRP Port Forwarding #%i", card->card_num + 1); snprintf(category, sizeof(category), "SLiRP Port Forwarding #%i", card->card_num + 1);
char key[20]; char key[20];
while (1) { while (1) {
sprintf(key, "%d_protocol", i); sprintf(key, "%d_protocol", i);
udp = strcmp(config_get_string(category, key, "tcp"), "udp") == 0; udp = strcmp(config_get_string(category, key, "tcp"), "udp") == 0;

File diff suppressed because it is too large Load Diff

View File

@@ -73,26 +73,25 @@
#include <86box/net_wd8003.h> #include <86box/net_wd8003.h>
#ifdef _WIN32 #ifdef _WIN32
#define WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN
#include <windows.h> # include <windows.h>
#include <winsock2.h> # include <winsock2.h>
#endif #endif
static const device_t net_none_device = { static const device_t net_none_device = {
.name = "None", .name = "None",
.internal_name = "none", .internal_name = "none",
.flags = 0, .flags = 0,
.local = NET_TYPE_NONE, .local = NET_TYPE_NONE,
.init = NULL, .init = NULL,
.close = NULL, .close = NULL,
.reset = NULL, .reset = NULL,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };
static const device_t *net_cards[] = { static const device_t *net_cards[] = {
&net_none_device, &net_none_device,
&threec503_device, &threec503_device,
@@ -118,72 +117,68 @@ static const device_t *net_cards[] = {
}; };
netcard_conf_t net_cards_conf[NET_CARD_MAX]; netcard_conf_t net_cards_conf[NET_CARD_MAX];
int net_card_current = 0; int net_card_current = 0;
/* Global variables. */ /* Global variables. */
int network_ndev; int network_ndev;
netdev_t network_devs[NET_HOST_INTF_MAX]; netdev_t network_devs[NET_HOST_INTF_MAX];
/* Local variables. */ /* Local variables. */
#ifdef ENABLE_NETWORK_LOG #ifdef ENABLE_NETWORK_LOG
int network_do_log = ENABLE_NETWORK_LOG; int network_do_log = ENABLE_NETWORK_LOG;
static FILE *network_dump = NULL; static FILE *network_dump = NULL;
static mutex_t *network_dump_mutex; static mutex_t *network_dump_mutex;
static void static void
network_log(const char *fmt, ...) network_log(const char *fmt, ...)
{ {
va_list ap; va_list ap;
if (network_do_log) { if (network_do_log) {
va_start(ap, fmt); va_start(ap, fmt);
pclog_ex(fmt, ap); pclog_ex(fmt, ap);
va_end(ap); va_end(ap);
} }
} }
static void static void
network_dump_packet(netpkt_t *pkt) network_dump_packet(netpkt_t *pkt)
{ {
if (!network_dump) if (!network_dump)
return; return;
struct timeval tv; struct timeval tv;
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
struct { struct {
uint32_t ts_sec, ts_usec, incl_len, orig_len; uint32_t ts_sec, ts_usec, incl_len, orig_len;
} pcap_packet_hdr = { } pcap_packet_hdr = {
tv.tv_sec, tv.tv_usec, pkt->len, pkt->len tv.tv_sec, tv.tv_usec, pkt->len, pkt->len
}; };
if (network_dump_mutex) if (network_dump_mutex)
thread_wait_mutex(network_dump_mutex); thread_wait_mutex(network_dump_mutex);
size_t written; size_t written;
if ((written = fwrite(&pcap_packet_hdr, 1, sizeof(pcap_packet_hdr), network_dump)) < sizeof(pcap_packet_hdr)) { if ((written = fwrite(&pcap_packet_hdr, 1, sizeof(pcap_packet_hdr), network_dump)) < sizeof(pcap_packet_hdr)) {
network_log("NETWORK: failed to write dump packet header\n"); network_log("NETWORK: failed to write dump packet header\n");
fseek(network_dump, -written, SEEK_CUR); fseek(network_dump, -written, SEEK_CUR);
} else { } else {
if ((written = fwrite(pkt->data, 1, pkt->len, network_dump)) < pkt->len) { if ((written = fwrite(pkt->data, 1, pkt->len, network_dump)) < pkt->len) {
network_log("NETWORK: failed to write dump packet data\n"); network_log("NETWORK: failed to write dump packet data\n");
fseek(network_dump, -written - sizeof(pcap_packet_hdr), SEEK_CUR); fseek(network_dump, -written - sizeof(pcap_packet_hdr), SEEK_CUR);
} }
fflush(network_dump); fflush(network_dump);
} }
if (network_dump_mutex) if (network_dump_mutex)
thread_release_mutex(network_dump_mutex); thread_release_mutex(network_dump_mutex);
} }
#else #else
#define network_log(fmt, ...) # define network_log(fmt, ...)
#define network_dump_packet(pkt) # define network_dump_packet(pkt)
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
static void static void
network_winsock_clean(void) network_winsock_clean(void)
@@ -218,22 +213,22 @@ network_init(void)
/* Initialize the Pcap system module, if present. */ /* Initialize the Pcap system module, if present. */
i = net_pcap_prepare(&network_devs[network_ndev]); i = net_pcap_prepare(&network_devs[network_ndev]);
if (i > 0) if (i > 0)
network_ndev += i; network_ndev += i;
#ifdef ENABLE_NETWORK_LOG #ifdef ENABLE_NETWORK_LOG
/* Start packet dump. */ /* Start packet dump. */
network_dump = fopen("network.pcap", "wb"); network_dump = fopen("network.pcap", "wb");
struct { struct {
uint32_t magic_number; uint32_t magic_number;
uint16_t version_major, version_minor; uint16_t version_major, version_minor;
int32_t thiszone; int32_t thiszone;
uint32_t sigfigs, snaplen, network; uint32_t sigfigs, snaplen, network;
} pcap_hdr = { } pcap_hdr = {
0xa1b2c3d4, 0xa1b2c3d4,
2, 4, 2, 4,
0, 0,
0, 65535, 1 0, 65535, 1
}; };
fwrite(&pcap_hdr, sizeof(pcap_hdr), 1, network_dump); fwrite(&pcap_hdr, sizeof(pcap_hdr), 1, network_dump);
fflush(network_dump); fflush(network_dump);
@@ -244,11 +239,10 @@ void
network_queue_init(netqueue_t *queue) network_queue_init(netqueue_t *queue)
{ {
queue->head = queue->tail = 0; queue->head = queue->tail = 0;
for (int i=0; i<NET_QUEUE_LEN; i++) { for (int i = 0; i < NET_QUEUE_LEN; i++) {
queue->packets[i].data = calloc(1, NET_MAX_FRAME); queue->packets[i].data = calloc(1, NET_MAX_FRAME);
queue->packets[i].len = 0; queue->packets[i].len = 0;
} }
} }
static bool static bool
@@ -267,8 +261,8 @@ static inline void
network_swap_packet(netpkt_t *pkt1, netpkt_t *pkt2) network_swap_packet(netpkt_t *pkt1, netpkt_t *pkt2)
{ {
netpkt_t tmp = *pkt2; netpkt_t tmp = *pkt2;
*pkt2 = *pkt1; *pkt2 = *pkt1;
*pkt1 = tmp; *pkt1 = tmp;
} }
int int
@@ -280,7 +274,7 @@ network_queue_put(netqueue_t *queue, uint8_t *data, int len)
netpkt_t *pkt = &queue->packets[queue->head]; netpkt_t *pkt = &queue->packets[queue->head];
memcpy(pkt->data, data, len); memcpy(pkt->data, data, len);
pkt->len = len; pkt->len = len;
queue->head = (queue->head + 1) & NET_QUEUE_LEN_MASK; queue->head = (queue->head + 1) & NET_QUEUE_LEN_MASK;
return 1; return 1;
} }
@@ -300,7 +294,8 @@ network_queue_put_swap(netqueue_t *queue, netpkt_t *src_pkt)
} }
static int static int
network_queue_get_swap(netqueue_t *queue, netpkt_t *dst_pkt) { network_queue_get_swap(netqueue_t *queue, netpkt_t *dst_pkt)
{
if (network_queue_empty(queue)) if (network_queue_empty(queue))
return 0; return 0;
@@ -333,18 +328,17 @@ network_queue_move(netqueue_t *dst_q, netqueue_t *src_q)
void void
network_queue_clear(netqueue_t *queue) network_queue_clear(netqueue_t *queue)
{ {
for (int i=0; i<NET_QUEUE_LEN; i++) { for (int i = 0; i < NET_QUEUE_LEN; i++) {
free(queue->packets[i].data); free(queue->packets[i].data);
queue->packets[i].len = 0; queue->packets[i].len = 0;
} }
queue->tail = queue->head = 0; queue->tail = queue->head = 0;
} }
static void static void
network_rx_queue(void *priv) network_rx_queue(void *priv)
{ {
netcard_t *card = (netcard_t *)priv; netcard_t *card = (netcard_t *) priv;
uint32_t new_link_state = net_cards_conf[card->card_num].link_state; uint32_t new_link_state = net_cards_conf[card->card_num].link_state;
if (new_link_state != card->link_state) { if (new_link_state != card->link_state) {
@@ -393,7 +387,7 @@ network_rx_queue(void *priv)
timer_on_auto(&card->timer, timer_period); timer_on_auto(&card->timer, timer_period);
bool activity = rx_bytes || tx_bytes; bool activity = rx_bytes || tx_bytes;
bool led_on = card->led_timer & 0x80000000; bool led_on = card->led_timer & 0x80000000;
if ((activity && !led_on) || (card->led_timer & 0x7fffffff) >= 150000) { if ((activity && !led_on) || (card->led_timer & 0x7fffffff) >= 150000) {
ui_sb_update_icon(SB_NETWORK | card->card_num, activity); ui_sb_update_icon(SB_NETWORK | card->card_num, activity);
card->led_timer = 0 | (activity << 31); card->led_timer = 0 | (activity << 31);
@@ -402,7 +396,6 @@ network_rx_queue(void *priv)
card->led_timer += timer_period; card->led_timer += timer_period;
} }
/* /*
* Attach a network card to the system. * Attach a network card to the system.
* *
@@ -413,29 +406,29 @@ network_rx_queue(void *priv)
netcard_t * netcard_t *
network_attach(void *card_drv, uint8_t *mac, NETRXCB rx, NETSETLINKSTATE set_link_state) network_attach(void *card_drv, uint8_t *mac, NETRXCB rx, NETSETLINKSTATE set_link_state)
{ {
netcard_t *card = calloc(1, sizeof(netcard_t)); netcard_t *card = calloc(1, sizeof(netcard_t));
card->queued_pkt.data = calloc(1, NET_MAX_FRAME); card->queued_pkt.data = calloc(1, NET_MAX_FRAME);
card->card_drv = card_drv; card->card_drv = card_drv;
card->rx = rx; card->rx = rx;
card->set_link_state = set_link_state; card->set_link_state = set_link_state;
card->tx_mutex = thread_create_mutex(); card->tx_mutex = thread_create_mutex();
card->rx_mutex = thread_create_mutex(); card->rx_mutex = thread_create_mutex();
card->card_num = net_card_current; card->card_num = net_card_current;
card->byte_period = NET_PERIOD_10M; card->byte_period = NET_PERIOD_10M;
for (int i=0; i<3; i++) { for (int i = 0; i < 3; i++) {
network_queue_init(&card->queues[i]); network_queue_init(&card->queues[i]);
} }
switch (net_cards_conf[net_card_current].net_type) { switch (net_cards_conf[net_card_current].net_type) {
case NET_TYPE_SLIRP: case NET_TYPE_SLIRP:
default: default:
card->host_drv = net_slirp_drv; card->host_drv = net_slirp_drv;
card->host_drv.priv = card->host_drv.init(card, mac, NULL); card->host_drv.priv = card->host_drv.init(card, mac, NULL);
break; break;
case NET_TYPE_PCAP: case NET_TYPE_PCAP:
card->host_drv = net_pcap_drv; card->host_drv = net_pcap_drv;
card->host_drv.priv = card->host_drv.init(card, mac, net_cards_conf[net_card_current].host_dev_name); card->host_drv.priv = card->host_drv.init(card, mac, net_cards_conf[net_card_current].host_dev_name);
break; break;
} }
@@ -443,7 +436,7 @@ network_attach(void *card_drv, uint8_t *mac, NETRXCB rx, NETSETLINKSTATE set_lin
if (!card->host_drv.priv) { if (!card->host_drv.priv) {
thread_close_mutex(card->tx_mutex); thread_close_mutex(card->tx_mutex);
thread_close_mutex(card->rx_mutex); thread_close_mutex(card->rx_mutex);
for (int i=0; i<3; i++) { for (int i = 0; i < 3; i++) {
network_queue_clear(&card->queues[i]); network_queue_clear(&card->queues[i]);
} }
@@ -466,7 +459,7 @@ netcard_close(netcard_t *card)
thread_close_mutex(card->tx_mutex); thread_close_mutex(card->tx_mutex);
thread_close_mutex(card->rx_mutex); thread_close_mutex(card->rx_mutex);
for (int i=0; i<3; i++) { for (int i = 0; i < 3; i++) {
network_queue_clear(&card->queues[i]); network_queue_clear(&card->queues[i]);
} }
@@ -474,7 +467,6 @@ netcard_close(netcard_t *card)
free(card); free(card);
} }
/* Stop any network activity. */ /* Stop any network activity. */
void void
network_close(void) network_close(void)
@@ -487,7 +479,6 @@ network_close(void)
network_log("NETWORK: closed.\n"); network_log("NETWORK: closed.\n");
} }
/* /*
* Reset the network card(s). * Reset the network card(s).
* *
@@ -508,16 +499,15 @@ network_reset(void)
#endif #endif
for (i = 0; i < NET_CARD_MAX; i++) { for (i = 0; i < NET_CARD_MAX; i++) {
if (!network_dev_available(i)) { if (!network_dev_available(i)) {
continue; continue;
} }
net_card_current = i; net_card_current = i;
device_add_inst(net_cards[net_cards_conf[i].device_num], i + 1); device_add_inst(net_cards[net_cards_conf[i].device_num], i + 1);
} }
} }
/* Queue a packet for transmission to one of the network providers. */ /* Queue a packet for transmission to one of the network providers. */
void void
network_tx(netcard_t *card, uint8_t *bufp, int len) network_tx(netcard_t *card, uint8_t *bufp, int len)
@@ -525,7 +515,8 @@ network_tx(netcard_t *card, uint8_t *bufp, int len)
network_queue_put(&card->queues[NET_QUEUE_TX_VM], bufp, len); network_queue_put(&card->queues[NET_QUEUE_TX_VM], bufp, len);
} }
int network_tx_pop(netcard_t *card, netpkt_t *out_pkt) int
network_tx_pop(netcard_t *card, netpkt_t *out_pkt)
{ {
int ret = 0; int ret = 0;
@@ -536,7 +527,8 @@ int network_tx_pop(netcard_t *card, netpkt_t *out_pkt)
return ret; return ret;
} }
int network_tx_popv(netcard_t *card, netpkt_t *pkt_vec, int vec_size) int
network_tx_popv(netcard_t *card, netpkt_t *pkt_vec, int vec_size)
{ {
int pkt_count = 0; int pkt_count = 0;
@@ -553,7 +545,8 @@ int network_tx_popv(netcard_t *card, netpkt_t *pkt_vec, int vec_size)
return pkt_count; return pkt_count;
} }
int network_rx_put(netcard_t *card, uint8_t *bufp, int len) int
network_rx_put(netcard_t *card, uint8_t *bufp, int len)
{ {
int ret = 0; int ret = 0;
@@ -564,7 +557,8 @@ int network_rx_put(netcard_t *card, uint8_t *bufp, int len)
return ret; return ret;
} }
int network_rx_put_pkt(netcard_t *card, netpkt_t *pkt) int
network_rx_put_pkt(netcard_t *card, netpkt_t *pkt)
{ {
int ret = 0; int ret = 0;
@@ -602,16 +596,15 @@ network_dev_to_id(char *devname)
{ {
int i = 0; int i = 0;
for (i=0; i<network_ndev; i++) { for (i = 0; i < network_ndev; i++) {
if (! strcmp((char *)network_devs[i].device, devname)) { if (!strcmp((char *) network_devs[i].device, devname)) {
return(i); return (i);
} }
} }
return(-1); return (-1);
} }
/* UI */ /* UI */
int int
network_dev_available(int id) network_dev_available(int id)
@@ -629,43 +622,40 @@ network_available(void)
{ {
int available = 0; int available = 0;
for (int i = 0; i < NET_CARD_MAX; i ++) { for (int i = 0; i < NET_CARD_MAX; i++) {
available |= network_dev_available(i); available |= network_dev_available(i);
} }
return available; return available;
} }
/* UI */ /* UI */
int int
network_card_available(int card) network_card_available(int card)
{ {
if (net_cards[card]) if (net_cards[card])
return(device_available(net_cards[card])); return (device_available(net_cards[card]));
return(1); return (1);
} }
/* UI */ /* UI */
const device_t * const device_t *
network_card_getdevice(int card) network_card_getdevice(int card)
{ {
return(net_cards[card]); return (net_cards[card]);
} }
/* UI */ /* UI */
int int
network_card_has_config(int card) network_card_has_config(int card)
{ {
if (!net_cards[card]) return(0); if (!net_cards[card])
return (0);
return(device_has_config(net_cards[card]) ? 1 : 0); return (device_has_config(net_cards[card]) ? 1 : 0);
} }
/* UI */ /* UI */
char * char *
network_card_get_internal_name(int card) network_card_get_internal_name(int card)
@@ -673,7 +663,6 @@ network_card_get_internal_name(int card)
return device_get_internal_name(net_cards[card]); return device_get_internal_name(net_cards[card]);
} }
/* UI */ /* UI */
int int
network_card_get_from_internal_name(char *s) network_card_get_from_internal_name(char *s)
@@ -681,9 +670,9 @@ network_card_get_from_internal_name(char *s)
int c = 0; int c = 0;
while (net_cards[c] != NULL) { while (net_cards[c] != NULL) {
if (! strcmp((char *)net_cards[c]->internal_name, s)) if (!strcmp((char *) net_cards[c]->internal_name, s))
return(c); return (c);
c++; c++;
} }
return 0; return 0;

View File

@@ -58,108 +58,101 @@
#include <86box/plat.h> #include <86box/plat.h>
#include <86box/plat_dynld.h> #include <86box/plat_dynld.h>
static void *pcap_handle; /* handle to WinPcap DLL */
static void *pcap_handle; /* handle to WinPcap DLL */
/* Pointers to the real functions. */ /* Pointers to the real functions. */
static int (*f_pcap_findalldevs)(pcap_if_t **,char *); static int (*f_pcap_findalldevs)(pcap_if_t **, char *);
static void (*f_pcap_freealldevs)(pcap_if_t *); static void (*f_pcap_freealldevs)(pcap_if_t *);
static pcap_t *(*f_pcap_open_live)(const char *,int,int,int,char *); static pcap_t *(*f_pcap_open_live)(const char *, int, int, int, char *);
static int (*f_pcap_next_ex)(pcap_t*,struct pcap_pkthdr**,const unsigned char**); static int (*f_pcap_next_ex)(pcap_t *, struct pcap_pkthdr **, const unsigned char **);
static void (*f_pcap_close)(pcap_t *); static void (*f_pcap_close)(pcap_t *);
static dllimp_t pcap_imports[] = { static dllimp_t pcap_imports[] = {
// clang-format off // clang-format off
{ "pcap_findalldevs", &f_pcap_findalldevs }, { "pcap_findalldevs", &f_pcap_findalldevs },
{ "pcap_freealldevs", &f_pcap_freealldevs }, { "pcap_freealldevs", &f_pcap_freealldevs },
{ "pcap_open_live", &f_pcap_open_live }, { "pcap_open_live", &f_pcap_open_live },
{ "pcap_next_ex", &f_pcap_next_ex }, { "pcap_next_ex", &f_pcap_next_ex },
{ "pcap_close", &f_pcap_close }, { "pcap_close", &f_pcap_close },
{ NULL, NULL }, { NULL, NULL },
// clang-format on // clang-format on
}; };
typedef struct { typedef struct {
char device[128]; char device[128];
char description[128]; char description[128];
} capdev_t; } capdev_t;
/* Retrieve an easy-to-use list of devices. */ /* Retrieve an easy-to-use list of devices. */
static int static int
get_devlist(capdev_t *list) get_devlist(capdev_t *list)
{ {
char errbuf[PCAP_ERRBUF_SIZE]; char errbuf[PCAP_ERRBUF_SIZE];
pcap_if_t *devlist, *dev; pcap_if_t *devlist, *dev;
int i = 0; int i = 0;
/* Retrieve the device list from the local machine */ /* Retrieve the device list from the local machine */
if (f_pcap_findalldevs(&devlist, errbuf) == -1) { if (f_pcap_findalldevs(&devlist, errbuf) == -1) {
fprintf(stderr,"Error in pcap_findalldevs_ex: %s\n", errbuf); fprintf(stderr, "Error in pcap_findalldevs_ex: %s\n", errbuf);
return(-1); return (-1);
} }
for (dev=devlist; dev!=NULL; dev=dev->next) { for (dev = devlist; dev != NULL; dev = dev->next) {
strcpy(list->device, dev->name); strcpy(list->device, dev->name);
if (dev->description) if (dev->description)
strcpy(list->description, dev->description); strcpy(list->description, dev->description);
else else
memset(list->description, '\0', sizeof(list->description)); memset(list->description, '\0', sizeof(list->description));
list++; list++;
i++; i++;
} }
/* Release the memory. */ /* Release the memory. */
f_pcap_freealldevs(devlist); f_pcap_freealldevs(devlist);
return(i); return (i);
} }
/* Simple HEXDUMP routine for raw data. */ /* Simple HEXDUMP routine for raw data. */
static void static void
hex_dump(unsigned char *bufp, int len) hex_dump(unsigned char *bufp, int len)
{ {
char asci[20]; char asci[20];
unsigned char c; unsigned char c;
long addr; long addr;
addr = 0; addr = 0;
while (len-- > 0) { while (len-- > 0) {
c = bufp[addr]; c = bufp[addr];
if ((addr % 16) == 0) if ((addr % 16) == 0)
printf("%04lx %02x", addr, c); printf("%04lx %02x", addr, c);
else else
printf(" %02x", c); printf(" %02x", c);
asci[(addr & 15)] = (uint8_t)isprint(c) ? c : '.'; asci[(addr & 15)] = (uint8_t) isprint(c) ? c : '.';
if ((++addr % 16) == 0) { if ((++addr % 16) == 0) {
asci[16] = '\0'; asci[16] = '\0';
printf(" | %s |\n", asci); printf(" | %s |\n", asci);
} }
} }
if (addr % 16) { if (addr % 16) {
while (addr % 16) { while (addr % 16) {
printf(" "); printf(" ");
asci[(addr & 15)] = ' '; asci[(addr & 15)] = ' ';
addr++; addr++;
} }
asci[16] = '\0'; asci[16] = '\0';
printf(" | %s |\n", asci); printf(" | %s |\n", asci);
} }
} }
/* Print a standard Ethernet MAC address. */ /* Print a standard Ethernet MAC address. */
static void static void
eth_praddr(unsigned char *ptr) eth_praddr(unsigned char *ptr)
{ {
printf("%02x:%02x:%02x:%02x:%02x:%02x", printf("%02x:%02x:%02x:%02x:%02x:%02x",
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]); ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
} }
/* Print a standard Ethernet header. */ /* Print a standard Ethernet header. */
static int static int
eth_prhdr(unsigned char *ptr) eth_prhdr(unsigned char *ptr)
@@ -167,66 +160,66 @@ eth_prhdr(unsigned char *ptr)
unsigned short type; unsigned short type;
printf("Ethernet "); printf("Ethernet ");
eth_praddr(ptr+6); eth_praddr(ptr + 6);
printf(" > "); printf(" > ");
eth_praddr(ptr); eth_praddr(ptr);
type = (ptr[12] << 8) | ptr[13]; type = (ptr[12] << 8) | ptr[13];
printf(" type %04x\n", type); printf(" type %04x\n", type);
return(14); return (14);
} }
/* Capture packets from the network, and print them. */ /* Capture packets from the network, and print them. */
static int static int
start_cap(char *dev) start_cap(char *dev)
{ {
char temp[PCAP_ERRBUF_SIZE]; char temp[PCAP_ERRBUF_SIZE];
struct pcap_pkthdr *hdr; struct pcap_pkthdr *hdr;
const unsigned char *pkt; const unsigned char *pkt;
struct tm *ltime; struct tm *ltime;
time_t now; time_t now;
pcap_t *pcap; pcap_t *pcap;
int rc; int rc;
/* Open the device for reading from it. */ /* Open the device for reading from it. */
pcap = f_pcap_open_live(dev, pcap = f_pcap_open_live(dev,
1518, /* MTU */ 1518, /* MTU */
1, /* promisc mode */ 1, /* promisc mode */
10, /* timeout */ 10, /* timeout */
temp); temp);
if (pcap == NULL) { if (pcap == NULL) {
fprintf(stderr, "Pcap: open_live(%s): %s\n", dev, temp); fprintf(stderr, "Pcap: open_live(%s): %s\n", dev, temp);
return(2); return (2);
} }
printf("Listening on '%s'..\n", dev); printf("Listening on '%s'..\n", dev);
for (;;) { for (;;) {
rc = f_pcap_next_ex(pcap, &hdr, &pkt); rc = f_pcap_next_ex(pcap, &hdr, &pkt);
if (rc < 0) break; if (rc < 0)
break;
/* Did we time out? */ /* Did we time out? */
if (rc == 0) continue; if (rc == 0)
continue;
/* Convert the timestamp to readable format. */ /* Convert the timestamp to readable format. */
now = hdr->ts.tv_sec; now = hdr->ts.tv_sec;
ltime = localtime(&now); ltime = localtime(&now);
strftime(temp, sizeof(temp), "%H:%M:%S", ltime); strftime(temp, sizeof(temp), "%H:%M:%S", ltime);
/* Process and print the packet. */ /* Process and print the packet. */
printf("\n<< %s,%.6ld len=%u\n", printf("\n<< %s,%.6ld len=%u\n",
temp, hdr->ts.tv_usec, hdr->len); temp, hdr->ts.tv_usec, hdr->len);
rc = eth_prhdr((unsigned char *)pkt); rc = eth_prhdr((unsigned char *) pkt);
hex_dump((unsigned char *)pkt+rc, hdr->len-rc); hex_dump((unsigned char *) pkt + rc, hdr->len - rc);
} }
/* All done, close up. */ /* All done, close up. */
f_pcap_close(pcap); f_pcap_close(pcap);
return(0); return (0);
} }
/* Show a list of available network interfaces. */ /* Show a list of available network interfaces. */
static void static void
show_devs(capdev_t *list, int num) show_devs(capdev_t *list, int num)
@@ -234,23 +227,22 @@ show_devs(capdev_t *list, int num)
int i; int i;
if (num > 0) { if (num > 0) {
printf("Available network interfaces:\n\n"); printf("Available network interfaces:\n\n");
for (i=0; i<num; i++) { for (i = 0; i < num; i++) {
printf(" %d - %s\n", i+1, list->device); printf(" %d - %s\n", i + 1, list->device);
if (list->description[0] != '\0') if (list->description[0] != '\0')
printf(" (%s)\n", list->description); printf(" (%s)\n", list->description);
else else
printf(" (No description available)\n"); printf(" (No description available)\n");
list++; list++;
printf("\n"); printf("\n");
} }
} else { } else {
printf("No interfaces found!\nMake sure WinPcap is installed.\n"); printf("No interfaces found!\nMake sure WinPcap is installed.\n");
} }
} }
void void
pclog(const char *fmt, ...) pclog(const char *fmt, ...)
{ {
@@ -261,12 +253,11 @@ pclog(const char *fmt, ...)
va_end(ap); va_end(ap);
} }
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
capdev_t interfaces[32]; capdev_t interfaces[32];
int numdev, i; int numdev, i;
/* Try loading the DLL. */ /* Try loading the DLL. */
#ifdef _WIN32 #ifdef _WIN32
@@ -278,39 +269,39 @@ main(int argc, char **argv)
#endif #endif
if (pcap_handle == NULL) { if (pcap_handle == NULL) {
#ifdef _WIN32 #ifdef _WIN32
fprintf(stderr, "Unable to load WinPcap DLL !\n"); fprintf(stderr, "Unable to load WinPcap DLL !\n");
#else #else
fprintf(stderr, "Unable to load libpcap.so !\n"); fprintf(stderr, "Unable to load libpcap.so !\n");
#endif #endif
return(1); return (1);
} }
/* Get the list. */ /* Get the list. */
numdev = get_devlist(interfaces); numdev = get_devlist(interfaces);
if (argc == 1) { if (argc == 1) {
/* No arguments, just show the list. */ /* No arguments, just show the list. */
show_devs(interfaces, numdev); show_devs(interfaces, numdev);
dynld_close(pcap_handle); dynld_close(pcap_handle);
return(numdev); return (numdev);
} }
/* Assume argument to be the interface number to listen on. */ /* Assume argument to be the interface number to listen on. */
i = atoi(argv[1]); i = atoi(argv[1]);
if (i < 0 || i > numdev) { if (i < 0 || i > numdev) {
fprintf(stderr, "Invalid interface number %d !\n", i); fprintf(stderr, "Invalid interface number %d !\n", i);
dynld_close(pcap_handle); dynld_close(pcap_handle);
return(1); return (1);
} }
/* Looks good, go and listen.. */ /* Looks good, go and listen.. */
i = start_cap(interfaces[i-1].device); i = start_cap(interfaces[i - 1].device);
dynld_close(pcap_handle); dynld_close(pcap_handle);
return(i); return (i);
} }