/// <summary>
        /// This simplified fsm only changes state according to
        /// three flags: ACK, FIN, SYN
        /// So only have flags here is enough,
        /// but we must figure out whether is this stream's corresponding source
        /// host sent or received these flags.
        /// We only use this to detect connection start and end.
        /// </summary>
        /// <param name="flags"></param>
        /// <param name="isReceived">true if flags was received by this tcb's corresponding host</param>
        public void Transit(TcpControlBits flags, bool isReceived)
        {
            switch (State)
            {
            case TcpState.CLOSED:
            {
                //if (isReceived && flags.SYN && !flags.ACK)
                //{
                //    state = TcpState.SYN_RECEIVED;
                //}
                //else if (!isReceived && flags.SYN && !flags.ACK)
                //{
                //    state = TcpState.SYN_SENT;
                //}
                if (isReceived)
                {
                    State = TcpState.ESTABLISHED;
                }
            }
            break;

            case TcpState.ESTABLISHED:
            {
                if (isReceived && flags.HasFlag(TcpControlBits.Fin))
                {
                    State = TcpState.CLOSED;
                }
            }
            break;
            }
        }
        private void ProceedResponce(Packet responce)
        {
            IpV4Datagram ipDatagram  = responce.Ethernet.IpV4;
            TcpDatagram  tcpDatagram = ipDatagram.Tcp;

            TcpControlBits bits  = tcpDatagram.ControlBits;
            bool           isSyn = bits.HasFlag(TcpControlBits.Synchronize) &&
                                   !bits.HasFlag(TcpControlBits.Acknowledgment);

            if (!isSyn)
            {
                return;
            }
            if (this.attempts.ContainsKey(ipDatagram.Source))
            {
                this.attempts[ipDatagram.Source]++;
            }
            else
            {
                this.attempts.Add(ipDatagram.Source, 1);
            }
            Console.WriteLine("{0}:{1} is trying to connect {2}:{3}.",
                              ipDatagram.Source,
                              tcpDatagram.SourcePort,
                              ipDatagram.Destination,
                              tcpDatagram.DestinationPort
                              );

            this.CheckConnections();
        }
Exemple #3
0
 private void CreateTcpLayer(out TcpLayer tcpLayer, TcpControlBits controlBits)
 {
     tcpLayer = new TcpLayer
     {
         SourcePort           = SourcePort,
         DestinationPort      = DestinationPort,
         SequenceNumber       = SeqNumber,
         AcknowledgmentNumber = AckNumber,
         ControlBits          = controlBits,
         Window = WindowSize,
     };
 }
Exemple #4
0
        private PortInfo ParsePortInfo(Packet responce)
        {
            TcpDatagram datagram = responce.Ethernet.IpV4.Tcp;

            TcpControlBits bits     = responce.Ethernet.IpV4.Tcp.ControlBits;
            bool           isSynAck = bits.HasFlag(TcpControlBits.Acknowledgment) &&
                                      bits.HasFlag(TcpControlBits.Synchronize);

            PortInfo info = new PortInfo(datagram.SourcePort, isSynAck);

            return(info);
        }
Exemple #5
0
        internal static void WriteHeader(byte[] buffer, int offset,
                                         ushort sourcePort, ushort destinationPort,
                                         uint sequenceNumber, uint acknowledgmentNumber,
                                         TcpControlBits controlBits, ushort window, ushort urgentPointer,
                                         TcpOptions options)
        {
            int headerLength = HeaderMinimumLength + options.BytesLength;

            WriteHeader(buffer, offset, sourcePort, destinationPort);
            buffer.Write(offset + Offset.SequenceNumber, sequenceNumber, Endianity.Big);
            buffer.Write(offset + Offset.AcknowledgmentNumber, acknowledgmentNumber, Endianity.Big);
            buffer.Write(offset + Offset.HeaderLengthAndFlags, (ushort)(((ushort)((headerLength / 4) << 12)) | (ushort)controlBits), Endianity.Big);
            buffer.Write(offset + Offset.Window, window, Endianity.Big);
            buffer.Write(offset + Offset.UrgentPointer, urgentPointer, Endianity.Big);
            options.Write(buffer, offset + Offset.Options);
        }
