+ // Check that it is coming in on the same interface
+ if(conn->Interface != Interface) continue;
+
+ // Check Source Port
+ if(conn->RemotePort != ntohs(hdr->SourcePort)) continue;
+
+ // Check Source IP
+ if(conn->Interface->Type == 6 && !IP6_EQU(conn->RemoteIP.v6, *(tIPv6*)Address))
+ continue;
+ if(conn->Interface->Type == 4 && !IP4_EQU(conn->RemoteIP.v4, *(tIPv4*)Address))
+ continue;
+
+ TCP_INT_HandleConnectionPacket(conn, hdr, Length);
+ return ;
+ }
+ }
+
+ Log_Log("TCP", "No Match");
+}
+
+/**
+ * \brief Handles a packet sent to a specific connection
+ * \param Connection TCP Connection pointer
+ * \param Header TCP Packet pointer
+ * \param Length Length of the packet
+ */
+void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Header, int Length)
+{
+ tTCPStoredPacket *pkt;
+ int dataLen;
+
+ if(Header->Flags & TCP_FLAG_SYN) {
+ Connection->NextSequenceRcv = ntohl(Header->SequenceNumber) + 1;
+ }
+
+ if( Connection->State == TCP_ST_SYN_SENT )
+ {
+ if( (Header->Flags & (TCP_FLAG_SYN|TCP_FLAG_ACK)) == (TCP_FLAG_SYN|TCP_FLAG_ACK) ) {
+
+ Header->DestPort = Header->SourcePort;
+ Header->SourcePort = htons(Connection->LocalPort);
+ Header->AcknowlegementNumber = htonl(Connection->NextSequenceRcv);
+ Header->SequenceNumber = htonl(Connection->NextSequenceSend);
+ Header->WindowSize = htons(TCP_WINDOW_SIZE);
+ Header->Flags = TCP_FLAG_ACK;
+ Header->DataOffset = (sizeof(tTCPHeader)/4) << 4;
+ Log_Log("TCP", "ACKing SYN-ACK");
+ TCP_SendPacket( Connection, sizeof(tTCPHeader), Header );
+ Connection->State = TCP_ST_OPEN;
+ }
+ }
+
+ // Get length of data
+ dataLen = Length - (Header->DataOffset>>4)*4;
+ Log_Log("TCP", "HandleConnectionPacket - dataLen = %i", dataLen);
+
+ if(Header->Flags & TCP_FLAG_ACK) {
+ // TODO: Process an ACKed Packet
+ Log_Log("TCP", "Conn %p, Packet 0x%x ACKed", Connection, Header->AcknowlegementNumber);
+ }
+
+ // TODO: Check what to do here
+ if(Header->Flags & TCP_FLAG_FIN) {
+ if( Connection->State == TCP_ST_FIN_SENT ) {
+ Connection->State = TCP_ST_FINISHED;
+ return ;
+ }
+ else {
+ Connection->State = TCP_ST_FINISHED;
+ Header->DestPort = Header->SourcePort;
+ Header->SourcePort = htons(Connection->LocalPort);
+ Header->AcknowlegementNumber = htonl(Connection->NextSequenceRcv);
+ Header->SequenceNumber = htonl(Connection->NextSequenceSend);
+ Header->Flags = TCP_FLAG_ACK;
+ TCP_SendPacket( Connection, sizeof(tTCPHeader), Header );
+ return ;
+ }
+ }
+
+ if(dataLen == 0) {
+ Log_Log("TCP", "Empty Packet");
+ return ;
+ }
+
+ // NOTES:
+ // Flags
+ // PSH - Has Data?
+ // /NOTES
+
+ // Allocate and fill cached packet
+ pkt = malloc( dataLen + sizeof(tTCPStoredPacket) );
+ pkt->Next = NULL;
+ pkt->Sequence = ntohl(Header->SequenceNumber);
+ pkt->Length = dataLen;
+ memcpy(pkt->Data, (Uint8*)Header + (Header->DataOffset>>4)*4, dataLen);
+
+ // Is this packet the next expected packet?
+ // TODO: Fix this to check if the packet is in the window.
+ if( pkt->Sequence != Connection->NextSequenceRcv )
+ {
+ tTCPStoredPacket *tmp, *prev = NULL;
+
+ Log_Log("TCP", "Out of sequence packet (0x%08x != 0x%08x)",
+ pkt->Sequence, Connection->NextSequenceRcv);
+
+ // No? Well, let's cache it and look at it later
+ SHORTLOCK( &Connection->lFuturePackets );
+ for(tmp = Connection->FuturePackets;
+ tmp;
+ prev = tmp, tmp = tmp->Next)
+ {
+ if(tmp->Sequence > pkt->Sequence) break;