From e9b63a7cc8abab8dfc2b491ef3841dfbeb22703d Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 16 Mar 2014 21:22:48 +0800 Subject: [PATCH] Tools/NetTest - Fixed ip checksum, pcap packet trace, cleanup --- Tools/NetTest_Runner/include/test.h | 4 +++ Tools/NetTest_Runner/ip.c | 14 ++++++-- Tools/NetTest_Runner/main.c | 48 ++++++++++++++++++++++++--- Tools/NetTest_Runner/net.c | 51 +++++++++++++++++++++++++++-- Tools/NetTest_Runner/stack.c | 2 ++ Tools/NetTest_Runner/tcp.c | 3 ++ Tools/NetTest_Runner/test_arp.c | 2 +- Tools/NetTest_Runner/test_tcp.c | 32 +++++++++++++----- Tools/nativelib/threads.c | 2 +- Tools/nativelib/threads_int.c | 2 +- 10 files changed, 139 insertions(+), 21 deletions(-) diff --git a/Tools/NetTest_Runner/include/test.h b/Tools/NetTest_Runner/include/test.h index 3559fafd..bf2da151 100644 --- a/Tools/NetTest_Runner/include/test.h +++ b/Tools/NetTest_Runner/include/test.h @@ -3,6 +3,8 @@ #ifndef _TEST_H_ #define _TEST_H_ +#include + #define TEST_SETNAME(name) test_setname(name) #define TEST_ASSERT(cnd) do{if(!(cnd)) {test_assertion_fail(__FILE__,__LINE__,"%s",#cnd);return false;}}while(0) #define TEST_ASSERT_REL(a,r,b) do{long long a_val=(a),b_val=(b);if(!(a_val r b_val)) {test_assertion_fail(__FILE__,__LINE__,"%s(0x%llx)%s%s(0x%llx)",#a,a_val,#r,#b,b_val);return false;}}while(0) @@ -11,6 +13,8 @@ extern void test_setname(const char *name); extern void test_message(const char *filename, int line, const char *msg, ...); extern void test_assertion_fail(const char *filename, int line, const char *test, ...); +extern void test_trace(const char *msg, ...); +extern void test_trace_hexdump(const char *hdr, const void *data, size_t len); #endif diff --git a/Tools/NetTest_Runner/ip.c b/Tools/NetTest_Runner/ip.c index 628fdbe8..eb53f7ed 100644 --- a/Tools/NetTest_Runner/ip.c +++ b/Tools/NetTest_Runner/ip.c @@ -25,8 +25,10 @@ typedef struct { // === CODE === uint16_t IP_Checksum(uint16_t Prev, size_t Length, const void *Data) { + //test_trace_hexdump("IP Checksum", Data, Length); + const uint16_t *words = Data; - uint32_t ret = ~Prev; + uint32_t ret = 0; for( int i = 0; i < Length/2; i ++ ) { ret += ntohs(*words); @@ -38,6 +40,12 @@ uint16_t IP_Checksum(uint16_t Prev, size_t Length, const void *Data) while( ret >> 16 ) ret = (ret & 0xFFFF) + (ret >> 16); + //test_trace("IP Checksum = %04x + 0x%x", ret, (~Prev) & 0xFFFF); + + ret += (~Prev) & 0xFFFF; + while( ret >> 16 ) + ret = (ret & 0xFFFF) + (ret >> 16); + return ~ret; } @@ -102,8 +110,8 @@ bool IP_Pkt_Check(size_t len, const void *data, size_t *ofs_out, int AF, const v TEST_ASSERT_REL(hdr.TTL, >, 1); // >1 because there's no intervening hops TEST_ASSERT_REL(hdr.Protocol, ==, proto); - TEST_ASSERT( memcmp(hdr.SrcAddr, Src, 4) == 0 ); - TEST_ASSERT( memcmp(hdr.DstAddr, Dst, 4) == 0 ); + if(Src) TEST_ASSERT( memcmp(hdr.SrcAddr, Src, 4) == 0 ); + if(Dst) TEST_ASSERT( memcmp(hdr.DstAddr, Dst, 4) == 0 ); *ofs_out = ofs + (hdr.VerLen & 0xF) * 4; return true; diff --git a/Tools/NetTest_Runner/main.c b/Tools/NetTest_Runner/main.c index 83ab6530..0c2b6c06 100644 --- a/Tools/NetTest_Runner/main.c +++ b/Tools/NetTest_Runner/main.c @@ -33,11 +33,11 @@ int main(int argc, char *argv[]) FILE *fp; fp = fopen("stdout.txt", "w"); fclose(fp); fp = fopen("stderr.txt", "w"); fclose(fp); + + Net_Open(0, "/tmp/acess2net"); for(int i = 0; tests[i]; i ++ ) { - Net_Open(0, "/tmp/acess2net"); - Stack_AddDevice("/tmp/acess2net", (char[]){TEST_MAC}); Stack_AddInterface("eth0", 4, (const char[]){TEST_IP}, 24); Stack_AddRoute(4, "\0\0\0\0", 0, (const char[]){HOST_IP}); @@ -54,9 +54,9 @@ int main(int argc, char *argv[]) teardown: Stack_Kill(); - Net_Close(0); - unlink("/tmp/acess2net"); } + Net_Close(0); + unlink("/tmp/acess2net"); return 0; } @@ -119,3 +119,43 @@ void test_assertion_fail(const char *filename, int line, const char *fmt, ...) fprintf(stderr, "\n"); } +void test_trace(const char *msg, ...) +{ + printf("TRACE: [%s] ", gsTestName); + va_list args; + va_start(args, msg); + vfprintf(stdout, msg, args); + va_end(args); + printf("\n"); +} +void test_trace_hexdump(const char *hdr, const void *data, size_t len) +{ + printf("TRACE: [%s] %s - %zi bytes\n", gsTestName, hdr, len); + const uint8_t *data8 = data; + while( len > 16 ) + { + printf("TRACE: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + data8[0], data8[1], data8[ 2], data8[ 3], data8[ 4], data8[ 5], data8[ 6], data8[ 7], + data8[8], data8[9], data8[10], data8[11], data8[12], data8[13], data8[14], data8[15] + ); + len -= 16; + data8 += 16; + } + printf("TRACE: "); + while( len > 8 ) + { + printf("%02x %02x %02x %02x %02x %02x %02x %02x ", + data8[0], data8[1], data8[ 2], data8[ 3], data8[ 4], data8[ 5], data8[ 6], data8[ 7] + ); + len -= 8; + data8 += 8; + } + while(len > 0) + { + printf("%02x ", data8[0]); + len --; + data8 ++; + } + printf("\n"); +} + diff --git a/Tools/NetTest_Runner/net.c b/Tools/NetTest_Runner/net.c index 05c4ca45..231df502 100644 --- a/Tools/NetTest_Runner/net.c +++ b/Tools/NetTest_Runner/net.c @@ -8,15 +8,16 @@ #include #include #include "net.h" - +#include #define CONNECT_TIMEOUT 10*1000 #define MAX_IFS 4 typedef struct { - int FD; + int FD; socklen_t addrlen; struct sockaddr_un addr; + FILE *CapFP; } tIf; // === PROTOTYPES === @@ -34,6 +35,29 @@ int Net_Open(int IfNum, const char *Path) if(gaInterfaces[IfNum].FD != 0) return 1; gaInterfaces[IfNum].addrlen = sizeof(gaInterfaces[IfNum].addr); gaInterfaces[IfNum].FD = Net_int_Open(Path); + + char cappath[] = "testif00.pcap"; + sprintf(cappath, "testif%i.pcap", IfNum); + gaInterfaces[IfNum].CapFP = fopen(cappath, "w"); + { + struct { + uint32_t magic_number; /* magic number */ + uint16_t version_major; /* major version number */ + uint16_t version_minor; /* minor version number */ + int32_t thiszone; /* GMT to local correction */ + uint32_t sigfigs; /* accuracy of timestamps */ + uint32_t snaplen; /* max length of captured packets, in octets */ + uint32_t network; /* data link type */ + } __attribute__((packed)) hdr = { + 0xa1b2c3d4, + 2,4, + 0, + 0, + 65535, + 1 + }; + fwrite(&hdr, sizeof(hdr), 1, gaInterfaces[IfNum].CapFP); + } return 0; } @@ -57,6 +81,7 @@ void Net_Close(int IfNum) assert(IfNum < MAX_IFS); close(gaInterfaces[IfNum].FD); gaInterfaces[IfNum].FD = 0; + fclose(gaInterfaces[IfNum].CapFP); } bool WaitOnFD(int FD, bool Write, unsigned int Timeout) @@ -96,6 +121,23 @@ bool Net_int_EnsureConnected(int IfNum) return true; } +void Net_int_SavePacket(tIf *If, size_t size, const void *data) +{ + struct timeval curtime; + gettimeofday(&curtime, NULL); + struct { + uint32_t ts_sec; + uint32_t ts_usec; + uint32_t incl_len; + uint32_t orig_len; + } __attribute__((packed)) hdr = { + curtime.tv_sec, curtime.tv_usec, + size, size + }; + fwrite(&hdr, sizeof(hdr), 1, If->CapFP); + fwrite(data, size, 1, If->CapFP); +} + size_t Net_Receive(int IfNum, size_t MaxLen, void *DestBuf, unsigned int Timeout) { assert(IfNum < MAX_IFS); @@ -103,7 +145,9 @@ size_t Net_Receive(int IfNum, size_t MaxLen, void *DestBuf, unsigned int Timeout if( Net_int_EnsureConnected(IfNum) && WaitOnFD(If->FD, false, Timeout) ) { - return recvfrom(If->FD, DestBuf, MaxLen, 0, &If->addr, &If->addrlen); + size_t rv = recvfrom(If->FD, DestBuf, MaxLen, 0, &If->addr, &If->addrlen); + Net_int_SavePacket(If, rv, DestBuf); + return rv; } return 0; } @@ -115,6 +159,7 @@ void Net_Send(int IfNum, size_t Length, const void *Buf) if( !WaitOnFD(If->FD, true, CONNECT_TIMEOUT) ) return ; + Net_int_SavePacket(If, Length, Buf); int rv = sendto(If->FD, Buf, Length, 0, &If->addr, If->addrlen); if( rv < 0 ) perror("Net_Send - send"); diff --git a/Tools/NetTest_Runner/stack.c b/Tools/NetTest_Runner/stack.c index 65f83522..7d5e2613 100644 --- a/Tools/NetTest_Runner/stack.c +++ b/Tools/NetTest_Runner/stack.c @@ -111,6 +111,8 @@ int Stack_Start(const char *Subcommand) fprintf(stderr, "posix_spawn failed: %s", strerror(rv)); return 1; } + + posix_spawn_file_actions_destroy(&fa); return 0; } diff --git a/Tools/NetTest_Runner/tcp.c b/Tools/NetTest_Runner/tcp.c index 0bf0a67f..22a21a16 100644 --- a/Tools/NetTest_Runner/tcp.c +++ b/Tools/NetTest_Runner/tcp.c @@ -28,6 +28,9 @@ uint16_t TCP_int_GetPseudoHeader(int AF, const void *SrcAddr, const void *DstAdd phdr[8] = 0; phdr[9] = pctl; *(uint16_t*)(phdr+10) = htons(Len); + + //test_trace_hexdump("TCP IPv4 PHdr", phdr, sizeof(phdr)); + return IP_Checksum(IP_CHECKSUM_START, 12, phdr); } else { diff --git a/Tools/NetTest_Runner/test_arp.c b/Tools/NetTest_Runner/test_arp.c index e97e2c35..92acc718 100644 --- a/Tools/NetTest_Runner/test_arp.c +++ b/Tools/NetTest_Runner/test_arp.c @@ -18,7 +18,7 @@ bool Test_ARP_Basic(void) TEST_ASSERT( ARP_Pkt_IsResponse(rxlen, rxbuf, BLOB(TEST_IP), BLOB(TEST_MAC)) ); // Request host machine's IP - ARP_SendRequest(0, HOST_IP_STR); + ARP_SendRequest(0, BLOB(HOST_IP)); TEST_ASSERT( Net_Receive(0, sizeof(rxbuf), rxbuf, 1000) == 0 ); #if 0 diff --git a/Tools/NetTest_Runner/test_tcp.c b/Tools/NetTest_Runner/test_tcp.c index 32f79c0f..1d7e8280 100644 --- a/Tools/NetTest_Runner/test_tcp.c +++ b/Tools/NetTest_Runner/test_tcp.c @@ -1,4 +1,9 @@ /* + * Acess2 Network Stack Tester + * - By John Hodge (thePowersGang) + * + * test_tcp.c + * - Tests for the behavior of the "Transmission Control Protocol" */ #include "test.h" #include "tests.h" @@ -16,7 +21,7 @@ bool Test_TCP_Basic(void) size_t rxlen, ofs; char rxbuf[MTU]; const int ERX_TIMEOUT = 1000; // Expect RX timeout (timeout=failure) - const int NRX_TIMEOUT = 1000; // Not expect RX timeout (timeout=success) + const int NRX_TIMEOUT = 250; // Not expect RX timeout (timeout=success) const char testblob[] = "HelloWorld, this is some random testing data for TCP\xFF\x00\x66\x12\x12"; const size_t testblob_len = sizeof(testblob); @@ -30,7 +35,7 @@ bool Test_TCP_Basic(void) // 1.1. Send SYN packet TCP_Send(0, 4, BLOB(TEST_IP), 1234, 80, seq_tx, seq_exp, TCP_SYN, 0x1000, testblob_len, testblob); // Expect a TCP_RST|TCP_ACK with SEQ=0,ACK=SEQ+LEN - TEST_ASSERT( rxlen = Net_Receive(0, sizeof(rxbuf), rxbuf, ERX_TIMEOUT) ); + TEST_ASSERT_rx(); TEST_ASSERT( TCP_Pkt_Check(rxlen, rxbuf, &ofs, 4, BLOB(TEST_IP), 80, 1234, 0, seq_tx+testblob_len, TCP_RST|TCP_ACK) ); TEST_ASSERT_REL(ofs, ==, rxlen); @@ -38,14 +43,14 @@ bool Test_TCP_Basic(void) // 1.2. Send a SYN,ACK packet TCP_Send(0, 4, BLOB(TEST_IP), 1234, 80, seq_tx, seq_exp, TCP_SYN|TCP_ACK, 0x1000, 0, NULL); // Expect a TCP_RST with SEQ=ACK - TEST_ASSERT( rxlen = Net_Receive(0, sizeof(rxbuf), rxbuf, ERX_TIMEOUT) ); + TEST_ASSERT_rx(); TEST_ASSERT( TCP_Pkt_Check(rxlen, rxbuf, &ofs, 4, BLOB(TEST_IP), 80, 1234, seq_exp, seq_tx+0, TCP_RST) ); TEST_ASSERT_REL(ofs, ==, rxlen); // 1.3. Send a RST packet TCP_Send(0, 4, BLOB(TEST_IP), 1234, 80, seq_tx, seq_exp, TCP_RST, 0x1000, 0, NULL); // Expect nothing - TEST_ASSERT( Net_Receive(0, sizeof(rxbuf), rxbuf, NRX_TIMEOUT) == 0 ); + TEST_ASSERT_no_rx(); // 1.3. Send a RST,ACK packet TCP_Send(0, 4, BLOB(TEST_IP), 1234, 80, seq_tx, seq_exp, TCP_RST|TCP_ACK, 0x1000, 0, NULL); @@ -68,7 +73,8 @@ bool Test_TCP_Basic(void) TCP_Send(0, 4, BLOB(TEST_IP), local_port, server_port, seq_tx, seq_exp, TCP_ACK, our_window, 0, NULL); // - Expect RST TEST_ASSERT_rx(); - TEST_ASSERT( TCP_Pkt_Check(rxlen, rxbuf, &ofs, 4, BLOB(TEST_IP), 80, 1234, seq_exp, seq_tx+0, TCP_RST) ); + TEST_ASSERT( TCP_Pkt_Check(rxlen, rxbuf, &ofs, 4, BLOB(TEST_IP), + server_port, local_port, seq_exp, seq_tx+0, TCP_RST) ); // 2.3. Begin hanshake (SYN) // TODO: "If the SYN bit is set, check the security." @@ -76,17 +82,19 @@ bool Test_TCP_Basic(void) // - Expect SYN,ACK with ACK == SEQ+1 TEST_ASSERT_rx(); TCP_SkipCheck_Seq(true); - TEST_ASSERT( TCP_Pkt_Check(rxlen, rxbuf, &ofs, 4, BLOB(TEST_IP), server_port, local_port, - 0, seq_tx+1, TCP_SYN|TCP_ACK) ); + TEST_ASSERT( TCP_Pkt_Check(rxlen, rxbuf, &ofs, 4, BLOB(TEST_IP), + server_port, local_port, 0, seq_tx+1, TCP_SYN|TCP_ACK) ); seq_exp = TCP_Pkt_GetSeq(rxlen, rxbuf, 4); // >>> STATE: SYN-RECEIVED // TODO: Test other transitions from SYN-RECEIVED // 2.4. Complete handshake, TCP ACK + seq_exp ++; + seq_tx ++; TCP_Send(0,4,BLOB(TEST_IP), local_port, server_port, seq_tx, seq_exp, TCP_ACK, our_window, 0, NULL); // - Expect nothing - TEST_ASSERT( Net_Receive(0, sizeof(rxbuf), rxbuf, NRX_TIMEOUT) == 0 ); + TEST_ASSERT_no_rx(); // >>> STATE: ESTABLISHED @@ -94,3 +102,11 @@ bool Test_TCP_Basic(void) return true; } + +bool Test_TCP_SYN_RECEIVED(void) +{ + // 1. Get into SYN-RECEIVED + + // 2. Send various non-ACK packets + return false; +} diff --git a/Tools/nativelib/threads.c b/Tools/nativelib/threads.c index 93db6c3c..dafdc404 100644 --- a/Tools/nativelib/threads.c +++ b/Tools/nativelib/threads.c @@ -5,7 +5,7 @@ * threads.c * - Threads handling */ -#define DEBUG 1 +#define DEBUG 0 #include #include #include diff --git a/Tools/nativelib/threads_int.c b/Tools/nativelib/threads_int.c index 87c60b1a..ca67ba42 100644 --- a/Tools/nativelib/threads_int.c +++ b/Tools/nativelib/threads_int.c @@ -8,7 +8,7 @@ * POSIX Mutex/Semaphore management * Wait state */ -#define DEBUG 1 +#define DEBUG 0 #include #include #include -- 2.20.1