1 
2 
3 #include   "tx_api.h"
4 #include   "nx_api.h"
5 extern void    test_control_return(UINT status);
6 #if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4)
7 #define     DEMO_STACK_SIZE         2048
8 
9 /* Define the ThreadX and NetX object control blocks...  */
10 
11 static TX_THREAD               ntest_0;
12 static TX_THREAD               ntest_1;
13 static NX_PACKET_POOL          pool_0;
14 static NX_IP                   ip_0;
15 static NX_IP                   ip_1;
16 
17 #ifdef FEATURE_NX_IPV6
18 static NXD_ADDRESS             ipv6_address;
19 static NXD_ADDRESS             router_address;
20 #endif
21 
22 /* Define the counters used in the test application...  */
23 
24 static ULONG                   error_counter;
25 static TX_MUTEX                mutex_0;
26 
27 /* Define thread prototypes.  */
28 
29 static void    ntest_0_entry(ULONG thread_input);
30 static void    ntest_1_entry(ULONG thread_input);
31 extern void    _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req);
32 
33 /* Define what the initial system looks like.  */
34 
35 #ifdef CTEST
test_application_define(void * first_unused_memory)36 VOID test_application_define(void *first_unused_memory)
37 #else
38 void    netx_ip_interface_detachment_test_application_define(void *first_unused_memory)
39 #endif
40 {
41 
42 CHAR    *pointer;
43 UINT    status;
44 
45     /* Setup the working pointer.  */
46     pointer =  (CHAR *) first_unused_memory;
47 
48     /* Create the main threads.  */
49     tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0,
50             pointer, DEMO_STACK_SIZE,
51             3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
52     pointer =  pointer + DEMO_STACK_SIZE;
53 
54     tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0,
55             pointer, DEMO_STACK_SIZE,
56             5, 5, TX_NO_TIME_SLICE, TX_AUTO_START);
57     pointer =  pointer + DEMO_STACK_SIZE;
58 
59     /* Initialize the NetX system.  */
60     nx_system_initialize();
61 
62     /* Create a packet pool.  */
63     status =  nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192);
64     pointer = pointer + 8192;
65 
66     if (status)
67         error_counter++;
68 
69     /* Create an IP instance.  */
70     status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver,
71             pointer, 2048, 1);
72     pointer =  pointer + 2048;
73 
74     /* Create another IP instance.  */
75     status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver,
76             pointer, 2048, 2);
77     pointer =  pointer + 2048;
78     if (status)
79         error_counter++;
80 
81     /* Attach the 2nd interface to IP instance0 */
82     status = nx_ip_interface_attach(&ip_0, "2nd interface", IP_ADDRESS(4, 3, 2, 10), 0xFF000000, _nx_ram_network_driver);
83     if(status != NX_SUCCESS)
84         error_counter++;
85 
86     /* Attach the 2nd interface to IP instance1 */
87     status = nx_ip_interface_attach(&ip_1, "2nd interface", IP_ADDRESS(4, 3, 2, 11), 0xFF000000, _nx_ram_network_driver);
88     if(status != NX_SUCCESS)
89         error_counter++;
90 
91     /* Enable ARP and supply ARP cache memory for IP Instance 0.  */
92     status =  nx_arp_enable(&ip_0, (void *) pointer, 1024);
93     pointer = pointer + 1024;
94     if (status)
95         error_counter++;
96 
97     /* Enable ARP and supply ARP cache memory for IP Instance 1.  */
98     status  =  nx_arp_enable(&ip_1, (void *) pointer, 1024);
99     pointer = pointer + 1024;
100 
101     if (status)
102         error_counter++;
103 
104     /* Enable ICMP processing for both IP instances.  */
105     status =  nx_icmp_enable(&ip_0);
106     status += nx_icmp_enable(&ip_1);
107 
108     /* Check TCP enable status.  */
109     if (status)
110         error_counter++;
111 
112 #ifdef NX_ENABLE_IP_STATIC_ROUTING
113     status = nx_ip_static_route_add(&ip_1, IP_ADDRESS(4, 3, 2, 1), 0xFFFFFF00UL, IP_ADDRESS(4, 3, 2, 10));
114 
115     /* Check status.  */
116     if (status)
117         error_counter++;
118 
119 #endif /* NX_ENABLE_IP_STATIC_ROUTING  */
120 
121 #ifdef FEATURE_NX_IPV6
122     /* Set ipv6 version and address.  */
123     ipv6_address.nxd_ip_version = NX_IP_VERSION_V6;
124     ipv6_address.nxd_ip_address.v6[0] = 0x20010000;
125     ipv6_address.nxd_ip_address.v6[1] = 0x00000000;
126     ipv6_address.nxd_ip_address.v6[2] = 0x00000000;
127     ipv6_address.nxd_ip_address.v6[3] = 0x10000001;
128 
129     /* Set interfaces' address */
130     status = nxd_ipv6_address_set(&ip_1, 0, &ipv6_address, 64, NX_NULL);
131 
132     if(status)
133         error_counter++;
134 
135     /* Set ipv6 version and address.  */
136     router_address.nxd_ip_version = NX_IP_VERSION_V6;
137     router_address.nxd_ip_address.v6[0] = 0x20010000;
138     router_address.nxd_ip_address.v6[1] = 0x00000000;
139     router_address.nxd_ip_address.v6[2] = 0x00000000;
140     router_address.nxd_ip_address.v6[3] = 0x10000002;
141 
142     /* Add the default router.  */
143     status = nxd_ipv6_default_router_add(&ip_1, &router_address, 1500, 0);
144 
145     /* Check status.  */
146     if (status)
147         error_counter++;
148 #endif /* FEATURE_NX_IPV6  */
149 }
150 
151 
152 
153 /* Define the test threads.  */
154 
ntest_0_entry(ULONG thread_input)155 static void    ntest_0_entry(ULONG thread_input)
156 {
157 
158 UINT        status;
159 NX_PACKET   *my_packet;
160 ULONG       pings_sent;
161 ULONG       ping_timeouts;
162 ULONG       ping_threads_suspended;
163 ULONG       ping_responses_received;
164 ULONG       icmp_checksum_errors;
165 ULONG       icmp_unhandled_messages;
166 
167 
168     /* Print out test information banner.  */
169     printf("NetX Test:   IP Interface Detachment Test..............................");
170 
171     /* Check for earlier error.  */
172     if (error_counter)
173     {
174         printf("ERROR!\n");
175         test_control_return(1);
176     }
177 
178     tx_mutex_create(&mutex_0, "mutex_0", TX_NO_INHERIT);
179 
180     tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
181 
182     /* Ping an unknown IP address. This will timeout after 100 ticks.  */
183     status =  nx_icmp_ping(&ip_0, IP_ADDRESS(4, 3, 2, 9), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE);
184 
185     /* Determine if the timeout error occurred.  */
186     if ((status != NX_NO_RESPONSE) || (my_packet))
187     {
188 
189         printf("ERROR!\n");
190         test_control_return(1);
191     }
192 
193     /* Now ping an IP address that does exist.  */
194     status =  nx_icmp_ping(&ip_0, IP_ADDRESS(4, 3, 2, 11), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE);
195     if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28))
196     {
197         printf("ERROR!\n");
198         test_control_return(1);
199     }
200 
201 
202     /* It should also be able to ping an IP address that is accessible via the primary interface. */
203     status =  nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE);
204     if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28))
205     {
206         printf("ERROR!\n");
207         test_control_return(1);
208     }
209 
210     /* Let ntest_1 detach the 2nd interface(4.3.2.11) from IP instance1. */
211     tx_mutex_put(&mutex_0);
212     tx_thread_sleep(1);
213     tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
214 
215      /* Now ping an IP address that has been detached. */
216     status =  nx_icmp_ping(&ip_0, IP_ADDRESS(4, 3, 2, 11), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE);
217     if ((status != NX_NO_RESPONSE) || (my_packet))
218     {
219         printf("ERROR!\n");
220         test_control_return(1);
221     }
222 
223     /* It should be able to ping an IP address that is accessible via the primary interface. */
224     status =  nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE);
225     if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28))
226     {
227         printf("ERROR!\n");
228         test_control_return(1);
229     }
230 
231     /* Let ntest_1 attach the interface(4.3.2.11) removed before, then detach the 1st interface(1.2.3.5) to IP instance1. */
232     tx_mutex_put(&mutex_0);
233     tx_thread_sleep(1);
234     tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
235 
236      /* Now ping an IP address that has been detached. */
237     status =  nx_icmp_ping(&ip_0, IP_ADDRESS(4, 3, 2, 11), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE);
238      if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28))
239     {
240         printf("ERROR!\n");
241         test_control_return(1);
242     }
243 
244     /* It should be able to ping an IP address that is accessible via the primary interface. */
245     status =  nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE);
246     if ((status != NX_NO_RESPONSE) || (my_packet))
247     {
248         printf("ERROR!\n");
249         test_control_return(1);
250     }
251 
252 
253     tx_mutex_delete(&mutex_0);
254 
255     /* Get ICMP information.  */
256     status += nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages);
257 
258 #ifndef NX_DISABLE_ICMP_INFO
259 
260     if ((pings_sent != 7) || (ping_timeouts != 3) || (ping_responses_received != 4) || (icmp_checksum_errors) || (icmp_unhandled_messages))
261     {
262         printf("ERROR!\n");
263         test_control_return(1);
264     }
265 #endif
266 
267     if(error_counter)
268     {
269 
270         printf("ERROR!\n");
271         test_control_return(1);
272     }
273     else
274     {
275 
276         printf("SUCCESS!\n");
277         test_control_return(0);
278     }
279 
280 }
281 
ntest_1_entry(ULONG thread_input)282 static void    ntest_1_entry(ULONG thread_input)
283 {
284 
285 UINT    status;
286 
287     tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
288 
289     /* Detach the 2nd interface(4.3.2.11) from IP instance1. */
290     status = nx_ip_interface_detach(&ip_1, 1);
291     if(status)
292         error_counter++;
293 
294     tx_mutex_put(&mutex_0);
295     tx_thread_sleep(1);
296     tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
297 
298     /* Attach the 2nd interface(4.3.2.11) removed before to IP instance1. */
299     status = nx_ip_interface_attach(&ip_1, "2nd interface", IP_ADDRESS(4, 3, 2, 11), 0xFF000000, _nx_ram_network_driver);
300 
301     /* Detach the 1st interface(1.2.3.5)from IP instance1. */
302     status += nx_ip_interface_detach(&ip_1, 0);
303 
304     if(status)
305         error_counter++;
306 
307     tx_mutex_put(&mutex_0);
308 
309 }
310 #else
311 
312 #ifdef CTEST
test_application_define(void * first_unused_memory)313 VOID test_application_define(void *first_unused_memory)
314 #else
315 void    netx_ip_interface_detachment_test_application_define(void *first_unused_memory)
316 #endif
317 {
318     printf("NetX Test:   IP Interface Detachment Test..............................N/A\n");
319     test_control_return(3);
320 }
321 #endif
322