private void OnPacketReceive(object sender, EventArgs <ArraySegment <byte> > e) { //Console.WriteLine("Received packet"); jp.Enqueue(Job.Create(() => { Packet p = new Packet(e.Value); if (firstMsg) { firstMsg = false; Console.WriteLine("Received TypeConverter"); ProcessTypeConverter(p); } else { Console.WriteLine("Received {0}", classNames[p.CategoryId]); mf.Handle(p, this); } })); }
private void HandlePacket(PcapDotNet.Packets.Packet packet) { //give up if 10 errors are seen to prevent unexpected crashes if (numErrors > 10) { return; } String srcIp = ""; TcpDatagram tcp = null; EthernetDatagram eth = packet.Ethernet; int dataStart = eth.HeaderLength; switch (eth.EtherType) { case EthernetType.IpV4: IpV4Datagram ip = eth.IpV4; tcp = ip.Tcp; srcIp = ip.Source.ToString(); dataStart += ip.HeaderLength + tcp.RealHeaderLength; break; case EthernetType.IpV6: IpV6Datagram ip6 = eth.IpV6; tcp = ip6.Tcp; srcIp = ip6.Source.ToString(); dataStart += 40 + tcp.RealHeaderLength; Console.WriteLine("IPv6?"); break; default: Console.WriteLine("We should never see anything not ipv4 or ipv6 since we filtered by tcp"); return; } ushort srcPort = tcp.SourcePort; int dataBytes = tcp.PayloadLength; bool syn = tcp.IsSynchronize; //Console.WriteLine("dataStart={0} dataByes={1} srcPort={2} syn={3} srcIp={4}",dataStart,dataBytes,srcPort,syn,srcIp); if (syn && dataBytes == 0) { ct = new ServiceCore.CryptoTransformHeroes(); ClearBuffer(); if (myIp == srcIp) { int dstPort = tcp.DestinationPort; encryptDict.TryGetValue(dstPort, out encrypt); serviceDict.TryGetValue(dstPort, out serviceType); } else { encryptDict.TryGetValue(srcPort, out encrypt); serviceDict.TryGetValue(srcPort, out serviceType); } Console.WriteLine("TCP connection starting with type {0} to {1}", encrypt, serviceType); SawSyn = true; return; } else if (!SawSyn) { Console.WriteLine("Haven't seen SYN yet from {0}", srcPort); return; } if (encrypt == EncryptionType.Relay || encrypt == EncryptionType.Pipe) { Console.WriteLine("Cannot handle type {0} from {1}", encrypt, serviceType); return; } if (dataBytes == 6 || dataBytes == 0) { //Console.WriteLine("Ping from port {0}", srcPort); ClearBuffer(); return; } //String timestamp = packet.Timestamp.ToString("yyyy-MM-dd hh:mm:ss.fff"); //Console.WriteLine("{0}: {1} bytes={2}", timestamp, connString, dataBytes); recvSize.AddLast(dataBytes); Buffer.BlockCopy(packet.Buffer, dataStart, buffer, bufLen, dataBytes); ArraySegment <byte> dataSeg = new ArraySegment <byte>(buffer, bufLen, dataBytes); Devcat.Core.Net.Message.Packet p = new Devcat.Core.Net.Message.Packet(dataSeg); if (encrypt == EncryptionType.Normal) { long salt = p.InstanceId; ct.Decrypt(dataSeg, salt); } bufLen += dataBytes; while (bufLen != 0) { dataSeg = new ArraySegment <byte>(buffer, 0, bufLen); p = new Devcat.Core.Net.Message.Packet(dataSeg); int pLen = 0; try { pLen = p.Length + p.BodyOffset; if (pLen == 0) { ClearBuffer(); //Console.WriteLine("Received ping"); return; } else { //Console.WriteLine("bufLen={0} pLen={1} recvSize={2}", bufLen, pLen, recvSizeToString()); } } catch (System.Runtime.Serialization.SerializationException) { //Console.WriteLine("{0}: Bad length {1}", connString, e.Message); RemovePacket(); numErrors++; continue; } if (pLen > bufLen) { return; } if (pLen <= 3 || pLen == 6) { //ClearBuffer(); ShortenBuffer(pLen); numErrors++; Console.WriteLine("{0}: Invalid data packet with Length={1}", connString, pLen); continue; } //Console.WriteLine("Read {0} bytes but need {1} bytes, creating object", bufLen, pLen); dataSeg = new ArraySegment <byte>(buffer, 0, pLen); p = new Devcat.Core.Net.Message.Packet(dataSeg); try { Console.WriteLine(p); if (srcIp == myIp) { Console.WriteLine("Client->{0}:", serviceType); } else { Console.WriteLine("Server {0}:", serviceType); } if (classNames.Count == 0) { ProcessTypeConverter(p); Console.WriteLine("Received TypeConverter"); //String reverse = reverseConnString(connString); //Console.WriteLine("Sending TypeConverter to Client {0}",reverse); //portHandler[reverse].processTypeConverter(p); } else { mf.Handle(p, null); } ShortenBuffer(pLen); } catch (InvalidOperationException e) { Console.WriteLine(e); String errMsg = e.Message; String className = ""; int categoryId = p.CategoryId; ShortenBuffer(pLen); MatchCollection mc; if (classNames.TryGetValue(categoryId, out className)) { LogUnhandledClass(className); return; } mc = Regex.Matches(errMsg, @"\.([^,\.]{2,})(,|$)"); if (mc.Count != 0) { className = mc[0].Groups[1].ToString(); LogUnhandledClass(className); return; } Console.WriteLine("{0}: Unknown class error {1}", connString, errMsg); } catch (System.Runtime.Serialization.SerializationException e) { Console.WriteLine("{0}: The packet wasn't ready {1}", connString, e.Message); RemovePacket(); numErrors++; } catch (System.ArgumentOutOfRangeException e) { Console.WriteLine("{0}: The packet was too short: {1}", connString, e.Message); ShortenBuffer(pLen); numErrors++; } catch (System.ArgumentException e) { Console.WriteLine("{0}: Serializing failed bacause a dict was made with 2 identical keys: {1}", connString, e.StackTrace); ClearBuffer(); numErrors++; } } }