1 /* This NetX test concentrates on the ICMP ping operation.  */
2 
3 #include   "tx_api.h"
4 #include   "nx_api.h"
5 #include   "nx_ip.h"
6 #include   "nx_icmp.h"
7 
8 extern void    test_control_return(UINT status);
9 #if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_FRAGMENTATION)
10 
11 #define     DEMO_STACK_SIZE         2048
12 
13 
14 /* Define the ThreadX and NetX object control blocks...  */
15 
16 static TX_THREAD               ntest_0;
17 
18 static NX_PACKET_POOL          pool_0;
19 static NX_IP                   ip_0;
20 static NX_IP                   ip_1;
21 
22 
23 /* Define the counters used in the test application...  */
24 
25 static ULONG                   error_counter;
26 static NXD_ADDRESS             global_address_0;
27 static NXD_ADDRESS             global_address_1;
28 
29 /* Define the ping message.  */
30 static CHAR                    ping_message[259];
31 
32 
33 /* Define thread prototypes.  */
34 
35 static void    ntest_0_entry(ULONG thread_input);
36 extern void    test_control_return(UINT status);
37 extern void    _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req);
38 
39 /* Define what the initial system looks like.  */
40 
41 #ifdef CTEST
test_application_define(void * first_unused_memory)42 VOID test_application_define(void *first_unused_memory)
43 #else
44 void    netx_icmp_ping6_fragment_test_application_define(void *first_unused_memory)
45 #endif
46 {
47 
48 CHAR    *pointer;
49 UINT    status;
50 
51 
52     /* Setup the working pointer.  */
53     pointer =  (CHAR *) first_unused_memory;
54 
55     /* Create the main thread.  */
56     tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0,
57             pointer, DEMO_STACK_SIZE,
58             4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
59     pointer =  pointer + DEMO_STACK_SIZE;
60 
61     /* Initialize the NetX system.  */
62     nx_system_initialize();
63 
64     /* Create a packet pool.  */
65     status =  nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 10240);
66     pointer = pointer + 10240;
67 
68     if (status)
69         error_counter++;
70 
71     /* Create an IP instance.  */
72     status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver,
73                     pointer, 2048, 1);
74     pointer =  pointer + 2048;
75 
76     /* Create another IP instance.  */
77     status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver,
78                     pointer, 2048, 2);
79     pointer =  pointer + 2048;
80     if (status)
81         error_counter++;
82 
83     /* Enable IPv6 */
84     status = nxd_ipv6_enable(&ip_0);
85     status += nxd_ipv6_enable(&ip_1);
86 
87     /* Check ipv6 enable status.  */
88     if(status)
89         error_counter++;
90 
91     /* Enable ICMPv6 processing for IP instances0 .  */
92     status = nxd_icmp_enable(&ip_0);
93     status += nxd_icmp_enable(&ip_1);
94 
95     /* Check ipv6 enable status.  */
96     if(status)
97         error_counter++;
98 
99     /* Enable fragment.  */
100     status = nx_ip_fragment_enable(&ip_0);
101     status += nx_ip_fragment_enable(&ip_1);
102 
103     /* Check fragment enable status.  */
104     if(status)
105         error_counter++;
106 
107     /* Set ipv6 global address for IP instance 0.  */
108     global_address_0.nxd_ip_version = NX_IP_VERSION_V6;
109     global_address_0.nxd_ip_address.v6[0] = 0x20010000;
110     global_address_0.nxd_ip_address.v6[1] = 0x00000000;
111     global_address_0.nxd_ip_address.v6[2] = 0x00000000;
112     global_address_0.nxd_ip_address.v6[3] = 0x10000001;
113 
114     /* Set the IPv6 address.  */
115     status = nxd_ipv6_address_set(&ip_0, 0, &global_address_0, 64, NX_NULL);
116 
117     /* Check status.  */
118     if(status)
119         error_counter++;
120 
121     /* Set ipv6 global address for IP instance 1.  */
122     global_address_1.nxd_ip_version = NX_IP_VERSION_V6;
123     global_address_1.nxd_ip_address.v6[0] = 0x20010000;
124     global_address_1.nxd_ip_address.v6[1] = 0x00000000;
125     global_address_1.nxd_ip_address.v6[2] = 0x00000000;
126     global_address_1.nxd_ip_address.v6[3] = 0x10000002;
127 
128     /* Set the IPv6 address.  */
129     status = nxd_ipv6_address_set(&ip_1, 0, &global_address_1, 64, NX_NULL);
130 
131     /* Check status.  */
132     if(status)
133         error_counter++;
134 }
135 
136 
137 /* Define the test threads.  */
138 
ntest_0_entry(ULONG thread_input)139 static void    ntest_0_entry(ULONG thread_input)
140 {
141 
142 UINT        status;
143 NX_PACKET   *my_packet;
144 UINT        i, index;
145 ULONG       pings_sent;
146 ULONG       ping_timeouts;
147 ULONG       ping_threads_suspended;
148 ULONG       ping_responses_received;
149 ULONG       icmp_checksum_errors;
150 ULONG       icmp_unhandled_messages;
151 
152 
153     /* Print out test information banner.  */
154     printf("NetX Test:   ICMP Ping6 Fragment Test..................................");
155 
156     /* Check for earlier error.  */
157     if (error_counter)
158     {
159 
160         printf("ERROR!\n");
161         test_control_return(1);
162     }
163 
164     /* Sleep 5 seconds for Duplicate Address Detected. */
165     tx_thread_sleep(5 * NX_IP_PERIODIC_RATE);
166 
167     /* Random genearte the write data.  */
168     for (i = 0; i < sizeof(ping_message); i ++)
169     {
170         ping_message[i] = (UCHAR)rand();
171     }
172 
173     /* Now ping an IP address that does exist.  */
174     /* The reply packet contains checksum 0. */
175     status =  nxd_icmp_ping(&ip_0, &global_address_1, ping_message, sizeof(ping_message), &my_packet, 2 * NX_IP_PERIODIC_RATE);
176 
177     /* Get ICMP information.  */
178     status += nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages);
179 
180 #ifndef NX_DISABLE_ICMP_INFO
181     if ((ping_timeouts != 0) || (pings_sent != 1) || (ping_responses_received != 1))
182     {
183         printf("ERROR!\n");
184         test_control_return(1);
185     }
186 #endif
187 
188     /* Determine if the timeout error occurred.  */
189     if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != sizeof(ping_message) /* data only */) ||
190         (ping_threads_suspended) || (icmp_checksum_errors) || (icmp_unhandled_messages) || error_counter)
191     {
192 
193         printf("ERROR!\n");
194         test_control_return(1);
195     }
196 
197     /* Compute a simple hash based on the dest_ip */
198     index = (UINT)((global_address_1.nxd_ip_address.v6[0] + global_address_1.nxd_ip_address.v6[1] + global_address_1.nxd_ip_address.v6[2] + global_address_1.nxd_ip_address.v6[3]) % (NX_IPV6_NEIGHBOR_CACHE_SIZE));
199 
200     /* Check the queued packet for ND CACHE.  */
201     if (ip_0.nx_ipv6_nd_cache[index].nx_nd_cache_packet_waiting_head)
202     {
203 
204         printf("ERROR!\n");
205         test_control_return(1);
206     }
207 
208 
209     printf("SUCCESS!\n");
210     test_control_return(0);
211 }
212 #else
213 #ifdef CTEST
test_application_define(void * first_unused_memory)214 VOID test_application_define(void *first_unused_memory)
215 #else
216 void    netx_icmp_ping6_fragment_test_application_define(void *first_unused_memory)
217 #endif
218 {
219 
220     /* Print out test information banner.  */
221     printf("NetX Test:   ICMP Ping6 Fragment Test..................................N/A\n");
222 
223     test_control_return(3);
224 }
225 #endif
226