mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-01-12 16:30:44 +00:00
Some clean-ups. Rewrite ethernet config interpreter. This implies some
prefs items changes but it should now be simpler to add other ethernet emulation means (slirp, tap-win32). # Basilisk II driver mode ether {guid} becomes ether b2ether etherguid {guid} # Basilisk II Router mode routerenabled true becomes ether router
This commit is contained in:
parent
9232fbe4df
commit
732109eff2
@ -49,6 +49,13 @@
|
|||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
|
|
||||||
|
// Ethernet device types
|
||||||
|
enum {
|
||||||
|
NET_IF_B2ETHER,
|
||||||
|
NET_IF_ROUTER,
|
||||||
|
NET_IF_FAKE,
|
||||||
|
};
|
||||||
|
|
||||||
// Options
|
// Options
|
||||||
bool ether_use_permanent = true;
|
bool ether_use_permanent = true;
|
||||||
static int16 ether_multi_mode = ETHER_MULTICAST_MAC;
|
static int16 ether_multi_mode = ETHER_MULTICAST_MAC;
|
||||||
@ -58,15 +65,12 @@ HANDLE ether_th;
|
|||||||
unsigned int ether_tid;
|
unsigned int ether_tid;
|
||||||
HANDLE ether_th1;
|
HANDLE ether_th1;
|
||||||
HANDLE ether_th2;
|
HANDLE ether_th2;
|
||||||
|
static int net_if_type = -1; // Ethernet device type
|
||||||
#ifdef SHEEPSHAVER
|
#ifdef SHEEPSHAVER
|
||||||
static bool net_open = false; // Flag: initialization succeeded, network device open
|
static bool net_open = false; // Flag: initialization succeeded, network device open
|
||||||
uint8 ether_addr[6]; // Our Ethernet address
|
uint8 ether_addr[6]; // Our Ethernet address
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Need to fake a NIC if there is none but the router module is activated.
|
|
||||||
bool ether_fake = false;
|
|
||||||
|
|
||||||
// These are protected by queue_csection
|
// These are protected by queue_csection
|
||||||
// Controls transfer for read thread to feed thread
|
// Controls transfer for read thread to feed thread
|
||||||
static CRITICAL_SECTION queue_csection;
|
static CRITICAL_SECTION queue_csection;
|
||||||
@ -133,9 +137,6 @@ static HANDLE int_sig = 0;
|
|||||||
static HANDLE int_sig2 = 0;
|
static HANDLE int_sig2 = 0;
|
||||||
static HANDLE int_send_now = 0;
|
static HANDLE int_send_now = 0;
|
||||||
|
|
||||||
static char edevice[512];
|
|
||||||
|
|
||||||
|
|
||||||
// Prototypes
|
// Prototypes
|
||||||
static WINAPI unsigned int ether_thread_feed_int(void *arg);
|
static WINAPI unsigned int ether_thread_feed_int(void *arg);
|
||||||
static WINAPI unsigned int ether_thread_get_packets_nt(void *arg);
|
static WINAPI unsigned int ether_thread_get_packets_nt(void *arg);
|
||||||
@ -181,47 +182,54 @@ bool ether_init(void)
|
|||||||
{
|
{
|
||||||
char str[256];
|
char str[256];
|
||||||
|
|
||||||
// Initialize NAT-Router
|
|
||||||
router_init();
|
|
||||||
|
|
||||||
// Do nothing if no Ethernet device specified
|
// Do nothing if no Ethernet device specified
|
||||||
const char *name = PrefsFindString("ether");
|
const char *name = PrefsFindString("ether");
|
||||||
if (name)
|
if (name == NULL)
|
||||||
strcpy(edevice, name);
|
return false;
|
||||||
|
|
||||||
bool there_is_a_router = PrefsFindBool("routerenabled");
|
ether_multi_mode = PrefsFindInt32("ethermulticastmode");
|
||||||
|
ether_use_permanent = PrefsFindBool("etherpermanentaddress");
|
||||||
|
|
||||||
if (!name || !*name) {
|
// Determine Ethernet device type
|
||||||
if( there_is_a_router ) {
|
net_if_type = -1;
|
||||||
strcpy( edevice, "None" );
|
if (strcmp(name, "router") == 0)
|
||||||
ether_fake = true;
|
net_if_type = NET_IF_ROUTER;
|
||||||
} else {
|
else
|
||||||
return false;
|
net_if_type = NET_IF_B2ETHER;
|
||||||
}
|
|
||||||
|
// Initialize NAT-Router
|
||||||
|
if (net_if_type == NET_IF_ROUTER) {
|
||||||
|
if (!router_init())
|
||||||
|
net_if_type = NET_IF_FAKE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ether_use_permanent = PrefsFindBool("etherpermanentaddress");
|
|
||||||
ether_multi_mode = PrefsFindInt32("ethermulticastmode");
|
|
||||||
|
|
||||||
// Open ethernet device
|
// Open ethernet device
|
||||||
if(ether_fake) {
|
const char *dev_name;
|
||||||
memcpy( ether_addr, router_mac_addr, 6 );
|
switch (net_if_type) {
|
||||||
D(bug("Fake ethernet address (same as router) %02x %02x %02x %02x %02x %02x\r\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));
|
case NET_IF_B2ETHER:
|
||||||
} else {
|
dev_name = PrefsFindString("etherguid");
|
||||||
fd = PacketOpenAdapter( name, ether_multi_mode );
|
break;
|
||||||
|
}
|
||||||
|
if (net_if_type == NET_IF_B2ETHER) {
|
||||||
|
if (dev_name == NULL) {
|
||||||
|
WarningAlert("No ethernet device GUID specified. Ethernet is not available.");
|
||||||
|
goto open_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = PacketOpenAdapter( dev_name, ether_multi_mode );
|
||||||
if (!fd) {
|
if (!fd) {
|
||||||
sprintf(str, "Could not open ethernet adapter %s.", name);
|
sprintf(str, "Could not open ethernet adapter %s.", dev_name);
|
||||||
WarningAlert(str);
|
WarningAlert(str);
|
||||||
goto open_error;
|
goto open_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get Ethernet address
|
// Get Ethernet address
|
||||||
if(!PacketGetMAC(fd,ether_addr,ether_use_permanent)) {
|
if(!PacketGetMAC(fd,ether_addr,ether_use_permanent)) {
|
||||||
sprintf(str, "Could not get hardware address of device %s. Ethernet is not available.", name);
|
sprintf(str, "Could not get hardware address of device %s. Ethernet is not available.", dev_name);
|
||||||
WarningAlert(str);
|
WarningAlert(str);
|
||||||
goto open_error;
|
goto open_error;
|
||||||
}
|
}
|
||||||
D(bug("Real ethernet address %02x %02x %02x %02x %02x %02x\r\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));
|
D(bug("Real ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));
|
||||||
|
|
||||||
const char *ether_fake_address;
|
const char *ether_fake_address;
|
||||||
ether_fake_address = PrefsFindString("etherfakeaddress");
|
ether_fake_address = PrefsFindString("etherfakeaddress");
|
||||||
@ -233,9 +241,13 @@ bool ether_init(void)
|
|||||||
sm[3] = ether_fake_address[i*2+1];
|
sm[3] = ether_fake_address[i*2+1];
|
||||||
ether_addr[i] = (uint8)strtoul(sm,0,0);
|
ether_addr[i] = (uint8)strtoul(sm,0,0);
|
||||||
}
|
}
|
||||||
D(bug("Fake ethernet address %02x %02x %02x %02x %02x %02x\r\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));
|
D(bug("Fake ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
memcpy( ether_addr, router_mac_addr, 6 );
|
||||||
|
D(bug("Fake ethernet address (same as router) %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));
|
||||||
|
}
|
||||||
|
|
||||||
// Start packet reception thread
|
// Start packet reception thread
|
||||||
int_ack = CreateSemaphore( 0, 0, 1, NULL);
|
int_ack = CreateSemaphore( 0, 0, 1, NULL);
|
||||||
@ -293,27 +305,14 @@ bool ether_init(void)
|
|||||||
|
|
||||||
ether_th = (HANDLE)_beginthreadex( 0, 0, ether_thread_feed_int, 0, 0, ðer_tid );
|
ether_th = (HANDLE)_beginthreadex( 0, 0, ether_thread_feed_int, 0, 0, ðer_tid );
|
||||||
if (!ether_th) {
|
if (!ether_th) {
|
||||||
D(bug("Failed to create ethernet thread\r\n"));
|
D(bug("Failed to create ethernet thread\n"));
|
||||||
goto open_error;
|
goto open_error;
|
||||||
}
|
}
|
||||||
thread_active = true;
|
thread_active = true;
|
||||||
#if 0
|
|
||||||
SetThreadPriority( ether_th, threads[THREAD_ETHER].priority_running );
|
|
||||||
SetThreadAffinityMask( ether_th, threads[THREAD_ETHER].affinity_mask );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
unsigned int dummy;
|
unsigned int dummy;
|
||||||
ether_th2 = (HANDLE)_beginthreadex( 0, 0, ether_thread_get_packets_nt, 0, 0, &dummy );
|
ether_th2 = (HANDLE)_beginthreadex( 0, 0, ether_thread_get_packets_nt, 0, 0, &dummy );
|
||||||
#if 0
|
|
||||||
SetThreadPriority( ether_th2, threads[THREAD_ETHER].priority_running );
|
|
||||||
SetThreadAffinityMask( ether_th2, threads[THREAD_ETHER].affinity_mask );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ether_th1 = (HANDLE)_beginthreadex( 0, 0, ether_thread_write_packets, 0, 0, &dummy );
|
ether_th1 = (HANDLE)_beginthreadex( 0, 0, ether_thread_write_packets, 0, 0, &dummy );
|
||||||
#if 0
|
|
||||||
SetThreadPriority( ether_th1, threads[THREAD_ETHER].priority_running );
|
|
||||||
SetThreadAffinityMask( ether_th1, threads[THREAD_ETHER].affinity_mask );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Everything OK
|
// Everything OK
|
||||||
return true;
|
return true;
|
||||||
@ -336,7 +335,7 @@ bool ether_init(void)
|
|||||||
int_send_now = 0;
|
int_send_now = 0;
|
||||||
thread_active = false;
|
thread_active = false;
|
||||||
}
|
}
|
||||||
if(!ether_fake) {
|
if(net_if_type == NET_IF_B2ETHER) {
|
||||||
PacketCloseAdapter(fd);
|
PacketCloseAdapter(fd);
|
||||||
}
|
}
|
||||||
fd = 0;
|
fd = 0;
|
||||||
@ -350,45 +349,39 @@ bool ether_init(void)
|
|||||||
|
|
||||||
void ether_exit(void)
|
void ether_exit(void)
|
||||||
{
|
{
|
||||||
D(bug("EtherExit\r\n"));
|
D(bug("EtherExit\n"));
|
||||||
|
|
||||||
// Take them down in a controlled way.
|
// Stop reception thread
|
||||||
thread_active = false;
|
thread_active = false;
|
||||||
|
|
||||||
// _asm int 3
|
|
||||||
|
|
||||||
D(bug("Closing ethernet device %s\r\n",edevice));
|
|
||||||
|
|
||||||
if(!*edevice) return;
|
|
||||||
|
|
||||||
if(int_ack) ReleaseSemaphore(int_ack,1,NULL);
|
if(int_ack) ReleaseSemaphore(int_ack,1,NULL);
|
||||||
if(int_sig) ReleaseSemaphore(int_sig,1,NULL);
|
if(int_sig) ReleaseSemaphore(int_sig,1,NULL);
|
||||||
if(int_sig2) ReleaseSemaphore(int_sig2,1,NULL);
|
if(int_sig2) ReleaseSemaphore(int_sig2,1,NULL);
|
||||||
if(int_send_now) ReleaseSemaphore(int_send_now,1,NULL);
|
if(int_send_now) ReleaseSemaphore(int_send_now,1,NULL);
|
||||||
|
|
||||||
D(bug("CancelIO if needed\r\n"));
|
D(bug("CancelIO if needed\n"));
|
||||||
if (fd && fd->hFile && pfnCancelIo)
|
if (fd && fd->hFile && pfnCancelIo)
|
||||||
pfnCancelIo(fd->hFile);
|
pfnCancelIo(fd->hFile);
|
||||||
|
|
||||||
// Wait max 2 secs to shut down pending io. After that, kill them.
|
// Wait max 2 secs to shut down pending io. After that, kill them.
|
||||||
D(bug("Wait delay\r\n"));
|
D(bug("Wait delay\n"));
|
||||||
for( int i=0; i<10; i++ ) {
|
for( int i=0; i<10; i++ ) {
|
||||||
if(!thread_active_1 && !thread_active_2 && !thread_active_3) break;
|
if(!thread_active_1 && !thread_active_2 && !thread_active_3) break;
|
||||||
Sleep(200);
|
Sleep(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(thread_active_1) {
|
if(thread_active_1) {
|
||||||
D(bug("Ether killing ether_th1\r\n"));
|
D(bug("Ether killing ether_th1\n"));
|
||||||
if(ether_th1) TerminateThread(ether_th1,0);
|
if(ether_th1) TerminateThread(ether_th1,0);
|
||||||
thread_active_1 = false;
|
thread_active_1 = false;
|
||||||
}
|
}
|
||||||
if(thread_active_2) {
|
if(thread_active_2) {
|
||||||
D(bug("Ether killing ether_th2\r\n"));
|
D(bug("Ether killing ether_th2\n"));
|
||||||
if(ether_th2) TerminateThread(ether_th2,0);
|
if(ether_th2) TerminateThread(ether_th2,0);
|
||||||
thread_active_2 = false;
|
thread_active_2 = false;
|
||||||
}
|
}
|
||||||
if(thread_active_3) {
|
if(thread_active_3) {
|
||||||
D(bug("Ether killing thread\r\n"));
|
D(bug("Ether killing thread\n"));
|
||||||
if(ether_th) TerminateThread(ether_th,0);
|
if(ether_th) TerminateThread(ether_th,0);
|
||||||
thread_active_3 = false;
|
thread_active_3 = false;
|
||||||
}
|
}
|
||||||
@ -397,7 +390,7 @@ void ether_exit(void)
|
|||||||
ether_th2 = 0;
|
ether_th2 = 0;
|
||||||
ether_th = 0;
|
ether_th = 0;
|
||||||
|
|
||||||
D(bug("Closing semaphores\r\n"));
|
D(bug("Closing semaphores\n"));
|
||||||
if(int_ack) {
|
if(int_ack) {
|
||||||
CloseHandle(int_ack);
|
CloseHandle(int_ack);
|
||||||
int_ack = 0;
|
int_ack = 0;
|
||||||
@ -422,7 +415,7 @@ void ether_exit(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove all protocols
|
// Remove all protocols
|
||||||
D(bug("Removing protocols\r\n"));
|
D(bug("Removing protocols\n"));
|
||||||
NetProtocol *p = prot_list;
|
NetProtocol *p = prot_list;
|
||||||
while (p) {
|
while (p) {
|
||||||
NetProtocol *next = p->next;
|
NetProtocol *next = p->next;
|
||||||
@ -431,25 +424,27 @@ void ether_exit(void)
|
|||||||
}
|
}
|
||||||
prot_list = 0;
|
prot_list = 0;
|
||||||
|
|
||||||
D(bug("Deleting sections\r\n"));
|
D(bug("Deleting sections\n"));
|
||||||
DeleteCriticalSection( &fetch_csection );
|
DeleteCriticalSection( &fetch_csection );
|
||||||
DeleteCriticalSection( &queue_csection );
|
DeleteCriticalSection( &queue_csection );
|
||||||
DeleteCriticalSection( &send_csection );
|
DeleteCriticalSection( &send_csection );
|
||||||
DeleteCriticalSection( &wpool_csection );
|
DeleteCriticalSection( &wpool_csection );
|
||||||
|
|
||||||
D(bug("Freeing read packets\r\n"));
|
D(bug("Freeing read packets\n"));
|
||||||
free_read_packets();
|
free_read_packets();
|
||||||
|
|
||||||
D(bug("Freeing write packets\r\n"));
|
D(bug("Freeing write packets\n"));
|
||||||
free_write_packets();
|
free_write_packets();
|
||||||
|
|
||||||
D(bug("Finalizing queue\r\n"));
|
D(bug("Finalizing queue\n"));
|
||||||
final_queue();
|
final_queue();
|
||||||
|
|
||||||
D(bug("Stopping router\r\n"));
|
if (net_if_type == NET_IF_ROUTER) {
|
||||||
router_final();
|
D(bug("Stopping router\n"));
|
||||||
|
router_final();
|
||||||
|
}
|
||||||
|
|
||||||
D(bug("EtherExit done\r\n"));
|
D(bug("EtherExit done\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -548,7 +543,7 @@ void EtherIRQ(void)
|
|||||||
OTLeaveInterrupt();
|
OTLeaveInterrupt();
|
||||||
|
|
||||||
// Acknowledge interrupt to reception thread
|
// Acknowledge interrupt to reception thread
|
||||||
D(bug(" EtherIRQ done\r\n"));
|
D(bug(" EtherIRQ done\n"));
|
||||||
ReleaseSemaphore(int_ack,1,NULL);
|
ReleaseSemaphore(int_ack,1,NULL);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -593,7 +588,7 @@ static void ether_dispatch_packet(uint32 packet, uint32 length)
|
|||||||
|
|
||||||
// Copy header to RHA
|
// Copy header to RHA
|
||||||
Mac2Mac_memcpy(ether_data + ed_RHA, packet, 14);
|
Mac2Mac_memcpy(ether_data + ed_RHA, packet, 14);
|
||||||
D(bug(" header %08lx%04lx %08lx%04lx %04lx\r\n", ReadMacInt32(ether_data + ed_RHA), ReadMacInt16(ether_data + ed_RHA + 4), ReadMacInt32(ether_data + ed_RHA + 6), ReadMacInt16(ether_data + ed_RHA + 10), ReadMacInt16(ether_data + ed_RHA + 12)));
|
D(bug(" header %08lx%04lx %08lx%04lx %04lx\n", ReadMacInt32(ether_data + ed_RHA), ReadMacInt16(ether_data + ed_RHA + 4), ReadMacInt32(ether_data + ed_RHA + 6), ReadMacInt16(ether_data + ed_RHA + 10), ReadMacInt16(ether_data + ed_RHA + 12)));
|
||||||
|
|
||||||
// Call protocol handler
|
// Call protocol handler
|
||||||
M68kRegisters r;
|
M68kRegisters r;
|
||||||
@ -602,7 +597,7 @@ static void ether_dispatch_packet(uint32 packet, uint32 length)
|
|||||||
r.a[0] = packet + 14; // Pointer to packet (Mac address, for ReadPacket)
|
r.a[0] = packet + 14; // Pointer to packet (Mac address, for ReadPacket)
|
||||||
r.a[3] = ether_data + ed_RHA + 14; // Pointer behind header in RHA
|
r.a[3] = ether_data + ed_RHA + 14; // Pointer behind header in RHA
|
||||||
r.a[4] = ether_data + ed_ReadPacket; // Pointer to ReadPacket/ReadRest routines
|
r.a[4] = ether_data + ed_ReadPacket; // Pointer to ReadPacket/ReadRest routines
|
||||||
D(bug(" calling protocol handler %08lx, type %08lx, length %08lx, data %08lx, rha %08lx, read_packet %08lx\r\n", prot->handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4]));
|
D(bug(" calling protocol handler %08lx, type %08lx, length %08lx, data %08lx, rha %08lx, read_packet %08lx\n", prot->handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4]));
|
||||||
Execute68k(prot->handler, &r);
|
Execute68k(prot->handler, &r);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -613,7 +608,7 @@ void EtherInterrupt(void)
|
|||||||
ether_do_interrupt();
|
ether_do_interrupt();
|
||||||
|
|
||||||
// Acknowledge interrupt to reception thread
|
// Acknowledge interrupt to reception thread
|
||||||
D(bug(" EtherIRQ done\r\n"));
|
D(bug(" EtherIRQ done\n"));
|
||||||
ReleaseSemaphore(int_ack,1,NULL);
|
ReleaseSemaphore(int_ack,1,NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -625,7 +620,7 @@ void EtherInterrupt(void)
|
|||||||
|
|
||||||
void ether_reset(void)
|
void ether_reset(void)
|
||||||
{
|
{
|
||||||
D(bug("EtherReset\r\n"));
|
D(bug("EtherReset\n"));
|
||||||
|
|
||||||
// Remove all protocols
|
// Remove all protocols
|
||||||
NetProtocol *p = prot_list;
|
NetProtocol *p = prot_list;
|
||||||
@ -644,16 +639,19 @@ void ether_reset(void)
|
|||||||
|
|
||||||
static int16 ether_do_add_multicast(uint8 *addr)
|
static int16 ether_do_add_multicast(uint8 *addr)
|
||||||
{
|
{
|
||||||
D(bug("ether_add_multicast\r\n"));
|
D(bug("ether_add_multicast\n"));
|
||||||
|
|
||||||
// We wouldn't need to do this
|
// We wouldn't need to do this
|
||||||
// if(ether_multi_mode != ETHER_MULTICAST_MAC) return noErr;
|
// if(ether_multi_mode != ETHER_MULTICAST_MAC) return noErr;
|
||||||
|
|
||||||
if (!ether_fake && !PacketAddMulticast( fd, addr)) {
|
switch (net_if_type) {
|
||||||
D(bug("WARNING: couldn't enable multicast address\r\n"));
|
case NET_IF_B2ETHER:
|
||||||
return eMultiErr;
|
if (!PacketAddMulticast( fd, addr)) {
|
||||||
} else {
|
D(bug("WARNING: couldn't enable multicast address\n"));
|
||||||
D(bug("ether_add_multicast: noErr\r\n"));
|
return eMultiErr;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
D(bug("ether_add_multicast: noErr\n"));
|
||||||
return noErr;
|
return noErr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -665,16 +663,20 @@ static int16 ether_do_add_multicast(uint8 *addr)
|
|||||||
|
|
||||||
int16 ether_do_del_multicast(uint8 *addr)
|
int16 ether_do_del_multicast(uint8 *addr)
|
||||||
{
|
{
|
||||||
D(bug("ether_del_multicast\r\n"));
|
D(bug("ether_del_multicast\n"));
|
||||||
|
|
||||||
// We wouldn't need to do this
|
// We wouldn't need to do this
|
||||||
// if(ether_multi_mode != ETHER_MULTICAST_MAC) return noErr;
|
// if(ether_multi_mode != ETHER_MULTICAST_MAC) return noErr;
|
||||||
|
|
||||||
if (!ether_fake && !PacketDelMulticast( fd, addr)) {
|
switch (net_if_type) {
|
||||||
D(bug("WARNING: couldn't disable multicast address\r\n"));
|
case NET_IF_B2ETHER:
|
||||||
return eMultiErr;
|
if (!PacketDelMulticast( fd, addr)) {
|
||||||
} else
|
D(bug("WARNING: couldn't disable multicast address\n"));
|
||||||
|
return eMultiErr;
|
||||||
|
}
|
||||||
|
default:
|
||||||
return noErr;
|
return noErr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -684,12 +686,12 @@ int16 ether_do_del_multicast(uint8 *addr)
|
|||||||
|
|
||||||
int16 ether_attach_ph(uint16 type, uint32 handler)
|
int16 ether_attach_ph(uint16 type, uint32 handler)
|
||||||
{
|
{
|
||||||
D(bug("ether_attach_ph type=0x%x, handler=0x%x\r\n",(int)type,handler));
|
D(bug("ether_attach_ph type=0x%x, handler=0x%x\n",(int)type,handler));
|
||||||
|
|
||||||
// Already attached?
|
// Already attached?
|
||||||
NetProtocol *p = find_protocol(type);
|
NetProtocol *p = find_protocol(type);
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
D(bug("ether_attach_ph: lapProtErr\r\n"));
|
D(bug("ether_attach_ph: lapProtErr\n"));
|
||||||
return lapProtErr;
|
return lapProtErr;
|
||||||
} else {
|
} else {
|
||||||
// No, create and attach
|
// No, create and attach
|
||||||
@ -698,7 +700,7 @@ int16 ether_attach_ph(uint16 type, uint32 handler)
|
|||||||
p->type = type;
|
p->type = type;
|
||||||
p->handler = handler;
|
p->handler = handler;
|
||||||
prot_list = p;
|
prot_list = p;
|
||||||
D(bug("ether_attach_ph: noErr\r\n"));
|
D(bug("ether_attach_ph: noErr\n"));
|
||||||
return noErr;
|
return noErr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -710,7 +712,7 @@ int16 ether_attach_ph(uint16 type, uint32 handler)
|
|||||||
|
|
||||||
int16 ether_detach_ph(uint16 type)
|
int16 ether_detach_ph(uint16 type)
|
||||||
{
|
{
|
||||||
D(bug("ether_detach_ph type=%08lx\r\n",(int)type));
|
D(bug("ether_detach_ph type=%08lx\n",(int)type));
|
||||||
|
|
||||||
NetProtocol *p = find_protocol(type);
|
NetProtocol *p = find_protocol(type);
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
@ -746,7 +748,7 @@ static void dump_packet( uint8 *packet, int length )
|
|||||||
sprintf(sm," %02x", (int)packet[i]);
|
sprintf(sm," %02x", (int)packet[i]);
|
||||||
strcat( buf, sm );
|
strcat( buf, sm );
|
||||||
}
|
}
|
||||||
strcat( buf, "\r\n" );
|
strcat( buf, "\n" );
|
||||||
bug(buf);
|
bug(buf);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -803,7 +805,7 @@ static void free_write_packets( void )
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
while(write_packet_pool) {
|
while(write_packet_pool) {
|
||||||
next = write_packet_pool->next;
|
next = write_packet_pool->next;
|
||||||
D(bug("Freeing write packet %ld\r\n",++i));
|
D(bug("Freeing write packet %ld\n",++i));
|
||||||
PacketFreePacket(write_packet_pool);
|
PacketFreePacket(write_packet_pool);
|
||||||
write_packet_pool = next;
|
write_packet_pool = next;
|
||||||
}
|
}
|
||||||
@ -814,7 +816,7 @@ void recycle_write_packet( LPPACKET Packet )
|
|||||||
EnterCriticalSection( &wpool_csection );
|
EnterCriticalSection( &wpool_csection );
|
||||||
Packet->next = write_packet_pool;
|
Packet->next = write_packet_pool;
|
||||||
write_packet_pool = Packet;
|
write_packet_pool = Packet;
|
||||||
D(bug("Pool size after recycling = %ld\r\n",get_write_packet_pool_sz()));
|
D(bug("Pool size after recycling = %ld\n",get_write_packet_pool_sz()));
|
||||||
LeaveCriticalSection( &wpool_csection );
|
LeaveCriticalSection( &wpool_csection );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -839,7 +841,7 @@ static LPPACKET get_write_packet( UINT len )
|
|||||||
Packet = PacketAllocatePacket(fd,len);
|
Packet = PacketAllocatePacket(fd,len);
|
||||||
}
|
}
|
||||||
|
|
||||||
D(bug("Pool size after get wr packet = %ld\r\n",get_write_packet_pool_sz()));
|
D(bug("Pool size after get wr packet = %ld\n",get_write_packet_pool_sz()));
|
||||||
|
|
||||||
LeaveCriticalSection( &wpool_csection );
|
LeaveCriticalSection( &wpool_csection );
|
||||||
|
|
||||||
@ -852,25 +854,33 @@ static unsigned int ether_thread_write_packets(void *arg)
|
|||||||
|
|
||||||
thread_active_1 = true;
|
thread_active_1 = true;
|
||||||
|
|
||||||
D(bug("ether_thread_write_packets start\r\n"));
|
D(bug("ether_thread_write_packets start\n"));
|
||||||
|
|
||||||
while(thread_active) {
|
while(thread_active) {
|
||||||
// must be alertable, otherwise write completion is never called
|
// must be alertable, otherwise write completion is never called
|
||||||
WaitForSingleObjectEx(int_send_now,INFINITE,TRUE);
|
WaitForSingleObjectEx(int_send_now,INFINITE,TRUE);
|
||||||
while( thread_active && (Packet = get_send_head()) != 0 ) {
|
while( thread_active && (Packet = get_send_head()) != 0 ) {
|
||||||
if(m_router_enabled && router_write_packet((uint8 *)Packet->Buffer, Packet->Length)) {
|
switch (net_if_type) {
|
||||||
|
case NET_IF_ROUTER:
|
||||||
|
if(router_write_packet((uint8 *)Packet->Buffer, Packet->Length)) {
|
||||||
|
Packet->bIoComplete = TRUE;
|
||||||
|
recycle_write_packet(Packet);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NET_IF_FAKE:
|
||||||
Packet->bIoComplete = TRUE;
|
Packet->bIoComplete = TRUE;
|
||||||
recycle_write_packet(Packet);
|
recycle_write_packet(Packet);
|
||||||
} else if(ether_fake) {
|
break;
|
||||||
Packet->bIoComplete = TRUE;
|
case NET_IF_B2ETHER:
|
||||||
recycle_write_packet(Packet);
|
if(!PacketSendPacket( fd, Packet, FALSE, TRUE )) {
|
||||||
} else if(!PacketSendPacket( fd, Packet, FALSE, TRUE )) {
|
// already recycled if async
|
||||||
// already recycled if async
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
D(bug("ether_thread_write_packets exit\r\n"));
|
D(bug("ether_thread_write_packets exit\n"));
|
||||||
|
|
||||||
thread_active_1 = false;
|
thread_active_1 = false;
|
||||||
|
|
||||||
@ -881,7 +891,7 @@ static BOOL write_packet( uint8 *packet, int len )
|
|||||||
{
|
{
|
||||||
LPPACKET Packet;
|
LPPACKET Packet;
|
||||||
|
|
||||||
D(bug("write_packet\r\n"));
|
D(bug("write_packet\n"));
|
||||||
|
|
||||||
Packet = get_write_packet(len);
|
Packet = get_write_packet(len);
|
||||||
if(Packet) {
|
if(Packet) {
|
||||||
@ -904,14 +914,14 @@ static BOOL write_packet( uint8 *packet, int len )
|
|||||||
|
|
||||||
static int16 ether_do_write(uint32 arg)
|
static int16 ether_do_write(uint32 arg)
|
||||||
{
|
{
|
||||||
D(bug("ether_write\r\n"));
|
D(bug("ether_write\n"));
|
||||||
|
|
||||||
// Copy packet to buffer
|
// Copy packet to buffer
|
||||||
uint8 packet[1514], *p = packet;
|
uint8 packet[1514], *p = packet;
|
||||||
int len = ether_arg_to_buffer(arg, p);
|
int len = ether_arg_to_buffer(arg, p);
|
||||||
|
|
||||||
if(len > 1514) {
|
if(len > 1514) {
|
||||||
D(bug("illegal packet length: %d\r\n",len));
|
D(bug("illegal packet length: %d\n",len));
|
||||||
return eLenErr;
|
return eLenErr;
|
||||||
} else {
|
} else {
|
||||||
#if MONITOR
|
#if MONITOR
|
||||||
@ -922,7 +932,7 @@ static int16 ether_do_write(uint32 arg)
|
|||||||
|
|
||||||
// Transmit packet
|
// Transmit packet
|
||||||
if (!write_packet(packet, len)) {
|
if (!write_packet(packet, len)) {
|
||||||
D(bug("WARNING: couldn't transmit packet\r\n"));
|
D(bug("WARNING: couldn't transmit packet\n"));
|
||||||
return excessCollsns;
|
return excessCollsns;
|
||||||
} else {
|
} else {
|
||||||
// It's up to the protocol drivers to do the error checking. Even if the
|
// It's up to the protocol drivers to do the error checking. Even if the
|
||||||
@ -956,7 +966,7 @@ void enqueue_packet( uint8 *buf, int sz )
|
|||||||
{
|
{
|
||||||
EnterCriticalSection( &queue_csection );
|
EnterCriticalSection( &queue_csection );
|
||||||
if(queue[queue_inx].sz > 0) {
|
if(queue[queue_inx].sz > 0) {
|
||||||
D(bug("ethernet queue full, packet dropped\r\n"));
|
D(bug("ethernet queue full, packet dropped\n"));
|
||||||
} else {
|
} else {
|
||||||
if(sz > 1514) sz = 1514;
|
if(sz > 1514) sz = 1514;
|
||||||
queue[queue_inx].sz = sz;
|
queue[queue_inx].sz = sz;
|
||||||
@ -993,7 +1003,7 @@ static void trigger_queue(void)
|
|||||||
{
|
{
|
||||||
EnterCriticalSection( &queue_csection );
|
EnterCriticalSection( &queue_csection );
|
||||||
if( queue[queue_head].sz > 0 ) {
|
if( queue[queue_head].sz > 0 ) {
|
||||||
D(bug(" packet received, triggering Ethernet interrupt\r\n"));
|
D(bug(" packet received, triggering Ethernet interrupt\n"));
|
||||||
SetInterruptFlag(INTFLAG_ETHER);
|
SetInterruptFlag(INTFLAG_ETHER);
|
||||||
TriggerInterrupt();
|
TriggerInterrupt();
|
||||||
// of course can't wait here.
|
// of course can't wait here.
|
||||||
@ -1042,19 +1052,19 @@ VOID CALLBACK packet_read_completion(
|
|||||||
if(count == pending_packet_sz[j] &&
|
if(count == pending_packet_sz[j] &&
|
||||||
memcmp(pending_packet[j],lpPacket->Buffer,count) == 0)
|
memcmp(pending_packet[j],lpPacket->Buffer,count) == 0)
|
||||||
{
|
{
|
||||||
D(bug("packet_read_completion discarding own packet.\r\n"));
|
D(bug("packet_read_completion discarding own packet.\n"));
|
||||||
dwNumberOfBytesTransfered = 0;
|
dwNumberOfBytesTransfered = 0;
|
||||||
|
|
||||||
j = (j+1) & (~(MAX_ECHO-1));
|
j = (j+1) & (~(MAX_ECHO-1));
|
||||||
if(j != echo_count) {
|
if(j != echo_count) {
|
||||||
D(bug("Wow, this fix made some good after all...\r\n"));
|
D(bug("Wow, this fix made some good after all...\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(dwNumberOfBytesTransfered) {
|
if(dwNumberOfBytesTransfered) {
|
||||||
if(!m_router_enabled || !router_read_packet((uint8 *)lpPacket->Buffer, dwNumberOfBytesTransfered)) {
|
if(net_if_type != NET_IF_ROUTER || !router_read_packet((uint8 *)lpPacket->Buffer, dwNumberOfBytesTransfered)) {
|
||||||
enqueue_packet( (LPBYTE)lpPacket->Buffer, dwNumberOfBytesTransfered );
|
enqueue_packet( (LPBYTE)lpPacket->Buffer, dwNumberOfBytesTransfered );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1098,7 +1108,7 @@ static bool allocate_read_packets(void)
|
|||||||
for( int i=0; i<PACKET_POOL_COUNT; i++ ) {
|
for( int i=0; i<PACKET_POOL_COUNT; i++ ) {
|
||||||
packets[i] = PacketAllocatePacket(fd,1514);
|
packets[i] = PacketAllocatePacket(fd,1514);
|
||||||
if(!packets[i]) {
|
if(!packets[i]) {
|
||||||
D(bug("allocate_read_packets: out of memory\r\n"));
|
D(bug("allocate_read_packets: out of memory\n"));
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1119,20 +1129,20 @@ static unsigned int ether_thread_get_packets_nt(void *arg)
|
|||||||
|
|
||||||
thread_active_2 = true;
|
thread_active_2 = true;
|
||||||
|
|
||||||
D(bug("ether_thread_get_packets_nt start\r\n"));
|
D(bug("ether_thread_get_packets_nt start\n"));
|
||||||
|
|
||||||
// Wait for packets to arrive.
|
// Wait for packets to arrive.
|
||||||
// Obey the golden rules; keep the reads pending.
|
// Obey the golden rules; keep the reads pending.
|
||||||
while(thread_active) {
|
while(thread_active) {
|
||||||
|
|
||||||
if(!ether_fake) {
|
if(net_if_type == NET_IF_B2ETHER) {
|
||||||
D(bug("Pending reads\r\n"));
|
D(bug("Pending reads\n"));
|
||||||
for( i=0; thread_active && i<PACKET_POOL_COUNT; i++ ) {
|
for( i=0; thread_active && i<PACKET_POOL_COUNT; i++ ) {
|
||||||
if(packets[i]->free) {
|
if(packets[i]->free) {
|
||||||
packets[i]->free = FALSE;
|
packets[i]->free = FALSE;
|
||||||
if(PacketReceivePacket(fd,packets[i],FALSE)) {
|
if(PacketReceivePacket(fd,packets[i],FALSE)) {
|
||||||
if(packets[i]->bIoComplete) {
|
if(packets[i]->bIoComplete) {
|
||||||
D(bug("Early io completion...\r\n"));
|
D(bug("Early io completion...\n"));
|
||||||
packet_read_completion(
|
packet_read_completion(
|
||||||
ERROR_SUCCESS,
|
ERROR_SUCCESS,
|
||||||
packets[i]->BytesReceived,
|
packets[i]->BytesReceived,
|
||||||
@ -1147,13 +1157,13 @@ static unsigned int ether_thread_get_packets_nt(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(thread_active && has_no_completed_io()) {
|
if(thread_active && has_no_completed_io()) {
|
||||||
D(bug("Waiting for int_sig2\r\n"));
|
D(bug("Waiting for int_sig2\n"));
|
||||||
// "problem": awakens twice in a row. Fix if you increase the pool size.
|
// "problem": awakens twice in a row. Fix if you increase the pool size.
|
||||||
WaitForSingleObjectEx(int_sig2,INFINITE,TRUE);
|
WaitForSingleObjectEx(int_sig2,INFINITE,TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
D(bug("ether_thread_get_packets_nt exit\r\n"));
|
D(bug("ether_thread_get_packets_nt exit\n"));
|
||||||
|
|
||||||
thread_active_2 = false;
|
thread_active_2 = false;
|
||||||
|
|
||||||
@ -1166,13 +1176,13 @@ static unsigned int ether_thread_feed_int(void *arg)
|
|||||||
|
|
||||||
thread_active_3 = true;
|
thread_active_3 = true;
|
||||||
|
|
||||||
D(bug("ether_thread_feed_int start\r\n"));
|
D(bug("ether_thread_feed_int start\n"));
|
||||||
|
|
||||||
while(thread_active) {
|
while(thread_active) {
|
||||||
D(bug("Waiting for int_sig\r\n"));
|
D(bug("Waiting for int_sig\n"));
|
||||||
WaitForSingleObject(int_sig,INFINITE);
|
WaitForSingleObject(int_sig,INFINITE);
|
||||||
// Looping this way to avoid a race condition.
|
// Looping this way to avoid a race condition.
|
||||||
D(bug("Triggering\r\n"));
|
D(bug("Triggering\n"));
|
||||||
looping = true;
|
looping = true;
|
||||||
while(thread_active && looping) {
|
while(thread_active && looping) {
|
||||||
trigger_queue();
|
trigger_queue();
|
||||||
@ -1180,10 +1190,10 @@ static unsigned int ether_thread_feed_int(void *arg)
|
|||||||
WaitForSingleObject(int_ack,INFINITE);
|
WaitForSingleObject(int_ack,INFINITE);
|
||||||
if(thread_active) looping = set_wait_request();
|
if(thread_active) looping = set_wait_request();
|
||||||
}
|
}
|
||||||
D(bug("Queue empty.\r\n"));
|
D(bug("Queue empty.\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
D(bug("ether_thread_feed_int exit\r\n"));
|
D(bug("ether_thread_feed_int exit\n"));
|
||||||
|
|
||||||
thread_active_3 = false;
|
thread_active_3 = false;
|
||||||
|
|
||||||
|
@ -62,7 +62,6 @@ uint32 macos_ip_address = 0;
|
|||||||
const uint8 router_mac_addr[6] = { '4', '2', '6', '7', '7', '9' };
|
const uint8 router_mac_addr[6] = { '4', '2', '6', '7', '7', '9' };
|
||||||
uint32 router_ip_address = 0;
|
uint32 router_ip_address = 0;
|
||||||
bool raw_sockets_available = false;
|
bool raw_sockets_available = false;
|
||||||
bool m_router_enabled = true;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -157,13 +156,11 @@ static WINAPI unsigned int router_expire_thread(void *arg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void router_init(void)
|
bool router_init(void)
|
||||||
{
|
{
|
||||||
InitializeCriticalSection( &router_section );
|
InitializeCriticalSection( &router_section );
|
||||||
|
|
||||||
m_router_enabled = PrefsFindBool("routerenabled");
|
if(dynsockets_init()) {
|
||||||
|
|
||||||
if(m_router_enabled && dynsockets_init()) {
|
|
||||||
char me[128];
|
char me[128];
|
||||||
if( _gethostname(me, sizeof(me)) == SOCKET_ERROR ) {
|
if( _gethostname(me, sizeof(me)) == SOCKET_ERROR ) {
|
||||||
D(bug("gethostname() failed, error = %d\r\n", _WSAGetLastError()));
|
D(bug("gethostname() failed, error = %d\r\n", _WSAGetLastError()));
|
||||||
@ -183,9 +180,10 @@ void router_init(void)
|
|||||||
init_tcp();
|
init_tcp();
|
||||||
init_udp();
|
init_udp();
|
||||||
init_ftp();
|
init_ftp();
|
||||||
} else {
|
return true;
|
||||||
m_router_enabled = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void router_final(void)
|
void router_final(void)
|
||||||
|
@ -44,8 +44,7 @@ extern bool raw_sockets_available;
|
|||||||
|
|
||||||
|
|
||||||
// Interface exposed to ether_windows module.
|
// Interface exposed to ether_windows module.
|
||||||
extern bool m_router_enabled;
|
bool router_init(void);
|
||||||
void router_init(void);
|
|
||||||
void router_final(void);
|
void router_final(void);
|
||||||
|
|
||||||
// Both of these return true if the ethernet module should drop the packet.
|
// Both of these return true if the ethernet module should drop the packet.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user