Tools/NetTest - Fixed ip checksum, pcap packet trace, cleanup
authorJohn Hodge <[email protected]>
Sun, 16 Mar 2014 13:22:48 +0000 (21:22 +0800)
committerJohn Hodge <[email protected]>
Sun, 16 Mar 2014 13:22:48 +0000 (21:22 +0800)
Tools/NetTest_Runner/include/test.h
Tools/NetTest_Runner/ip.c
Tools/NetTest_Runner/main.c
Tools/NetTest_Runner/net.c
Tools/NetTest_Runner/stack.c
Tools/NetTest_Runner/tcp.c
Tools/NetTest_Runner/test_arp.c
Tools/NetTest_Runner/test_tcp.c
Tools/nativelib/threads.c
Tools/nativelib/threads_int.c

index 3559faf..bf2da15 100644 (file)
@@ -3,6 +3,8 @@
 #ifndef _TEST_H_
 #define _TEST_H_
 
+#include <stddef.h>
+
 #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
 
index 628fdbe..eb53f7e 100644 (file)
@@ -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;
index 83ab653..0c2b6c0 100644 (file)
@@ -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");
+}
+
index 05c4ca4..231df50 100644 (file)
@@ -8,15 +8,16 @@
 #include <assert.h>
 #include <sys/select.h>
 #include "net.h"
-
+#include <stdint.h>
 
 #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");
index 65f8352..7d5e261 100644 (file)
@@ -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;
 }
index 0bf0a67..22a21a1 100644 (file)
@@ -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 {
index e97e2c3..92acc71 100644 (file)
@@ -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   
index 32f79c0..1d7e828 100644 (file)
@@ -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;
+}
index 93db6c3..dafdc40 100644 (file)
@@ -5,7 +5,7 @@
  * threads.c
  * - Threads handling
  */
-#define DEBUG  1
+#define DEBUG  0
 #include <acess.h>
 #include <threads.h>
 #include <threads_int.h>
index 87c60b1..ca67ba4 100644 (file)
@@ -8,7 +8,7 @@
  * POSIX Mutex/Semaphore management
  * Wait state
  */
-#define DEBUG  1
+#define DEBUG  0
 #include <stddef.h>
 #include <stdlib.h>
 #include <stdint.h>

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