Exemple #6
0
        internal static void WriteHeader(byte[] buffer, int offset,
                                         ushort sourcePort, ushort destinationPort,
                                         uint sequenceNumber, uint acknowledgmentNumber,
                                         TcpControlBits controlBits, ushort window, ushort urgentPointer,
                                         TcpOptions options)
        {
            int headerLength = HeaderMinimumLength + options.BytesLength;

            WriteHeader(buffer, offset, sourcePort, destinationPort);
            buffer.Write(offset + Offset.SequenceNumber, sequenceNumber, Endianity.Big);
            buffer.Write(offset + Offset.AcknowledgmentNumber, acknowledgmentNumber, Endianity.Big);
            buffer.Write(offset + Offset.HeaderLengthAndFlags, (ushort)(((ushort)((headerLength / 4) << 12)) | (ushort)controlBits), Endianity.Big);
            buffer.Write(offset + Offset.Window, window, Endianity.Big);
            buffer.Write(offset + Offset.UrgentPointer, urgentPointer, Endianity.Big);
            options.Write(buffer, offset + Offset.Options);
        }
Exemple #7
0
        internal static void WriteHeader(byte[] buffer, int offset, ushort sourcePort, ushort destinationPort, uint sequenceNumber, uint acknowledgmentNumber, TcpControlBits controlBits, ushort window, ushort urgentPointer, TcpOptions options)
        {
            int num = 20 + options.BytesLength;

            TransportDatagram.WriteHeader(buffer, offset, sourcePort, destinationPort);
            ByteArrayExtensions.Write(buffer, offset + 4, sequenceNumber, Endianity.Big);
            ByteArrayExtensions.Write(buffer, offset + 8, acknowledgmentNumber, Endianity.Big);
            ByteArrayExtensions.Write(buffer, offset + 12, (ushort)((TcpControlBits)(num / 4 << 12) | controlBits), Endianity.Big);
            ByteArrayExtensions.Write(buffer, offset + 14, window, Endianity.Big);
            ByteArrayExtensions.Write(buffer, offset + 18, urgentPointer, Endianity.Big);
            options.Write(buffer, offset + 20);
        }
        void SendTcpCtrlPacket(uint AcknowledgmentNumber, TcpControlBits CtrlBits, TcpOptions TcpOptions)
        {
            _last_acknowledgment_number = AcknowledgmentNumber;
            EthernetLayer ethernetLayer =
                new EthernetLayer
            {
                Source      = _adapter.MAC,
                Destination = _remote_mac,
                EtherType   = EthernetType.None,   // Will be filled automatically.
            };

            VLanTaggedFrameLayer vlanLayer =
                new VLanTaggedFrameLayer
            {
                PriorityCodePoint        = ClassOfService.Background,
                CanonicalFormatIndicator = false,
                VLanIdentifier           = _adapter.VLAN,
                EtherType = EthernetType.None,
            };

            IpV4Layer ipV4Layer =
                new IpV4Layer
            {
                Source             = _adapter.IP,
                CurrentDestination = _remote_ip,
                Fragmentation      = new IpV4Fragmentation(IpV4FragmentationOptions.DoNotFragment, 0),
                HeaderChecksum     = null, // Will be filled automatically.
                Identification     = _current_ip_id++,
                Options            = IpV4Options.None,
                Protocol           = null, // Will be filled automatically.
                Ttl           = TTL,
                TypeOfService = 0,
            };

            TcpLayer tcpLayer =
                new TcpLayer
            {
                SourcePort           = _local_port,
                DestinationPort      = _remote_port,
                Checksum             = null, // Will be filled automatically.
                SequenceNumber       = _current_sequence_number,
                AcknowledgmentNumber = _last_acknowledgment_number,
                ControlBits          = CtrlBits,
                Window        = _local_tcp_window_size,
                UrgentPointer = 0,
                Options       = TcpOptions
            };

            if (_adapter.VLAN > 1)
            {
                VirtualNetwork.Instance.SendPacket(PacketBuilder.Build(DateTime.Now, ethernetLayer, vlanLayer, ipV4Layer, tcpLayer));
            }
            else
            {
                VirtualNetwork.Instance.SendPacket(PacketBuilder.Build(DateTime.Now, ethernetLayer, ipV4Layer, tcpLayer));
            }

            if (CtrlBits != TcpControlBits.Acknowledgment)
            {
                _current_sequence_number++;
                _next_ack_num = _current_sequence_number;
            }
        }
 void SendTcpCtrlPacket(uint AcknowledgmentNumber, TcpControlBits CtrlBits)
 {
     SendTcpCtrlPacket(AcknowledgmentNumber, CtrlBits, TcpOptions.None);
 }
