예제 #1
0
        private NumCheckResult CheckNumbers(TCP tcp)
        {
            ACKMyNumber = true;
            if (tcp.AcknowledgementNumber != MySequenceNumber)
            {
                ACKMyNumber = false;
                Console.Error.WriteLine("Unexpected Acknowledgement Number, Got " + tcp.AcknowledgementNumber + " Expected " + MySequenceNumber);
                if (tcp.AcknowledgementNumber != OldMyNumber)
                {
                    throw new Exception("Unexpected Acknowledgement Number did not Match Old Number of " + OldMyNumber);
                }
            }

            if (tcp.SequenceNumber != ExpectedSequenceNumber)
            {
                if (tcp.GetPayload().Length == 0)
                {
                    Console.Error.WriteLine("Unexpected Sequence Number From Act Packet, Got " + tcp.SequenceNumber + " Expected " + ExpectedSequenceNumber);
                }
                else
                {
                    if (ReceivedSequenceNumbers.Contains(tcp.SequenceNumber))
                    {
                        Console.Error.WriteLine("Got an Old Seq Number on an Data packet");
                        return(NumCheckResult.GotOldData);
                    }
                    else
                    {
                        throw new Exception("Unexpected Sequence Number From Data Packet, Got " + tcp.SequenceNumber + " Expected " + ExpectedSequenceNumber);
                    }
                }
            }

            return(NumCheckResult.OK);
        }
예제 #2
0
        private NumCheckResult CheckNumbers(TCP tcp)
        {
            GetAllMyNumbers(out UInt32 seqNum, out List <UInt32> oldSeqNums);

            Log_Verb("CHECK_NUMBERS");
            Log_Verb("[SRV]CurrSeqNumber = " + seqNum + " [PS2]Ack Number = " + tcp.AcknowledgementNumber);
            Log_Verb("[SRV]CurrAckNumber = " + expectedSeqNumber + " [PS2]Seq Number = " + tcp.SequenceNumber);
            Log_Verb("[PS2]Data Length = " + tcp.GetPayload().Length);

            if (tcp.AcknowledgementNumber != seqNum)
            {
                Log_Verb("[PS2]Sent Outdated Acknowledgement Number, Got " + tcp.AcknowledgementNumber + " Expected " + seqNum);
                if (!oldSeqNums.Contains(tcp.AcknowledgementNumber))
                {
                    Log_Error("Unexpected Acknowledgement Number did not Match Old Numbers, Got " + tcp.AcknowledgementNumber + " Expected " + seqNum);
                    throw new Exception("Unexpected Acknowledgement Number did not Match Old Numbers, Got " + tcp.AcknowledgementNumber + " Expected " + seqNum);
                }
            }
            else
            {
                Log_Verb("[PS2]CurrSeqNumber Acknowleged By PS2");
                myNumberACKed.Set();
            }

            if (tcp.SequenceNumber != expectedSeqNumber)
            {
                if (tcp.GetPayload().Length == 0)
                {
                    Log_Verb("[PS2]Sent Unexpected Sequence Number From ACK Packet, Got " + tcp.SequenceNumber + " Expected " + expectedSeqNumber);
                }
                else
                {
                    if (receivedPS2SeqNumbers.Contains(tcp.SequenceNumber))
                    {
                        Log_Error("[PS2]Sent an Old Seq Number on an Data packet, Got " + tcp.SequenceNumber + " Expected " + expectedSeqNumber);
                        return(NumCheckResult.GotOldData);
                    }
                    else
                    {
                        Log_Error("[PS2]Sent Unexpected Sequence Number From Data Packet, Got " + tcp.SequenceNumber + " Expected " + expectedSeqNumber);
                        throw new Exception("Unexpected Sequence Number From Data Packet, Got " + tcp.SequenceNumber + " Expected " + expectedSeqNumber);
                    }
                }
            }

            return(NumCheckResult.OK);
        }
예제 #3
0
        private void ErrorOnNonEmptyPacket(TCP tcp)
        {
            NumCheckResult ResultFIN = CheckNumbers(tcp);

            if (ResultFIN == NumCheckResult.GotOldData)
            {
                return;
            }
            if (ResultFIN == NumCheckResult.Bad)
            {
                Log_Error("Bad TCP Numbers Received"); throw new Exception("Bad TCP Numbers Received");
            }
            if (tcp.GetPayload().Length > 0)
            {
                uint delta = GetDelta(expectedSeqNumber, tcp.SequenceNumber);
                if (delta == 0)
                {
                    return;
                }
                Log_Error("Invalid Packet, Packet Has Data");

                throw new Exception("Invalid Packet");
            }
        }
