#ifdef UNDEFINED
To do:
options:
continuous until ^c
raw data to disk
Cocoa app
Log to file
Reset or clear buffer
#endif // UNDEFINED
#include <ctype.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/IOCFSerialize.h>
#include <IOKit/network/IONetworkLib.h>
#include <IOKit/IOTypes.h>
#include <mach/mach.h>
#include <mach/mach_interface.h>
#include <sys/time.h>
#include <sys/file.h>
int DumpLog();
void OutputBuffer();
kern_return_t io_connect_method_structureI_structureO(
mach_port_t connection,
int selector,
io_struct_inband_t input,
mach_msg_type_number_t inputCnt,
io_struct_inband_t output,
mach_msg_type_number_t *outputCnt );
enum
{
kSelectLoopbackMAC = 0x20,
kSelectLoopbackPHY = 0x21,
kRltkUserCmd_GetLog = 0x30, kRltkUserCmd_GetRegs = 0x31, kRltkUserCmd_GetOneReg = 0x32, kRltkUserCmd_GetTxRing = 0x33, kRltkUserCmd_GetRxRing = 0x34, kRltkUserCmd_WriteOneReg = 0x35,
kRltkUserCmd_ReadAllMII = 0x50, kRltkUserCmd_ReadMII = 0x51, kRltkUserCmd_WriteMII = 0x52 };
typedef struct
{
UInt32 reqID;
UInt8 *pLogBuffer;
UInt32 logBufferSz;
} UCRequest;
UCRequest gUCRequest;
io_object_t getInterfaceWithName( mach_port_t masterPort, char *className );
int main( int argc, char **argv )
{
if ( argc == 1 ) return DumpLog();
printf( "usage: %s # to dump RTL8139 log on local machine\n", argv[0] );
return 1;
}
io_object_t getInterfaceWithName( mach_port_t masterPort, char *className )
{
io_iterator_t ite;
io_object_t obj = 0;
io_name_t name;
kern_return_t rc;
kern_return_t kr;
kr = IORegistryCreateIterator( masterPort,
kIOServicePlane,
true,
&ite );
if ( kr != kIOReturnSuccess )
{
printf( "IORegistryCreateIterator() error %08lx\n", (unsigned long)kr);
return 0;
}
while ( (obj = IOIteratorNext( ite )) )
{
if ( IOObjectConformsTo( obj, (char*)className ) )
{
break;
}
else
{
rc = IOObjectGetClass( obj, name );
if ( rc == kIOReturnSuccess )
{
}
}
IOObjectRelease( obj );
obj = 0;
}
IORegistryDisposeEnumerator( ite );
return obj;
}
FILE* CreateLogFile()
{
time_t now;
struct tm *lt;
char filename[ 100 ];
time( &now );
lt = localtime( &now );
sprintf( filename, "log.%d.%d.%02d%02d.%02d",
lt->tm_mon+1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec );
printf( "Writing log to %s\n", filename );
return fopen( filename, "w" );
}
void OutputBuffer()
{
char buffer[ 256 ];
UInt32 *pl; UInt8 *pb; UInt8 lefty; UInt32 microsec; UInt32 i, x, p1, p2;
buffer[ 4 ] = 0; pl = (UInt32*)gUCRequest.pLogBuffer;
x = pl[ 3 ] - pl[ 1 ] - 0x30; printf( "\n\t%8lx %8lx %8lx %8lx\t[%lx:]\n", pl[0], pl[1], pl[2], pl[3], x );
pl += 4;
printf( "\t%8lx %8lx %8lx %8lx\n", pl[0], pl[1], pl[2], pl[3] );
pl += 4;
printf( "\t%8lx %8lx %8lx %8lx\n", pl[0], pl[1], pl[2], pl[3] );
pl += 4;
for ( i = 3; i < gUCRequest.logBufferSz / 0x10; ++i )
{
if ( *pl == 0xDEBEEFED || *pl == 0 )
break;
lefty = (UInt8)(*pl >> 24);
microsec = *pl++ & 0x00FFFFFF;
p1 = *pl++;
p2 = *pl++;
pb = (UInt8*)pl;
pl++;
buffer[0] = pb[3];
buffer[1] = pb[2];
buffer[2] = pb[1];
buffer[3] = pb[0];
printf( "%8lx: %3d %6ld %8lx %8lx\t%s\n", i * 0x10, lefty, microsec, p1, p2, buffer );
}
*(UInt32*)gUCRequest.pLogBuffer = 0xFeedBeef; return;
}
int DumpLog()
{
mach_port_t masterPort;
io_object_t netif; io_connect_t conObj; kern_return_t kr;
UCRequest inStruct;
UInt32 outSize = sizeof( UCRequest );
kr = IOMasterPort( bootstrap_port, &masterPort );
if ( kr != KERN_SUCCESS )
{
printf( "IOMasterPort() failed: %08lx\n", (unsigned long)kr );
return -1;
}
netif = getInterfaceWithName( masterPort, "com_apple_driver_RTL8139" );
if ( !netif )
{
printf( "getInterfaceWithName failed.\n" );
exit( 0 );
}
kr = IOServiceOpen( netif, mach_task_self(), 'Rltk', &conObj );
if ( kr != kIOReturnSuccess )
{
printf( "Open device failed 0x%x\n", kr );
IOObjectRelease( netif );
exit( 0 );
}
inStruct.reqID = kRltkUserCmd_GetLog;
kr = io_connect_method_structureI_structureO(
conObj,
0,
(void*)&inStruct,
sizeof( inStruct ),
(void*)&gUCRequest,
(mach_msg_type_number_t*)&outSize );
if ( kr != kIOReturnSuccess )
{
printf( "Request failed 0x%x\n", kr );
}
else
{
{
OutputBuffer();
}
}
IOServiceClose( conObj );
IOObjectRelease( netif );
exit( 0 );
}