public async static Task LoadPcap(string path, Action <byte[], DateTime> callback, IProgress <float> progress = null) { byte[] headerBuffer = new byte[16]; int bytesRead; using (FileStream fs = File.OpenRead(path)) { // Skip global header fs.Seek(24, SeekOrigin.Begin); while ((bytesRead = await fs.ReadAsync(headerBuffer, 0, 16)) == 16) { PacketParser.ParsePacket(headerBuffer, 0, out PcapPacketHeader header); if (header.incl_len > maxPacketSize) { return; } byte[] message = new byte[header.incl_len]; bytesRead = await fs.ReadAsync(message, 0, (int)header.incl_len); if (bytesRead != header.incl_len) { return; } callback(message, DateTimeOffset.FromUnixTimeSeconds(header.ts_sec).DateTime.AddTicks(header.ts_usec * 10)); if (progress != null) { progress.Report((float)fs.Position * 100 / fs.Length); } } } }
private void parsePacket(byte[] message, DateTime time, bool isClient = false, bool isReplay = false) { if (!EnabledBox.Checked) { return; } if (!isReplay) { DumpManager.Pcap(message); } var pktHeaderLength = PacketParser.ParsePacket <FFXIVSegmentHeader>(message, 0, out var pktHeader); var parsedValues = new Dictionary <string, string>(); parsedValues.Add("ID", string.Format("{1}{0}", isClient ? 'C' : 'S', time.ToString("yyyyMMdd-HHmmss-ffffff"))); parsedValues.Add("SSize", string.Format("{0}", pktHeader.Size)); parsedValues.Add("Source", string.Format("{0:X8}", pktHeader.SourceActorId)); parsedValues.Add("Target", string.Format("{0:X8}", pktHeader.TargetActorId)); parsedValues.Add("SType", pktHeader.SegmentType.ToString()); parsedValues.Add("SReserved", string.Format("{0:X4}", pktHeader.Reserved)); int dumpOffset = pktHeaderLength; switch (pktHeader.SegmentType) { case SegmentType.ClientKeepAlive: case SegmentType.ServerKeepAlive: // PacketParser.ParsePacket<FFXIVKeepAliveData>(message, pktHeaderLength, out var pktBody); // parsedValues.Add("Data", string.Format("Id={0}, Timestamp={1}", pktBody.Id, pktBody.Timestamp)); // AddToPacketList(parsedValues); break; case SegmentType.IPC: var ipcHeaderLength = PacketParser.ParsePacket <FFXIVIpcHeader>(message, pktHeaderLength, out var ipcHeader); dumpOffset = pktHeaderLength + ipcHeaderLength; parsedValues.Add("IPC-Reserved", string.Format("0:{0:X2} 1:{1:X2} 4: {2:X4} 12: {3:X8}", ipcHeader.Reserved1, ipcHeader.Reserved2, ipcHeader.Unknown2, ipcHeader.UnknownC)); Type EnumType = isClient ? typeof(ClientZoneIpcType) : typeof(ServerZoneIpcType); parsedValues.Add("IPC-Type", string.Format("{0:X4}", ipcHeader.Type)); IPCBase ipc = null; if (Enum.IsDefined(EnumType, ipcHeader.Type)) { parsedValues.Add("IPC-TypeName", Enum.GetName(EnumType, ipcHeader.Type)); ipc = PacketParser.ParseIPCPacket((ServerZoneIpcType)ipcHeader.Type, message, dumpOffset, parsedValues); } else { parsedValues.Add("Data", string.Format("Server={0}, Timestamp={1}", ipcHeader.ServerId, ipcHeader.Timestamp)); } string dump = DumpManager.Dump(parsedValues, message, dumpOffset); if (ipc == null || ipc.Dump) { // DumpManager.Write(parsedValues, dump); } if (ipc == null || ipc.Display) { if (!IpcTypeFilter.ContainsKey(ipcHeader.Type)) { IpcTypeFilter.Add(ipcHeader.Type, true); var item = new ListViewItem(); item.Tag = ipcHeader.Type; if (parsedValues.ContainsKey("IPC-TypeName")) { item.Text = string.Format("{0} - {1}", parsedValues["IPC-Type"], parsedValues["IPC-TypeName"]); } else { item.Text = parsedValues["IPC-Type"]; } item.Checked = true; ipcTypesList.Invoke((MethodInvoker)(() => ipcTypesList.Items.Add(item))); } if (IpcTypeFilter[ipcHeader.Type]) { AddToPacketList(new PacketItemDetail() { ipc = ipc, ipcHeader = ipcHeader, segmentHeader = pktHeader, dump = dump, parsedValues = parsedValues }); } } break; default: if (!isReplay) { DumpManager.Write(parsedValues, message, dumpOffset); } break; } }