//use this one instead of the constructor to speed things up by reducing Exceptions public static bool TryParse(Frame parentFrame, int packetStartIndex, int packetEndIndex, bool clientToServer, out AbstractPacket result) { result = null; //start testing to see if this is a valid Spotify packet if (clientToServer) { //check if the keyExchangePacketLength equals the application data length ushort keyExchangePacketLength = Utils.ByteConverter.ToUInt16(parentFrame.Data, packetStartIndex + 2); if (keyExchangePacketLength != packetEndIndex - packetStartIndex + 1) { return(false); } //it is now pretty probable that what we have is a spotify packet //but not sure enough since TDS (MS-SQL) has the length field in the same place... ushort version = Utils.ByteConverter.ToUInt16(parentFrame.Data, packetStartIndex); if (version != 0x02 && version != 0x03) { return(false); } try { result = new SpotifyKeyExchangePacket(parentFrame, packetStartIndex, packetEndIndex, clientToServer); } catch { result = null; } } else { //the best I can do with the server->client packet is to ensure that the length of the data matches what the content says it should be if (packetEndIndex - packetStartIndex + 1 < 381) //from version 2 { return(false); //too short message } //if(packetEndIndex-packetStartIndex+1>381+256+256)//from version 2 if (packetEndIndex - packetStartIndex + 1 > 388 + 256 + 256 + 4 * 65535) //from version 3 { return(false); //too long message } //380+username_length+padding_length int v2expectedLength = -1; if (packetStartIndex + 380 + parentFrame.Data[packetStartIndex + 17] <= packetEndIndex) { v2expectedLength = 380 + parentFrame.Data[packetStartIndex + 17] + parentFrame.Data[packetStartIndex + 380 + parentFrame.Data[packetStartIndex + 17]]; } int v3expectedLength = -1; if (packetStartIndex + 0x182 + 1 <= packetEndIndex) { v3expectedLength = 0x184 + parentFrame.Data[packetStartIndex + 0x17a] + parentFrame.Data[packetStartIndex + 0x17b] + Utils.ByteConverter.ToUInt16(parentFrame.Data, packetStartIndex + 0x17c) + Utils.ByteConverter.ToUInt16(parentFrame.Data, packetStartIndex + 0x17e) + Utils.ByteConverter.ToUInt16(parentFrame.Data, packetStartIndex + 0x180) + Utils.ByteConverter.ToUInt16(parentFrame.Data, packetStartIndex + 0x182); } //see if any of the lengths match if (packetEndIndex - packetStartIndex + 1 != v2expectedLength && packetEndIndex - packetStartIndex + 1 != v3expectedLength) { return(false); } try { result = new SpotifyKeyExchangePacket(parentFrame, packetStartIndex, packetEndIndex, clientToServer); } catch { result = null; } } if (result == null) { return(false); } else { return(true); } }
private AbstractPacket GetProtocolPacket(ApplicationLayerProtocol protocol, bool clientToServer) { AbstractPacket packet = null; if (protocol == ApplicationLayerProtocol.Dns) { if (DnsPacket.TryParse(this.ParentFrame, this.PacketStartIndex + this.dataOffsetByteCount, this.PacketEndIndex, true, out DnsPacket dnsPacket)) { return(dnsPacket); } } else if (protocol == ApplicationLayerProtocol.FtpControl) { if (FtpPacket.TryParse(this.ParentFrame, this.PacketStartIndex + this.dataOffsetByteCount, this.PacketEndIndex, clientToServer, out packet)) { return(packet); } } else if (protocol == ApplicationLayerProtocol.Http) { if (HttpPacket.TryParse(this.ParentFrame, this.PacketStartIndex + this.dataOffsetByteCount, this.PacketEndIndex, out packet)) { return(packet); } } else if (protocol == ApplicationLayerProtocol.Http2) { if (Http2Packet.TryParse(this.ParentFrame, this.PacketStartIndex + this.dataOffsetByteCount, this.PacketEndIndex, out packet)) { return(packet); } } else if (protocol == ApplicationLayerProtocol.Irc) { if (IrcPacket.TryParse(this.ParentFrame, this.PacketStartIndex + this.dataOffsetByteCount, this.PacketEndIndex, out packet)) { return(packet); } } else if (protocol == ApplicationLayerProtocol.IEC_104) { if (IEC_60870_5_104Packet.TryParse(this.ParentFrame, this.PacketStartIndex + this.dataOffsetByteCount, this.PacketEndIndex, out packet)) { return(packet); } } else if (protocol == ApplicationLayerProtocol.Imap) { return(new ImapPacket(this.ParentFrame, this.PacketStartIndex + this.dataOffsetByteCount, this.PacketEndIndex, clientToServer)); } else if (protocol == ApplicationLayerProtocol.Kerberos) { return(new KerberosPacket(this.ParentFrame, this.PacketStartIndex + this.dataOffsetByteCount, this.PacketEndIndex, true)); } else if (protocol == ApplicationLayerProtocol.Lpd) { if (LpdPacket.TryParse(this.ParentFrame, this.PacketStartIndex + this.dataOffsetByteCount, this.PacketEndIndex, clientToServer, out packet)) { return(packet); } } else if (protocol == ApplicationLayerProtocol.ModbusTCP) { if (ModbusTcpPacket.TryParse(this.ParentFrame, this.PacketStartIndex + this.dataOffsetByteCount, this.PacketEndIndex, this.sourcePort, this.destinationPort, out packet)) { return(packet); } } else if (protocol == ApplicationLayerProtocol.NetBiosNameService) { return(new NetBiosNameServicePacket(this.ParentFrame, this.PacketStartIndex + this.dataOffsetByteCount, this.PacketEndIndex)); } else if (protocol == ApplicationLayerProtocol.NetBiosSessionService) { if (NetBiosSessionService.TryParse(this.ParentFrame, this.PacketStartIndex + this.dataOffsetByteCount, this.PacketEndIndex, this.sourcePort, this.destinationPort, out packet, this.IsVirtualPacketFromTrailingDataInTcpSegment)) { return(packet); } } else if (protocol == ApplicationLayerProtocol.OpenFlow) { if (OpenFlowPacket.TryParse(this.ParentFrame, this.PacketStartIndex + this.dataOffsetByteCount, this.PacketEndIndex, out packet)) { return(packet); } } else if (protocol == ApplicationLayerProtocol.Oscar) { if (OscarPacket.TryParse(this.ParentFrame, this.PacketStartIndex + this.dataOffsetByteCount, this.PacketEndIndex, out packet)) { return(packet); } } else if (protocol == ApplicationLayerProtocol.OscarFileTransfer) { if (OscarFileTransferPacket.TryParse(this.ParentFrame, this.PacketStartIndex + this.dataOffsetByteCount, this.PacketEndIndex, out packet)) { return(packet); } } else if (protocol == ApplicationLayerProtocol.Pop3) { return(new Pop3Packet(this.ParentFrame, this.PacketStartIndex + this.dataOffsetByteCount, this.PacketEndIndex, clientToServer)); } else if (protocol == ApplicationLayerProtocol.Sip) { return(new SipPacket(this.ParentFrame, this.PacketStartIndex + this.DataOffsetByteCount, this.PacketEndIndex)); } else if (protocol == ApplicationLayerProtocol.Smtp) { return(new SmtpPacket(this.ParentFrame, this.PacketStartIndex + this.dataOffsetByteCount, this.PacketEndIndex, clientToServer)); } else if (protocol == ApplicationLayerProtocol.Socks) { if (SocksPacket.TryParse(this.ParentFrame, this.PacketStartIndex + this.dataOffsetByteCount, this.PacketEndIndex, clientToServer, out packet)) { return(packet); } } else if (protocol == ApplicationLayerProtocol.SpotifyServerProtocol) { if (SpotifyKeyExchangePacket.TryParse(this.ParentFrame, this.PacketStartIndex + this.dataOffsetByteCount, this.PacketEndIndex, clientToServer, out packet)) { return(packet); } } else if (protocol == ApplicationLayerProtocol.Ssh) { if (SshPacket.TryParse(this.ParentFrame, this.PacketStartIndex + this.dataOffsetByteCount, this.PacketEndIndex, out packet)) { return(packet); } } else if (protocol == ApplicationLayerProtocol.Ssl) { if (SslPacket.TryParse(this.ParentFrame, this.PacketStartIndex + this.dataOffsetByteCount, this.PacketEndIndex, out packet)) { return(packet); } } else if (protocol == ApplicationLayerProtocol.TabularDataStream) { return(new TabularDataStreamPacket(this.ParentFrame, this.PacketStartIndex + this.dataOffsetByteCount, this.PacketEndIndex)); } else if (protocol == ApplicationLayerProtocol.Tpkt) { if (TpktPacket.TryParse(ParentFrame, this.PacketStartIndex + this.dataOffsetByteCount, this.PacketEndIndex, this, out packet)) { return(packet); } } return(packet); }
internal IEnumerable <AbstractPacket> GetSubPackets(bool includeSelfReference, ISessionProtocolFinder protocolFinder, bool clientToServer) { if (includeSelfReference) { yield return(this); } if (PacketStartIndex + dataOffsetByteCount < PacketEndIndex) { AbstractPacket packet = null; foreach (ApplicationLayerProtocol protocol in protocolFinder.GetProbableApplicationLayerProtocols()) { try{ if (protocol == ApplicationLayerProtocol.Dns) { packet = new DnsPacket(ParentFrame, PacketStartIndex + dataOffsetByteCount, PacketEndIndex); protocolFinder.ConfirmedApplicationLayerProtocol = ApplicationLayerProtocol.Dns; break; } else if (protocol == ApplicationLayerProtocol.FtpControl) { if (FtpPacket.TryParse(ParentFrame, PacketStartIndex + dataOffsetByteCount, PacketEndIndex, clientToServer, out packet)) { protocolFinder.ConfirmedApplicationLayerProtocol = ApplicationLayerProtocol.FtpControl; break; } } else if (protocol == ApplicationLayerProtocol.Http) { if (HttpPacket.TryParse(ParentFrame, PacketStartIndex + dataOffsetByteCount, PacketEndIndex, out packet)) { protocolFinder.ConfirmedApplicationLayerProtocol = ApplicationLayerProtocol.Http; break; } } else if (protocol == ApplicationLayerProtocol.Irc) { if (IrcPacket.TryParse(ParentFrame, PacketStartIndex + dataOffsetByteCount, PacketEndIndex, out packet)) { protocolFinder.ConfirmedApplicationLayerProtocol = ApplicationLayerProtocol.Irc; break; } } else if (protocol == ApplicationLayerProtocol.IEC_104) { if (IEC_60870_5_104Packet.TryParse(ParentFrame, PacketStartIndex + dataOffsetByteCount, PacketEndIndex, out packet)) { protocolFinder.ConfirmedApplicationLayerProtocol = ApplicationLayerProtocol.IEC_104; break; } } else if (protocol == ApplicationLayerProtocol.NetBiosNameService) { packet = new NetBiosNameServicePacket(ParentFrame, PacketStartIndex + dataOffsetByteCount, PacketEndIndex); protocolFinder.ConfirmedApplicationLayerProtocol = ApplicationLayerProtocol.NetBiosNameService; break; } else if (protocol == ApplicationLayerProtocol.NetBiosSessionService) { if (NetBiosSessionService.TryParse(ParentFrame, PacketStartIndex + dataOffsetByteCount, PacketEndIndex, out packet)) { //packet = new NetBiosSessionService(ParentFrame, PacketStartIndex+dataOffsetByteCount, PacketEndIndex, false); protocolFinder.ConfirmedApplicationLayerProtocol = ApplicationLayerProtocol.NetBiosSessionService; break; } } else if (protocol == ApplicationLayerProtocol.Oscar) { if (OscarPacket.TryParse(ParentFrame, PacketStartIndex + dataOffsetByteCount, PacketEndIndex, out packet)) { protocolFinder.ConfirmedApplicationLayerProtocol = ApplicationLayerProtocol.Oscar; break; } } else if (protocol == ApplicationLayerProtocol.OscarFileTransfer) { if (OscarFileTransferPacket.TryParse(ParentFrame, PacketStartIndex + dataOffsetByteCount, PacketEndIndex, out packet)) { protocolFinder.ConfirmedApplicationLayerProtocol = ApplicationLayerProtocol.OscarFileTransfer; break; } } else if (protocol == ApplicationLayerProtocol.Smtp) { packet = new SmtpPacket(ParentFrame, PacketStartIndex + dataOffsetByteCount, PacketEndIndex, clientToServer); protocolFinder.ConfirmedApplicationLayerProtocol = ApplicationLayerProtocol.Smtp; break; } else if (protocol == ApplicationLayerProtocol.SpotifyServerProtocol) { if (SpotifyKeyExchangePacket.TryParse(ParentFrame, PacketStartIndex + dataOffsetByteCount, PacketEndIndex, clientToServer, out packet)) { protocolFinder.ConfirmedApplicationLayerProtocol = ApplicationLayerProtocol.SpotifyServerProtocol; break; } } else if (protocol == ApplicationLayerProtocol.Ssh) { if (SshPacket.TryParse(ParentFrame, PacketStartIndex + dataOffsetByteCount, PacketEndIndex, out packet)) { protocolFinder.ConfirmedApplicationLayerProtocol = ApplicationLayerProtocol.Ssh; break; } } else if (protocol == ApplicationLayerProtocol.Ssl) { if (SslPacket.TryParse(ParentFrame, PacketStartIndex + dataOffsetByteCount, PacketEndIndex, out packet)) { protocolFinder.ConfirmedApplicationLayerProtocol = ApplicationLayerProtocol.Ssl; break; } } else if (protocol == ApplicationLayerProtocol.TabularDataStream) { packet = new TabularDataStreamPacket(ParentFrame, PacketStartIndex + dataOffsetByteCount, PacketEndIndex); protocolFinder.ConfirmedApplicationLayerProtocol = ApplicationLayerProtocol.TabularDataStream; break; } } catch (Exception) { packet = null; } } if (packet == null) { packet = new RawPacket(ParentFrame, PacketStartIndex + dataOffsetByteCount, PacketEndIndex); } yield return(packet); foreach (AbstractPacket subPacket in packet.GetSubPackets(false)) { yield return(subPacket); } } }