我一直在创建一个虚拟以太网接口。我已经与控制应用程序打开了异步通信,每次有新数据包时,都会通知控制应用程序,然后询问数据包数据。数据包数据存储在一个简单的结构中,uint8_t[1600]
用于字节和uint32_t
长度。每次数据包可用时,dext 都能够使用虚拟数据填充此结构,并且虚拟数据在控制应用程序上可见。但是,我正在努力用真实的数据包数据填充它。
IOUserNetworkPacket
提供有关数据包的元数据。它包含数据包时间戳、大小等,但似乎不包含数据包的数据。有GetDataOffset()
和GetMemorySegmentOffset()
方法似乎返回数据包数据在其内存缓冲区中的位置的字节偏移量。我的直觉告诉我将此偏移量添加到数据包数据存储位置的指针上。问题是我不知道数据包实际存储在哪里。
我知道他们是由 管理的IOUserNetworkPacketBufferPool
,但我不认为那是他们的记忆所在。有CopyMemoryDescriptor()
给出IOMemoryDescriptor
其内容的方法。我尝试使用描述符创建一个IOMemoryMap
,使用它来调用GetAddress()
. 指向所有提到的对象的指针会导致垃圾数据。
我一定是完全错误的。如果有人知道如何访问数据包数据,或者有任何想法,我将不胜感激。谢谢。
内的代码片段IOUserClient::ExternalMethod
:
case GetPacket:
{
IOUserNetworkPacket *packet =
ivars->m_provider->getPacket();
GetPacket_Output output;
output.packet_size = packet->getDataLength();
IOUserNetworkPacketBufferPool *pool;
packet->GetPacketBufferPool(&pool);
IOMemoryDescriptor *memory = nullptr;
pool->CopyMemoryDescriptor(&memory);
IOMemoryMap *map = nullptr;
memory->CreateMapping(0, 0, 0, 0, 0, &map);
uint64_t address = map->GetAddress()
+ packet->getMemorySegmentOffset();
memcpy(output.packet_data,
(void*)address, packet->getDataLength());
in_arguments->structureOutput = OSData::withBytes(
&output, sizeof(GetPacket_Output));
// free stuff
} break;