public Segment(SegmentHeader header, IpcHeader ipcHeader, byte[] ipcData) { Header = header; IpcHeader = ipcHeader; IpcData = ipcData; }
private unsafe void DeviceOnPacketArrival(object sender, CaptureEventArgs e) { var fullPacket = Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data); var packet = fullPacket.Extract <TcpPacket>(); if (!packet.Push) { return; // Only TCP PSH has actual data; ACK does not } var ipv4Info = fullPacket.Extract <IPv4Packet>(); var connection = new StringBuilder(ipv4Info.SourceAddress.ToString()) .Append(':') .Append(packet.SourcePort.ToString()) .Append("=>") .Append(ipv4Info.DestinationAddress) .Append(':') .Append(packet.DestinationPort.ToString()) .ToString(); // All FFXIV packets begin with a packet header... fixed(void *payload = &packet.PayloadData[0]) { var packetHeader = Marshal.PtrToStructure <PacketHeader>(new IntPtr(payload)); if (!IsMagical(packetHeader)) { return; } // ...possibly with a compressed payload, using var remainder = new UnmanagedMemoryStream( (byte *)payload + 40, packet.PayloadData.Length - 40, packet.PayloadData.Length * 2, FileAccess.ReadWrite); if (packetHeader.IsCompressed) { using var deflateStream = new DeflateStream(remainder, CompressionMode.Decompress); deflateStream.CopyTo(remainder); } // ...followed by one or more segment headers, var segmentPtr = remainder.PositionPointer; var segments = new List <Segment>(); for (var i = 0; i < packetHeader.SegmentCount; i++) { var segmentHeader = Marshal.PtrToStructure <SegmentHeader>(new IntPtr(segmentPtr)); // ...potentially with an IPC header and body. IpcHeader ipcHeader = null; var ipcData = new byte[0]; if (segmentHeader.Type == SegmentType.Ipc) { ipcHeader = Marshal.PtrToStructure <IpcHeader>(new IntPtr(segmentPtr + 16)); ipcData = new byte[segmentHeader.Size]; using var ipcDataStreamUnmanaged = new UnmanagedMemoryStream(segmentPtr + 32, segmentHeader.Size); using var ipcDataStream = new MemoryStream(ipcData, writable: true); ipcDataStreamUnmanaged.CopyTo(ipcDataStream); OnIpcMessageReceived?.Invoke(connection, new FFXIVIpcMessage(ipcHeader, ipcData)); segmentPtr += 16 + segmentHeader.Size; } segments.Add(new Segment(segmentHeader, ipcHeader, ipcData)); } OnPacketReceived?.Invoke(connection, new FFXIVPacket(packetHeader, segments)); } }
public FFXIVIpcMessage(IpcHeader header, byte[] data) { Header = header; Data = data; }