1 /* This is the test control routine the NetX TCP/IP stack.  All tests are dispatched from this routine.  */
2 #ifndef NX_CRYPTO_STANDALONE_ENABLE
3 #include "tx_api.h"
4 #include "nx_api.h"
5 #else
6 #include "nx_crypto_port.h"
7 #endif
8 #include <stdio.h>
9 #include "nx_crypto.h"
10 
11 #if defined(__linux__) && defined(USE_FORK)
12 #undef __suseconds_t_defined
13 #undef _STRUCT_TIMEVAL
14 #undef _SYS_SELECT_H
15 #include <unistd.h>
16 #include <signal.h>
17 #include <sys/wait.h>
18 #include <sys/poll.h>
19 
20 void fork_child();
21 #endif
22 
23 /*
24 #define NETXTEST_TIMEOUT_DISABLE
25 */
26 
27 #ifdef NX_CRYPTO_STANDALONE_ENABLE
28 #define tx_kernel_enter()  test_application_define(0);
29 #endif
30  FILE *stream;
31 
32 #define TEST_STACK_SIZE         4096
33 
34 #ifdef NX_CRYPTO_STANDALONE_ENABLE
35 #define NX_IP_PERIODIC_RATE  100
36 #endif
37 
38 /* 1 minute. */
39 #define TEST_TIMEOUT_LOW        (60 * NX_IP_PERIODIC_RATE)
40 /* 15 minutes. */
41 #define TEST_TIMEOUT_MID        (900 * NX_IP_PERIODIC_RATE)
42 /* 120 minutes. */
43 #define TEST_TIMEOUT_HIGH       (7200 * NX_IP_PERIODIC_RATE)
44 
45 /* Define the test control ThreadX objects...  */
46 #ifndef NX_CRYPTO_STANDALONE_ENABLE
47 TX_THREAD       test_control_thread;
48 #ifndef NETXTEST_TIMEOUT_DISABLE
49 TX_SEMAPHORE    test_control_sema;
50 #endif
51 #endif
52 
53 /* Define the test control global variables.   */
54 
55 ULONG           test_control_return_status;
56 ULONG           test_control_successful_tests;
57 ULONG           test_control_failed_tests;
58 ULONG           test_control_warning_tests;
59 ULONG           test_control_na_tests;
60 
61 /* Remember the start of free memory.  */
62 
63 UCHAR           *test_free_memory_ptr;
64 #ifndef NX_CRYPTO_STANDALONE_ENABLE
65 extern volatile UINT   _tx_thread_preempt_disable;
66 #endif
67 /* Define test entry pointer type.  */
68 
69 typedef  struct TEST_ENTRY_STRUCT
70 {
71     VOID        (*test_entry)(void *);
72     UINT        timeout;
73 } TEST_ENTRY;
74 
75 
76 /* Define the prototypes for the test entry points.  */
77 void nx_secure_3des_test_application_define(void *first_unused_memory);
78 void nx_secure_3des_error_checking_test_application_define(void *first_unused_memory);
79 void nx_secure_des_test_application_define(void *first_unused_memory);
80 void nx_secure_des_error_checking_test_application_define(void *first_unused_memory);
81 void nx_secure_drbg_test_application_define(void *first_unused_memory);
82 void nx_secure_ec_test_application_define(void *first_unused_memory);
83 void nx_secure_ec_additional_test_application_define(void *first_unused_memory);
84 void nx_secure_ecdh_test_application_define(void *first_unused_memory);
85 void nx_secure_ecdh_error_checking_test_application_define(void *first_unused_memory);
86 void nx_secure_ecdh_self_test_application_define(void *first_unused_memory);
87 void nx_secure_ecdsa_test_application_define(void *first_unused_memory);
88 void nx_secure_ecdsa_error_checking_test_application_define(void *first_unused_memory);
89 void nx_secure_ecjpake_self_test_application_define(void *first_unused_memory);
90 void nx_secure_aes_additional_test_application_define(void *first_unused_memory);
91 void nx_secure_sha_additional_test_application_define(void *first_unused_memory);
92 void nx_secure_sha256_test_application_define(void *);
93 void nx_secure_sha256_rfc_test_application_define(void *);
94 void nx_secure_sha384_test_application_define(void *);
95 void nx_secure_sha512_test_application_define(void *);
96 void nx_secure_hmac_md5_test_application_define(void *first_unused_memory);
97 void nx_secure_hmac_md5_error_checking_test_application_define(void *first_unused_memory);
98 void nx_secure_hmac_sha1_test_application_define(void *first_unused_memory);
99 void nx_secure_hmac_sha256_test_application_define(void *);
100 void nx_secure_hmac_sha384_test_application_define(void *);
101 void nx_secure_hmac_sha512_test_application_define(void *);
102 void nx_secure_huge_number_test_application_define(void *first_unused_memory);
103 void nx_secure_md5_test_application_define(void *first_unused_memory);
104 void nx_secure_rsa_test_application_define(void *);
105 void nx_secure_rsa_error_checking_test_application_define(void *);
106 void nx_secure_aes_test_application_define(void *first_unused_memory);
107 void nx_secure_aes_ccm_test_application_define(void *first_unused_memory);
108 void nx_secure_phash_prf_test_application_define(void *);
109 void nx_secure_pkcs1_v1_5_test_application_define(void *first_unused_memory);
110 void test_application_define(void *first_unused_memory);
111 
112 #define INCLUDE_TWO_WAY_TEST 1
113 
114 #ifdef NX_SECURE_TLS_CLIENT_DISABLED
115 #undef INCLUDE_TWO_WAY_TEST
116 #define INCLUDE_TWO_WAY_TEST 0
117 #endif
118 
119 #ifdef NX_SECURE_TLS_SERVER_DISABLED
120 #undef INCLUDE_TWO_WAY_TEST
121 #define INCLUDE_TWO_WAY_TEST 0
122 #endif
123 
124 /* Define the array of test entry points.  */
125 
126 TEST_ENTRY  test_control_tests[] =
127 {
128 
129 #ifdef CTEST
130     {test_application_define, TEST_TIMEOUT_HIGH},
131 #else /* CTEST */
132     /* Crypto test. */
133     {nx_secure_des_test_application_define, TEST_TIMEOUT_LOW},
134     {nx_secure_des_error_checking_test_application_define, TEST_TIMEOUT_LOW},
135     {nx_secure_drbg_test_application_define, TEST_TIMEOUT_LOW},
136     {nx_secure_ec_test_application_define, TEST_TIMEOUT_LOW},
137     {nx_secure_ec_additional_test_application_define, TEST_TIMEOUT_LOW},
138     {nx_secure_ecdh_test_application_define, TEST_TIMEOUT_LOW},
139     {nx_secure_ecdh_error_checking_test_application_define, TEST_TIMEOUT_LOW},
140     {nx_secure_ecdh_self_test_application_define, TEST_TIMEOUT_LOW},
141     {nx_secure_ecdsa_test_application_define, TEST_TIMEOUT_MID},
142     {nx_secure_ecdsa_error_checking_test_application_define, TEST_TIMEOUT_MID},
143     {nx_secure_ecjpake_self_test_application_define, TEST_TIMEOUT_MID},
144     {nx_secure_3des_test_application_define, TEST_TIMEOUT_LOW},
145     {nx_secure_3des_error_checking_test_application_define, TEST_TIMEOUT_LOW},
146     {nx_secure_sha256_test_application_define, TEST_TIMEOUT_LOW},
147     {nx_secure_sha256_rfc_test_application_define, TEST_TIMEOUT_LOW},
148     {nx_secure_sha384_test_application_define, TEST_TIMEOUT_LOW},
149     {nx_secure_sha512_test_application_define, TEST_TIMEOUT_LOW},
150     {nx_secure_sha_additional_test_application_define, TEST_TIMEOUT_LOW},
151     {nx_secure_hmac_md5_test_application_define, TEST_TIMEOUT_LOW},
152     {nx_secure_hmac_md5_error_checking_test_application_define, TEST_TIMEOUT_LOW},
153     {nx_secure_hmac_sha1_test_application_define, TEST_TIMEOUT_LOW},
154     {nx_secure_hmac_sha256_test_application_define, TEST_TIMEOUT_LOW},
155     {nx_secure_hmac_sha384_test_application_define, TEST_TIMEOUT_LOW},
156     {nx_secure_hmac_sha512_test_application_define, TEST_TIMEOUT_LOW},
157     {nx_secure_huge_number_test_application_define, TEST_TIMEOUT_LOW},
158     {nx_secure_md5_test_application_define, TEST_TIMEOUT_LOW},
159     {nx_secure_rsa_test_application_define, TEST_TIMEOUT_MID},
160     {nx_secure_rsa_error_checking_test_application_define, TEST_TIMEOUT_MID},
161     {nx_secure_aes_test_application_define, TEST_TIMEOUT_LOW},
162     {nx_secure_aes_additional_test_application_define, TEST_TIMEOUT_LOW},
163     {nx_secure_aes_ccm_test_application_define, TEST_TIMEOUT_LOW},
164     {nx_secure_phash_prf_test_application_define, TEST_TIMEOUT_LOW},
165     {nx_secure_pkcs1_v1_5_test_application_define, TEST_TIMEOUT_LOW},
166 #endif /* CTEST */
167     {NX_CRYPTO_NULL, TEST_TIMEOUT_LOW},
168 };
169 
170 /* Define thread prototypes.  */
171 
172 void  test_control_thread_entry(ULONG thread_input);
173 void  test_control_return(UINT status);
174 void  test_control_cleanup(void);
175 void  _nx_ram_network_driver_reset(void);
176 
177 /* Define necessary external references.  */
178 #ifndef NX_CRYPTO_STANDALONE_ENABLE
179 #ifdef __ghs
180 extern TX_MUTEX                 __ghLockMutex;
181 #endif
182 
183 extern TX_TIMER                 *_tx_timer_created_ptr;
184 extern ULONG                    _tx_timer_created_count;
185 #ifndef TX_TIMER_PROCESS_IN_ISR
186 extern TX_THREAD                _tx_timer_thread;
187 #endif
188 extern TX_THREAD                *_tx_thread_created_ptr;
189 extern ULONG                    _tx_thread_created_count;
190 extern TX_SEMAPHORE             *_tx_semaphore_created_ptr;
191 extern ULONG                    _tx_semaphore_created_count;
192 extern TX_QUEUE                 *_tx_queue_created_ptr;
193 extern ULONG                    _tx_queue_created_count;
194 extern TX_MUTEX                 *_tx_mutex_created_ptr;
195 extern ULONG                    _tx_mutex_created_count;
196 extern TX_EVENT_FLAGS_GROUP     *_tx_event_flags_created_ptr;
197 extern ULONG                    _tx_event_flags_created_count;
198 extern TX_BYTE_POOL             *_tx_byte_pool_created_ptr;
199 extern ULONG                    _tx_byte_pool_created_count;
200 extern TX_BLOCK_POOL            *_tx_block_pool_created_ptr;
201 extern ULONG                    _tx_block_pool_created_count;
202 
203 extern NX_PACKET_POOL *         _nx_packet_pool_created_ptr;
204 extern ULONG                    _nx_packet_pool_created_count;
205 extern NX_IP *                  _nx_ip_created_ptr;
206 extern ULONG                    _nx_ip_created_count;
207 #endif
208 
209 /* Define main entry point.  */
main()210 int main()
211 {
212 
213 #ifdef NX_CRYPTO_SELF_TEST
214     nx_crypto_initialize();
215 
216     _nx_crypto_method_self_test(0);
217 #endif
218 
219 #if 0
220     /* Reassign "stdout" to "freopen.out": */
221     stream = freopen( "test_result.txt", "w", stdout );
222 #endif
223 
224 #if defined(__linux__) && defined(USE_FORK)
225     fork_child();
226 #else
227 
228     /* Enter the ThreadX kernel or use the test_application_define mapped to tx_kernel_enter when NX_CRYPTO_STANDALONE_ENABLE  */
229     tx_kernel_enter();
230 
231 #endif
232 
233     return 0;
234 }
235 
236 #if defined(__linux__) && defined(USE_FORK)
237 static pid_t child_pid = -1;
238 static UINT test_index = 0;
239 static int result_fd[2];
240 
kill_child(int sig)241 void kill_child(int sig)
242 {
243 CHAR data[4]={0, 1, 0, 0};
244 
245     printf("killed by SIGALRM!\n");
246     fflush(stdout);
247     write(result_fd[1], data, sizeof(data));
248     exit(1);
249 }
250 
fork_child()251 void fork_child()
252 {
253 INT status;
254 CHAR data[4];
255 struct pollfd fds;
256 
257     while (test_control_tests[test_index].test_entry != NX_CRYPTO_NULL)
258     {
259 
260         /* Create pipe for communicating. */
261         pipe(result_fd);
262         fds.fd = result_fd[0];
263         fds.events=POLLIN | POLLOUT | POLLERR;
264 
265         /* Fork test process. */
266         child_pid = fork();
267         if (child_pid > 0)
268         {
269             wait(&status);
270             poll(&fds, 1, 0);
271             if (fds.revents & POLLIN)
272             {
273                 read(result_fd[0], data, sizeof(data));
274                 test_control_successful_tests += (ULONG)data[0];
275                 test_control_failed_tests += (ULONG)data[1];
276                 test_control_warning_tests += (ULONG)data[2];
277                 test_control_na_tests += (ULONG)data[3];
278             }
279             else
280             {
281 
282                 /* The child process crashes. */
283                 printf("ERROR!\n");
284                 test_control_failed_tests++;
285             }
286 
287             fflush(stdout);
288 
289             test_index++;
290         }
291         else
292         {
293 
294             /* Setup SIGALRM callback function. */
295             signal(SIGALRM, (void (*)(int))kill_child);
296 
297             /* Initialize the results. */
298             test_control_successful_tests = 0;
299             test_control_failed_tests = 0;
300             test_control_warning_tests = 0;
301             test_control_na_tests = 0;
302 
303             /* Setup timeout alarm. */
304             alarm(test_control_tests[test_index].timeout / NX_IP_PERIODIC_RATE);
305 
306             /* Enter the ThreadX kernel.  */
307             tx_kernel_enter();
308             return;
309         }
310     }
311 
312     /* Finished with all tests, print results and return!  */
313     printf("**** Testing Complete ****\n");
314     printf("**** Test Summary:  Tests Passed:  %lu   Tests Warning:  %lu   Tests Failed:  %lu\n", test_control_successful_tests, test_control_warning_tests, test_control_failed_tests);
315 #ifdef BATCH_TEST
316     exit(test_control_failed_tests);
317 #endif
318 }
319 
320 /* Define what the initial system looks like.  */
321 
tx_application_define(void * first_unused_memory)322 void    tx_application_define(void *first_unused_memory)
323 {
324 
325     /* Dispatch the test.  */
326     (test_control_tests[test_index].test_entry)(first_unused_memory);
327 }
328 
test_control_return(UINT status)329 void  test_control_return(UINT status)
330 {
331 UINT    old_posture = TX_INT_ENABLE;
332 INT     exit_code = status;
333 CHAR    data[4];
334 
335     fflush(stdout);
336 
337     /* Initialize result through pipe. */
338     data[0] = (CHAR)test_control_successful_tests;
339     data[1] = (CHAR)test_control_failed_tests;
340     data[2] = (CHAR)test_control_warning_tests;
341     data[3] = (CHAR)test_control_na_tests;
342 
343     /* Save the status in a global.  */
344     test_control_return_status = status;
345 
346     /* Ensure interrupts are enabled.  */
347     old_posture = tx_interrupt_control(TX_INT_ENABLE);
348 
349     /* Determine if it was successful or not.  */
350     if((status == 1) || (_tx_thread_preempt_disable) || (old_posture == TX_INT_DISABLE))
351     {
352         data[1]++;
353         exit_code = 1;
354     }
355     else if(status == 2)
356     {
357         data[2]++;
358         exit_code = 2;
359     }
360     else if(status == 0)
361     {
362         data[0]++;
363         exit_code = 0;
364     }
365     else if(status == 3)
366     {
367         data[3]++;
368         exit_code = 3;
369     }
370 
371     /* Send result through pipe. */
372     write(result_fd[1], data, sizeof(data));
373     exit(exit_code);
374 }
375 
376 #else
377 /* Define what the initial system looks like.  */
378 
tx_application_define(void * first_unused_memory)379 void    tx_application_define(void *first_unused_memory)
380 {
381     UCHAR    *pointer;
382 
383     /* Setup a pointer to the first unused memory.  */
384     pointer = (UCHAR *)   first_unused_memory;
385 
386 #ifndef NX_CRYPTO_STANDALONE_ENABLE
387     /* Create the test control thread.  */
388     tx_thread_create(&test_control_thread, "test control thread", test_control_thread_entry, 0,
389         pointer, TEST_STACK_SIZE,
390         0, 0, TX_NO_TIME_SLICE, TX_AUTO_START);
391 #else
392     test_control_thread_entry(0);
393 #endif
394 
395     pointer = pointer + TEST_STACK_SIZE;
396 
397 #ifndef NX_CRYPTO_STANDALONE_ENABLE
398 #ifndef NETXTEST_TIMEOUT_DISABLE
399     /* Create the test control semaphore.  */
400     tx_semaphore_create(&test_control_sema, "Test control semaphore", 0);
401 #endif
402 #endif
403 
404     /* Remember the free memory pointer.  */
405     test_free_memory_ptr = pointer;
406 }
407 
408 /* Define the test control thread.  This thread is responsible for dispatching all of the
409 tests in the ThreadX test suite.  */
410 
test_control_thread_entry(ULONG thread_input)411 void  test_control_thread_entry(ULONG thread_input)
412 {
413     UINT    i;
414 
415     /* Loop to process all tests...  */
416     i = 0;
417     while (test_control_tests[i].test_entry != NX_CRYPTO_NULL)
418     {
419 
420         /* Dispatch the test.  */
421         (test_control_tests[i++].test_entry)(test_free_memory_ptr);
422 
423         if (test_control_return_status != 3)
424         {
425 #ifndef NX_CRYPTO_STANDALONE_ENABLE
426 #ifdef NETXTEST_TIMEOUT_DISABLE
427             /* Suspend control test to allow test to run.  */
428             tx_thread_suspend(&test_control_thread);
429 #else
430             if(tx_semaphore_get(&test_control_sema, test_control_tests[i - 1].timeout))
431             {
432 
433                 /* Test case timeouts. */
434                 printf("ERROR!\n");
435                 test_control_failed_tests++;
436 
437             }
438 #endif
439 #endif
440         }
441         else
442             test_control_return_status = 0;
443 
444         /* Test finished, cleanup in preparation for the next test.  */
445         test_control_cleanup();
446         fflush(stdout);
447     }
448 
449     /* Finished with all tests, print results and return!  */
450     printf("**** Testing Complete ****\n");
451     printf("**** Test Summary:  Tests Passed:  %lu   Tests Warning:  %lu   Tests Failed:  %lu\n", test_control_successful_tests, test_control_warning_tests, test_control_failed_tests);
452 #if 0
453     fclose(stream);
454 #endif
455 #ifdef BATCH_TEST
456     exit(test_control_failed_tests);
457 #endif
458 
459 }
460 
test_control_return(UINT status)461 void  test_control_return(UINT status)
462 {
463 #ifndef NX_CRYPTO_STANDALONE_ENABLE
464     UINT    old_posture = TX_INT_ENABLE;
465 #endif
466 
467     /* Save the status in a global.  */
468     test_control_return_status = status;
469 #ifndef NX_CRYPTO_STANDALONE_ENABLE
470     /* Ensure interrupts are enabled.  */
471     old_posture = tx_interrupt_control(TX_INT_ENABLE);
472 #endif
473 
474     /* Determine if it was successful or not.  */
475 #ifndef NX_CRYPTO_STANDALONE_ENABLE
476     if((status == 1) || (_tx_thread_preempt_disable) || (old_posture == TX_INT_DISABLE))
477 #else
478     if(status == 1)
479 #endif
480         test_control_failed_tests++;
481     else if(status == 2)
482         test_control_warning_tests++;
483     else if(status == 0)
484         test_control_successful_tests++;
485     else if(status == 3)
486         test_control_na_tests++;
487 #ifndef NX_CRYPTO_STANDALONE_ENABLE
488 #ifdef NETXTEST_TIMEOUT_DISABLE
489     /* Resume the control thread to fully exit the test.  */
490     tx_thread_resume(&test_control_thread);
491 #else
492     if(test_control_return_status != 3)
493         tx_semaphore_put(&test_control_sema);
494 #endif
495 #endif
496 }
497 
test_control_cleanup(void)498 void  test_control_cleanup(void)
499 {
500 #ifndef NX_CRYPTO_STANDALONE_ENABLE
501     TX_MUTEX        *mutex_ptr;
502     TX_THREAD       *thread_ptr;
503 
504     /* Delete all queues.  */
505     while(_tx_queue_created_ptr)
506     {
507 
508         /* Delete queue.  */
509         tx_queue_delete(_tx_queue_created_ptr);
510     }
511 
512     /* Delete all semaphores.  */
513     while(_tx_semaphore_created_ptr)
514     {
515 #ifndef NETXTEST_TIMEOUT_DISABLE
516         if(_tx_semaphore_created_ptr != &test_control_sema)
517         {
518 
519             /* Delete semaphore.  */
520             tx_semaphore_delete(_tx_semaphore_created_ptr);
521         }
522         else if(_tx_semaphore_created_count == 1)
523             break;
524         else
525         {
526             /* Delete semaphore.  */
527             tx_semaphore_delete(_tx_semaphore_created_ptr -> tx_semaphore_created_next);
528         }
529 #else
530         /* Delete semaphore.  */
531         tx_semaphore_delete(_tx_semaphore_created_ptr);
532 #endif
533     }
534 
535     /* Delete all event flag groups.  */
536     while(_tx_event_flags_created_ptr)
537     {
538 
539         /* Delete event flag group.  */
540         tx_event_flags_delete(_tx_event_flags_created_ptr);
541     }
542 
543     /* Delete all byte pools.  */
544     while(_tx_byte_pool_created_ptr)
545     {
546 
547         /* Delete byte pool.  */
548         tx_byte_pool_delete(_tx_byte_pool_created_ptr);
549     }
550 
551     /* Delete all block pools.  */
552     while(_tx_block_pool_created_ptr)
553     {
554 
555         /* Delete block pool.  */
556         tx_block_pool_delete(_tx_block_pool_created_ptr);
557     }
558 
559     /* Delete all timers.  */
560     while(_tx_timer_created_ptr)
561     {
562 
563         /* Deactivate timer.  */
564         tx_timer_deactivate(_tx_timer_created_ptr);
565 
566         /* Delete timer.  */
567         tx_timer_delete(_tx_timer_created_ptr);
568     }
569 
570     /* Delete all mutexes (except for system mutex).  */
571     while(_tx_mutex_created_ptr)
572     {
573 
574         /* Setup working mutex pointer.  */
575         mutex_ptr = _tx_mutex_created_ptr;
576 
577 #ifdef __ghs
578 
579         /* Determine if the mutex is the GHS system mutex.  If so, don't delete!  */
580         if(mutex_ptr == &__ghLockMutex)
581         {
582 
583             /* Move to next mutex.  */
584             mutex_ptr = mutex_ptr -> tx_mutex_created_next;
585         }
586 
587         /* Determine if there are no more mutexes to delete.  */
588         if(_tx_mutex_created_count == 1)
589             break;
590 #endif
591 
592         /* Delete mutex.  */
593         tx_mutex_delete(mutex_ptr);
594     }
595 
596     /* Delete all threads, except for timer thread, and test control thread.  */
597     while (_tx_thread_created_ptr)
598     {
599 
600         /* Setup working pointer.  */
601         thread_ptr = _tx_thread_created_ptr;
602 
603 #ifdef TX_TIMER_PROCESS_IN_ISR
604 
605         /* Determine if there are more threads to delete.  */
606         if(_tx_thread_created_count == 1)
607             break;
608 
609         /* Determine if this thread is the test control thread.  */
610         if(thread_ptr == &test_control_thread)
611         {
612 
613             /* Move to the next thread pointer.  */
614             thread_ptr = thread_ptr -> tx_thread_created_next;
615         }
616 #else
617 
618         /* Determine if there are more threads to delete.  */
619         if(_tx_thread_created_count == 2)
620             break;
621 
622         /* Move to the thread not protected.  */
623         while ((thread_ptr == &_tx_timer_thread) || (thread_ptr == &test_control_thread))
624         {
625 
626             /* Yes, move to the next thread.  */
627             thread_ptr = thread_ptr -> tx_thread_created_next;
628         }
629 #endif
630 
631         /* First terminate the thread to ensure it is ready for deletion.  */
632         tx_thread_terminate(thread_ptr);
633 
634         /* Delete the thread.  */
635         tx_thread_delete(thread_ptr);
636     }
637 #endif
638 
639     /* At this point, only the test control thread and the system timer thread and/or mutex should still be
640     in the system.  */
641 
642 #ifdef NX_PCAP_ENABLE
643     /* Close the pcap file.  */
644     close_pcap_file();
645 #endif
646 }
647 #endif
648