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

@ -19,24 +19,82 @@
#include "../EXI_Device.h"
#include "../EXI_DeviceEthernet.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()
{
close(fd);
fd = -1;
return true;
// TODO: Actually deactivate
}
bool CEXIETHERNET::isActivated()
{
return false;
//TODO: Never Activated Yet!
return fd != -1 ? true : false;
}
bool CEXIETHERNET::activate() {
if(isActivated())
return true;
else
if( (fd = open("/dev/net/tun", O_RDWR)) < 0)
{
DEBUGPRINT("Couldn't Open device\n");
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)
{
@ -46,18 +104,14 @@ bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size)
DEBUGPRINT( "%02X", etherpckt[a]);
}
DEBUGPRINT( " : Size: %d\n", size);
int raw_socket = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
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);
int numBytesWrit = write(fd, etherpckt, size);
if(numBytesWrit != size)
{
DEBUGPRINT("BBA sendPacket %i only got %i bytes sent!\n", size, numBytesWrit);
return false;
}
else
DEBUGPRINT("Sent out the correct number of bytes: %d\n", size);
//fwrite(etherpckt, size, size, raw_socket);
/*DWORD numBytesWrit;
OVERLAPPED overlap;

View file

@ -137,8 +137,12 @@ bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size)
DWORD numBytesWrit;
OVERLAPPED overlap;
//ZERO_OBJECT(overlap);
//overlap.hEvent = mHRecvEvent;
WriteFile(mHAdapter, etherpckt, size, &numBytesWrit, &overlap);
overlap.hEvent = mHRecvEvent;
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)
{
DEBUGPRINT("BBA sendPacket %i only got %i bytes sent!\n", size, numBytesWrit);

View file

@ -23,7 +23,7 @@
#include "EXI_Device.h"
#include "EXI_DeviceEthernet.h"
//#define SONICDEBUG
#define SONICDEBUG
void DEBUGPRINT (const char * format, ...)
{
@ -95,7 +95,6 @@ CEXIETHERNET::CEXIETHERNET() :
Expecting = EXPECT_NONE;
mExpectVariableLengthImmWrite = false;
mBbaMem[BBA_NWAYS] = (BBA_NWAYS_LS10 | BBA_NWAYS_LPNWAY | BBA_NWAYS_ANCLPT | BBA_NWAYS_10TXF);
}
void CEXIETHERNET::SetCS(int cs)
@ -130,10 +129,10 @@ bool CEXIETHERNET::IsInterruptSet()
void CEXIETHERNET::recordSendComplete()
{
mBbaMem[0x00] &= ~0x06;
mBbaMem[BBA_NCRA] &= ~0x06;
if(mBbaMem[0x08] & BBA_INTERRUPT_SENT)
{
mBbaMem[0x09] |= BBA_INTERRUPT_SENT;
mBbaMem[BBA_IR] |= BBA_INTERRUPT_SENT;
DEBUGPRINT( "\t\tBBA Send interrupt raised\n");
//exit(0);
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);
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)
{
_uData = Common::swap32(_uData);
@ -218,16 +219,15 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
exit(0);
//throw hardware_fatal_exception("BBA Transmit without a packet!");
}
// TODO: Actually Make it send a packet
sendPacket(mWriteBuffer.p(), mWriteBuffer.size());
mReadyToSend = false;
//exit(0);
}
mBbaMem[0x00] = MAKE(u8, SwappedData);
mBbaMem[BBA_NCRA] = MAKE(u8, SwappedData);
}
break;
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))
{
DEBUGPRINT("ACTIVATING!\n");
@ -242,7 +242,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
//exit(0);
assert(_uSize == 2 || _uSize == 1);
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();
break;
case BBA_RWP: //RWP - Receive Buffer Write Page Pointer
@ -388,8 +388,6 @@ u32 CEXIETHERNET::ImmRead(u32 _uSize)
}
u32 uResult = 0;
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?
uResult = Common::swap32(uResult); //Whinecube : we have a byteswap problem...
@ -410,7 +408,7 @@ void CEXIETHERNET::DMAWrite(u32 _uAddr, u32 _uSize)
{
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));
return;
}

View file

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