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

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -52,14 +52,14 @@
#include <wchar.h>
#include <stdbool.h>
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# include <winsock2.h>
#else
#include <poll.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/select.h>
# include <poll.h>
# include <unistd.h>
# include <fcntl.h>
# include <sys/select.h>
#endif
#define HAVE_STDARG_H
@@ -82,45 +82,45 @@ enum {
};
#ifdef __APPLE__
#include <pcap/pcap.h>
# include <pcap/pcap.h>
#else
typedef int bpf_int32;
typedef int bpf_int32;
typedef unsigned int bpf_u_int32;
/*
* The instruction data structure.
*/
struct bpf_insn {
unsigned short code;
unsigned char jt;
unsigned char jf;
bpf_u_int32 k;
unsigned short code;
unsigned char jt;
unsigned char jf;
bpf_u_int32 k;
};
/*
* Structure for "pcap_compile()", "pcap_setfilter()", etc..
*/
struct bpf_program {
unsigned int bf_len;
unsigned int bf_len;
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 timeval ts;
bpf_u_int32 caplen;
bpf_u_int32 len;
struct timeval ts;
bpf_u_int32 caplen;
bpf_u_int32 len;
};
struct pcap_if {
struct pcap_if *next;
char *name;
char *description;
void *addresses;
bpf_u_int32 flags;
char *name;
char *description;
void *addresses;
bpf_u_int32 flags;
};
struct pcap_send_queue {
@@ -154,39 +154,39 @@ typedef struct {
uint8_t *mac_addr;
} 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. */
static const char *(*f_pcap_lib_version)(void);
static int (*f_pcap_findalldevs)(pcap_if_t **,char *);
static void (*f_pcap_freealldevs)(void *);
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_setfilter)(void *,void *);
static const char *(*f_pcap_lib_version)(void);
static int (*f_pcap_findalldevs)(pcap_if_t **, char *);
static void (*f_pcap_freealldevs)(void *);
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_setfilter)(void *, void *);
static const unsigned char
*(*f_pcap_next)(void *,void *);
static int (*f_pcap_sendpacket)(void *,const unsigned char *,int);
static void (*f_pcap_close)(void *);
static int (*f_pcap_setnonblock)(void*, int, char*);
static int (*f_pcap_set_immediate_mode)(void *, int);
static int (*f_pcap_set_promisc)(void *, int);
static int (*f_pcap_set_snaplen)(void *, int);
static int (*f_pcap_dispatch)(void *, int, pcap_handler callback, u_char *user);
static void *(*f_pcap_create)(const char *, char*);
static int (*f_pcap_activate)(void *);
static void *(*f_pcap_geterr)(void *);
*(*f_pcap_next)(void *, void *);
static int (*f_pcap_sendpacket)(void *, const unsigned char *, int);
static void (*f_pcap_close)(void *);
static int (*f_pcap_setnonblock)(void *, int, char *);
static int (*f_pcap_set_immediate_mode)(void *, int);
static int (*f_pcap_set_promisc)(void *, int);
static int (*f_pcap_set_snaplen)(void *, int);
static int (*f_pcap_dispatch)(void *, int, pcap_handler callback, u_char *user);
static void *(*f_pcap_create)(const char *, char *);
static int (*f_pcap_activate)(void *);
static void *(*f_pcap_geterr)(void *);
#ifdef _WIN32
static HANDLE (*f_pcap_getevent)(void *);
static int (*f_pcap_sendqueue_queue)(void *, void *, void *);
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_destroy)(void *);
static int (*f_pcap_sendqueue_queue)(void *, void *, void *);
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_destroy)(void *);
#else
static int (*f_pcap_get_selectable_fd)(void *);
static int (*f_pcap_get_selectable_fd)(void *);
#endif
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_freealldevs", &f_pcap_freealldevs },
{ "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_destroy", &f_pcap_sendqueue_destroy },
#else
{ "pcap_get_selectable_fd", &f_pcap_get_selectable_fd },
{ "pcap_get_selectable_fd", &f_pcap_get_selectable_fd },
#endif
{ NULL, NULL },
};
@@ -224,20 +224,19 @@ pcap_log(const char *fmt, ...)
va_list ap;
if (pcap_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define pcap_log(fmt, ...)
# define pcap_log(fmt, ...)
#endif
static void
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);
pcap->pkt.len = h->caplen;
network_rx_put_pkt(pcap->card, &pcap->pkt);
@@ -248,15 +247,15 @@ void
net_pcap_in(void *pcap, uint8_t *bufp, int len)
{
if (pcap == NULL)
return;
return;
f_pcap_sendpacket((void *)pcap, bufp, len);
f_pcap_sendpacket((void *) pcap, bufp, len);
}
void
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);
}
@@ -264,14 +263,14 @@ net_pcap_in_available(void *priv)
static void
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");
HANDLE events[NET_EVENT_MAX];
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_RX] = f_pcap_getevent((void *)pcap->pcap);
events[NET_EVENT_TX] = net_event_get_handle(&pcap->tx_event);
events[NET_EVENT_RX] = f_pcap_getevent((void *) pcap->pcap);
bool run = true;
@@ -297,7 +296,7 @@ net_pcap_thread(void *priv)
break;
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;
}
}
@@ -308,7 +307,7 @@ net_pcap_thread(void *priv)
static void
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");
@@ -341,9 +340,8 @@ net_pcap_thread(void *priv)
}
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");
@@ -360,9 +358,9 @@ net_pcap_thread(void *priv)
int
net_pcap_prepare(netdev_t *list)
{
char errbuf[PCAP_ERRBUF_SIZE];
char errbuf[PCAP_ERRBUF_SIZE];
pcap_if_t *devlist, *dev;
int i = 0;
int i = 0;
/* Try loading the DLL. */
#ifdef _WIN32
@@ -374,44 +372,44 @@ net_pcap_prepare(netdev_t *list)
#endif
if (libpcap_handle == NULL) {
pcap_log("PCAP: error loading pcap module\n");
return(-1);
return (-1);
}
/* Retrieve the device list from the local machine */
if (f_pcap_findalldevs(&devlist, errbuf) == -1) {
pcap_log("PCAP: error in pcap_findalldevs: %s\n", errbuf);
return(-1);
pcap_log("PCAP: error in pcap_findalldevs: %s\n", errbuf);
return (-1);
}
for (dev=devlist; dev!=NULL; dev=dev->next) {
if (i >= (NET_HOST_INTF_MAX - 1))
break;
for (dev = devlist; dev != NULL; dev = dev->next) {
if (i >= (NET_HOST_INTF_MAX - 1))
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->description, '\0', sizeof(list->description));
memset(list->device, '\0', sizeof(list->device));
memset(list->description, '\0', sizeof(list->description));
strncpy(list->device, dev->name, sizeof(list->device) - 1);
if (dev->description) {
strncpy(list->description, dev->description, sizeof(list->description) - 1);
} else {
/* 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->device, dev->name, sizeof(list->device) - 1);
if (dev->description) {
strncpy(list->description, dev->description, sizeof(list->description) - 1);
} else {
/* 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);
}
list++; i++;
list++;
i++;
}
/* Release the memory. */
f_pcap_freealldevs(devlist);
return(i);
return (i);
}
/*
* Initialize (Win)Pcap for use.
*
@@ -422,12 +420,12 @@ net_pcap_prepare(netdev_t *list)
void *
net_pcap_init(const netcard_t *card, const uint8_t *mac_addr, void *priv)
{
char errbuf[PCAP_ERRBUF_SIZE];
char *str;
char filter_exp[255];
char errbuf[PCAP_ERRBUF_SIZE];
char *str;
char filter_exp[255];
struct bpf_program fp;
char *intf_name = (char*)priv;
char *intf_name = (char *) priv;
/* Did we already load the library? */
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);
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));
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;
}
} 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);
free(pcap);
return NULL;
@@ -523,7 +521,7 @@ net_pcap_close(void *priv)
if (!priv)
return;
net_pcap_t *pcap = (net_pcap_t *)priv;
net_pcap_t *pcap = (net_pcap_t *) priv;
pcap_log("PCAP: closing.\n");
@@ -541,10 +539,10 @@ net_pcap_close(void *priv)
free(pcap->pkt.data);
#ifdef _WIN32
f_pcap_sendqueue_destroy((void*)pcap->pcap_queue);
f_pcap_sendqueue_destroy((void *) pcap->pcap_queue);
#endif
/* 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->stop_event);

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -39,10 +39,10 @@
#include <86box/config.h>
#include <86box/video.h>
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#else
#include <poll.h>
# include <poll.h>
#endif
#include <86box/net_event.h>
@@ -75,37 +75,33 @@ typedef struct {
#ifdef ENABLE_SLIRP_LOG
int slirp_do_log = ENABLE_SLIRP_LOG;
static void
slirp_log(const char *fmt, ...)
{
va_list ap;
if (slirp_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define slirp_log(fmt, ...)
# define slirp_log(fmt, ...)
#endif
static void
net_slirp_guest_error(const char *msg, void *opaque)
{
slirp_log("SLiRP: guest_error(): %s\n", msg);
}
static int64_t
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 *
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;
}
static void
net_slirp_timer_free(void *timer, void *opaque)
{
@@ -122,14 +117,12 @@ net_slirp_timer_free(void *timer, void *opaque)
free(timer);
}
static void
net_slirp_timer_mod(void *timer, int64_t expire_timer, void *opaque)
{
timer_on_auto(timer, expire_timer * 1000);
}
static void
net_slirp_register_poll_fd(int fd, void *opaque)
{
@@ -137,7 +130,6 @@ net_slirp_register_poll_fd(int fd, void *opaque)
(void) opaque;
}
static void
net_slirp_unregister_poll_fd(int fd, void *opaque)
{
@@ -145,14 +137,12 @@ net_slirp_unregister_poll_fd(int fd, void *opaque)
(void) opaque;
}
static void
net_slirp_notify(void *opaque)
{
(void) opaque;
}
ssize_t
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);
memcpy(slirp->pkt.data, (uint8_t*) qp, pkt_len);
memcpy(slirp->pkt.data, (uint8_t *) qp, pkt_len);
slirp->pkt.len = pkt_len;
network_rx_put_pkt(slirp->card, &slirp->pkt);
return pkt_len;
}
#ifdef _WIN32
static int
net_slirp_add_poll(int fd, int events, void *opaque)
{
net_slirp_t *slirp = (net_slirp_t *) opaque;
long bitmask = 0;
net_slirp_t *slirp = (net_slirp_t *) opaque;
long bitmask = 0;
if (events & SLIRP_POLL_IN)
bitmask |= FD_READ | FD_ACCEPT;
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;
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));
if (new) {
slirp->pfd = new;
slirp->pfd = new;
slirp->pfd_size = newsize;
}
}
if ((slirp->pfd_len < slirp->pfd_size)) {
int idx = slirp->pfd_len++;
int idx = slirp->pfd_len++;
slirp->pfd[idx].fd = fd;
int pevents = 0;
int pevents = 0;
if (events & SLIRP_POLL_IN)
pevents |= POLLIN;
if (events & SLIRP_POLL_OUT)
@@ -225,8 +214,8 @@ net_slirp_add_poll(int fd, int events, void *opaque)
static int
net_slirp_get_revents(int idx, void *opaque)
{
net_slirp_t *slirp = (net_slirp_t *) opaque;
int ret = 0;
net_slirp_t *slirp = (net_slirp_t *) opaque;
int ret = 0;
WSANETWORKEVENTS ev;
if (WSAEnumNetworkEvents(idx, slirp->sock_event, &ev) != 0) {
return ret;
@@ -242,9 +231,9 @@ net_slirp_get_revents(int idx, void *opaque)
} \
} while (0)
WSA_TO_POLL(FD_READ, SLIRP_POLL_IN);
WSA_TO_POLL(FD_ACCEPT, SLIRP_POLL_IN);
WSA_TO_POLL(FD_WRITE, SLIRP_POLL_OUT);
WSA_TO_POLL(FD_READ, SLIRP_POLL_IN);
WSA_TO_POLL(FD_ACCEPT, SLIRP_POLL_IN);
WSA_TO_POLL(FD_WRITE, SLIRP_POLL_OUT);
WSA_TO_POLL(FD_CONNECT, SLIRP_POLL_OUT);
WSA_TO_POLL(FD_OOB, SLIRP_POLL_PRI);
WSA_TO_POLL(FD_CLOSE, SLIRP_POLL_HUP);
@@ -255,9 +244,9 @@ net_slirp_get_revents(int idx, void *opaque)
static int
net_slirp_get_revents(int idx, void *opaque)
{
net_slirp_t *slirp = (net_slirp_t *) opaque;
int ret = 0;
int events = slirp->pfd[idx].revents;
net_slirp_t *slirp = (net_slirp_t *) opaque;
int ret = 0;
int events = slirp->pfd[idx].revents;
if (events & POLLIN)
ret |= SLIRP_POLL_IN;
if (events & POLLOUT)
@@ -273,15 +262,15 @@ net_slirp_get_revents(int idx, void *opaque)
#endif
static const SlirpCb slirp_cb = {
.send_packet = net_slirp_send_packet,
.guest_error = net_slirp_guest_error,
.clock_get_ns = net_slirp_clock_get_ns,
.timer_new = net_slirp_timer_new,
.timer_free = net_slirp_timer_free,
.timer_mod = net_slirp_timer_mod,
.register_poll_fd = net_slirp_register_poll_fd,
.send_packet = net_slirp_send_packet,
.guest_error = net_slirp_guest_error,
.clock_get_ns = net_slirp_clock_get_ns,
.timer_new = net_slirp_timer_new,
.timer_free = net_slirp_timer_free,
.timer_mod = net_slirp_timer_mod,
.register_poll_fd = net_slirp_register_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. */
@@ -299,7 +288,7 @@ net_slirp_in(net_slirp_t *slirp, uint8_t *pkt, int pkt_len)
void
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);
}
@@ -314,16 +303,16 @@ net_slirp_thread(void *priv)
HANDLE events[3];
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_RX] = slirp->sock_event;
bool run = true;
events[NET_EVENT_TX] = net_event_get_handle(&slirp->tx_event);
events[NET_EVENT_RX] = slirp->sock_event;
bool run = true;
while (run) {
uint32_t timeout = -1;
slirp_pollfds_fill(slirp->slirp, &timeout, net_slirp_add_poll, slirp);
if (timeout < 0)
timeout = INFINITE;
int ret = WaitForMultipleObjects(3, events, FALSE, (DWORD)timeout);
int ret = WaitForMultipleObjects(3, events, FALSE, (DWORD) timeout);
switch (ret - WAIT_OBJECT_0) {
case NET_EVENT_STOP:
run = false;
@@ -341,7 +330,6 @@ net_slirp_thread(void *priv)
default:
slirp_pollfds_poll(slirp->slirp, ret == WAIT_FAILED, net_slirp_get_revents, slirp);
break;
}
}
@@ -398,11 +386,11 @@ net_slirp_init(const netcard_t *card, const uint8_t *mac_addr, void *priv)
slirp_log("SLiRP: initializing...\n");
net_slirp_t *slirp = calloc(1, sizeof(net_slirp_t));
memcpy(slirp->mac_addr, mac_addr, sizeof(slirp->mac_addr));
slirp->card = (netcard_t*)card;
slirp->card = (netcard_t *) card;
#ifndef _WIN32
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);
#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 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 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 */
/* Initialize SLiRP. */
@@ -424,10 +412,10 @@ net_slirp_init(const netcard_t *card, const uint8_t *mac_addr, void *priv)
}
/* Set up port forwarding. */
int udp, external, internal, i = 0;
int udp, external, internal, i = 0;
char category[32];
snprintf(category, sizeof(category), "SLiRP Port Forwarding #%i", card->card_num + 1);
char key[20];
char key[20];
while (1) {
sprintf(key, "%d_protocol", i);
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>
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# include <winsock2.h>
#endif
static const device_t net_none_device = {
.name = "None",
.name = "None",
.internal_name = "none",
.flags = 0,
.local = NET_TYPE_NONE,
.init = NULL,
.close = NULL,
.reset = NULL,
.flags = 0,
.local = NET_TYPE_NONE,
.init = NULL,
.close = NULL,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
static const device_t *net_cards[] = {
&net_none_device,
&threec503_device,
@@ -118,72 +117,68 @@ static const device_t *net_cards[] = {
};
netcard_conf_t net_cards_conf[NET_CARD_MAX];
int net_card_current = 0;
int net_card_current = 0;
/* Global variables. */
int network_ndev;
netdev_t network_devs[NET_HOST_INTF_MAX];
int network_ndev;
netdev_t network_devs[NET_HOST_INTF_MAX];
/* Local variables. */
#ifdef ENABLE_NETWORK_LOG
int network_do_log = ENABLE_NETWORK_LOG;
static FILE *network_dump = NULL;
int network_do_log = ENABLE_NETWORK_LOG;
static FILE *network_dump = NULL;
static mutex_t *network_dump_mutex;
static void
network_log(const char *fmt, ...)
{
va_list ap;
if (network_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
static void
network_dump_packet(netpkt_t *pkt)
{
if (!network_dump)
return;
return;
struct timeval tv;
gettimeofday(&tv, NULL);
struct {
uint32_t ts_sec, ts_usec, incl_len, orig_len;
uint32_t ts_sec, ts_usec, incl_len, orig_len;
} 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)
thread_wait_mutex(network_dump_mutex);
thread_wait_mutex(network_dump_mutex);
size_t written;
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");
fseek(network_dump, -written, SEEK_CUR);
network_log("NETWORK: failed to write dump packet header\n");
fseek(network_dump, -written, SEEK_CUR);
} else {
if ((written = fwrite(pkt->data, 1, pkt->len, network_dump)) < pkt->len) {
network_log("NETWORK: failed to write dump packet data\n");
fseek(network_dump, -written - sizeof(pcap_packet_hdr), SEEK_CUR);
}
fflush(network_dump);
if ((written = fwrite(pkt->data, 1, pkt->len, network_dump)) < pkt->len) {
network_log("NETWORK: failed to write dump packet data\n");
fseek(network_dump, -written - sizeof(pcap_packet_hdr), SEEK_CUR);
}
fflush(network_dump);
}
if (network_dump_mutex)
thread_release_mutex(network_dump_mutex);
thread_release_mutex(network_dump_mutex);
}
#else
#define network_log(fmt, ...)
#define network_dump_packet(pkt)
# define network_log(fmt, ...)
# define network_dump_packet(pkt)
#endif
#ifdef _WIN32
static void
network_winsock_clean(void)
@@ -218,22 +213,22 @@ network_init(void)
/* Initialize the Pcap system module, if present. */
i = net_pcap_prepare(&network_devs[network_ndev]);
if (i > 0)
network_ndev += i;
network_ndev += i;
#ifdef ENABLE_NETWORK_LOG
/* Start packet dump. */
network_dump = fopen("network.pcap", "wb");
struct {
uint32_t magic_number;
uint16_t version_major, version_minor;
int32_t thiszone;
uint32_t sigfigs, snaplen, network;
uint32_t magic_number;
uint16_t version_major, version_minor;
int32_t thiszone;
uint32_t sigfigs, snaplen, network;
} pcap_hdr = {
0xa1b2c3d4,
2, 4,
0,
0, 65535, 1
0xa1b2c3d4,
2, 4,
0,
0, 65535, 1
};
fwrite(&pcap_hdr, sizeof(pcap_hdr), 1, network_dump);
fflush(network_dump);
@@ -244,11 +239,10 @@ void
network_queue_init(netqueue_t *queue)
{
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].len = 0;
queue->packets[i].len = 0;
}
}
static bool
@@ -267,8 +261,8 @@ static inline void
network_swap_packet(netpkt_t *pkt1, netpkt_t *pkt2)
{
netpkt_t tmp = *pkt2;
*pkt2 = *pkt1;
*pkt1 = tmp;
*pkt2 = *pkt1;
*pkt1 = tmp;
}
int
@@ -280,7 +274,7 @@ network_queue_put(netqueue_t *queue, uint8_t *data, int len)
netpkt_t *pkt = &queue->packets[queue->head];
memcpy(pkt->data, data, len);
pkt->len = len;
pkt->len = len;
queue->head = (queue->head + 1) & NET_QUEUE_LEN_MASK;
return 1;
}
@@ -300,7 +294,8 @@ network_queue_put_swap(netqueue_t *queue, netpkt_t *src_pkt)
}
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))
return 0;
@@ -333,18 +328,17 @@ network_queue_move(netqueue_t *dst_q, netqueue_t *src_q)
void
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);
queue->packets[i].len = 0;
}
queue->tail = queue->head = 0;
}
static void
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;
if (new_link_state != card->link_state) {
@@ -393,7 +387,7 @@ network_rx_queue(void *priv)
timer_on_auto(&card->timer, timer_period);
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) {
ui_sb_update_icon(SB_NETWORK | card->card_num, activity);
card->led_timer = 0 | (activity << 31);
@@ -402,7 +396,6 @@ network_rx_queue(void *priv)
card->led_timer += timer_period;
}
/*
* Attach a network card to the system.
*
@@ -413,29 +406,29 @@ network_rx_queue(void *priv)
netcard_t *
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->card_drv = card_drv;
card->rx = rx;
card->set_link_state = set_link_state;
card->tx_mutex = thread_create_mutex();
card->rx_mutex = thread_create_mutex();
card->card_num = net_card_current;
card->byte_period = NET_PERIOD_10M;
card->card_drv = card_drv;
card->rx = rx;
card->set_link_state = set_link_state;
card->tx_mutex = thread_create_mutex();
card->rx_mutex = thread_create_mutex();
card->card_num = net_card_current;
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]);
}
switch (net_cards_conf[net_card_current].net_type) {
case NET_TYPE_SLIRP:
default:
card->host_drv = net_slirp_drv;
card->host_drv = net_slirp_drv;
card->host_drv.priv = card->host_drv.init(card, mac, NULL);
break;
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);
break;
}
@@ -443,7 +436,7 @@ network_attach(void *card_drv, uint8_t *mac, NETRXCB rx, NETSETLINKSTATE set_lin
if (!card->host_drv.priv) {
thread_close_mutex(card->tx_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]);
}
@@ -466,7 +459,7 @@ netcard_close(netcard_t *card)
thread_close_mutex(card->tx_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]);
}
@@ -474,7 +467,6 @@ netcard_close(netcard_t *card)
free(card);
}
/* Stop any network activity. */
void
network_close(void)
@@ -487,7 +479,6 @@ network_close(void)
network_log("NETWORK: closed.\n");
}
/*
* Reset the network card(s).
*
@@ -508,16 +499,15 @@ network_reset(void)
#endif
for (i = 0; i < NET_CARD_MAX; i++) {
if (!network_dev_available(i)) {
continue;
}
if (!network_dev_available(i)) {
continue;
}
net_card_current = i;
device_add_inst(net_cards[net_cards_conf[i].device_num], i + 1);
net_card_current = i;
device_add_inst(net_cards[net_cards_conf[i].device_num], i + 1);
}
}
/* Queue a packet for transmission to one of the network providers. */
void
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);
}
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;
@@ -536,7 +527,8 @@ int network_tx_pop(netcard_t *card, netpkt_t *out_pkt)
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;
@@ -553,7 +545,8 @@ int network_tx_popv(netcard_t *card, netpkt_t *pkt_vec, int vec_size)
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;
@@ -564,7 +557,8 @@ int network_rx_put(netcard_t *card, uint8_t *bufp, int len)
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;
@@ -602,16 +596,15 @@ network_dev_to_id(char *devname)
{
int i = 0;
for (i=0; i<network_ndev; i++) {
if (! strcmp((char *)network_devs[i].device, devname)) {
return(i);
}
for (i = 0; i < network_ndev; i++) {
if (!strcmp((char *) network_devs[i].device, devname)) {
return (i);
}
}
return(-1);
return (-1);
}
/* UI */
int
network_dev_available(int id)
@@ -629,43 +622,40 @@ network_available(void)
{
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);
}
return available;
}
/* UI */
int
network_card_available(int card)
{
if (net_cards[card])
return(device_available(net_cards[card]));
return (device_available(net_cards[card]));
return(1);
return (1);
}
/* UI */
const device_t *
network_card_getdevice(int card)
{
return(net_cards[card]);
return (net_cards[card]);
}
/* UI */
int
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 */
char *
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]);
}
/* UI */
int
network_card_get_from_internal_name(char *s)
@@ -681,9 +670,9 @@ network_card_get_from_internal_name(char *s)
int c = 0;
while (net_cards[c] != NULL) {
if (! strcmp((char *)net_cards[c]->internal_name, s))
return(c);
c++;
if (!strcmp((char *) net_cards[c]->internal_name, s))
return (c);
c++;
}
return 0;

View File

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