예제 #1
0
 public Segment(SegmentHeader header, IpcHeader ipcHeader, byte[] ipcData)
 {
     Header    = header;
     IpcHeader = ipcHeader;
     IpcData   = ipcData;
 }
예제 #2
0
        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));
            }
        }
예제 #3
0
 public FFXIVIpcMessage(IpcHeader header, byte[] data)
 {
     Header = header;
     Data   = data;
 }