예제 #4
0
        //PS2 Sending Data
        private bool SendData(TCP tcp)
        {
            if (tcp.SYN)
            {
                Log_Error("Attempt to Connect to an open Port");
                throw new Exception("Attempt to Connect to an open Port");
            }
            if (tcp.URG)
            {
                throw new Exception("Urgent Data Not Supported");
            }
            for (int i = 0; i < tcp.Options.Count; i++)
            {
                switch (tcp.Options[i].Code)
                {
                case 0:    //End
                case 1:    //Nop
                    continue;

                case 8:
                    lastRecivedTimeStamp = ((TCPopTS)(tcp.Options[i])).SenderTimeStamp;
                    break;

                default:
                    Log_Error("Got Unknown Option " + tcp.Options[i].Code);
                    throw new Exception("Got Unknown Option " + tcp.Options[i].Code);
                    //break;
                }
            }

            windowSize = tcp.WindowSize << windowScale;

            NumCheckResult Result = CheckNumbers(tcp);
            uint           delta  = GetDelta(expectedSeqNumber, tcp.SequenceNumber);

            if (Result == NumCheckResult.GotOldData)
            {
                Log_Verb("[PS2] New Data Offset: " + delta + " bytes");
                Log_Verb("[PS2] New Data Length: " + ((uint)tcp.GetPayload().Length - delta) + " bytes");
            }
            if (Result == NumCheckResult.Bad)
            {
                Log_Error("Bad TCP Numbers Received"); throw new Exception("Bad TCP Numbers Received");
            }
            if (tcp.GetPayload().Length != 0)
            {
                if (tcp.GetPayload().Length - delta > 0)
                {
                    Log_Verb("[PS2] Sending: " + tcp.GetPayload().Length + " bytes");
                    receivedPS2SeqNumbers.RemoveAt(0);
                    receivedPS2SeqNumbers.Add(expectedSeqNumber);
                    //Send the Data
                    try
                    {
                        int    sent    = 0;
                        byte[] payload = tcp.GetPayload();
                        while (sent != payload.Length)
                        {
                            SocketError err;
                            try
                            {
                                sent = client.Send(payload, sent, payload.Length - sent, SocketFlags.None, out err);
                            }
                            catch (ObjectDisposedException) { err = SocketError.Shutdown; }
                            if (err != SocketError.WouldBlock & err != SocketError.Success)
                            {
                                throw new SocketException((int)err);
                            }
                            if (err == SocketError.WouldBlock)
                            {
                                System.Threading.Thread.Sleep(0);
                            }
                        }
                    }
                    catch (SocketException e)
                    {
                        Log_Error("TCP Send Error: " + e.Message);
                        Log_Error("Error Code: " + e.ErrorCode);
                        //Connection Lost
                        //Send Shutdown by RST (Untested)
                        client.Close();
                        CloseByRemoteRST();

                        return(true);
                    }
                    unchecked
                    {
                        expectedSeqNumber += ((uint)tcp.GetPayload().Length - delta);
                    }
                    //Done send
                }
                //ACK data
                Log_Verb("[SRV] ACK Data: " + expectedSeqNumber);
                TCP ret = CreateBasePacket();
                ret.ACK = true;

                PushRecvBuff(ret);
            }
            return(true);
        }
