#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/IOBSD.h>
#include <IOKit/network/IONetworkLib.h>
#include <IOKit/network/IONetworkInterface.h>
#include <IOKit/network/IONetworkController.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <mach/mach_interface.h>
#include <IOKit/iokitmig.h> // mig generated
IOReturn IONetworkOpen(io_object_t obj, io_connect_t * con)
{
return IOServiceOpen(obj, mach_task_self(), kIONUCType, con);
}
IOReturn IONetworkClose(io_connect_t con)
{
return IOServiceClose(con);
}
IOReturn IONetworkWriteData(io_connect_t con,
IONDHandle dataHandle,
UInt8 * srcBuf,
UInt32 inSize)
{
IOReturn kr;
if (!srcBuf || !inSize)
return kIOReturnBadArgument;
kr = io_connect_method_scalarI_structureI(
con,
kIONUCWriteNetworkDataIndex,
(int *) &dataHandle,
1,
(char *) srcBuf,
inSize);
return kr;
}
IOReturn IONetworkReadData(io_connect_t con,
IONDHandle dataHandle,
UInt8 * destBuf,
UInt32 * inOutSizeP)
{
IOReturn kr;
if (!destBuf || !inOutSizeP)
return kIOReturnBadArgument;
kr = io_connect_method_scalarI_structureO(
con,
kIONUCReadNetworkDataIndex,
(int *) &dataHandle,
1,
(char *) destBuf,
(int *) inOutSizeP);
return kr;
}
IOReturn IONetworkResetData(io_connect_t con, IONDHandle dataHandle)
{
IOReturn kr;
mach_msg_type_number_t zero = 0;
kr = io_connect_method_scalarI_scalarO(
con,
kIONUCResetNetworkDataIndex,
(int *) &dataHandle,
1,
0,
&zero);
return kr;
}
IOReturn IONetworkGetDataCapacity(io_connect_t con,
IONDHandle dataHandle,
UInt32 * capacityP)
{
mach_msg_type_number_t one = 1;
if (!capacityP)
return kIOReturnBadArgument;
return io_connect_method_scalarI_scalarO(
con,
kIONUCGetNetworkDataCapacityIndex,
(int *) &dataHandle,
1,
(int *) capacityP,
&one);
}
IOReturn IONetworkGetDataHandle(io_connect_t con,
const char * dataName,
IONDHandle * dataHandleP)
{
UInt32 nameSize;
mach_msg_type_number_t outCount = sizeof(*dataHandleP);
if (!dataName || !dataHandleP)
return kIOReturnBadArgument;
nameSize = strlen(dataName) + 1;
return io_connect_method_structureI_structureO(
con,
kIONUCGetNetworkDataHandleIndex,
(char *) dataName,
nameSize,
(char *) dataHandleP,
&outCount);
}
#define kIONetworkInterfaceProperties "IONetworkInterfaceProperties"
#define kIORequiredPacketFilters "IORequiredPacketFilters"
static void
GetDictionaryValueUsingKeysApplier( const void * value,
void * context )
{
CFDictionaryRef * dict = (CFDictionaryRef *) context;
if ( ( *dict ) &&
( CFGetTypeID(*dict) == CFDictionaryGetTypeID() ) )
*dict = CFDictionaryGetValue( *dict, value );
else
*dict = 0;
}
static CFTypeRef
GetDictionaryValueUsingKeys( CFDictionaryRef dict,
CFArrayRef keysArray,
CFTypeID typeID )
{
CFArrayApplyFunction( keysArray,
CFRangeMake(0, CFArrayGetCount(keysArray)),
GetDictionaryValueUsingKeysApplier,
&dict );
if ( dict && (CFGetTypeID(dict) != typeID) ) dict = 0;
return dict;
}
static CFDictionaryRef
CreateNestedDictionariesUsingKeys( CFArrayRef keysArray,
CFTypeRef value )
{
CFDictionaryRef dict = 0;
CFDictionaryRef prevDict;
CFIndex index, count;
CFStringRef keys[1];
CFTypeRef values[1];
count = CFArrayGetCount(keysArray);
for ( index = count - 1;
index >= 0;
index-- )
{
prevDict = dict;
keys[0] = CFArrayGetValueAtIndex( keysArray, index );
values[0] = ( prevDict ) ? prevDict : value;
dict = CFDictionaryCreate( NULL,
(void *) keys,
(void *) values,
1,
&kCFCopyStringDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks );
if ( prevDict ) CFRelease( prevDict );
if ( dict == 0 ) break;
}
return dict;
}
IOReturn
IONetworkGetPacketFiltersMask( io_connect_t connect,
const io_name_t filterGroup,
UInt32 * filtersMask,
IOOptionBits options )
{
IOReturn kr;
io_service_t service = 0;
CFMutableDictionaryRef dict = 0;
CFArrayRef keysArray = 0;
CFStringRef group = 0;
CFStringRef keys[2];
CFTypeRef value;
do {
*filtersMask = 0;
kr = IOConnectGetService( connect, &service );
if ( kr != kIOReturnSuccess ) break;
if ( kIONetworkSupportedPacketFilters & options )
{
io_service_t parentService;
kr = IORegistryEntryGetParentEntry( service, kIOServicePlane,
&parentService );
if ( kr != kIOReturnSuccess ) break;
IOObjectRelease( service );
service = parentService;
}
kr = IORegistryEntryCreateCFProperties( service,
&dict,
kCFAllocatorDefault,
kNilOptions );
if ( kr != kIOReturnSuccess ) break;
group = CFStringCreateWithCString( kCFAllocatorDefault, filterGroup,
CFStringGetSystemEncoding() );
if ( group == 0 )
{
kr = kIOReturnNoMemory;
break;
}
keys[0] = (kIONetworkSupportedPacketFilters & options) ?
CFSTR( kIOPacketFilters ) :
CFSTR( kIORequiredPacketFilters );
keys[1] = group;
keysArray = CFArrayCreate( NULL, (void *)keys, 2, &kCFTypeArrayCallBacks );
if ( keysArray == 0 )
{
kr = kIOReturnNoMemory;
break;
}
value = GetDictionaryValueUsingKeys( dict, keysArray, CFNumberGetTypeID() );
if ( value == 0 )
{
kr = kIOReturnNotFound;
break;
}
CFNumberGetValue( (CFNumberRef)value, kCFNumberLongType, filtersMask );
}
while ( 0 );
if ( dict ) CFRelease( dict );
if ( group ) CFRelease( group );
if ( keysArray ) CFRelease( keysArray );
if ( service ) IOObjectRelease( service );
return kr;
}
IOReturn
IONetworkSetPacketFiltersMask( io_connect_t connect,
const io_name_t filterGroup,
UInt32 filtersMask,
IOOptionBits options )
{
IOReturn kr = kIOReturnNoMemory;
CFStringRef keys[3];
CFArrayRef keysArray = 0;
CFStringRef group = 0;
CFNumberRef num = 0;
CFDictionaryRef dict = 0;
do {
num = CFNumberCreate( kCFAllocatorDefault,
kCFNumberLongType,
&filtersMask );
if ( num == 0 ) break;
group = CFStringCreateWithCString( kCFAllocatorDefault, filterGroup,
CFStringGetSystemEncoding() );
if ( group == 0 ) break;
keys[0] = CFSTR( kIONetworkInterfaceProperties );
keys[1] = CFSTR( kIORequiredPacketFilters );
keys[2] = group;
keysArray = CFArrayCreate( NULL, (void *)keys, 3, &kCFTypeArrayCallBacks );
if ( keysArray == 0 ) break;
dict = CreateNestedDictionariesUsingKeys( keysArray, num );
if ( dict == 0 ) break;
kr = IOConnectSetCFProperties( connect, dict );
}
while ( 0 );
if ( num ) CFRelease( num );
if ( group ) CFRelease( group );
if ( keysArray ) CFRelease( keysArray );
if ( dict ) CFRelease( dict );
return kr;
}