Slight cleanup in the main file. Win32 tries sending the packet, but fails with error 0x57 or 0x6 in WriteFile function, depending on how I have it set up. Linux sends out the packet, or at least it says it sends it out. Requires root priv in Linux and openVPN installed to use the /dev/net/tun device.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3217 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Sonicadvance1
2009-05-13 15:34:38 +00:00
parent 5cefdb2c4f
commit 9b7b44fff6
4 changed files with 84 additions and 27 deletions

View File

@ -20,23 +20,81 @@
#include "../EXI_DeviceEthernet.h" #include "../EXI_DeviceEthernet.h"
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <stropts.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/if_tun.h>
int fd = -1;
bool CEXIETHERNET::deactivate() bool CEXIETHERNET::deactivate()
{ {
close(fd);
fd = -1;
return true; return true;
// TODO: Actually deactivate
} }
bool CEXIETHERNET::isActivated() bool CEXIETHERNET::isActivated()
{ {
return false; return fd != -1 ? true : false;
//TODO: Never Activated Yet!
} }
bool CEXIETHERNET::activate() { bool CEXIETHERNET::activate() {
if(isActivated()) if(isActivated())
return true; return true;
else if( (fd = open("/dev/net/tun", O_RDWR)) < 0)
{
DEBUGPRINT("Couldn't Open device\n");
return false; return false;
//TODO: Activate Device! }
struct ifreq ifr;
int err;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP;
strncpy(ifr.ifr_name, "Dolphin", IFNAMSIZ);
if( (err = ioctl(fd, TUNSETIFF, (void*) &ifr)) < 0)
{
close(fd);
fd = -1;
DEBUGPRINT(" Error with IOCTL: 0x%X\n", err);
return false;
}
DEBUGPRINT("Returned Socket name is: %s\n", ifr.ifr_name);
return true;
}
bool CEXIETHERNET::startRecv() {
DEBUGPRINT("Start Receive!\n");
exit(0);
/*if(!isActivated())
return false;// Should actually be an assert
DEBUGPRINT("startRecv... ");
if(mWaiting) {
DEBUGPRINT("already waiting\n");
return true;
}
DWORD BytesRead = 0;
DWORD *Buffer = (DWORD *)malloc(2048); // Should be enough
DWORD res = ReadFile(mHAdapter, Buffer, BytesRead,
&mRecvBufferLength, &mReadOverlapped);
mRecvBuffer.write(BytesRead, Buffer);
free(Buffer);
if(res) { //Operation completed immediately
DEBUGPRINT("completed, res %i\n", res);
mWaiting = true;
} else {
res = GetLastError();
if (res == ERROR_IO_PENDING) { //'s ok :)
DEBUGPRINT("pending\n");
//WaitCallback will be called
mWaiting = true;
} else { //error occurred
return false;
}
}
return true;*/
} }
bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size) bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size)
{ {
@ -46,18 +104,14 @@ bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size)
DEBUGPRINT( "%02X", etherpckt[a]); DEBUGPRINT( "%02X", etherpckt[a]);
} }
DEBUGPRINT( " : Size: %d\n", size); DEBUGPRINT( " : Size: %d\n", size);
int raw_socket = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); int numBytesWrit = write(fd, etherpckt, size);
DEBUGPRINT("Raw socket is : %d\n", raw_socket);
int sm=1;
const int *val=&sm;
int result = setsockopt(raw_socket, IPPROTO_IP, IP_HDRINCL, val, sizeof(sm));
DEBUGPRINT("Result is : %d\n", result);
int numBytesWrit = write(raw_socket, etherpckt, size);
if(numBytesWrit != size) if(numBytesWrit != size)
{ {
DEBUGPRINT("BBA sendPacket %i only got %i bytes sent!\n", size, numBytesWrit); DEBUGPRINT("BBA sendPacket %i only got %i bytes sent!\n", size, numBytesWrit);
return false; return false;
} }
else
DEBUGPRINT("Sent out the correct number of bytes: %d\n", size);
//fwrite(etherpckt, size, size, raw_socket); //fwrite(etherpckt, size, size, raw_socket);
/*DWORD numBytesWrit; /*DWORD numBytesWrit;
OVERLAPPED overlap; OVERLAPPED overlap;

View File

@ -137,8 +137,12 @@ bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size)
DWORD numBytesWrit; DWORD numBytesWrit;
OVERLAPPED overlap; OVERLAPPED overlap;
//ZERO_OBJECT(overlap); //ZERO_OBJECT(overlap);
//overlap.hEvent = mHRecvEvent; overlap.hEvent = mHRecvEvent;
WriteFile(mHAdapter, etherpckt, size, &numBytesWrit, &overlap); if(!WriteFile(mHAdapter, etherpckt, size, &numBytesWrit, &overlap))
{ // Fail Boat
DWORD res = GetLastError();
DEBUGPRINT("Failed to send packet with error 0x%X\n", res);
}
if(numBytesWrit != size) if(numBytesWrit != size)
{ {
DEBUGPRINT("BBA sendPacket %i only got %i bytes sent!\n", size, numBytesWrit); DEBUGPRINT("BBA sendPacket %i only got %i bytes sent!\n", size, numBytesWrit);

View File

@ -23,7 +23,7 @@
#include "EXI_Device.h" #include "EXI_Device.h"
#include "EXI_DeviceEthernet.h" #include "EXI_DeviceEthernet.h"
//#define SONICDEBUG #define SONICDEBUG
void DEBUGPRINT (const char * format, ...) void DEBUGPRINT (const char * format, ...)
{ {
@ -95,7 +95,6 @@ CEXIETHERNET::CEXIETHERNET() :
Expecting = EXPECT_NONE; Expecting = EXPECT_NONE;
mExpectVariableLengthImmWrite = false; mExpectVariableLengthImmWrite = false;
mBbaMem[BBA_NWAYS] = (BBA_NWAYS_LS10 | BBA_NWAYS_LPNWAY | BBA_NWAYS_ANCLPT | BBA_NWAYS_10TXF);
} }
void CEXIETHERNET::SetCS(int cs) void CEXIETHERNET::SetCS(int cs)
@ -130,10 +129,10 @@ bool CEXIETHERNET::IsInterruptSet()
void CEXIETHERNET::recordSendComplete() void CEXIETHERNET::recordSendComplete()
{ {
mBbaMem[0x00] &= ~0x06; mBbaMem[BBA_NCRA] &= ~0x06;
if(mBbaMem[0x08] & BBA_INTERRUPT_SENT) if(mBbaMem[0x08] & BBA_INTERRUPT_SENT)
{ {
mBbaMem[0x09] |= BBA_INTERRUPT_SENT; mBbaMem[BBA_IR] |= BBA_INTERRUPT_SENT;
DEBUGPRINT( "\t\tBBA Send interrupt raised\n"); DEBUGPRINT( "\t\tBBA Send interrupt raised\n");
//exit(0); //exit(0);
m_bInterruptSet = true; m_bInterruptSet = true;
@ -155,6 +154,8 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
DEBUGPRINT( "IMM Write, size 0x%x, data 0x%x mWriteP 0x%x\n", _uSize, _uData, mWriteP); DEBUGPRINT( "IMM Write, size 0x%x, data 0x%x mWriteP 0x%x\n", _uSize, _uData, mWriteP);
if (mExpectVariableLengthImmWrite) if (mExpectVariableLengthImmWrite)
{ {
DEBUGPRINT("Variable Length IMM Write: Size: %d _uData: 0x%08X swapped: 0x%08X\n", _uSize, _uData, Common::swap32(_uData));
// TODO: Use Swapped or unswapped?
if(_uSize == 4) if(_uSize == 4)
{ {
_uData = Common::swap32(_uData); _uData = Common::swap32(_uData);
@ -218,16 +219,15 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
exit(0); exit(0);
//throw hardware_fatal_exception("BBA Transmit without a packet!"); //throw hardware_fatal_exception("BBA Transmit without a packet!");
} }
// TODO: Actually Make it send a packet
sendPacket(mWriteBuffer.p(), mWriteBuffer.size()); sendPacket(mWriteBuffer.p(), mWriteBuffer.size());
mReadyToSend = false; mReadyToSend = false;
//exit(0); //exit(0);
} }
mBbaMem[0x00] = MAKE(u8, SwappedData); mBbaMem[BBA_NCRA] = MAKE(u8, SwappedData);
} }
break; break;
case BBA_NWAYC: case BBA_NWAYC:
DEBUGPRINT( "\t[INFO]BBA_NWAYCn"); DEBUGPRINT( "\t[INFO]BBA_NWAYC\n");
if(Common::swap32(_uData) & (BBA_NWAYC_ANE | BBA_NWAYC_ANS_RA)) if(Common::swap32(_uData) & (BBA_NWAYC_ANE | BBA_NWAYC_ANS_RA))
{ {
DEBUGPRINT("ACTIVATING!\n"); DEBUGPRINT("ACTIVATING!\n");
@ -242,7 +242,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
//exit(0); //exit(0);
assert(_uSize == 2 || _uSize == 1); assert(_uSize == 2 || _uSize == 1);
mRBRPP = (u8)_uData << 8; //Whinecube: I hope this works with both write sizes. mRBRPP = (u8)_uData << 8; //Whinecube: I hope this works with both write sizes.
mRBEmpty = mRBRPP == ((u32)mCbw.p_write() + CB_OFFSET); mRBEmpty = (mRBRPP == ((u32)mCbw.p_write() + CB_OFFSET));
checkRecvBuffer(); checkRecvBuffer();
break; break;
case BBA_RWP: //RWP - Receive Buffer Write Page Pointer case BBA_RWP: //RWP - Receive Buffer Write Page Pointer
@ -388,8 +388,6 @@ u32 CEXIETHERNET::ImmRead(u32 _uSize)
} }
u32 uResult = 0; u32 uResult = 0;
memcpy(&uResult, mBbaMem + mReadP, _uSize); memcpy(&uResult, mBbaMem + mReadP, _uSize);
if(mReadP == 0x31)
uResult = (BBA_NWAYS_LS10 | BBA_NWAYS_LPNWAY |BBA_NWAYS_ANCLPT | BBA_NWAYS_10TXF);
// TODO: We do as well? // TODO: We do as well?
uResult = Common::swap32(uResult); //Whinecube : we have a byteswap problem... uResult = Common::swap32(uResult); //Whinecube : we have a byteswap problem...
@ -410,7 +408,7 @@ void CEXIETHERNET::DMAWrite(u32 _uAddr, u32 _uSize)
{ {
if(mExpectVariableLengthImmWrite) if(mExpectVariableLengthImmWrite)
{ {
DEBUGPRINT("Address is 0x%x and size is 0x%x\n", _uAddr, _uSize); DEBUGPRINT("DMA Write: Address is 0x%x and size is 0x%x\n", _uAddr, _uSize);
mWriteBuffer.write(_uSize, Memory::GetPointer(_uAddr)); mWriteBuffer.write(_uSize, Memory::GetPointer(_uAddr));
return; return;
} }

View File

@ -123,13 +123,14 @@ private:
bool isActivated(); bool isActivated();
bool resume(); bool resume();
bool startRecv(); bool startRecv();
volatile bool mWaiting;
#ifdef _WIN32 #ifdef _WIN32
HANDLE mHAdapter, mHRecvEvent, mHReadWait; HANDLE mHAdapter, mHRecvEvent, mHReadWait;
DWORD mMtu; DWORD mMtu;
OVERLAPPED mReadOverlapped; OVERLAPPED mReadOverlapped;
WriteBuffer mRecvBuffer; WriteBuffer mRecvBuffer;
DWORD mRecvBufferLength; DWORD mRecvBufferLength;
volatile bool mWaiting;
static VOID CALLBACK ReadWaitCallback(PVOID lpParameter, BOOLEAN TimerFired); static VOID CALLBACK ReadWaitCallback(PVOID lpParameter, BOOLEAN TimerFired);
#endif #endif