예제 #5
0
        public override bool send(IPPayload payload)
        {
            TCP tcp = (TCP)payload;

            if (DestPort != 0)
            {
                if (!(tcp.DestinationPort == DestPort && tcp.SourcePort == SrcPort))
                {
                    Console.Error.WriteLine("TCP packet invalid for current session (Duplicate key?)");
                    return(false);
                }
            }

            if (tcp.RST == true) //Test this
            {
                if (client.Connected)
                {
                    lock (sentry)
                    {
                        client.Close();
                    }
                    state = TCPState.Closed;
                    open  = false;
                    return(true);
                }
            }

            switch (state)
            {
            case TCPState.None:
                #region "SYN"
                DestPort = tcp.DestinationPort;
                SrcPort  = tcp.SourcePort;
                if (tcp.SYN == false)
                {
                    PerformRST();
                    Console.Error.WriteLine("Connection Not in Connected State");
                    return(true);
                }
                ExpectedSequenceNumber = tcp.SequenceNumber + 1;
                //Fill out last received numbers
                ReceivedSequenceNumbers.Add(tcp.SequenceNumber);
                ReceivedSequenceNumbers.Add(tcp.SequenceNumber);
                ReceivedSequenceNumbers.Add(tcp.SequenceNumber);
                ReceivedSequenceNumbers.Add(tcp.SequenceNumber);
                ReceivedSequenceNumbers.Add(tcp.SequenceNumber);

                for (int i = 0; i < tcp.Options.Count; i++)
                {
                    switch (tcp.Options[i].Code)
                    {
                    case 0:         //End
                    case 1:         //Nop
                        continue;

                    case 2:         //MSS
                        MaxSegmentSize = ((TCPopMSS)(tcp.Options[i])).MaxSegmentSize;
                        break;

                    case 3:         //WinScale
                        //Console.Error.WriteLine("Got WinScale");
                        // = ((TCPopWS)(tcp.Options[i])).WindowScale;
                        break;

                    case 8:         //TimeStamp
                        LastRecivedTimeStamp = ((TCPopTS)(tcp.Options[i])).SenderTimeStamp;
                        SendTimeStamps       = true;
                        TimeStamp.Start();
                        break;

                    default:
                        Console.Error.WriteLine("Got Unknown Option " + tcp.Options[i].Code);
                        throw new Exception();
                        //break;
                    }
                }

                client = new TcpClient();
                IPAddress address = new IPAddress(DestIP);
                client.BeginConnect(address, DestPort, new AsyncCallback(AsyncConnectComplete), tcp);
                state = TCPState.SendingSYN_ACK;
                open  = true;
                return(true);

                #endregion
            case TCPState.SendingSYN_ACK:
                return(true);    //Ignore reconnect attempts while we are still attempting connection

            case TCPState.SentSYN_ACK:
                #region "Syn-Ack"
                lock (sentry)
                {
                    if (tcp.SYN == true)
                    {
                        throw new Exception("Attempt to Connect to an operning Port");
                    }
                    NumCheckResult Result = CheckNumbers(tcp);
                    if (Result == NumCheckResult.Bad)
                    {
                        throw new Exception("Bad TCP Number Received");
                    }

                    for (int i = 0; i < tcp.Options.Count; i++)
                    {
                        switch (tcp.Options[i].Code)
                        {
                        case 0:         //End
                        case 1:         //Nop
                            continue;

                        case 8:         //Timestamp
                            LastRecivedTimeStamp = ((TCPopTS)(tcp.Options[i])).SenderTimeStamp;
                            break;

                        default:
                            Console.Error.WriteLine("Got Unknown Option " + tcp.Options[i].Code);
                            throw new Exception();
                            //break;
                        }
                    }
                    //Next packet will be data
                    state = TCPState.Connected;
                }
                return(true);

                #endregion
            case TCPState.Connected:
                #region "Connected"
                if (tcp.SYN == true)
                {
                    throw new Exception("Attempt to Connect to an open Port");
                }
                lock (sentry)
                {
                    for (int i = 0; i < tcp.Options.Count; i++)
                    {
                        switch (tcp.Options[i].Code)
                        {
                        case 0:        //End
                        case 1:        //Nop
                            continue;

                        case 8:
                            //Console.Error.WriteLine("Got TimeStamp");
                            LastRecivedTimeStamp = ((TCPopTS)(tcp.Options[i])).SenderTimeStamp;
                            break;

                        default:
                            Console.Error.WriteLine("Got Unknown Option " + tcp.Options[i].Code);
                            throw new Exception();
                            //break;
                        }
                    }
                    NumCheckResult Result = CheckNumbers(tcp);
                    if (Result == NumCheckResult.GotOldData)
                    {
                        throw new NotImplementedException();
                        //return true;
                    }
                    if (Result == NumCheckResult.Bad)
                    {
                        throw new Exception("Bad TCP Number Received");
                    }
                    if (tcp.FIN == true)     //Connection Close Part 1, receive FIN from PS2
                    {
                        PerformCloseByPS2();
                        return(true);
                    }
                    if (tcp.GetPayload().Length != 0)
                    {
                        ReceivedSequenceNumbers.RemoveAt(0);
                        ReceivedSequenceNumbers.Add(ExpectedSequenceNumber);
                        //Send the Data
                        try
                        {
                            client.GetStream().Write(tcp.GetPayload(), 0, tcp.GetPayload().Length);
                        } catch (Exception e)
                        {
                            System.Windows.Forms.MessageBox.Show("Got IO Error :" + e.ToString());
                            //Connection Lost
                            //Send Shutdown (Untested)
                            PerformRST();
                            open = false;
                            return(true);
                        }
                        unchecked
                        {
                            ExpectedSequenceNumber += ((uint)tcp.GetPayload().Length);
                        }
                        //Done send

                        //ACK data
                        TCP ret = CreateBasePacket();
                        ret.ACK = true;
                        recvbuff.Add(ret);
                    }
                }
                return(true);

                #endregion
            case TCPState.ConnectionClosedByPS2AndRemote:
                #region "Closing"
                //Close Part 4, Recive ACK from PS2
                Console.Error.WriteLine("Compleated Close By PS2");
                NumCheckResult ResultFIN = CheckNumbers(tcp);
                if (ResultFIN == NumCheckResult.GotOldData)
                {
                    return(false);
                }
                if (ResultFIN == NumCheckResult.Bad)
                {
                    throw new Exception("Bad TCP Number Received");
                }
                state = TCPState.Closed;
                open  = false;
                return(true);

                #endregion
            case TCPState.ConnectionClosedByRemote:
                #region "Closing"
                //Expect fin+ack
                if (tcp.FIN == true)
                {
                    Console.Error.WriteLine("Compleated Close By Remote");
                    ReceivedSequenceNumbers.RemoveAt(0);
                    ReceivedSequenceNumbers.Add(ExpectedSequenceNumber);
                    unchecked
                    {
                        ExpectedSequenceNumber += 1;
                    }
                    TCP ret = CreateBasePacket();

                    ret.ACK = true;

                    recvbuff.Add(ret);
                    state = TCPState.ConnectionClosedByPS2AndRemote;
                    open  = false;
                    return(true);
                }
                //throw new Exception("Invalid Packet");
                return(false);

                //break;
                #endregion
            default:
                throw new Exception("Invalid State");
            }
        }