clang-format in src/network/
This commit is contained in:
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
};
|
||||
|
@@ -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
@@ -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;
|
||||
|
@@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user