1 /* This NetX test reading overflow when processing abnormal packet.  */
2 
3 /* Invalid name string */
4 static unsigned char invalid_response_0[] = {
5 0x1C, 0x1A, 0xDF, 0xB0, 0x2F, 0x0A, 0x74, 0xB6,
6 0xB6, 0x40, 0x93, 0x2D, 0x08, 0x00, 0x45, 0x00,
7 0x00, 0x69, 0x72, 0x5D, 0x00, 0x00, 0x40, 0x11,
8 0x80, 0xA6, 0xC0, 0xA8, 0x01, 0xFE, 0xC0, 0xA8,
9 0x04, 0x32, 0x00, 0x35, 0xC8, 0xE1, 0x00, 0x55,
10 0x4C, 0x59, 0x88, 0xCC, 0x81, 0x80, 0x00, 0x01,
11 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0x63,
12 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x73, 0x34, 0x06,
13 0x67, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x03, 0x63,
14 0x6F, 0x6D, 0x00, 0x00, 0x01, 0x00, 0x01, 0xC0,
15 0x0C, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00,
16 0xC3, 0x00, 0x0C, 0x37, 0x63, 0x6C, 0x69, 0x65,
17 0x6E, 0x74, 0x73, 0x01, 0x6C, 0xC0, 0x15, 0xC0,
18 0x31, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01,
19 0x2C, 0x00, 0x04, 0xAC, 0xD9, 0x03, 0xCE
20 };
21 
22 /* Invalid name string */
23 static unsigned char invalid_response_1[] = {
24 0x1C, 0x1A, 0xDF, 0xB0, 0x2F, 0x0A, 0x74, 0xB6,
25 0xB6, 0x40, 0x93, 0x2D, 0x08, 0x00, 0x45, 0x00,
26 0x00, 0x69, 0x72, 0x5D, 0x00, 0x00, 0x40, 0x11,
27 0x80, 0xA6, 0xC0, 0xA8, 0x01, 0xFE, 0xC0, 0xA8,
28 0x04, 0x32, 0x00, 0x35, 0xC8, 0xE1, 0x00, 0x55,
29 0x4C, 0x59, 0x88, 0xCC, 0x81, 0x80, 0x00, 0x01,
30 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0x63,
31 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x73, 0x34, 0x06,
32 0x67, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x03, 0x63,
33 0x6F, 0x6D, 0x00, 0x00, 0x01, 0x00, 0x01, 0xC0,
34 0x0C, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00,
35 0xC3, 0x00, 0x0C, 0x37, 0x63, 0x6C, 0x69, 0x65,
36 0x6E, 0x74, 0x73, 0x01, 0x6C, 0xC0, 0x15, 0xC0,
37 0x4C, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01,
38 0x2C, 0x00, 0x04, 0xAC, 0xD9, 0x03, 0xC0
39 };
40 
41 /* Invalid name string */
42 static unsigned char invalid_response_2[] = {
43 0x1C, 0x1A, 0xDF, 0xB0, 0x2F, 0x0A, 0x74, 0xB6,
44 0xB6, 0x40, 0x93, 0x2D, 0x08, 0x00, 0x45, 0x00,
45 0x00, 0x69, 0x72, 0x5D, 0x00, 0x00, 0x40, 0x11,
46 0x80, 0xA6, 0xC0, 0xA8, 0x01, 0xFE, 0xC0, 0xA8,
47 0x04, 0x32, 0x00, 0x35, 0xC8, 0xE1, 0x00, 0x55,
48 0x4C, 0x59, 0x88, 0xCC, 0x81, 0x80, 0x00, 0x01,
49 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0x63,
50 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x73, 0x34, 0x06,
51 0x67, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x03, 0x63,
52 0x6F, 0x6D, 0x00, 0x00, 0x01, 0x00, 0x01, 0xC0,
53 0x0C, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00,
54 0xC3, 0x00, 0x0C, 0x37, 0x63, 0x6C, 0x69, 0x65,
55 0x6E, 0x74, 0x73, 0x01, 0x6C, 0xC0, 0x15, 0xC0,
56 0x4B, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01,
57 0x2C, 0x00, 0x04, 0xAC, 0xD9, 0x01, 0x01
58 };
59 
60 /* Invalid IP address */
61 static unsigned char invalid_response_3[] =
62 {
63 0x1C, 0x1A, 0xDF, 0xB0, 0x2F, 0x0A, 0x74, 0xB6,
64 0xB6, 0x40, 0x93, 0x2D, 0x08, 0x00, 0x45, 0x00,
65 0x00, 0x69, 0x72, 0x5D, 0x00, 0x00, 0x40, 0x11,
66 0x80, 0xA6, 0xC0, 0xA8, 0x01, 0xFE, 0xC0, 0xA8,
67 0x04, 0x32, 0x00, 0x35, 0xC8, 0xE1, 0x00, 0x55,
68 0x4C, 0x59, 0x88, 0xCC, 0x81, 0x80, 0x00, 0x01,
69 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0x63,
70 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x73, 0x34, 0x06,
71 0x67, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x03, 0x63,
72 0x6F, 0x6D, 0x00, 0x00, 0x01, 0x00, 0x01, 0xC0,
73 0x0C, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00,
74 0xC3, 0x00, 0x0C, 0x07, 0x63, 0x6C, 0x69, 0x65,
75 0x6E, 0x74, 0x73, 0x01, 0x6C, 0xC0, 0x15, 0xC0,
76 0x31, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01,
77 0x2C, 0x00, 0x04, 0xAC, 0xD9, 0x03
78 };
79 
80 /* Valid response */
81 static unsigned char valid_response[] =
82 {
83 0x1C, 0x1A, 0xDF, 0xB0, 0x2F, 0x0A, 0x74, 0xB6,
84 0xB6, 0x40, 0x93, 0x2D, 0x08, 0x00, 0x45, 0x00,
85 0x00, 0x69, 0x72, 0x5D, 0x00, 0x00, 0x40, 0x11,
86 0x80, 0xA6, 0xC0, 0xA8, 0x01, 0xFE, 0xC0, 0xA8,
87 0x04, 0x32, 0x00, 0x35, 0xC8, 0xE1, 0x00, 0x55,
88 0x4C, 0x59, 0x88, 0xCC, 0x81, 0x80, 0x00, 0x01,
89 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0x63,
90 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x73, 0x34, 0x06,
91 0x67, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x03, 0x63,
92 0x6F, 0x6D, 0x00, 0x00, 0x01, 0x00, 0x01, 0xC0,
93 0x0C, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00,
94 0xC3, 0x00, 0x0C, 0x07, 0x63, 0x6C, 0x69, 0x65,
95 0x6E, 0x74, 0x73, 0x01, 0x6C, 0xC0, 0x15, 0xC0,
96 0x31, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01,
97 0x2C, 0x00, 0x04, 0xAC, 0xD9, 0x03, 0xCE
98 };
99 
100 static unsigned char invalid_response_txt[] =
101 {
102 0x18, 0x03, 0x73, 0x33, 0xc1, 0xbd, 0xc8, 0x3a,
103 0x35, 0x60, 0x4b, 0x46, 0x08, 0x00, 0x45, 0x00,
104 0x00, 0x96, 0xc1, 0xa0, 0x00, 0x00, 0x40, 0x11,
105 0x36, 0xfc, 0xc0, 0xa8, 0x00, 0x01, 0xc0, 0xa8,
106 0x00, 0x69, 0x00, 0x35, 0xc1, 0x8b, 0x00, 0x82,
107 0xec, 0x71, 0x00, 0x02, 0x81, 0x80, 0x00, 0x01,
108 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x67,
109 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f,
110 0x6d, 0x00, 0x00, 0x10, 0x00, 0x01, 0xc0, 0x0c,
111 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10,
112 0x00, 0x52, 0x52, 0x76, 0x3d, 0x73, 0x70, 0x66,
113 0x31, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64,
114 0x65, 0x3a, 0x5f, 0x6e, 0x65, 0x74, 0x62, 0x6c,
115 0x6f, 0x63, 0x6b, 0x73, 0x2e, 0x67, 0x6f, 0x6f,
116 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x20,
117 0x69, 0x70, 0x34, 0x3a, 0x32, 0x31, 0x36, 0x2e,
118 0x37, 0x33, 0x2e, 0x39, 0x33, 0x2e, 0x37, 0x30,
119 0x2f, 0x33, 0x31, 0x20, 0x69, 0x70, 0x34, 0x3a,
120 0x32, 0x31, 0x36, 0x2e, 0x37, 0x33, 0x2e, 0x39,
121 0x33, 0x2e, 0x37, 0x32, 0x2f, 0x33, 0x31, 0x20,
122 0x7e, 0x61, 0x6c, 0x6c
123 };
124 
125 
126 #include   "tx_api.h"
127 #include   "nx_api.h"
128 #include   "nx_udp.h"
129 #include   "nxd_dns.h"
130 #include   "nx_ram_network_driver_test_1500.h"
131 
132 extern void    test_control_return(UINT status);
133 #if !defined(NX_DISABLE_IPV4)
134 
135 #define     DEMO_STACK_SIZE         2048
136 
137 
138 /* Define the ThreadX and NetX object control blocks...  */
139 
140 static TX_THREAD               thread_0;
141 static TX_THREAD               thread_1;
142 
143 static NX_PACKET_POOL          pool_0;
144 static NX_IP                   client_ip;
145 static NX_IP                   server_ip;
146 
147 static NX_UDP_SOCKET           server_socket;
148 static NX_DNS                  client_dns;
149 
150 
151 #ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL
152 NX_PACKET_POOL                 client_pool;
153 #endif
154 
155 static UCHAR                   pool_buffer[8192] = {0};
156 static UCHAR                   record_buffer[500];
157 
158 /* Define the counters used in the demo application...  */
159 
160 static UINT                    status;
161 static ULONG                   error_counter;
162 
163 /* Define thread prototypes.  */
164 
165 static void    thread_0_entry(ULONG thread_input);
166 static void    thread_1_entry(ULONG thread_input);
167 extern void    _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req);
168 
169 #define        DNS_START_OFFSET (14 + 20 + 8)
170 
171 /* Define what the initial system looks like.  */
172 
173 #ifdef CTEST
test_application_define(void * first_unused_memory)174 VOID test_application_define(void *first_unused_memory)
175 #else
176 void    netx_dns_abnormal_packet_test_application_define(void *first_unused_memory)
177 #endif
178 {
179 
180 CHAR    *pointer;
181 
182     /* Setup the working pointer.  */
183     pointer =  (CHAR *) first_unused_memory;
184 
185     /* Create the DNS main thread.  */
186     tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
187             pointer, DEMO_STACK_SIZE,
188             4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
189     pointer =  pointer + DEMO_STACK_SIZE;
190 
191     /* .  */
192     tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0,
193             pointer, DEMO_STACK_SIZE,
194             3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
195     pointer =  pointer + DEMO_STACK_SIZE;
196 
197     /* Initialize the NetX system.  */
198     nx_system_initialize();
199 
200     /* Create a packet pool.  */
201     status =  nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1500, pool_buffer, 8192);
202 
203 #ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL
204 
205     /* Create the packet pool for the DNS Client to send packets.
206 
207         If the DNS Client is configured for letting the host application create
208         the DNS packet pool, (see NX_DNS_CLIENT_USER_CREATE_PACKET_POOL option), see
209        nx_dns_create() for guidelines on packet payload size and pool size.
210        packet traffic for NetX Duo processes.
211     */
212     status =  nx_packet_pool_create(&client_pool, "DNS Client Packet Pool", NX_DNS_PACKET_PAYLOAD, pointer, NX_DNS_PACKET_POOL_SIZE);
213 
214     pointer = pointer + NX_DNS_PACKET_POOL_SIZE;
215 
216     /* Check for pool creation error.  */
217     if (status)
218         return;
219 #endif
220 
221     /* Check for pool creation error.  */
222     if (status)
223         error_counter++;
224 
225     /* Create an IP instance.  */
226     status = nx_ip_create(&client_ip, "NetX IP Instance 0", IP_ADDRESS(192, 168, 100, 98), 0xFFFF0000UL, &pool_0, _nx_ram_network_driver_512,
227                     pointer, 2048, 1);
228     pointer =  pointer + 2048;
229 
230     /* Create another IP instance.  */
231     status += nx_ip_create(&server_ip, "NetX IP Instance 1", IP_ADDRESS(192, 168, 100, 2), 0xFFFF0000UL, &pool_0, _nx_ram_network_driver_512,
232                     pointer, 2048, 1);
233     pointer =  pointer + 2048;
234 
235     /* Check for IP create errors.  */
236     if (status)
237         error_counter++;
238 
239     /* Enable ARP and supply ARP cache memory for IP Instance 0.  */
240     status =  nx_arp_enable(&client_ip, (void *) pointer, 1024);
241     pointer = pointer + 1024;
242 
243     /* Enable ARP and supply ARP cache memory for IP Instance 1.  */
244     status +=  nx_arp_enable(&server_ip, (void *) pointer, 1024);
245     pointer = pointer + 1024;
246 
247     /* Check for ARP enable errors.  */
248     if (status)
249         error_counter++;
250 
251     /* Enable UDP traffic.  */
252     status =  nx_udp_enable(&client_ip);
253     status += nx_udp_enable(&server_ip);
254 
255     /* Check for UDP enable errors.  */
256     if (status)
257         error_counter++;
258 }
259 
260 
261 
262 /* Define the test threads.  */
263 
thread_0_entry(ULONG thread_input)264 static void    thread_0_entry(ULONG thread_input)
265 {
266 ULONG       host_ip_address;
267 UINT        i;
268 UINT        test_num;
269 
270     /* Print out some test information banners.  */
271     printf("NetX Test:   DNS Abnormal Packet Test..................................");
272 
273     /* Check for earlier error.  */
274     if(error_counter)
275     {
276         printf("ERROR!\n");
277         test_control_return(1);
278     }
279 
280     /* Create a DNS instance for the Client.  Note this function will create
281        the DNS Client packet pool for creating DNS message packets intended
282        for querying its DNS server. */
283     status =  nx_dns_create(&client_dns, &client_ip, (UCHAR *)"DNS Client");
284 
285     /* Check status.  */
286     if(status)
287     {
288         printf("ERROR!\n");
289         test_control_return(1);
290     }
291 
292     /* Is the DNS client configured for the host application to create the pecket pool? */
293 #ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL
294 
295     /* Yes, use the packet pool created above which has appropriate payload size
296        for DNS messages. */
297      status = nx_dns_packet_pool_set(&client_dns, &client_pool);
298 
299      /* Check for set DNS packet pool error.  */
300     if(status)
301     {
302         printf("ERROR!\n");
303         test_control_return(1);
304     }
305 
306 #endif /* NX_DNS_CLIENT_USER_CREATE_PACKET_POOL */
307 
308     /* Add an IPv4 server address to the Client list. */
309     status = nx_dns_server_add(&client_dns, IP_ADDRESS(192, 168, 100, 2));
310 
311     /* Check status.  */
312     if(status)
313     {
314         printf("ERROR!\n");
315         test_control_return(1);
316     }
317 
318     client_dns.nx_dns_retries = 1;
319 
320 #ifdef NX_DNS_CACHE_ENABLE
321     test_num = 4;
322 #else
323     test_num = 1;
324 #endif
325 
326     for (i = 0; i < test_num; i++)
327     {
328         status = nx_dns_host_by_name_get(&client_dns, (UCHAR *)"berkeley.edu", &host_ip_address, NX_IP_PERIODIC_RATE);
329 
330         /* Check status.  */
331         if(status == NX_SUCCESS)
332         {
333             error_counter++;
334         }
335     }
336 
337 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
338     status = nx_dns_host_text_get(&client_dns, (UCHAR *)"google.com", &record_buffer[0], sizeof(record_buffer), NX_IP_PERIODIC_RATE);
339 
340     /* Check status.  */
341     if(status == NX_SUCCESS)
342     {
343         error_counter++;
344     }
345 #endif
346 
347     /* Determine if the test was successful.  */
348     if(error_counter)
349     {
350         printf("ERROR!\n");
351         test_control_return(1);
352     }
353     else
354     {
355         printf("SUCCESS!\n");
356         test_control_return(0);
357     }
358 }
359 
360 
thread_1_entry(ULONG thread_input)361 static void    thread_1_entry(ULONG thread_input)
362 {
363 
364 NX_PACKET   *my_packet;
365 UINT        port;
366 USHORT      nx_dns_transmit_id;
367 UCHAR       *data_ptr;
368 NX_PACKET   *response_packet;
369 UCHAR       *invalid_responses[] =
370 {
371 #ifdef NX_DNS_CACHE_ENABLE
372     invalid_response_0,
373     invalid_response_1,
374     invalid_response_2,
375 #endif
376     invalid_response_3,
377 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
378     invalid_response_txt,
379 #endif
380 };
381 UINT       invalid_responses_len[] =
382 {
383 #ifdef NX_DNS_CACHE_ENABLE
384     sizeof(invalid_response_0),
385     sizeof(invalid_response_1),
386     sizeof(invalid_response_2),
387 #endif
388     sizeof(invalid_response_3),
389 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
390     sizeof(invalid_response_txt),
391 #endif
392 };
393 UCHAR       *response_ptr;
394 UINT        response_len;
395 UINT        i;
396 UINT        test_num = sizeof(invalid_responses_len) / sizeof(UINT);
397 
398     /* Create a UDP socket act as the DNS server.  */
399     status = nx_udp_socket_create(&server_ip, &server_socket, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5);
400 
401     /* Check status.  */
402     if (status)
403     {
404         error_counter++;
405     }
406 
407     /* Bind the UDP socket to the IP port.  */
408     status =  nx_udp_socket_bind(&server_socket, 53, TX_WAIT_FOREVER);
409 
410 
411     /* Act as the DNS server to receive the DNS query and send the DNS response.  */
412 
413     for (i = 0; i < test_num; i ++)
414     {
415 
416         /* Receive a UDP packet.  */
417         status = nx_udp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE);
418 
419         /* Check status.  */
420         if (status)
421         {
422             error_counter++;
423             return;
424         }
425 
426         /* Get the DNS client UDP port.  */
427         status = nx_udp_packet_info_extract(my_packet, NX_NULL, NX_NULL, &port, NX_NULL);
428 
429         /* Check status.  */
430         if (status)
431         {
432             error_counter++;
433             return;
434         }
435 
436         /* Get the DNS transmit ID.  */
437         if (i == 1)
438         {
439             client_dns.nx_dns_transmit_id = 0xc00c;
440             nx_dns_transmit_id = client_dns.nx_dns_transmit_id;
441         }
442         else
443         {
444             data_ptr = my_packet -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET;
445             nx_dns_transmit_id = *data_ptr++;
446             nx_dns_transmit_id = (USHORT)((nx_dns_transmit_id << 8) | *data_ptr);
447         }
448 
449 
450         /* Release the packet.  */
451         nx_packet_release(my_packet);
452 
453         /* Send the DNS response packet.  */
454         /* Allocate a response packet.  */
455         status =  nx_packet_allocate(&pool_0, &response_packet, NX_UDP_PACKET, TX_WAIT_FOREVER);
456 
457         /* Check status.  */
458         if (status)
459         {
460             error_counter++;
461             return;
462         }
463 
464         response_ptr = invalid_responses[i];
465         response_len = invalid_responses_len[i];
466 
467         /* Write the DNS response messages into the packet payload!  */
468         memcpy(response_packet -> nx_packet_prepend_ptr, response_ptr + DNS_START_OFFSET, response_len - DNS_START_OFFSET);
469 
470         /* Adjust the write pointer.  */
471         response_packet -> nx_packet_length =  response_len - DNS_START_OFFSET;
472         response_packet -> nx_packet_append_ptr =  response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length;
473 
474         /* Update the DNS transmit ID.  */
475         data_ptr = response_packet -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET;
476         *data_ptr++ = (UCHAR)(nx_dns_transmit_id >> 8);
477         *data_ptr = (UCHAR)nx_dns_transmit_id;
478 
479         /* Send the UDP packet with the correct port.  */
480         status =  nx_udp_socket_send(&server_socket, response_packet, IP_ADDRESS(192, 168, 100, 98), port);
481 
482         /* Check the status.  */
483         if (status)
484         {
485             error_counter++;
486             nx_packet_release(response_packet);
487             return;
488         }
489     }
490 
491     /* Unbind the UDP socket.  */
492     status =  nx_udp_socket_unbind(&server_socket);
493 
494     /* Check status.  */
495     if (status)
496     {
497         error_counter++;
498         return;
499     }
500 
501     /* Delete the UDP socket.  */
502     status =  nx_udp_socket_delete(&server_socket);
503 
504     /* Check status.  */
505     if (status)
506     {
507         error_counter++;
508         return;
509     }
510 
511     /* Let the DNS threads execute.    */
512     tx_thread_relinquish();
513 }
514 #else
515 
516 #ifdef CTEST
test_application_define(void * first_unused_memory)517 VOID test_application_define(void *first_unused_memory)
518 #else
519 void    netx_dns_abnormal_packet_test_application_define(void *first_unused_memory)
520 #endif
521 
522 {
523 
524     /* Print out test information banner.  */
525     printf("NetX Test:   DNS Abnormal Packet Test..................................N/A\n");
526     test_control_return(3);
527 
528 }
529 #endif
530