Exemple #10
0
        /// <summary>
        /// Reassembly tcp stream
        /// </summary>
        /// <param name="sequence">Sequence number of the tcp packet</param>
        /// <param name="acknowledgement">Acknowledgement number of the tcp packet</param>
        /// <param name="length">Length of the original payload data</param>
        /// <param name="data">Actual captured data</param>
        /// <param name="flags">All control bits of the tcp packet</param>
        /// <param name="pair">Tcp end point pair, we use its AEP as source and BEP as destination</param>
        private void tcp_reassemble(UInt32 sequence, UInt32 acknowledgement, UInt32 length, Byte[] data,
                                    TcpControlBits flags, TcpPair pair)
        {
            // First to get a TcpConnection object, which can either be seen before
            // or a newly created one.
            TcpConnection conn = GetConnection(pair);

            // Check our direction.
            int dir = conn.Pair.AEP.Equals(pair.AEP) ? 0 : 1;

            // Cache some useful object, this is packet receiver. (Only reference here.)
            TCB       tcb    = conn.ControlBlock(dir);
            TcpStream stream = conn.Stream(dir);

            // Whether we have trunced the packet
            if (data.Length < length)
            {
                stream.IsTrunced = true;
            }

            // Before adding data for this flow to the data_out_file, check whether
            // this frame acks fragments that were already seen. This happens when
            // frames are not in the capture file, but were actually seen by the
            // receiving host.
            if (conn.Stream(1 - dir).FragListHead != null)
            {
                while (checkFragment(conn, 1 - dir, acknowledgement))
                {
                    ;
                }
            }

            // now lets get the sequence number stuff figured out
            if (tcb.State == TcpState.CLOSED)
            {
                // Transmit FSM state.
                tcb.Transit(flags, true);
                conn.ControlBlock(1 - dir).Transit(flags, false); // the other side.

                // This is the first time we see sequence number (in this direction)
                tcb.seq = sequence + length;
                if (flags.HasFlag(TcpControlBits.Synchronize))
                {
                    tcb.seq++; // we hold next seq, and in case of syn, next seq is sequence+1
                }
                else
                {
                    // A new conversation should start with three-way handshake, thus syn should be set
                    // but if not, it may means that we are dealing with a connection
                    // which was captured half way.
                    stream.IsTrunced = true;
                }

                conn.WritePacketData(dir, data);
                return;
            }

            // If we got here, it means we've seen packets in this connection and direction

            // transit fsm state.
            tcb.Transit(flags, true);
            conn.ControlBlock(1 - dir).Transit(flags, false);

            // Warning: I didn't care about sequence number wrap-around in
            // all comparisons of sequence numbers. I'm not sure if this will
            // cause problems.
            // check if this packet is in right place
            if (sequence < tcb.seq)
            {
                // the sequence number seems dated,
                // but check the end to make sure it has no more
                // info than we have seen.
                UInt32 endseq = sequence + length;
                if (endseq > tcb.seq)
                {
                    // here's more than we have seen.
                    // Get the payload that we have not seen.
                    UInt32 new_offset = tcb.seq - sequence;

                    if (data.Length <= new_offset)
                    {
                        // Unfortunately, we didn't captured that.
                        // so only useless data left.
                        data             = null;
                        stream.IsTrunced = true;
                    }
                    else
                    {
                        Byte[] tmp = new Byte[data.Length - new_offset];
                        Array.Copy(data, new_offset, tmp, 0, tmp.Length);
                        data = tmp;
                    }

                    // Make things appear to be right on time.
                    sequence = tcb.seq;
                    length   = endseq - sequence;
                }
            }

            if (sequence == tcb.seq)
            {
                // right on time
                tcb.seq += length;
                if (flags.HasFlag(TcpControlBits.Synchronize))
                {
                    tcb.seq++;
                }

                if (data != null)
                {
                    conn.WritePacketData(dir, data);
                }

                if (flags.HasFlag(TcpControlBits.Fin))
                {
                    if (conn.CloseStream(dir))
                    {
                        CloseConnection(conn);
                    }
                }

                // done with the packet, see if it cause a fragment to fit.
                // pass 0 to ack because we don't need to check ack here.
                // should been checked above, before add data.
                while (checkFragment(conn, dir, 0))
                {
                    ;
                }
            }
            else
            {
                // out of order packet
                if (data.Length > 0 && sequence > tcb.seq)
                {
                    TcpFrag frag = new TcpFrag()
                    {
                        seq   = sequence,
                        len   = length,
                        data  = data,
                        flags = flags
                    };

                    // Add to fragment list
                    if (stream.FragListHead == null)
                    {
                        frag.next           = null;
                        stream.FragListHead = frag;
                    }
                    else
                    {
                        frag.next           = stream.FragListHead;
                        stream.FragListHead = frag;
                    }
                }
            }
        }