diff --git a/skyscraper8/GSE/BbframeDeencapsulator2.cs b/skyscraper8/GSE/BbframeDeencapsulator2.cs index 4a11988..684025d 100644 --- a/skyscraper8/GSE/BbframeDeencapsulator2.cs +++ b/skyscraper8/GSE/BbframeDeencapsulator2.cs @@ -8,13 +8,14 @@ using System.Text; using System.Threading.Tasks; using System.Xml.Linq; using skyscraper5.Skyscraper.Net.Pcap; +using skyscraper8.GSE.MisProcessors; namespace skyscraper8.GSE { - internal class BbframeDeencapsulator2 : IBbframeDeencapsulator + public class BbframeDeencapsulator2 : IBbframeDeencapsulator { [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct bbheader + public struct bbheader { public byte MaType1; public byte MaType2; @@ -29,7 +30,7 @@ namespace skyscraper8.GSE } [StructLayout(LayoutKind.Sequential, Pack = 1)] - unsafe struct Layer3 + public unsafe struct Layer3 { public byte l3sync; public bbheader header; @@ -54,6 +55,9 @@ namespace skyscraper8.GSE Layer3 myLayer; while (true) { + if (inbuf.Position == inbuf.Length) + return; + if (inbuf.Peek() == 0xb8) break; inbuf.ReadByte(); @@ -69,6 +73,8 @@ namespace skyscraper8.GSE { while (true) { + if (inbuf.Position == inbuf.Length) + return; if (inbuf.Peek() == 0xb8) break; fail = inbuf.Read(inData, 0, 1); @@ -83,6 +89,8 @@ namespace skyscraper8.GSE if (fail != bblength) break; myLayer = MemoryMarshal.Read(inData); + + byte streamType = myLayer.header.Sync; byte mis = myLayer.header.MaType2; if (misStreams == null) @@ -90,124 +98,27 @@ namespace skyscraper8.GSE if (misStreams[mis] == null) { logger.InfoFormat("Found MIS {0}", mis); - misStreams[mis] = new MisProcessor(); + MisProcessor processor; + switch (streamType) + { + case 0: + processor = new _0x00_Gse(); + break; + default: + processor = new UnknownStreamType(streamType,mis); + break; + } + + misStreams[mis] = processor; } - int pos = 0; - while (pos < bblength - 4) - { - int gseLength = ((myLayer.Data[pos] & 0x0f) << 8) | (myLayer.Data[pos + 1]); - if ((myLayer.Data[pos] & 0xf0) == 0) break; - if (gseLength + 2 > bblength - pos) break; - if (!misStreams[mis].ProcessBbFrame(&myLayer.Data[pos], gseLength)) - break; - pos += gseLength += 2; - } + misStreams[mis].PushPacket(bblength, myLayer); + + } } private MisProcessor[] misStreams; - private class MisProcessor - { - private byte[][] fragmentor; - private int[] fragmentorLength; - private int[] fragmentorPos; - private PcapWriter pcapWriter; - - public MisProcessor() - { - fragmentor = new byte[256][]; - fragmentorLength = new int[256]; - fragmentorPos = new int[256]; - FileStream fileStream = File.OpenWrite(string.Format("{0}.pcap", DateTime.Now.Ticks)); - pcapWriter = new PcapWriter(fileStream, TcpdumpNetworkType.RawIp); - } - - private unsafe void Copy(byte* src, byte[] dst, int srcOffset, int dstOffset, int len) - { - for (int i = 0; i < len; i++) - { - dst[dstOffset + i] = src[srcOffset + i]; - } - } - - public unsafe bool ProcessBbFrame(byte* payload, int gseLength) - { - uint offset = 0; - uint fragId = 0; - - if ((payload[0] & 0xc0) == 0x80) - { - fragId = payload[2]; - int length = (payload[3] << 8) | payload[4]; - if (fragmentor[fragId] != null) - fragmentor[fragId] = null; - fragmentor[fragId] = new byte[length + 2]; - fragmentorLength[fragId] = length + 2; - fragmentor[fragId][0] = payload[0]; - fragmentor[fragId][1] = payload[1]; - fragmentor[fragId][0] |= 0xc0; - Copy(payload, fragmentor[fragId], 5, 2, gseLength - 3); - fragmentorPos[fragId] = gseLength - 1; - } - else if ((payload[0] & 0xc0) == 0x00) - { - throw new NotImplementedException("inbetween packet"); - } - else if ((payload[0] & 0xc0) == 0x40) - { - fragId = payload[2]; - if (fragmentor[fragId] == null) - return true; - - Copy(payload, fragmentor[fragId], 3, fragmentorPos[fragId], gseLength - 5); - fragmentorPos[fragId] += gseLength - 1; - fixed (byte* p = fragmentor[fragId]) - { - ProcessBbFrame(p, fragmentorLength[fragId]); - } - fragmentor[fragId] = null; - - } - else if ((payload[0] & 0xc0) == 0xc0) - { - if (payload[offset + 2] == 0x00 && payload[offset + 3] == 0x04) - { - throw new NotImplementedException("ethertype 0x0400"); - } - else if (payload[offset + 2] == 0x00 && payload[offset + 3] == 0x00) - { - throw new NotImplementedException("ethertype 0x0000"); - } - else if (payload[offset + 2] == 0x08 && payload[offset + 3] == 0x00) - { - if ((payload[0] & 0x30) == 0x01) - { - offset += 3; //3-byte label - } - else if ((payload[0] & 0x30) == 0x00) - { - offset += 6; //MAC address - } - - offset += 4; - - //at this point, the IP header starts at "offset" - long sinkSize = gseLength + 2 - offset; - byte[] sink = new byte[sinkSize]; - Copy(payload, sink, (int)offset, 0, (int)sinkSize); - pcapWriter.WritePacket(sink); - return true; - } - - //throw new NotImplementedException("complete packet"); - } - else if ((payload[0] & 0x0f0) == 0x00) - { - throw new NotImplementedException("padding packet"); - } - return true; - } - } + } } diff --git a/skyscraper8/GSE/MisProcessor.cs b/skyscraper8/GSE/MisProcessor.cs new file mode 100644 index 0000000..7d86931 --- /dev/null +++ b/skyscraper8/GSE/MisProcessor.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.GSE +{ + public interface MisProcessor + { + public unsafe void PushPacket(int bblength, BbframeDeencapsulator2.Layer3 myLayer); + } +} diff --git a/skyscraper8/GSE/MisProcessors/0x00_Gse.cs b/skyscraper8/GSE/MisProcessors/0x00_Gse.cs new file mode 100644 index 0000000..317bca1 --- /dev/null +++ b/skyscraper8/GSE/MisProcessors/0x00_Gse.cs @@ -0,0 +1,131 @@ +using skyscraper5.Skyscraper.Net.Pcap; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.GSE.MisProcessors +{ + internal class _0x00_Gse : MisProcessor + { + private byte[][] fragmentor; + private int[] fragmentorLength; + private int[] fragmentorPos; + private PcapWriter pcapWriter; + + public _0x00_Gse() + { + fragmentor = new byte[256][]; + fragmentorLength = new int[256]; + fragmentorPos = new int[256]; + FileStream fileStream = File.OpenWrite(string.Format("{0}.pcap", DateTime.Now.Ticks)); + pcapWriter = new PcapWriter(fileStream, TcpdumpNetworkType.RawIp); + } + + public unsafe void PushPacket(int bblength, BbframeDeencapsulator2.Layer3 myLayer) + { + int pos = 0; + while (pos < bblength - 4) + { + int gseLength = ((myLayer.Data[pos] & 0x0f) << 8) | (myLayer.Data[pos + 1]); + if ((myLayer.Data[pos] & 0xf0) == 0) break; + if (gseLength + 2 > bblength - pos) break; + if (!ProcessBbFrame(&myLayer.Data[pos], gseLength)) + break; + pos += gseLength += 2; + } + } + + private unsafe void Copy(byte* src, byte[] dst, int srcOffset, int dstOffset, int len) + { + for (int i = 0; i < len; i++) + { + dst[dstOffset + i] = src[srcOffset + i]; + } + } + + private unsafe bool ProcessBbFrame(byte* payload, int gseLength) + { + uint offset = 0; + uint fragId = 0; + + if ((payload[0] & 0xc0) == 0x80) + { + fragId = payload[2]; + int length = (payload[3] << 8) | payload[4]; + if (fragmentor[fragId] != null) + fragmentor[fragId] = null; + fragmentor[fragId] = new byte[length + 2]; + fragmentorLength[fragId] = length + 2; + fragmentor[fragId][0] = payload[0]; + fragmentor[fragId][1] = payload[1]; + fragmentor[fragId][0] |= 0xc0; + Copy(payload, fragmentor[fragId], 5, 2, gseLength - 3); + fragmentorPos[fragId] = gseLength - 1; + } + else if ((payload[0] & 0xc0) == 0x00) + { + fragId = payload[2]; + if (fragmentor[fragId] == null) + return true; + + Copy(payload, fragmentor[fragId], 3, fragmentorPos[fragId], gseLength - 1); + fragmentorPos[fragId] += gseLength - 1; + } + else if ((payload[0] & 0xc0) == 0x40) + { + fragId = payload[2]; + if (fragmentor[fragId] == null) + return true; + + Copy(payload, fragmentor[fragId], 3, fragmentorPos[fragId], gseLength - 5); + fragmentorPos[fragId] += gseLength - 1; + fixed (byte* p = fragmentor[fragId]) + { + ProcessBbFrame(p, fragmentorLength[fragId]); + } + fragmentor[fragId] = null; + + } + else if ((payload[0] & 0xc0) == 0xc0) + { + if (payload[offset + 2] == 0x00 && payload[offset + 3] == 0x04) + { + throw new NotImplementedException("ethertype 0x0400"); + } + else if (payload[offset + 2] == 0x00 && payload[offset + 3] == 0x00) + { + throw new NotImplementedException("ethertype 0x0000"); + } + else if (payload[offset + 2] == 0x08 && payload[offset + 3] == 0x00) + { + if ((payload[0] & 0x30) == 0x01) + { + offset += 3; //3-byte label + } + else if ((payload[0] & 0x30) == 0x00) + { + offset += 6; //MAC address + } + + offset += 4; + + //at this point, the IP header starts at "offset" + long sinkSize = gseLength + 2 - offset; + byte[] sink = new byte[sinkSize]; + Copy(payload, sink, (int)offset, 0, (int)sinkSize); + pcapWriter.WritePacket(sink); + return true; + } + + //throw new NotImplementedException("complete packet"); + } + else if ((payload[0] & 0x0f0) == 0x00) + { + throw new NotImplementedException("padding packet"); + } + return true; + } + } +} diff --git a/skyscraper8/GSE/MisProcessors/UnknownStreamType.cs b/skyscraper8/GSE/MisProcessors/UnknownStreamType.cs new file mode 100644 index 0000000..9ce9190 --- /dev/null +++ b/skyscraper8/GSE/MisProcessors/UnknownStreamType.cs @@ -0,0 +1,38 @@ +using log4net; +using skyscraper5.Skyscraper.Scraper; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.GSE.MisProcessors +{ + internal class UnknownStreamType : MisProcessor + { + private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); + private bool[] warningsSpoken; + private byte mis; + + public UnknownStreamType(byte streamType, byte mis) + { + this.mis = mis; + this.warningsSpoken = new bool[256]; + this.EncounterPacket(streamType); + } + + private void EncounterPacket(byte streamType) + { + if (!warningsSpoken[streamType]) + { + logger.WarnFormat("This is a valid GS, however, it not GSE (type 0), but type {0}, which is not supported yet. Please consider sharing a sample of this stream.", streamType); + warningsSpoken[streamType] = true; + } + } + + public unsafe void PushPacket(int bblength, BbframeDeencapsulator2.Layer3 myLayer) + { + EncounterPacket(myLayer.header.Sync); + } + } +} diff --git a/skyscraper8/Properties/launchSettings.json b/skyscraper8/Properties/launchSettings.json index e904b69..9a0c143 100644 --- a/skyscraper8/Properties/launchSettings.json +++ b/skyscraper8/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "skyscraper8": { "commandName": "Project", - "commandLineArgs": "stid135test \"\\\\utena\\mergerfs\\Skyscraper\\dab_thor_10717_v_max-sx8.ts\"", + "commandLineArgs": "stid135test \"C:\\Users\\Sascha Schiemann\\Desktop\\Neuer Ordner\\12554h.ts\"", "remoteDebugEnabled": false }, "Container (Dockerfile)": {