Tools/NetTest - TCP stack testing, going well
[tpg/acess2.git] / Tools / NetTest_Runner / tcp.c
index 56c5571..0bf0a67 100644 (file)
@@ -19,6 +19,23 @@ typedef struct {
 } __attribute__((packed)) tTCPHeader;
 
 // === CODE ===
+uint16_t TCP_int_GetPseudoHeader(int AF, const void *SrcAddr, const void *DstAddr, uint8_t pctl, size_t Len)
+{
+       if( AF == 4 ) {
+               uint8_t phdr[12];
+               memcpy(phdr+0, SrcAddr, 4);
+               memcpy(phdr+4, DstAddr, 4);
+               phdr[8] = 0;
+               phdr[9] = pctl;
+               *(uint16_t*)(phdr+10) = htons(Len);
+               return IP_Checksum(IP_CHECKSUM_START, 12, phdr);
+       }
+       else {
+               TEST_WARN("TCP unknown AF %i", AF);
+               return 0;
+       }
+}
+
 void TCP_Send(int IF, int AF, const void *IP, short sport, short dport,
        uint32_t seq, uint32_t ack, uint8_t flags, uint16_t window,
        size_t data_len, const void *data
@@ -29,13 +46,14 @@ void TCP_Send(int IF, int AF, const void *IP, short sport, short dport,
        hdr.DPort = htons(dport);
        hdr.Seq = htonl(seq);
        hdr.Ack = htonl(ack);
-       hdr.DataOfs = sizeof(hdr)/4;
+       hdr.DataOfs = (sizeof(hdr)/4) << 4;
        hdr.Flags = flags;
        hdr.Window = htons(window);
        hdr.Checksum = htons(0);
        hdr.UrgPtr = htons(0);
 
-       uint16_t        checksum = IP_CHECKSUM_START;
+       uint16_t        checksum;
+       checksum = TCP_int_GetPseudoHeader(AF, BLOB(HOST_IP), IP, IPPROTO_TCP, sizeof(hdr)+data_len);
        checksum = IP_Checksum(checksum, sizeof(hdr), &hdr);
        checksum = IP_Checksum(checksum, data_len, data);
        hdr.Checksum = htons( checksum );
@@ -45,30 +63,56 @@ void TCP_Send(int IF, int AF, const void *IP, short sport, short dport,
        IP_Send(IF, AF, BLOB(HOST_IP), IP, IPPROTO_TCP, 2, buflens, bufs);
 }
 
-bool TCP_Pkt_Check(size_t len, const void *data, size_t *out_ofs, int AF, const void *IP, short sport, short dport,
-       uint8_t flags)
+struct {
+       bool    Seq;
+       bool    Ack;
+       bool    SPort;
+}      gTCP_Skips;
+
+void TCP_SkipCheck_Seq(bool Skip) {
+       gTCP_Skips.Seq = Skip;
+}
+
+bool TCP_Pkt_Check(size_t len, const void *data, size_t *out_ofs,
+       int AF, const void *IP, short sport, short dport,
+       uint32_t seq, uint32_t ack, uint8_t flags)
 {
        size_t  ofs;
        if( !IP_Pkt_Check(len, data, &ofs, AF, IP, BLOB(HOST_IP), IPPROTO_TCP) )
                return false;
+       // TODO: IP has its own length field, use that?
        
        tTCPHeader      hdr;
        TEST_ASSERT_REL(len - ofs, >=, sizeof(hdr));    
        memcpy(&hdr, (char*)data + ofs, sizeof(hdr));
        
-       TEST_ASSERT_REL( ntohs(hdr.SPort), ==, sport );
+       TEST_ASSERT_REL( hdr.DataOfs >> 4, >=, sizeof(hdr)/4 );
+       if( !gTCP_Skips.SPort ) TEST_ASSERT_REL( ntohs(hdr.SPort), ==, sport );
        TEST_ASSERT_REL( ntohs(hdr.DPort), ==, dport );
-       // TODO: Checks on Seq/Ack
+       if( !gTCP_Skips.Seq )   TEST_ASSERT_REL( ntohl(hdr.Seq), ==, seq );
+       if( !gTCP_Skips.Ack )   TEST_ASSERT_REL( ntohl(hdr.Ack), ==, ack );
        TEST_ASSERT_REL( hdr.Flags, ==, flags);
 
        uint16_t        real_cksum = htons(hdr.Checksum);
        hdr.Checksum = 0;
-       uint16_t        calc_cksum = IP_CHECKSUM_START;
+       uint16_t        calc_cksum;
+       calc_cksum = TCP_int_GetPseudoHeader(AF, IP, BLOB(HOST_IP), IPPROTO_TCP, len-ofs);
        calc_cksum = IP_Checksum(calc_cksum, sizeof(hdr), &hdr);
        calc_cksum = IP_Checksum(calc_cksum, len - ofs - sizeof(hdr), (char*)data+ofs+sizeof(hdr));
        TEST_ASSERT_REL( real_cksum, ==, calc_cksum );
-       
+
+       memset(&gTCP_Skips, 0, sizeof(gTCP_Skips));
+
        *out_ofs = ofs + sizeof(hdr);
        return true;
 }
 
+uint32_t TCP_Pkt_GetSeq(size_t len, const void *data, int AF) {
+       size_t  ofs;
+       IP_Pkt_Check(len, data, &ofs, AF, NULL, NULL, IPPROTO_TCP);
+       
+       tTCPHeader      hdr;
+       memcpy(&hdr, (char*)data + ofs, sizeof(hdr));
+       return ntohl(hdr.Seq);
+}
+

UCC git Repository :: git.ucc.asn.au