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