1 /* This NetX test concentrates on basic IPv6 fragmentation. */
2 /* Test sequence:
3 * 1. ip_0 allocate one packets.
4 * 1. ip_0 add the Hop-by-Hop Option, 2 bytes(next header, option length) + 128 bytes(option length).
5 * 1. ip_0 append the data 1000 bytes.
6 * 2. ip_0 discard the packets excpet the header packet, packet length also is 2 + 128 + 1000.
7 * 3. ip_0 call nxd_ip_raw_packet_send to send the packet with Hop-by-Hop Option.
8 * 4. ip_0 call nx_ipv6_fragment_process to fragment packet and send the fragmentation packets.
9 * 5. check if the driver receive fragmentation packet form ip_0.
10 Test pointer:
11 * 1. in _nx_ipv6_packet_copy failure since the next packet of source packet is NX_NULL, cover the following code.
12 if ((source_pkt == NX_NULL) || (dest_pkt == NX_NULL))
13 return(NX_NOT_SUCCESSFUL);
14 * 2. in nx_ipv6_fragment_process failure since _nx_ipv6_packet_copy failure, cover the following code:
15 // For the first packet, the prepend pointer is already at the begining of the IP header.
16 if (_nx_ipv6_packet_copy(source_packet, first_fragment, fragment_size))
17 break;
18 */
19
20
21 #include "tx_api.h"
22 #include "nx_api.h"
23 #if !defined(NX_DISABLE_FRAGMENTATION) && defined(FEATURE_NX_IPV6)
24 #include "nx_ipv6.h"
25 #define DEMO_STACK_SIZE 2048
26
27
28 /* Define the ThreadX and NetX object control blocks... */
29
30 static TX_THREAD thread_0;
31
32 static NX_PACKET_POOL pool_0;
33 static NX_IP ip_0;
34 static NX_IP ip_1;
35
36 static NXD_ADDRESS ipv6_address_0;
37 static NXD_ADDRESS ipv6_address_1;
38
39
40 /* Define the counters used in the demo application... */
41
42 static ULONG error_counter;
43 static ULONG fragmentation_counter;
44
45 /* Define thread prototypes. */
46
47 static void thread_0_entry(ULONG thread_input);
48 extern void test_control_return(UINT status);
49 extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req);
50 extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr);
51 static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr);
52
53 static CHAR msg[1500]={'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
54
55 /* Define what the initial system looks like. */
56
57 #ifdef CTEST
test_application_define(void * first_unused_memory)58 VOID test_application_define(void *first_unused_memory)
59 #else
60 void netx_ipv6_fragmentation_error_test2_application_define(void *first_unused_memory)
61 #endif
62 {
63
64 CHAR *pointer;
65 UINT status;
66
67
68 /* Setup the working pointer. */
69 pointer = (CHAR *) first_unused_memory;
70
71 error_counter = 0;
72 fragmentation_counter = 0;
73
74 /* Create the main thread. */
75 tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
76 pointer, DEMO_STACK_SIZE,
77 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
78 pointer = pointer + DEMO_STACK_SIZE;
79
80 /* Initialize the NetX system. */
81 nx_system_initialize();
82
83 /* Create a packet pool. */
84 status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 128, pointer, 128*60);
85 pointer = pointer + 128*60;
86
87 /* Check for pool creation error. */
88 if (status)
89 error_counter++;
90
91 /* Create an IP instance. */
92 status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver,
93 pointer, 2048, 1);
94 pointer = pointer + 2048;
95
96 /* Create another IP instance. */
97 status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver,
98 pointer, 2048, 1);
99 pointer = pointer + 2048;
100
101 /* Check for IP create errors. */
102 if (status)
103 error_counter++;
104
105 status = nxd_ipv6_enable(&ip_0);
106 status += nxd_ipv6_enable(&ip_1);
107 if (status)
108 error_counter++;
109
110 /* Enable IP fragmentation logic on both IP instances. */
111 status = nx_ip_fragment_enable(&ip_0);
112 status += nx_ip_fragment_enable(&ip_1);
113 if (status)
114 error_counter++;
115
116 /* Enable IP raw feature on both IP instances. */
117 status = nx_ip_raw_packet_enable(&ip_0);
118 status += nx_ip_raw_packet_enable(&ip_1);
119 if (status)
120 error_counter++;
121
122 status = nxd_icmp_enable(&ip_0);
123 status += nxd_icmp_enable(&ip_1);
124 if (status)
125 error_counter++;
126
127 /* Set ipv6 version and address. */
128 ipv6_address_0.nxd_ip_version = NX_IP_VERSION_V6;
129 ipv6_address_0.nxd_ip_address.v6[0] = 0x20010000;
130 ipv6_address_0.nxd_ip_address.v6[1] = 0x00000000;
131 ipv6_address_0.nxd_ip_address.v6[2] = 0x00000000;
132 ipv6_address_0.nxd_ip_address.v6[3] = 0x10000001;
133
134 ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6;
135 ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000;
136 ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000;
137 ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000;
138 ipv6_address_1.nxd_ip_address.v6[3] = 0x10000002;
139
140 /* Set interfaces' address */
141 status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_0, 64, NX_NULL);
142 status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_1, 64, NX_NULL);
143
144 if(status)
145 error_counter++;
146
147 }
148
149
150 /* Define the test threads. */
151
thread_0_entry(ULONG thread_input)152 static void thread_0_entry(ULONG thread_input)
153 {
154
155 UINT status;
156 UCHAR data;
157 NX_PACKET *my_packet;
158
159
160 /* Print out some test information banners. */
161 printf("NetX Test: IPv6 Fragmentation Error Test2............................");
162
163 /* Check for earlier error. */
164 if (error_counter)
165 {
166 printf("ERROR!\n");
167 test_control_return(1);
168 }
169
170 /* DAD */
171 tx_thread_sleep(5 * NX_IP_PERIODIC_RATE);
172
173 /* Set the callback function. */
174 advanced_packet_process_callback = my_packet_process;
175
176 /* Allocate a packet. */
177 status = nx_packet_allocate(&pool_0, &my_packet, NX_IPv6_PACKET, TX_WAIT_FOREVER);
178
179 /* Check status. */
180 if (status != NX_SUCCESS)
181 {
182 printf("ERROR!\n");
183 test_control_return(1);
184 }
185
186 /* Added Hop-by-Hop Options header to let the unfragmentable size exceed one packet. */
187
188 /* Added the Next header. */
189 data = 23;
190 status = nx_packet_data_append(my_packet, &data, 1, &pool_0, NX_IP_PERIODIC_RATE);
191
192 /* Added the Hdr Ext Len. */
193 data = 16;
194 status += nx_packet_data_append(my_packet, &data, 1, &pool_0, NX_IP_PERIODIC_RATE);
195
196 /* Added the Options. */
197 status += nx_packet_data_append(my_packet, msg, 16 * 8, &pool_0, NX_IP_PERIODIC_RATE);
198
199 /* Check for error. */
200 if(status)
201 {
202 printf("ERROR!\n");
203 test_control_return(1);
204 }
205
206 /* Write ABCs into the packet payload! */
207 status = nx_packet_data_append(my_packet, msg, 1000, &pool_0, NX_IP_PERIODIC_RATE);
208
209 /* Check for error. */
210 if(status)
211 {
212 printf("ERROR!\n");
213 test_control_return(1);
214 }
215
216 /* Discard the packets except the header packet. */
217 my_packet -> nx_packet_next = NX_NULL;
218 my_packet -> nx_packet_last = NX_NULL;
219
220 /* Send the raw packet for Hop-by-Hop Option. */
221 status = nxd_ip_raw_packet_send(&ip_0, my_packet, &ipv6_address_1, NX_PROTOCOL_NEXT_HEADER_HOP_BY_HOP, 255, NX_IP_NORMAL);
222
223 /* Check for error. */
224 if(status)
225 {
226 printf("ERROR!\n");
227 test_control_return(1);
228 }
229
230 /* Check for error. */
231 if((error_counter) || (fragmentation_counter))
232 {
233 printf("ERROR!\n");
234 test_control_return(1);
235 }
236 else
237 {
238
239 printf("SUCCESS!\n");
240 test_control_return(0);
241 }
242 }
243
my_packet_process(NX_IP * ip_ptr,NX_PACKET * packet_ptr,UINT * operation_ptr,UINT * delay_ptr)244 static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr)
245 {
246
247 /* Check if receive IPv6 fragmentation packet from ip_0, except NA and NS(IPv6(40) + NS/NA(32)). */
248 if ((ip_ptr == &ip_0) && (packet_ptr -> nx_packet_length > 72))
249 {
250
251 /* Updated the packet_counter. */
252 fragmentation_counter ++;
253 }
254
255 return NX_TRUE;
256 }
257
258 #else
259 extern void test_control_return(UINT status);
260
261 #ifdef CTEST
test_application_define(void * first_unused_memory)262 VOID test_application_define(void *first_unused_memory)
263 #else
264 void netx_ipv6_fragmentation_error_test2_application_define(void *first_unused_memory)
265 #endif
266 {
267
268 printf("NetX Test: IPv6 Fragmentation Error Test2............................N/A\n");
269 test_control_return(3);
270 }
271 #endif /* NX_DISABLE_FRAGMENTATION */
272