Updated network code, major cleanup. SLiRP and Pcap both tested. UI configuration will need extra work by Kotori.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
#
|
||||
# Modified Makefile for Win32 MinGW 32-bit environment.
|
||||
#
|
||||
# Version: @(#)Makefile.mingw 1.0.10 2017/05/10
|
||||
# Version: @(#)Makefile.mingw 1.0.11 2017/05/11
|
||||
#
|
||||
# Authors: Kotori, <oubattler@gmail.com>
|
||||
# Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -132,7 +132,7 @@ DEVOBJ = bugger.o lpt.o serial.o \
|
||||
cdrom-dosbox.o cdrom-image.o cdrom-ioctl.o cdrom-null.o
|
||||
USBOBJ = usb.o
|
||||
NETOBJ = network.o \
|
||||
net_pcap.o \
|
||||
net_pcap.o net_slirp.o \
|
||||
net_ne2000.o
|
||||
SCSIOBJ = scsi.o scsi_disk.o scsi_buslogic.o scsi_aha154x.o
|
||||
SNDOBJ = sound.o \
|
||||
|
||||
12
src/config.c
12
src/config.c
@@ -21,7 +21,6 @@
|
||||
#include "model.h"
|
||||
#include "mouse.h"
|
||||
#include "network.h"
|
||||
#include "net_ne2000.h"
|
||||
#include "nvr.h"
|
||||
#include "plat-joystick.h"
|
||||
#include "scsi.h"
|
||||
@@ -545,9 +544,9 @@ void loadconfig(wchar_t *fn)
|
||||
scsi_card_current = 0;
|
||||
|
||||
/* network */
|
||||
p = (char *)config_get_string(NULL, "netcard", "");
|
||||
if (p != NULL)
|
||||
network_setup(p);
|
||||
p = (char *)config_get_string(NULL, "net_card", "");
|
||||
network_type = config_get_int(NULL, "net_type", -1);
|
||||
network_setup(p);
|
||||
|
||||
p = (char *)config_get_string(NULL, "model", "");
|
||||
if (p)
|
||||
@@ -843,9 +842,12 @@ void saveconfig(void)
|
||||
|
||||
config_set_string(NULL, "scsicard", scsi_card_get_internal_name(scsi_card_current));
|
||||
|
||||
config_set_string(NULL, "netcard", network_card_get_internal_name(network_card_current));
|
||||
config_set_string(NULL, "net_card", network_card_get_internal_name(network_card));
|
||||
config_set_int(NULL, "net_type", network_type);
|
||||
#if 1
|
||||
config_set_int(NULL, "maclocal", ne2000_get_maclocal());
|
||||
config_set_int(NULL, "maclocal_pci", ne2000_get_maclocal_pci());
|
||||
#endif
|
||||
|
||||
config_set_string(NULL, "model", model_get_internal_name());
|
||||
config_set_int(NULL, "cpu_manufacturer", cpu_manufacturer);
|
||||
|
||||
1329
src/net_ne2000.c
1329
src/net_ne2000.c
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Definitions for the NE2000 ethernet controller.
|
||||
*
|
||||
* Version: @(#)net_ne2000.h 1.0.1 2017/05/09
|
||||
* Version: @(#)net_ne2000.h 1.0.2 2017/05/11
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*/
|
||||
@@ -16,6 +16,12 @@
|
||||
# define NET_NE2000_H
|
||||
|
||||
|
||||
#define NE2K_NE1000 1 /* 8bit ISA NE1000 */
|
||||
#define NE2K_NE2000 2 /* 16bit ISA NE2000 */
|
||||
#define NE2K_RTL8029AS 3 /* 32bi PCI Realtek 8029AS */
|
||||
|
||||
|
||||
extern device_t ne1000_device;
|
||||
extern device_t ne2000_device;
|
||||
extern device_t rtl8029as_device;
|
||||
|
||||
|
||||
212
src/net_pcap.c
Normal file
212
src/net_pcap.c
Normal file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Handle WinPcap library processing.
|
||||
*
|
||||
* Version: @(#)net_pcap.c 1.0.1 2017/05/11
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pcap.h>
|
||||
#include "ibm.h"
|
||||
#include "config.h"
|
||||
#include "thread.h"
|
||||
#include "device.h"
|
||||
#include "network.h"
|
||||
|
||||
|
||||
static pcap_t *pcap; /* handle to WinPcap library */
|
||||
static thread_t *poll_tid;
|
||||
static NETRXCB poll_rx; /* network RX function to call */
|
||||
static void *poll_arg; /* network RX function arg */
|
||||
|
||||
|
||||
/* Check if the interface has a packet for us. */
|
||||
static void
|
||||
poll_thread(void *arg)
|
||||
{
|
||||
const unsigned char *data;
|
||||
uint8_t *mac = (uint8_t *)arg;
|
||||
struct pcap_pkthdr h;
|
||||
event_t *evt;
|
||||
uint32_t mac_cmp32[2];
|
||||
uint16_t mac_cmp16[2];
|
||||
|
||||
pclog("PCAP: polling thread started, arg %08lx\n", arg);
|
||||
|
||||
/* Create a waitable event. */
|
||||
evt = thread_create_event();
|
||||
pclog("PCAP: poll event is %08lx\n", evt);
|
||||
|
||||
while (pcap != NULL) {
|
||||
/* Wait for the next packet to arrive. */
|
||||
data = pcap_next(pcap, &h);
|
||||
if (data != NULL) {
|
||||
/* Received MAC. */
|
||||
mac_cmp32[0] = *(uint32_t *)(data+6);
|
||||
mac_cmp16[0] = *(uint16_t *)(data+10);
|
||||
|
||||
/* Local MAC. */
|
||||
mac_cmp32[1] = *(uint32_t *)mac;
|
||||
mac_cmp16[1] = *(uint16_t *)(mac+4);
|
||||
if ((mac_cmp32[0] != mac_cmp32[1]) ||
|
||||
(mac_cmp16[0] != mac_cmp16[1])) {
|
||||
if (poll_rx != NULL)
|
||||
poll_rx(poll_arg, (uint8_t *)data, h.caplen);
|
||||
} else {
|
||||
/* Mark as invalid packet. */
|
||||
data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we did not get anything, wait a while. */
|
||||
if (data == NULL)
|
||||
thread_wait_event(evt, 10);
|
||||
}
|
||||
|
||||
thread_destroy_event(evt);
|
||||
poll_tid = NULL;
|
||||
|
||||
pclog("PCAP: polling stopped.\n");
|
||||
}
|
||||
|
||||
|
||||
/* Initialize WinPcap for us. */
|
||||
int
|
||||
network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg)
|
||||
{
|
||||
char temp[PCAP_ERRBUF_SIZE];
|
||||
char filter_exp[255];
|
||||
struct bpf_program fp;
|
||||
char *dev;
|
||||
|
||||
/* Messy, but gets rid of a lot of useless info. */
|
||||
strcpy(temp, pcap_lib_version());
|
||||
dev = strchr(temp, '(');
|
||||
if (dev != NULL) *(dev-1) = '\0';
|
||||
pclog("Initializing WinPcap, version %s\n", temp);
|
||||
|
||||
/* Get the value of our capture interface. */
|
||||
dev = config_get_string(NULL, "pcap_device", NULL);
|
||||
if (dev == NULL) {
|
||||
pclog(" No network device configured!\n");
|
||||
return(-1);
|
||||
}
|
||||
pclog(" Network interface: '%s'\n", dev);
|
||||
|
||||
pcap = pcap_open_live(dev, /* interface name */
|
||||
1518, /* maximum packet size */
|
||||
1, /* promiscuous mode? */
|
||||
10, /* timeout in msec */
|
||||
temp); /* error buffer */
|
||||
if (pcap == NULL) {
|
||||
pclog("Unable to open WinPcap: %s!\n", temp);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Create a MAC address based packet filter. */
|
||||
pclog("Building packet filter ...");
|
||||
sprintf(filter_exp,
|
||||
"( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
if (pcap_compile(pcap, &fp, filter_exp, 0, 0xffffffff) != -1) {
|
||||
pclog("...");
|
||||
if (pcap_setfilter(pcap, &fp) == -1) {
|
||||
pclog(" error installing filter!\n");
|
||||
} else {
|
||||
pclog("!\nUsing filter\t[%s]\n", filter_exp);
|
||||
}
|
||||
} else {
|
||||
pclog(" could not compile filter!\n");
|
||||
}
|
||||
|
||||
/* Save the callback info. */
|
||||
poll_rx = func;
|
||||
poll_arg = arg;
|
||||
|
||||
pclog("PCAP: creating thread..\n");
|
||||
poll_tid = thread_create(poll_thread, mac);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* Close up shop. */
|
||||
void
|
||||
network_pcap_close(void)
|
||||
{
|
||||
pcap_t *pc;
|
||||
|
||||
if (pcap != NULL) {
|
||||
pclog("Closing WinPcap\n");
|
||||
|
||||
/* Tell the polling thread to shut down. */
|
||||
pc = pcap; pcap = NULL;
|
||||
#if 1
|
||||
/* Terminate the polling thread. */
|
||||
if (poll_tid != NULL) {
|
||||
thread_kill(poll_tid);
|
||||
poll_tid = NULL;
|
||||
}
|
||||
#else
|
||||
/* Wait for the polling thread to shut down. */
|
||||
while (poll_tid != NULL)
|
||||
;
|
||||
#endif
|
||||
|
||||
/* OK, now shut down WinPcap itself. */
|
||||
pcap_close(pc);
|
||||
}
|
||||
poll_rx = NULL;
|
||||
poll_arg = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Send a packet to the Pcap interface. */
|
||||
void
|
||||
network_pcap_in(uint8_t *bufp, int len)
|
||||
{
|
||||
if (pcap != NULL)
|
||||
pcap_sendpacket(pcap, bufp, len);
|
||||
}
|
||||
|
||||
|
||||
/* Retrieve an easy-to-use list of devices. */
|
||||
int
|
||||
network_devlist(netdev_t *list)
|
||||
{
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
pcap_if_t *devlist, *dev;
|
||||
int i = 0;
|
||||
|
||||
/* Retrieve the device list from the local machine */
|
||||
if (pcap_findalldevs(&devlist, errbuf) == -1) {
|
||||
pclog("NETWORK: 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++;
|
||||
}
|
||||
|
||||
/* Release the memory. */
|
||||
pcap_freealldevs(devlist);
|
||||
|
||||
return(i);
|
||||
}
|
||||
199
src/net_slirp.c
Normal file
199
src/net_slirp.c
Normal file
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Handle SLiRP library processing.
|
||||
*
|
||||
* Version: @(#)net_slirp.c 1.0.1 2017/05/11
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "slirp/slirp.h"
|
||||
#include "slirp/queue.h"
|
||||
#include "ibm.h"
|
||||
#include "config.h"
|
||||
#include "device.h"
|
||||
#include "thread.h"
|
||||
#include "network.h"
|
||||
|
||||
|
||||
static queueADT slirpq; /* SLiRP library handle */
|
||||
static thread_t *poll_tid;
|
||||
static NETRXCB poll_rx; /* network RX function to call */
|
||||
static void *poll_arg; /* network RX function arg */
|
||||
static int fizz;
|
||||
|
||||
|
||||
/* Instead of calling this and crashing some times
|
||||
or experencing jitter, this is called by the
|
||||
60Hz clock which seems to do the job. */
|
||||
static void
|
||||
slirp_tic(void)
|
||||
{
|
||||
int ret2,nfds;
|
||||
struct timeval tv;
|
||||
fd_set rfds, wfds, xfds;
|
||||
int tmo;
|
||||
nfds=-1;
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_ZERO(&wfds);
|
||||
FD_ZERO(&xfds);
|
||||
tmo = slirp_select_fill(&nfds, &rfds, &wfds, &xfds); /* this can crash */
|
||||
if (tmo < 0) {
|
||||
tmo = 500;
|
||||
}
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = tmo; /* basilisk default 10000 */
|
||||
|
||||
ret2 = select(nfds+1, &rfds, &wfds, &xfds, &tv);
|
||||
if (ret2 >= 0) {
|
||||
slirp_select_poll(&rfds, &wfds, &xfds);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Check if the interface has a packet for us. */
|
||||
static void
|
||||
poll_thread(void *arg)
|
||||
{
|
||||
uint8_t *mac = (uint8_t *)arg;
|
||||
struct queuepacket *qp;
|
||||
event_t *evt;
|
||||
|
||||
pclog("SLiRP: polling thread started, arg %08lx\n", arg);
|
||||
|
||||
/* Create a waitable event. */
|
||||
evt = thread_create_event();
|
||||
pclog("SLiRP: poll event is %08lx\n", evt);
|
||||
|
||||
while (slirpq != NULL) {
|
||||
if (++fizz > 1200) {
|
||||
fizz = 0;
|
||||
slirp_tic();
|
||||
}
|
||||
|
||||
/* Wait for the next packet to arrive. */
|
||||
if (QueuePeek(slirpq) == 0) {
|
||||
/* If we did not get anything, wait a while. */
|
||||
thread_wait_event(evt, 10);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Grab a packet from the queue. */
|
||||
qp = QueueDelete(slirpq);
|
||||
pclog("SLiRP: inQ:%d got a %dbyte packet @%08lx\n",
|
||||
QueuePeek(slirpq), qp->len, qp);
|
||||
|
||||
if (poll_rx != NULL)
|
||||
poll_rx(poll_arg, (uint8_t *)&qp->data, qp->len);
|
||||
|
||||
/* Done with this one. */
|
||||
free(qp);
|
||||
}
|
||||
|
||||
thread_destroy_event(evt);
|
||||
poll_tid = NULL;
|
||||
|
||||
pclog("SLiRP: polling stopped.\n");
|
||||
}
|
||||
|
||||
|
||||
/* Initialize SLiRP for us. */
|
||||
int
|
||||
network_slirp_setup(uint8_t *mac, NETRXCB func, void *arg)
|
||||
{
|
||||
int rc;
|
||||
|
||||
pclog("Initializing SLiRP\n");
|
||||
|
||||
if (slirp_init() != 0) {
|
||||
pclog("SLiRP could not be initialized!\n");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
slirpq = QueueCreate();
|
||||
pclog(" Packet queue is at %08lx\n", &slirpq);
|
||||
|
||||
fizz = 0;
|
||||
|
||||
/* Save the callback info. */
|
||||
poll_rx = func;
|
||||
poll_arg = arg;
|
||||
|
||||
pclog("SLiRP: creating thread..\n");
|
||||
poll_tid = thread_create(poll_thread, mac);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
network_slirp_close(void)
|
||||
{
|
||||
queueADT sl;
|
||||
|
||||
if (slirpq != NULL) {
|
||||
pclog("Closing SLiRP\n");
|
||||
|
||||
/* Tell the polling thread to shut down. */
|
||||
sl = slirpq; slirpq = NULL;
|
||||
#if 1
|
||||
/* Terminate the polling thread. */
|
||||
if (poll_tid != NULL) {
|
||||
thread_kill(poll_tid);
|
||||
poll_tid = NULL;
|
||||
}
|
||||
#else
|
||||
/* Wait for the polling thread to shut down. */
|
||||
while (poll_tid != NULL)
|
||||
;
|
||||
#endif
|
||||
|
||||
/* OK, now shut down SLiRP itself. */
|
||||
QueueDestroy(sl);
|
||||
slirp_exit(0);
|
||||
}
|
||||
|
||||
poll_rx = NULL;
|
||||
poll_arg = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Send a packet to the SLiRP interface. */
|
||||
void
|
||||
network_slirp_in(uint8_t *pkt, int pkt_len)
|
||||
{
|
||||
if (slirpq != NULL)
|
||||
slirp_input((const uint8_t *)pkt, pkt_len);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
slirp_output(const uint8_t *pkt, int pkt_len)
|
||||
{
|
||||
struct queuepacket *qp;
|
||||
|
||||
if (slirpq != NULL) {
|
||||
qp = (struct queuepacket *)malloc(sizeof(struct queuepacket));
|
||||
qp->len = pkt_len;
|
||||
memcpy(qp->data, pkt, pkt_len);
|
||||
QueueEnter(slirpq, qp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
slirp_can_output(void)
|
||||
{
|
||||
return((slirpq != NULL)?1:0);
|
||||
}
|
||||
197
src/network.c
197
src/network.c
@@ -8,7 +8,11 @@
|
||||
*
|
||||
* Implementation of the network module.
|
||||
*
|
||||
* Version: @(#)network.c 1.0.2 2017/05/09
|
||||
* NOTE The definition of the netcard_t is currently not optimal;
|
||||
* it should be malloc'ed and then linked to the NETCARD def.
|
||||
* Will be done later.
|
||||
*
|
||||
* Version: @(#)network.c 1.0.2 2017/05/11
|
||||
*
|
||||
* Authors: Kotori, <oubattler@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -18,99 +22,161 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "ibm.h"
|
||||
#include "config.h"
|
||||
#include "device.h"
|
||||
#include "timer.h"
|
||||
#include "thread.h"
|
||||
#include "network.h"
|
||||
#include "net_ne2000.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
char name[64];
|
||||
char internal_name[32];
|
||||
device_t *device;
|
||||
} NETCARD;
|
||||
|
||||
typedef struct {
|
||||
void (*poller)(void *);
|
||||
void *priv;
|
||||
} NETPOLL;
|
||||
|
||||
|
||||
static int net_handlers_num;
|
||||
static int net_poll_time = 0;
|
||||
static int net_poll_time;
|
||||
static NETPOLL net_handlers[8];
|
||||
static NETCARD net_cards[] = {
|
||||
{ "None", "none", NULL },
|
||||
{ "Novell NE2000", "ne2k", &ne2000_device },
|
||||
{ "Realtek RTL8029AS", "ne2kpci", &rtl8029as_device },
|
||||
{ "", "", NULL }
|
||||
static netcard_t net_cards[] = {
|
||||
{ "None", "none", NULL,
|
||||
NULL, NULL },
|
||||
{ "Novell NE1000", "ne1k", &ne1000_device,
|
||||
NULL, NULL },
|
||||
{ "Novell NE2000", "ne2k", &ne2000_device,
|
||||
NULL, NULL },
|
||||
{ "Realtek RTL8029AS", "ne2kpci", &rtl8029as_device,
|
||||
NULL, NULL },
|
||||
{ "", "", NULL,
|
||||
NULL, NULL }
|
||||
};
|
||||
|
||||
|
||||
int network_card_current = 0;
|
||||
uint8_t ethif;
|
||||
int inum;
|
||||
int network_card;
|
||||
int network_type;
|
||||
|
||||
|
||||
static void
|
||||
net_poll(void *priv)
|
||||
{
|
||||
int c;
|
||||
|
||||
/* Reset the poll timer. */
|
||||
net_poll_time += (int)((double)TIMER_USEC * (1000000.0/8.0/3000.0));
|
||||
|
||||
/* If we have active cards.. */
|
||||
if (net_handlers_num) {
|
||||
/* .. poll each of them. */
|
||||
for (c=0; c<net_handlers_num; c++) {
|
||||
net_handlers[c].poller(net_handlers[c].priv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the configured network cards. */
|
||||
/*
|
||||
* Initialize the configured network cards.
|
||||
*
|
||||
* This function gets called only once, from the System
|
||||
* Platform initialization code (currently in pc.c) to
|
||||
* set our local stuff to a known state.
|
||||
*/
|
||||
void
|
||||
network_init(void)
|
||||
{
|
||||
network_card_current = 0;
|
||||
net_handlers_num = 0;
|
||||
net_poll_time = 0;
|
||||
network_card = 0;
|
||||
network_type = -1;
|
||||
}
|
||||
|
||||
|
||||
/* Reset the network card(s). */
|
||||
/*
|
||||
* Set up the network for a card.
|
||||
*
|
||||
* This function gets called whenever we load a new
|
||||
* system configuration file. It only grabs the variables
|
||||
* from that file, and saves them locally.
|
||||
*/
|
||||
void
|
||||
network_setup(char *name)
|
||||
{
|
||||
/* No platform support, give up. */
|
||||
if (network_type < 0) return;
|
||||
|
||||
network_card = network_card_get_from_internal_name(name);
|
||||
if (network_card == 0) return;
|
||||
|
||||
pclog("NETWORK: set up for card '%s' (%d) in %s\n",
|
||||
name, network_card, (network_type==1)?"SLiRP":"WinPcap");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Attach a network card to the system.
|
||||
*
|
||||
* This function is called by a hardware driver ("card") after it has
|
||||
* finished initializing itself, to link itself to the platform support
|
||||
* modules.
|
||||
*/
|
||||
int
|
||||
network_attach(void *dev, uint8_t *mac, NETRXCB rx)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (! network_card) return(ret);
|
||||
|
||||
/* Save the card's callback info. */
|
||||
net_cards[network_card].private = dev;
|
||||
net_cards[network_card].rx = rx;
|
||||
|
||||
/* Start the platform module. */
|
||||
switch(network_type) {
|
||||
case 0:
|
||||
ret = network_pcap_setup(mac, rx, dev);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
ret = network_slirp_setup(mac, rx, dev);
|
||||
break;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/* Stop any network activity. */
|
||||
void
|
||||
network_close(void)
|
||||
{
|
||||
switch(network_type) {
|
||||
case 0:
|
||||
network_pcap_close();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
network_slirp_close();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Reset the network card(s).
|
||||
*
|
||||
* This function is called each time the system is reset,
|
||||
* either a hard reset (including power-up) or a soft reset
|
||||
* including C-A-D reset.) It is responsible for connecting
|
||||
* everything together.
|
||||
*/
|
||||
void
|
||||
network_reset(void)
|
||||
{
|
||||
pclog("NETWORK: reset (card=%d)\n", network_card_current);
|
||||
pclog("NETWORK: reset (card=%d)\n", network_card);
|
||||
|
||||
if (! network_card_current) return;
|
||||
/* Just in case.. */
|
||||
network_close();
|
||||
|
||||
if (net_cards[network_card_current].device) {
|
||||
/* If no active card, we're done. */
|
||||
if (!network_card || (network_type<0)) return;
|
||||
|
||||
/* Add the (new?) card to the I/O system. */
|
||||
if (net_cards[network_card].device) {
|
||||
pclog("NETWORK: adding device '%s'\n",
|
||||
net_cards[network_card_current].name);
|
||||
device_add(net_cards[network_card_current].device);
|
||||
net_cards[network_card].name);
|
||||
device_add(net_cards[network_card].device);
|
||||
}
|
||||
|
||||
pclog("NETWORK: adding timer...\n");
|
||||
timer_add(net_poll, &net_poll_time, TIMER_ALWAYS_ENABLED, NULL);
|
||||
}
|
||||
|
||||
|
||||
/* Add a handler for a network card. */
|
||||
/* Transmit a packet to one of the network providers. */
|
||||
void
|
||||
network_add_handler(void (*poller)(void *), void *p)
|
||||
network_tx(uint8_t *bufp, int len)
|
||||
{
|
||||
net_handlers[net_handlers_num].poller = poller;
|
||||
net_handlers[net_handlers_num].priv = p;
|
||||
net_handlers_num++;
|
||||
switch(network_type) {
|
||||
case 0:
|
||||
network_pcap_in(bufp, len);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
network_slirp_in(bufp, len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* UI */
|
||||
int
|
||||
network_card_available(int card)
|
||||
{
|
||||
@@ -121,6 +187,7 @@ network_card_available(int card)
|
||||
}
|
||||
|
||||
|
||||
/* UI */
|
||||
char *
|
||||
network_card_getname(int card)
|
||||
{
|
||||
@@ -128,6 +195,7 @@ network_card_getname(int card)
|
||||
}
|
||||
|
||||
|
||||
/* UI */
|
||||
device_t *
|
||||
network_card_getdevice(int card)
|
||||
{
|
||||
@@ -135,6 +203,7 @@ network_card_getdevice(int card)
|
||||
}
|
||||
|
||||
|
||||
/* UI */
|
||||
int
|
||||
network_card_has_config(int card)
|
||||
{
|
||||
@@ -144,6 +213,7 @@ network_card_has_config(int card)
|
||||
}
|
||||
|
||||
|
||||
/* UI */
|
||||
char *
|
||||
network_card_get_internal_name(int card)
|
||||
{
|
||||
@@ -151,6 +221,7 @@ network_card_get_internal_name(int card)
|
||||
}
|
||||
|
||||
|
||||
/* UI */
|
||||
int
|
||||
network_card_get_from_internal_name(char *s)
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Definitions for the network module.
|
||||
*
|
||||
* Version: @(#)network.h 1.0.1 2017/05/09
|
||||
* Version: @(#)network.h 1.0.2 2017/05/11
|
||||
*
|
||||
* Authors: Kotori, <oubattler@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -18,28 +18,58 @@
|
||||
# include <stdint.h>
|
||||
|
||||
|
||||
#define NE2000 1
|
||||
#define RTL8029AS 2
|
||||
#define NE1000 1
|
||||
#define NE2000 2
|
||||
#define RTL8029AS 3
|
||||
|
||||
|
||||
extern int network_card_current;
|
||||
extern uint8_t ethif;
|
||||
extern int inum;
|
||||
typedef void (*NETRXCB)(void *, uint8_t *, int);
|
||||
|
||||
|
||||
typedef struct {
|
||||
char name[64];
|
||||
char internal_name[32];
|
||||
device_t *device;
|
||||
void *private;
|
||||
int (*poll)(void *);
|
||||
NETRXCB rx;
|
||||
} netcard_t;
|
||||
|
||||
typedef struct {
|
||||
char device[128];
|
||||
char description[128];
|
||||
} netdev_t;
|
||||
|
||||
|
||||
/* Global variables. */
|
||||
extern int network_card;
|
||||
extern int network_type;
|
||||
|
||||
|
||||
/* Function prototypes. */
|
||||
extern void network_init(void);
|
||||
extern void network_setup(char *);
|
||||
extern int network_attach(void *, uint8_t *, NETRXCB);
|
||||
extern void network_close(void);
|
||||
extern void network_reset(void);
|
||||
extern void network_add_handler(void (*poller)(void *p), void *p);
|
||||
extern void network_tx(uint8_t *, int);
|
||||
|
||||
extern int network_card_available(int card);
|
||||
extern char *network_card_getname(int card);
|
||||
extern int network_card_has_config(int card);
|
||||
extern char *network_card_get_internal_name(int card);
|
||||
extern int network_card_get_from_internal_name(char *s);
|
||||
extern struct device_t *network_card_getdevice(int card);
|
||||
extern int network_pcap_setup(uint8_t *, NETRXCB, void *);
|
||||
extern void network_pcap_close(void);
|
||||
extern void network_pcap_in(uint8_t *, int);
|
||||
extern int network_devlist(netdev_t *);
|
||||
|
||||
extern void initpcap(void);
|
||||
extern void closepcap(void);
|
||||
extern int network_slirp_setup(uint8_t *, NETRXCB, void *);
|
||||
extern void network_slirp_close(void);
|
||||
extern void network_slirp_in(uint8_t *, int);
|
||||
|
||||
extern int network_devlist(netdev_t *);
|
||||
extern int network_card_available(int);
|
||||
extern char *network_card_getname(int);
|
||||
extern int network_card_has_config(int);
|
||||
extern char *network_card_get_internal_name(int);
|
||||
extern int network_card_get_from_internal_name(char *);
|
||||
extern struct device_t *network_card_getdevice(int);
|
||||
|
||||
|
||||
#endif /*NETWORK_H*/
|
||||
|
||||
1
src/pc.c
1
src/pc.c
@@ -686,4 +686,5 @@ void closepc(void)
|
||||
closevideo();
|
||||
device_close_all();
|
||||
midi_close();
|
||||
network_close();
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ static void win_settings_init()
|
||||
|
||||
/* Peripherals category */
|
||||
temp_scsi_card = scsi_card_current;
|
||||
temp_net_card = network_card_current;
|
||||
temp_net_card = network_card;
|
||||
strncpy(temp_hdc_name, hdd_controller_name, sizeof(temp_hdc_name) - 1);
|
||||
temp_ide_ter = ide_enable[2];
|
||||
temp_ide_ter_irq = ide_irq[2];
|
||||
@@ -168,7 +168,7 @@ static int win_settings_changed()
|
||||
|
||||
/* Peripherals category */
|
||||
i = i || (scsi_card_current != temp_scsi_card);
|
||||
i = i || (network_card_current != temp_net_card);
|
||||
i = i || (network_card != temp_net_card);
|
||||
i = i || strncmp(temp_hdc_name, hdd_controller_name, sizeof(temp_hdc_name) - 1);
|
||||
i = i || (temp_ide_ter != ide_enable[2]);
|
||||
i = i || (temp_ide_ter_irq != ide_irq[2]);
|
||||
@@ -259,7 +259,7 @@ static void win_settings_save()
|
||||
|
||||
/* Peripherals category */
|
||||
scsi_card_current = temp_scsi_card;
|
||||
network_card_current = temp_net_card;
|
||||
network_card = temp_net_card;
|
||||
strncpy(hdd_controller_name, temp_hdc_name, sizeof(temp_hdc_name) - 1);
|
||||
ide_enable[2] = temp_ide_ter;
|
||||
ide_irq[2] = temp_ide_ter_irq;
|
||||
|
||||
Reference in New Issue
Block a user