Tools/NetTest - TCP test passing with connection opened/used/closed
[tpg/acess2.git] / Tools / NetTest_Runner / test_tcp.c
1 /*
2  * Acess2 Network Stack Tester
3  * - By John Hodge (thePowersGang)
4  *
5  * test_tcp.c
6  * - Tests for the behavior of the "Transmission Control Protocol"
7  */
8 #include "test.h"
9 #include "tests.h"
10 #include "net.h"
11 #include "stack.h"
12 #include "arp.h"
13 #include "tcp.h"
14 #include <string.h>
15
16 #define TEST_ASSERT_rx()        TEST_ASSERT( rxlen = Net_Receive(0, sizeof(rxbuf), rxbuf, ERX_TIMEOUT) )
17 #define TEST_ASSERT_no_rx()     TEST_ASSERT( Net_Receive(0, sizeof(rxbuf), rxbuf, NRX_TIMEOUT) == 0 )
18
19 bool Test_TCP_Basic(void)
20 {
21         TEST_SETNAME(__func__);
22         size_t  rxlen, ofs, len;
23         char rxbuf[MTU];
24         const int       ERX_TIMEOUT = 1000;     // Expect RX timeout (timeout=failure)
25         const int       NRX_TIMEOUT = 250;      // Not expect RX timeout (timeout=success)
26         
27         const char testblob[] = "HelloWorld, this is some random testing data for TCP\xFF\x00\x66\x12\x12";
28         const size_t    testblob_len = sizeof(testblob);
29         
30         // 1. Test packets to closed port
31         // > RFC793 Pg.65
32         const uint16_t  our_window = 0x1000;
33         uint32_t        seq_tx = 0x1000;
34         uint32_t        seq_exp = 0x33456;
35         
36         // 1.1. Send SYN packet
37         TCP_Send(0, 4, BLOB(TEST_IP), 1234, 80, seq_tx, seq_exp, TCP_SYN, 0x1000, testblob_len, testblob);
38         // Expect a TCP_RST|TCP_ACK with SEQ=0,ACK=SEQ+LEN
39         TEST_ASSERT_rx();
40         TEST_ASSERT( TCP_Pkt_Check(rxlen, rxbuf, &ofs, &len, 4, BLOB(TEST_IP), 80, 1234,
41                 0, seq_tx+testblob_len, TCP_RST|TCP_ACK) );
42         TEST_ASSERT_REL(ofs, ==, rxlen);
43         
44         // 1.2. Send a SYN,ACK packet
45         TCP_Send(0, 4, BLOB(TEST_IP), 1234, 80, seq_tx, seq_exp, TCP_SYN|TCP_ACK, 0x1000, 0, NULL);
46         // Expect a TCP_RST with SEQ=ACK
47         TEST_ASSERT_rx();
48         TEST_ASSERT( TCP_Pkt_Check(rxlen, rxbuf, &ofs, &len, 4, BLOB(TEST_IP), 80, 1234, seq_exp, seq_tx+0, TCP_RST) );
49         TEST_ASSERT_REL(ofs, ==, rxlen);
50         
51         // 1.3. Send a RST packet
52         TCP_Send(0, 4, BLOB(TEST_IP), 1234, 80, seq_tx, seq_exp, TCP_RST, 0x1000, 0, NULL);
53         // Expect nothing
54         TEST_ASSERT_no_rx();
55         
56         // 1.3. Send a RST,ACK packet
57         TCP_Send(0, 4, BLOB(TEST_IP), 1234, 80, seq_tx, seq_exp, TCP_RST|TCP_ACK, 0x1000, 0, NULL);
58         // Expect nothing
59         TEST_ASSERT_no_rx();
60
61         
62         // 2. Establishing connection with a server
63         const int server_port = 7;
64         const int local_port = 11234;
65         Stack_SendCommand("tcp_echo_server %i", server_port);
66
67         // >>> STATE: LISTEN
68
69         // 2.1. Send RST
70         TCP_Send(0, 4, BLOB(TEST_IP), local_port, server_port, seq_tx, seq_exp, TCP_RST, our_window, 0, NULL);
71         // - Expect nothing
72         TEST_ASSERT_no_rx();
73         // 2.2. Send ACK
74         TCP_Send(0, 4, BLOB(TEST_IP), local_port, server_port, seq_tx, seq_exp, TCP_ACK, our_window, 0, NULL);
75         // - Expect RST
76         TEST_ASSERT_rx();
77         TEST_ASSERT( TCP_Pkt_Check(rxlen, rxbuf, &ofs, &len, 4, BLOB(TEST_IP),
78                 server_port, local_port, seq_exp, seq_tx+0, TCP_RST) );
79
80         // 2.3. Begin hanshake (SYN)
81         // TODO: "If the SYN bit is set, check the security."
82         TCP_Send(0, 4, BLOB(TEST_IP), local_port, server_port, seq_tx, 0, TCP_SYN, our_window, 0, NULL);
83         // - Expect SYN,ACK with ACK == SEQ+1
84         TEST_ASSERT_rx();
85         TCP_SkipCheck_Seq(true);
86         TEST_ASSERT( TCP_Pkt_Check(rxlen, rxbuf, &ofs, &len, 4, BLOB(TEST_IP),
87                 server_port, local_port, 0, seq_tx+1, TCP_SYN|TCP_ACK) );
88         seq_exp = TCP_Pkt_GetSeq(rxlen, rxbuf, 4);
89
90         // >>> STATE: SYN-RECEIVED
91         // TODO: Test other transitions from SYN-RECEIVED
92                 
93         // 2.4. Complete handshake, TCP ACK
94         seq_exp ++;
95         seq_tx ++;
96         TCP_Send(0,4,BLOB(TEST_IP), local_port, server_port, seq_tx, seq_exp, TCP_ACK, our_window, 0, NULL);
97         // - Expect nothing
98         TEST_ASSERT_no_rx();
99
100         // >>> STATE: ESTABLISHED
101         
102         // 2.5. Send data
103         TCP_Send(0,4,BLOB(TEST_IP), local_port, server_port, seq_tx, seq_exp,
104                 TCP_ACK|TCP_PSH, our_window, testblob_len, testblob);
105         seq_tx += testblob_len;
106         // Expect burst delayed ACK
107         TEST_ASSERT_rx();
108         TEST_ASSERT( TCP_Pkt_Check(rxlen, rxbuf, &ofs, &len, 4, BLOB(TEST_IP),
109                 server_port, local_port, seq_exp, seq_tx, TCP_ACK) );
110         TEST_ASSERT_REL( len, ==, 0 );
111
112         // Expect echoed reponse with ACK
113         TEST_ASSERT_rx();
114         TEST_ASSERT( TCP_Pkt_Check(rxlen, rxbuf, &ofs, &len, 4, BLOB(TEST_IP),
115                 server_port, local_port, seq_exp, seq_tx, TCP_ACK|TCP_PSH) );
116         TEST_ASSERT_REL( len, ==, testblob_len );
117         TEST_ASSERT( memcmp(rxbuf + ofs, testblob, testblob_len) == 0 );
118         seq_exp += testblob_len;
119         
120         // 2.6. Close connection (TCP FIN)
121         TCP_Send(0,4,BLOB(TEST_IP), local_port, server_port, seq_tx, seq_exp,
122                 TCP_ACK|TCP_FIN, our_window, 0, NULL);
123         seq_tx ++;      // Empty = 1 byte
124         // Expect ACK? (Does acess do delayed ACKs here?)
125         TEST_ASSERT_rx();
126         TEST_ASSERT( TCP_Pkt_Check(rxlen, rxbuf, &ofs, &len, 4, BLOB(TEST_IP),
127                 server_port, local_port, seq_exp, seq_tx, TCP_ACK) );
128         TEST_ASSERT_REL( len, ==, 0 );
129         // >>> STATE: CLOSE WAIT
130         
131         // Expect FIN
132         TEST_ASSERT_rx();
133         TEST_ASSERT( TCP_Pkt_Check(rxlen, rxbuf, &ofs, &len, 4, BLOB(TEST_IP),
134                 server_port, local_port, seq_exp, 0, TCP_FIN) );
135         TEST_ASSERT_REL( len, ==, 0 );
136         
137         // >>> STATE: LAST-ACK
138
139         // 2.7 Send ACK of FIN
140         TCP_Send(0,4,BLOB(TEST_IP), local_port, server_port, seq_tx, seq_exp,
141                 TCP_ACK, our_window, 0, NULL);
142         // Expect no response
143         TEST_ASSERT_no_rx();
144         
145         // >>> STATE: CLOSED
146         
147         return true;
148 }
149
150 bool Test_TCP_SYN_RECEIVED(void)
151 {
152         // 1. Get into SYN-RECEIVED
153         
154         // 2. Send various non-ACK packets
155         return false;
156 }

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