X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Tools%2FNetTest_Runner%2Ftcp.c;fp=Tools%2FNetTest_Runner%2Ftcp.c;h=0bf0a67f9b515617bd6f495d37ee52d6828bebf3;hb=d2f1a4c62225533351551870cbe44d94a4ec4fab;hp=56c557179a366c3ed0efa85855099320e822d0e5;hpb=f08ffb4a09855859328b73127ad5a62505564612;p=tpg%2Facess2.git diff --git a/Tools/NetTest_Runner/tcp.c b/Tools/NetTest_Runner/tcp.c index 56c55717..0bf0a67f 100644 --- a/Tools/NetTest_Runner/tcp.c +++ b/Tools/NetTest_Runner/tcp.c @@ -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); +} +